Hello! So continuing with the x86_64-gnu port, I wrote and tweaked some things and got it to compile further, and now I'm facing linking issues. I've been scratching my head (figuratively...) about this one for > 24 hours now, so it's only appropriate that I ask for some help. First, the error message: x86_64-gnu-gcc -nostdlib -nostartfiles -r -o elf/librtld.map.o elf/librtld.mapT.o '-Wl,-(' elf/dl-allobjs.os libc_pic.a mach/libmachuser_pic.a hurd/libhurduser_pic.a -lgcc '-Wl,-)' -Wl,-Map,elf/librtld.mapT x86_64-gnu/bin/ld: libc_pic.a(_exit.os): in function `__GI__exit': posix/../sysdeps/mach/hurd/_exit.c:50: multiple definition of `__GI__exit'; elf/dl-allobjs.os:elf/../sysdeps/mach/hurd/dl-sysdep.c:728: first defined here x86_64-gnu/bin/ld: libc_pic.a(strtoul.os): in function `__GI___strtoul_internal': stdlib/../sysdeps/wordsize-64/strtoul.c:108: multiple definition of `__GI___strtoul_internal'; elf/dl-allobjs.os:elf/../sysdeps/mach/hurd/dl-sysdep.c:713: first defined here (I've trimmed down the paths to be less unwieldy; in reality they're all absolute, e.g. /home/sergey/dev/crosshurd64/src/glibc/build/elf/librtld.map.o) My understanding is that __GI__ symbols are created by the hidden_proto/hidden_def macros from include/libc-symbols.h, and used for avoiding PLT when using glibc symbols from inside glibc itself (how it's different to the __-prefixed symbols, I have not yet figured out). There is indeed the __GI__exit strong .text symbol in both libc_pic.a(_exit.os) and elf/dl-allobjs.os: $ nm -A libc_pic.a 2>/dev/null | rg __GI__exit libc_pic.a:version.os: U __GI__exit libc_pic.a:abort.os: U __GI__exit libc_pic.a:exit.os: U __GI__exit libc_pic.a:_exit.os:0000000000000460 T __GI__exit libc_pic.a:daemon.os: U __GI__exit libc_pic.a:openchild.os: U __GI__exit libc_pic.a:forkpty.os: U __GI__exit $ nm -A elf/dl-allobjs.os | rg _exit elf/dl-allobjs.os:00000000000192b0 T __check__exit_no_hidden elf/dl-allobjs.os:00000000000192b0 W _exit elf/dl-allobjs.os:00000000000192b0 T __GI__exit elf/dl-allobjs.os: U __proc_mark_exit but this same thing is true of my i686-gnu build, which somehow works! $ nm -A libc_pic.a 2>/dev/null | rg __GI__exit libc_pic.a:version.os: U __GI__exit libc_pic.a:abort.os: U __GI__exit libc_pic.a:exit.os: U __GI__exit libc_pic.a:_exit.os:000004a0 T __GI__exit libc_pic.a:daemon.os: U __GI__exit libc_pic.a:openchild.os: U __GI__exit libc_pic.a:forkpty.os: U __GI__exit $ nm -A elf/dl-allobjs.os | rg _exit elf/dl-allobjs.os:000190a0 T __check__exit_no_hidden elf/dl-allobjs.os:000190a0 W _exit elf/dl-allobjs.os:000190a0 T __GI__exit elf/dl-allobjs.os: U __proc_mark_exit Here, it just says i686-gnu-gcc -nostdlib -nostartfiles -r -o elf/librtld.map.o elf/librtld.mapT.o '-Wl,-(' elf/dl-allobjs.os libc_pic.a mach/libmachuser_pic.a hurd/libhurduser_pic.a -lgcc '-Wl,-)' -Wl,-Map,elf/librtld.mapT i686-gnu/bin/ld: warning: elf/dl-allobjs.os: requires executable stack (because the .note.GNU-stack section is executable) (Again, I've trimmed the paths.) Questions: 1. What is this about, what's it even trying to do? If this is linking the dynamic linker (ld.so / rtld — these are the same thing, right?), then why does it need the dl-sysdep version if the real version is available? If this is something else, such as maybe testing that the dynamic linker and glibc proper don't have symbol conflicts, then clearly they do! 2. Why does dl-sysdep define a strong __GI__exit and not a weak one? Isn't the point to upgrade to the full version once it's available? (But would that even work, considering __GI__ function calls do not go through PLT?) 3. How come this works on i686-gnu, the duplicated symbols are clearly present there too! 4. Whatever the answer to #2 is, why doesn't it work on x86_64-gnu? Sergey