std library hooks

Artur Skawina art.08.09 at gmail.com
Sun Apr 15 13:05:40 PDT 2012


On 04/15/12 20:57, Nick Sabalausky wrote:
> "Artur Skawina" <art.08.09 at gmail.com> wrote in message 
> news:mailman.1765.1334495618.4860.digitalmars-d at puremagic.com...
>>
>> 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.
>>
> 
> So if you want to override a symbol in druntime, then in the same module 
> where you provide your own version, you *also* have to override every other 
> symbol from the same druntime module that's used anywhere in your app or 
> else you'll get a multiple definition error?

Yes.

> Sounds like a mess.

Overriding just parts of an implementation could be dangerous, it's a safe
default.

You *can* ignore the conflict, eg in the ld case just add
"-Wl,--allow-multiple-definition" to the DFLAGS, don't use LTO, and it will
let you do things like:

   extern (C) void* gc_malloc(int) { assert(0); }
   
   import std.stdio;
   void main(string[] argv) {
      string s1 = argv[0];
      s1 = "*" ~ s1;
      writeln(s1);
   }

which will trigger the assert when the array op tries to allocate memory.

artur


More information about the Digitalmars-d mailing list