Created attachment 8651 [details] .so with supposedly broken structure I originally reported the Bug to Android since a generated .so file could not by loaded by their linker/loader but they claim ld is a fault for generating a flawed ELF structure. To quote: "The so file in question is a strange one. Android linker assumes that phdr table is part of loadable segment but looking at the bad.so the load segment has the offset > sizeof(ehdr) + sizeof(phdr), so it ends up not being mapped into the memory - hence inaccessible after the library is loaded. I think the ld is broken (or very old). What does ld --version say? There are some other irregularities like one load segment for data and executable with RWE permission. And p_vaddr which might assume fixed load-address despite the fact that the object type is set to ET_DYN." For my minimal test case I linked an object file (generated from a C file with an empty function) like this: $ ld -L /usr/lib/android-ndk/x86/usr/lib -o client-ndk-x86.so -shared -nostdlib -lc obj-client-ndk-x86/test.o As mentioned in the original bug report, ld.gold generates an ELF structure which works for the Android loader.
-nostdlib is a gcc option, not a ld option. It looks to me like your version of ld is treating the option as if it were -n.
Your analysis is correct, thank you. While "-nostdlib" actually is a ld option (at least in my ld according to --help and man page), I rechecked and noticed I passed another gcc parameter "-no-enum-size-warning" to ld which seems to behave like "-n" as you suggested hence you can label this as user error but I keep wondering how this parameter handling could be useful/intended. The man page says "For options whose names are a single letter, option arguments must either follow the option letter without intervening whitespace, or be given as separate arguments immediately following the option that requires them." so "-no-enum-size-warning" would be taken as "-n" with value "o-enum-size-warning". Yet according to the man page "-n" does not take a value, so it seems the trailing characters will be silently discarded. Is this parameter-handling behavior intended this way? (Should one open a new bug to discuss that?)
Even worse, the actual error is the missing dash in the beginning. "--no-enum-size-warning" *is* a ld parameter but without the first dash it behaves like "-n".
The option -no-enum-size-warning is handled as -n -o -enum-size-warning. In other words, the -n option, followed by the -o option, setting the name of the output file to -enum-size-warning. Perhaps in your case you had a subsequent -o option setting a different output file name--that last -o option on the command line takes precedence. Yes, one dash or two makes a difference.
> Yes, one dash or two makes a difference. Using single-dash arguments can then be considered pretty dangerous in ld since any small typo (or using a parameter that might only exist in some other ld version) in the argument results in ld looking for single letter arguments (even in concatenation) which it almost always find. $ ld -nostdlib # correct $ ld -nostdllib # incorrect, results in -n -o stdllib Much safer is double dash: $ ld --nostdlib # correct $ ld --nostdllib ld: unrecognized option '--nostdllib' I figure a lot of people and application rely on single letter concatenation like this, but probably also a lot of people suffer from incorrectly applied settings without even knowing.