https://sourceware.org/bugzilla/show_bug.cgi?id=33577
--- Comment #43 from Ali Bahrami <ali_swbugzilla at emvision dot com> --- (In reply to Michael Matz from comment #42) > We noted that here: > https://sourceware.org/pipermail/binutils/2025-November/145608.html > with reply here: > https://sourceware.org/pipermail/binutils/2025-November/145643.html . I see, and I agree with the comment in the second one that those words were a relatively later addition, though they do reflect how the Solaris ld has always done it. My fuzzy memory of this is that I added them while working on PSARC 2008/603 ELF objects to adopt GNU-style Versym indexes The Sun style originally did not put version indexes for externally defined symbols into the versym section, setting those values all to 0, so while one could deduce that an object had a version dependency on another object, we could not discern specifically which symbols were responsible. We decided to adopt that part of the GNU extensions, and in doing that work, it dawned on me that index 0 has implications beyond local symbols, leading to questions, and a doc update. > I don't think any independendness comes into play here. The ones arguing > for changing the GNU versioning implementation ultimately always come from > reading the current Solaris docu, i.e. with the clarifications of NDX_LOCAL. Great to know. I continue to be grateful for how closely GNU has stuck to ELF, as well as to these Sun additions, but I try not to take it for granted. > Btw, people also try to read into it that it's fine to use NDX_LOCAL also > for _defined_ symbols. AFAICS even the clarification in the Solaris>=11 > docu only accepts that when there's no verdef section in the defining file. The use of NDX_LOCAL for globals is very limited. One might might interpret this as a license: - A global symbol defined within an object that does not have a SHT_SUNW_verdef version definition section. However, I think that rule is intended to describe a dependency that doesn't have a verdef. Note that the text below this list goes on to say: Versions defined by an object are assigned version indexes starting at 1 and incremented by 1 for each version. Index 1 is reserved for the first global version. If the object does not have a SHT_SUNW_verdef version definition section, then all the global symbols defined by the object receive index 1. If the object does have a version definition section, then VER_NDX_GLOBAL simply refers to the first such version Forgive the verbosity, but a concrete example might be useful. This hello world program is not itself versioned, but it links to libc, which is, and so, all of its own definitions end up in version 1 even though it, itself, does not have a verdef, % cc hello.c % elfdump -v a.out Version Needed Section: .SUNW_version index file version [2] libc.so.1 SYSVABI_1.3 % elfdump -sN.dynsym a.out Symbol Table Section: .dynsym index value size type bind oth ver shndx name [0] 0 0 NOTY LOCL D 0 UNDEF [1] 0x8060d7c 0x4 OBJT GLOB X 1 .data __xargc [2] 0x8050968 0 FUNC GLOB D 2 UNDEF printf [3] 0x8050918 0 OBJT GLOB D 1 .plt _PROCEDURE_LINKAGE_TABLE_ [4] 0x8060d5c 0x4 OBJT WEAK X 1 .data environ [5] 0x8060c04 0 OBJT GLOB D 1 .dynamic _DYNAMIC [6] 0x8060db0 0 OBJT GLOB D 1 .data _edata [7] 0x8060d78 0x4 OBJT GLOB X 1 .data ___Argv [8] 0x8050b90 0x1b FUNC GLOB D 1 .init _init [9] 0x8050bc7 0 OBJT GLOB D 1 .fini _etext [10] 0 0 NOTY GLOB D 1 ABS __fsr_init_value [11] 0x8050b60 0x2f FUNC GLOB D 1 .text main [12] 0x8060d5c 0x4 OBJT GLOB X 1 .data _environ [13] 0x8060bc8 0 OBJT GLOB P 1 .got _GLOBAL_OFFSET_TABLE_ [14] 0x8060d80 0x4 OBJT GLOB X 1 .data __xargv [15] 0x8060da8 0x4 OBJT GLOB D 1 .data __xpg4 [16] 0x80508fc 0x4 OBJT GLOB X 1 .rodata _lib_version [17] 0x8050958 0 FUNC GLOB D 2 UNDEF _exit [18] 0x8050948 0 FUNC GLOB D 2 UNDEF atexit [19] 0x8050928 0 FUNC GLOB D 2 UNDEF __fpstart [20] 0x8060dac 0x4 OBJT GLOB D 1 .data __xpg6 [21] 0x8050938 0 FUNC GLOB D 2 UNDEF exit [22] 0x8060db0 0 OBJT GLOB D 1 .data _end [23] 0x8050980 0x86 FUNC GLOB X 1 .text _start [24] 0x8050bac 0x1b FUNC GLOB D 1 .fini _fini [25] 0x8060d60 0x18 OBJT GLOB X 1 .data __environ_lock [26] 0x8060d84 0x4 OBJT GLOB X 1 .data __longdouble_used As long as versioning is in play, global definitions that are not otherwise directed to a different version via a mapfile/linker-script, end up in version 1. And since nearly everything has a dependency on libc, which is versioned, it's hard to make an object on Solaris that doesn't assign these cases to index 1 Note that Rainer manages some modern Solaris systems in the gcc test farm, and it should be possible to get shell access in order to poke at these details if that would be useful. > What's your take on that? Is a NDX_LOCAL, defined STB_GLOBAL symbol in > a file that has the verdef section (GNU or Sun variant) available to resolve > against, or not? Should it be? I'm not sure those symbols are useful. Consider the case that Rainer presented at the start of this, a weak reference, for which no definition was found during the link-edit. If symbol resolution is done for it, nothing will be found. However, it seems that we do support it. % cc -m64 -Kpic -G -o vers33.so vers33.c -Mvers33.map % elfdump -L vers33.so Procedure Linkage Table Section: .plt index addr GOT-index GOT-addr [1] 0x960 [4] 0x100a08 show_undef_weak % dis -F foo vers33.so disassembly for vers33.so foo() foo: 55 pushq %rbp foo+0x1: 48 8b ec movq %rsp,%rbp foo+0x4: 48 8b 05 75 00 10 movq +0x100075(%rip),%rax <0x100a00> 00 foo+0xb: 48 85 c0 testq %rax,%rax foo+0xe: 74 05 je +0x5 <foo+0x15> foo+0x10: e8 cb ff ff ff call -0x35 <0x960> foo+0x15: c9 leave I created a hello world program to call foo(), and debugging diagnostics show that we chase it and fail to find anything: % LD_DEBUG=symbols ./a.out |& grep show_undef 09599: symbol=show_undef_weak; lookup in file=a.out [ ELF ] 09599: symbol=show_undef_weak; lookup in file=./vers33.so [ ELF ] 09599: symbol=show_undef_weak; lookup in file=/lib/64/libc.so.1 [ ELF ] I think this says that such symbols are resolved, but there's likely no resulting benefit. ----- I'd also like to say that I fully agree that these changes to the GNU toolchain do need to be phased in over time, seeding the capability and then waiting for awhile before switching over to using it. The chaos of an abrupt switch for such a small thing just isn't worth the cost, but it would be nice to get there gradually. Our original ask, that is be changed immediately, was due to thinking it was just a minor bookkeeping matter. We've since been educated to its much larger impact. -- You are receiving this mail because: You are on the CC list for the bug.
