All, (ld linker gurus especially), I am befuddled by the behavior of gcc/ld in compiling/linking a couple of c/assembly files that I need help figuring out. The files are just a couple of the example files which I'm building as a 32-bit elf file on x86_64. For some reason when ld is called by gcc, the build fails. Calling ld standalone works fine. I need to understand what default behavior of the gcc/collect2/ld call is causing the problem and how I can fix it. I also have one other question at the end concerning why '-dynamic-linker /lib/ld-linux.so.2' is expressly required if it is the default, but that is separate from this first issue. For the first issue, the assembly/c files are all contained in: [a whopping 3.7k total] http://www.3111skyline.com/dl/bugs/openSuSE/131/pcasm.tar.bz2 I built the assembly files without issue using: $ nasm -felf -D ELF_TYPE -o asm_io.o asm_io.asm $ nasm -felf -o first.o first.asm Compiling the c file to object and performing an independent link produces a working executable (there is a 32/64 bit issue left, but irrelevant to this discussion): $ gcc -c -m32 -o main.o main.c $ ld -dynamic-linker /lib/ld-linux.so.2 \ -o first first.o asm_io.o main.o \ -m elf_i386 -lc Attempting to compile/link with gcc is where the problem arises. If I replace the compile of main.c to object with a request that gcc perform the compile/link, the build fails: $ gcc -v -m32 -o first main.c first.o asm_io.o -Wl,-melf_i386 <snip> x86_64-suse-linux/bin/ld: cannot find -lgcc_s collect2: error: ld returned 1 exit status Now, the part I'm stumped with is why is the link failing? The full compiler output is at: [newlines provided for readability] http://www.3111skyline.com/dl/bugs/openSuSE/131/pcasm/asm_io_main_build-alc.... Looking at the final collect2 output, you see: COLLECT_GCC_OPTIONS='-v' '-m32' '-o' 'first' '-mtune=generic' '-march=i586' /usr/lib64/gcc/x86_64-suse-linux/4.8/collect2 --build-id --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o first <snip> showing the '-dynamic-linker /lib/ld-linux.so.2' option is selected. So why does the link fail? Looking further, I see what appears like the likely suspects, but I am not familiar enough with the --as-needed --no-as-needed options to know if this is in fact the cause: <snip> -melf_i386 -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed <snip> The manual says: --as-needed --no-as-needed This option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option. Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not. --as-needed causes a DT_NEEDED tag to only be emitted for a library that at that point in the link satisfies a non-weak undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries, a non-weak undefined symbol reference from another dynamic library. Object files or libraries appearing on the command line after the library in question do not affect whether the library is seen as needed. This is similar to the rules for extraction of object files from archives. --no-as-needed restores the default behaviour. (https://sourceware.org/binutils/docs/ld/Options.html#Options) This seems to indicate for -lgcc_s that a DT_NEEDED tag will only be emitted if -lgcc_s satisfies: (1.) a non-weak undefined symbol reference from a regular object file or (2.) a non-weak undefined symbol reference from another dynamic library Since, libgcc_s is not needed, what is causing either of the criteria (1.) or (2.) to be satisfied? Is it some default? More importantly, how to tell the linker not to look for it? Is there some additional option I can pass or rearrange the order of the gcc command that would help? Lastly, if '-dynamic-linker /lib/ld-linux.so.2' is the default, then why must it be expressly included with the standalone ld call in order to produce a working executable? If it is omitted, the executable is produced, but inoperable due to /usr/lib/libc.so.1 being used instead of /lib/ld-linux.so.2 in the executable -- which I'm having difficulty understanding. Specifically, if linked with: $ ld -dynamic-linker /lib/ld-linux.so.2 \ -o first first.o asm_io.o main.o \ -m elf_i386 -lc the executable works and contains the following explicit reference to /lib/ld-linux.so.2: $ hexdump -C -s 272 -n 32 first 00000110 01 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 |..../lib/ld-linu| 00000120 78 2e 73 6f 2e 32 00 00 03 00 00 00 05 00 00 00 |x.so.2..........| However if linked using the following: $ ld -o first first.o asm_io.o main.o -m elf_i386 -lc /usr/lib/libc.so.1 takes its place and the executable fails: $ hexdump -C -s 272 -n 32 first.sav 00000110 01 00 00 00 2f 75 73 72 2f 6c 69 62 2f 6c 69 62 |..../usr/lib/lib| 00000120 63 2e 73 6f 2e 31 00 00 03 00 00 00 05 00 00 00 |c.so.1..........| The files are identical in all other respects: $ l first* -rwxr-xr-x 1 david david 8030 Oct 21 03:15 first -rwxr-xr-x 1 david david 8030 Oct 20 21:31 first.sav But one runs, one doesn't: $ ./first Enter a number: 10 Enter another number: 14 Register Dump # 1 EAX = 00000018 EBX = 00000018 ECX = F7796132 EDX = F778B650 ESI = FFF7240C EDI = 08048290 EBP = FFF723FC ESP = FFF723DC EIP = 080482C7 FLAGS = 0216 AF PF Memory Dump # 2 Address = 0804A044 0804A040 72 3A 20 00 59 6F 75 20 65 6E 74 65 72 65 64 20 "r: ?You entered " 0804A050 00 20 61 6E 64 20 00 2C 20 74 68 65 20 73 75 6D "? and ?, the sum" You entered 10 and 14, the sum of these is 24 $ ./first.sav bash: ./first.sav: No such file or directory Why does expressly including '-dynamic-linker /lib/ld-linux.so.2' make that difference if it is the default? -- David C. Rankin, J.D.,P.E. -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse+owner@opensuse.org