std library hooks

Artur Skawina art.08.09 at gmail.com
Sun Apr 15 06:12:33 PDT 2012


On 04/15/12 07:08, Nick Sabalausky wrote:
> "Walter Bright" <newshound2 at digitalmars.com> wrote in message 
> news:jmdhof$1v3v$1 at digitalmars.com...
>> On 4/14/2012 4:54 PM, Manu wrote:
>>> I just tried it, and I got the error I expected:
>>>
>>> LIBCMTD.lib(atox.obj) : error LNK2005: _atoi already defined in Unit.obj
>>>
>>> In C, I would always explicitly declare weak linkage to do this... what's 
>>> the
>>> point of the weak attribute if not for this?
>>
>> First you need to find out why you have multiple definitions of the same 
>> symbol being linked together. For example, do not specify libcmtd.lib to 
>> the linker, then link, then see what your unresolved symbols are.
> 
> This contradicts what you said earlier about symbols in obj files always 
> overriding ones in lib files. Either obj symbols override lib symbols or 
> they conflict. Manu demonstrated that they conflict, rather than override. 
> How is your suggestion for replacing druntime functions supposed to work 
> when the linker is just going to bitch about them being "already defined"?

Static libraries (*.a) are basically just collections of compiled objects (*.o).
So if you have a library "alloc" module/unit which provides
   Mutex malloc_mutex;
   void* malloc(int) {...}
   void free(void*) {...}
when the lib gets built this unit is compiled to "m.o"; then the same thing
happens to every other source module, and then all the *.o  files are merged
into the final "library.a".
Now, if you declare your own "malloc" symbol, having the same mangled name,
in your application, do not implement the "free" function. and link it like
this: "... myapp.o mymalloc.o library.a ...", then the linker will pick up
the first "malloc" symbol it finds, ie the one in your "mymalloc.o" file.
But if "free" isn't also defined there, but was used in myapp.o (or mymalloc
itself) then it's still undefined, so the linker keeps looking for that. It
will find it in "library.a"s "alloc.o" module and include that. But as
"alloc.o" also defines "malloc" and the two symbols point to different things,
there's now a conflict.

There's nothing subtle or unpredictable about this - you can assume linking
works like this: every missing symbol is looked for in every object that comes
*after* the one that needs the symbol. The linker can completely forget about
every processed library once it has scanned it once, and move over to the next
one given on the command line. There are options to change the behavior
(eg ld's "-( -l1 -l2 ... -)"), but then the linker has to keep repeating the
process as long as some progress is made - which can obviously be a lot slower
and/or require more resources than just providing the libs in the correct order.

Some linkers may default to the inefficient cyclical search, compilers can
generate the *.o files in different ways that make the issue go away (eg by
placing the symbols into different sections, so that pulling in one symbol does
not automatically also include other locally unreferenced ones) etc. Then
there is also C's special "common" treatment for uninitialized data. But in
general the simple approach above should work almost everywhere.

On 04/15/12 13:55, Manu wrote:
> Basically, if an object in a lib defines multiple symbols, and I use one, but attempt to 'override' the other, is there a way to avoid this collision?
> Is this the reason that CRT implementations always seem to strictly have one single .c file per CRT function?

Yes. You could use per-symbol function- and data- sections, but, unless the
symbols are always supposed to work together, having them in different units
is usually best.

(D's module system makes things a bit more complicated, as the module name is
part of the mangled symbol name and there's also moduleinfo data)

artur


More information about the Digitalmars-d mailing list