ELF Dynamic Loading - defined but STB_WEAK symbols

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

ELF Dynamic Loading - defined but STB_WEAK symbols

Post by thepowersgang »

I recently fixed my dynamic loader to correctly handle symbol resolution with respect to weakly bound external symbols (e.g. g++ emits weak references to the java exception handling routines, but checks if they resolved before calling them).

However, I spotted an edge case that either the ELF docs (http://www.skyfree.org/linux/references/ELF_Format.pdf) aren't very clear on, or I'm just missing the general case it fits into.

If a symbol is defined as STB_WEAK, but has a definition (i.e. the section index isn't SHN_UNDEF), does it get overridden by STB_WEAK definitions in the same process? (Presumably it'd be overridden by STB_GLOBAL definitions)

I _guess_ that they're supposed to resolve to the first present definition if all available ones are STB_WEAK, but I would prefer it if someone knew the correct way.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: ELF Dynamic Loading - defined but STB_WEAK symbols

Post by alexfru »

Is this case supposed to differ from linking a bunch of object files, two of which define the same global symbol?
I mean, if one of the two object files is pulled in, but not the other, there's no conflict.
E.g. you could define your own strlen() in your C code and typically another strlen() wouldn't be pulled from an object file residing in libc.a.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: ELF Dynamic Loading - defined but STB_WEAK symbols

Post by thepowersgang »

It does, as this is at dynamic linking time, and the STB_WEAK symbols in this case appear to include 'type_info' structures (which are defined by the ABI to be unique, i.e. comparing the pointers of the structures is sufficient for checking if they're equal)

For STB_GLOBAL/STB_LOCAL symbols, I just leave them be at dynamic linking (which acts the same as your case, there could be multiple versions of strlen, and nobody would care)
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Re: ELF Dynamic Loading - defined but STB_WEAK symbols

Post by jnc100 »

The Itanium C++ ABI seems to suggest that type_info structures should be unique (link), and goes on to state that type_info structures should only be defined in the object file defining the first non-pure virtual function in the respective class.

Do you have any examples where there are multiple definitions of the same type_info object?

Regards,
John.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: ELF Dynamic Loading - defined but STB_WEAK symbols

Post by thepowersgang »

Yes, it seems that both my GUI's shared library and my C++ support library define typeinfo for out_of_range and a couple of other types, which is why I'm thinking they're supposed to be merged (but not quite sure which to, if there is a defined order)

A filtered snippet from my kernel log (showing binaries mapped for PID11, and the warning emitted when a symbol with a definition has binding of STB_WEAK)

Code: Select all

tpg@ted$ cat QemuLog.txt | c++filt | grep 'typeinfo\|Mapped' | grep 12
00000000005517d [Binary  ] 12 - PID 12 - Mapped '/Acess/Apps/AxWin/4.0/AxWinUI' to *0x8048000
00000000005521d [Binary  ] 12 - PID 12 - Mapped '/Acess/Libs/ld-acess.so' to *0xBBFF0000
00000000005509d [Binary  ] 12 - PID 12 - Mapped '/Acess/Libs/libaxwin4.so' to *0xBBFE0000
Log: 00005539 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::out_of_range'
Log: 00005576 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::out_of_range'
Log: 00005713 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::logic_error'
Log: 00005715 [12] WARN: TODO: Weak bound local symbols 'typeinfo for AxWin::CIPCChannel_AcessIPCPipe'
Log: 00005754 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::length_error'
Log: 00005814 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::logic_error'
Log: 00005832 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for AxWin::IIPCChannel'
Log: 00005846 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::length_error'
Log: 00005882 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for AxWin::CIPCChannel_AcessIPCPipe'
Log: 00005896 [12] WARN: TODO: Weak bound local symbols 'typeinfo for AxWin::IIPCChannel'
00000000005901d [Binary  ] 12 - PID 12 - Mapped '/Acess/Libs/libc.so' to *0xBBFD0000
00000000005908d [Binary  ] 12 - PID 12 - Mapped '/Acess/Libs/libc++.so' to *0xBBFC0000
Log: 00005915 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for __cxxabiv1::__si_class_type_info'
Log: 00005925 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::out_of_range'
Log: 00005955 [12] WARN: TODO: Weak bound local symbols 'typeinfo for __cxxabiv1::__vmi_class_type_info'
Log: 00005968 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::out_of_range'
Log: 00006018 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::class_generic_category'
Log: 00006021 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::error_category'
Log: 00006028 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::system_error'
Log: 00006045 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for __cxxabiv1::__class_type_info'
Log: 00006048 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::exception'
Log: 00006083 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::logic_error'
Log: 00006086 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::type_info'
Log: 00006102 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::system_error'
Log: 00006109 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for __cxxabiv1::__vmi_class_type_info'
Log: 00006120 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::class_system_category'
Log: 00006144 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::length_error'
Log: 00006156 [12] WARN: TODO: Weak bound local symbols 'typeinfo for __cxxabiv1::__class_type_info'
Log: 00006187 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::logic_error'
Log: 00006210 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::length_error'
Log: 00006223 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::class_generic_category'
Log: 00006228 [12] WARN: TODO: Weak bound local symbols 'typeinfo for __cxxabiv1::__si_class_type_info'
Log: 00006262 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::type_info'
Log: 00006263 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::exception'
Log: 00006290 [12] WARN: TODO: Weak bound local symbols 'typeinfo for std::error_category'
Log: 00006292 [12] WARN: TODO: Weak bound local symbols 'typeinfo name for std::class_system_category'
00000000006303d [Binary  ] 12 - PID 12 - Mapped '/Acess/Libs/libposix.so' to *0xBBFB0000
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: ELF Dynamic Loading - defined but STB_WEAK symbols

Post by Candy »

> which is why I'm thinking they're supposed to be merged (but not quite sure which to, if there is a defined order)

Weak symbols are intended as the default-implementation, if no strong symbol exists (ie, it's like a fallback). If you have only fallbacks, and you have multiple, then they're interchangeable functionally, but you must pick only one so that all users refer to the same one.

It doesn't matter which typeinfo struct you use, as long as its constraints (typeid(x) == typeid(y) when same type) hold.

Same goes for vtables (that probably are also weak symbols) - just pick one; they must be identical. If you want to show off, compare them to show they're identical too & warn/error when they're not. Kind of hard to do though since symbols don't carry a length field.
Post Reply