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

Reply via email to