Bug 868662
Summary: | /lib/ld64.so.1: bad ELF Interpreter: No such file or directory | ||
---|---|---|---|
Product: | [Fedora] Fedora | Reporter: | tim <tim> |
Component: | binutils | Assignee: | Nick Clifton <nickc> |
Status: | CLOSED NOTABUG | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
Severity: | low | Docs Contact: | |
Priority: | unspecified | ||
Version: | 17 | CC: | jakub, nickc |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | x86_64 | ||
OS: | Unspecified | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2012-10-27 06:54:45 UTC | Type: | Bug |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
tim
2012-10-21 14:19:29 UTC
Hi Tim, > When I use > ld hello.o -o hello -lc Generally speaking this is a bad idea. Unless you are really confident with using the linker it is a better idea to let gcc create the linker command line for you. Ie: gcc -nostartfiles hello.o -o hello -lc > Now perhaps this was intended and I was supposed to use this anyway, > but I was wondering why ld uses /lib/ld64.so.1 as default if that > file doesn't exist (or at least it doesn't seem to exist in fedora > 17). That's the reason. The default is setup for a generic system not Fedora. > Shouldn't it use /lib64/ld-2.15.so by default if no other linker is > specified? Only if that interpreter exists. On Fedora 15 for example interpreter would be /lib64/ld-2.14.so. This is why using gcc to drive the linker is usually the best idea. I take your point however that the default interpreter could be made release specific, changing with each release as necessary. But that seems like a lot of hassle to me. If you are trying to drive the linker directly, then you should be able to choose the correct interpreter for yourself and not have to rely upon builtin defaults. Cheers Nick I think nothing should change in binutils, this is a clear user error. ld shouldn't be used directly if people don't know what they are doing. Hi.. Thanks for the replies.
I'm not suggesting a change to binutils. Or not a big one anyway.. But look at the bigger picture. Isn't it possible to symlink /lib/ld64.so.1 to /lib64/ld-2.15.so so that the default setting would still work? As I understand, dynamic libraries use the same approach so that applications may be compiled against somelib.1.2 and use everything from 1.2.0.0 to 1.2.99.999 as long as the system on which they run has the symlink for somelib.1.2 linked to the right version (provided some version of that lib doesn't break compatibility of course)
Jakub: I understand why you say that people shouldn't use ld if they don't know what they're doing, but if no one would ever experiment with it once in a while, who are we going to ask in the future when we need an expert on the subject? I suppose that you learned a thing or two through experimenting.. :)
I agree it was (even kinda obviously) a user error. But I don't want to use gcc like the rest of the plebs because I'm writing a compiler and so I'd like to learn as much as I can about ld and stuff around it. Could be I'm using the wrong approach and I should link my compiler with a library that implements the linker (perhaps that same ld-2.15.so?) so that my program can produce an executable without having to produce a temp file and call the linker as a separate process.
Anyway, I thought this could have been a problem with the way binutils was configured (been given an incorrect path/filename) while running ./configure. But thinking back, I realize that any such thing would probably have been noticed much earlier through much more severe problems (unless everything in Fedora is statically linked, which I don't really expect :D)
> Only if that interpreter exists. On Fedora 15 for example interpreter
> would be /lib64/ld-2.14.so. This is why using gcc to drive the linker
> is usually the best idea.
Nick: Thanks for clearing up some of the fog.. I'm not entirely sure we understand each other though. Clearly (at least to me at the moment), the ld process links the executable in such a way that the path/filename to the interpreter is included in the executable header somewhere or it is some initialization code that tries to call the interpreter or something, but the path/filename seems to be hard coded anyway.
So clearly, the ld process either has that path/filename hardcoded as well or uses some setting for it. Either way, it encodes /lib/ld64.so.1 as the path/filename for the interpreter to use into the executable. But what good would that be if the interpreter on every system may be a different version or even in a different directory?
What I'm trying to say is that, as most distributions probably are stubborn enough to put the interpreter somewhere else and don't provide a symlink (if that approach is at all possible) to the right file, what use is that default ever going to be? So you might as well change it and have it match the interpreter for the system you're using it on.. (I don't know if it is possible to change it at all though)
It certainly saves having to override the default every time one uses/experiments with ld directly and it would also help some people who are new to linux software development to get started with the whole circus of makefiles, automake, ./configure and all other complexities they might not be used to, for example when coming from a luxury IDE on some other platform where they just need to press F5/F9 to run their application.. :)
Greetz,
Tim.
If you are writing a compiler targetting x86_64, you should spend time to find out what other compilers are passing to the linker and why, read the corresponding psABIs etc. You'd learn the name of the x86_64-linux dynamic linker is /lib64/ld-linux-x86-64.so.2, for which there is a symlink maintained in glibc and would pass -dynamic-linker /lib64/ld-linux-x86-64.so.2 if creating binaries for x86_64-linux. Similarly for all other targets you want to support. There are many other ld options that are desirable to pass, -dynamic-linker isn't the only one. Hi Tim, > understand each other though. Clearly (at least to me at the moment), the ld > process links the executable in such a way that the path/filename to the > interpreter is included in the executable header somewhere It is. Have a look at the .interp section in the executable. > So clearly, the ld process either has that path/filename hardcoded as well > or uses some setting for it. Take a look at the definition of ELF64_DYNAMIC_INTERPRETER in bfd/elf64-x86-64.c in the binutils sources. > What I'm trying to say is that, as most distributions probably are stubborn > enough to put the interpreter somewhere else and don't provide a symlink (if > that approach is at all possible) to the right file, what use is that > default ever going to be? So you might as well change it and have it match > the interpreter for the system you're using it on. So you are suggesting a patch similar to this one (although extended to cover other architectures, not just the x86_64): *** ../binutils-2.23.51.0.3.orig/bfd/elf64-x86-64.c 2012-10-25 12:14:31.077299227 +0100 --- bfd/elf64-x86-64.c 2012-10-25 12:14:49.874307932 +0100 *************** elf_x86_64_write_core_note (bfd *abfd, c *** 508,515 **** /* The name of the dynamic interpreter. This is put in the .interp section. */ ! #define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1" ! #define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1" /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid copying dynamic variables from a shared lib into an app's dynbss --- 508,515 ---- /* The name of the dynamic interpreter. This is put in the .interp section. */ ! #define ELF64_DYNAMIC_INTERPRETER "/lib64/ld-2.15.so" ! #define ELF32_DYNAMIC_INTERPRETER "/lib/ld-2.15.so" /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid copying dynamic variables from a shared lib into an app's dynbss The problem with this is that the patch will have to be updated whenever the dynamic interpreter is changed. Since the interpreter is not part of the binutils package that means that someone (= probably me...) will have to monitor every glibc change to see if it alters the interpreter. Which is a pain, and not something that I really want to do. Also, another point is that having the wrong default dynamic interpreter name built into the linker can actually be helpful. It started you on your search for why your program did not run, and I am sure that you would agree that you have learnt a lot in the process. So, this is what I will do. I am not going to apply this patch just for you. But, if some more people complain, and agree that the patch should go in, then I will bow to public pressure and add it to the binutils rpm. Cheers Nick Hi Nick, Jakub, Tnx for the excellent replies. That patch was more or less what I was suggesting. IMHO it makes more sense not to confuse the people who are new to this sort of trickery.. There is a lot of incorrect info out there that is easily found through google, (as I noticed when most examples I found seem to suggest using ld in stead of gcc - and even use it incorrectly). Though it may be I've only seen the problem cases or I misunderstood the situation, I don't think the philosophy should be to make it harder than it needs to be if it can be avoided. I see what you're saying though. I wouldn't want to have to keep an eye on every dependency just in case something changes and I'd need to change everything that depends on those changes. Surely no one can expect you guys to maneuver yourselves into dependency hell. And I guess the symlink approach that I suggested is just an easier, bit of a workaround to basically do the same thing (with the difference that binaries that had this default setting would still be guided at runtime to the right interpreter, but that's a minor advantage I guess).. Still, you'd need to change the symlink each time the interpreter changes so it doesn't matter much in terms of maintenance.. I wonder if there could be some way this could be automated so you wouldn't have to think about it. Somewhat like the akmod package for nvidia that takes care of keeping the kernel module up to date after receiving a kernel update. This could detect if the version/filename/location for the interpreter(s) change and update these lines to match the right files.. #define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1" #define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1" Or, if the /lib64/ld-linux-x86-64.so.2 symlink is maintained by glibc, shouldn't the ELF64_DYNAMIC_INTERPRETER macro simply be set to that? I don't think it's a big issue though. It's true that through this trouble, I've learned some things and I appreciate that. But you know, I have a fulltime job as software developer next to doing a little development at home. So with the little time I have left next to my job, I don't want to spend most of that going through heaps of documentation that generally seem to tell me lots of interesting stuff but not what I want to know at that moment. But make no mistake: I *do* use books and documentation, but only to look something up when I need to (and I didn't expect to need to know specifics of ld at this moment). The mistakes that I made with ld here was partly because I was used to that approach from previous experiments a long time ago (and even then I probably got it from an example on some forum) and because I didn't want to depend on gcc, but also not wanting to spend a lot of time figuring out the exactly right way to use ld. It's like I would tell someone I want to use linux and they would recommend me to use linux-from-scratch, which basically is just a manual explaining how to build yourself a working linux environment from source). But I don't want to build one, I want to use one (which is why I use Fedora - more or less comfortable for the somewhat power user, but still easy and fast to get up and running). In this case I was excited about doing some experiments with x64 assembly and in stead I had to get the problems with linking out of the way first. I think this is one of the bigger reasons why a lot of people try linux and quickly give up on it. They don't want to spend hours fixing other problems than they were planning to tackle. Which is why I was very annoyed I had to find an alternative to gnome because I didn't want to learn a new desktop philosophy when I was perfectly happy with gnome 2. Yes, I could probably have downloaded the gnome 2 sources or MATE or something alike, but I chose to settle for XFCE because once again, I want to spend my time working on my own ideas. I read once that linux is about freedom, but I don't quite agree. I'd ask whose freedom: that of the user or that of the developer? It can't be the freedom of the user if they were forced to move from gnome 2 to gnome 3. Anyway thanks a lot guys.. I think we can consider this issue closed if you agree. Cheers, Tim. ld is a linker not just for Linux, but for various other OSes too. As such, hardcoding in it the Linux name of the dynamic linker, when e.g. psABI says differently, is IMHO a bad idea. The binutils sources usually default to whatever the particular psABI requires. The standard place where the Linux dynamic linker name is hardcoded is the compiler driver. |