This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: gold: Something special about malloc/calloc/realloc/free symbols?


On 01/10/2017 10:44 PM, Paul Smith wrote:
Thanks for the reply Florian!

On Tue, 2017-01-10 at 12:40 +0100, Florian Weimer wrote:
On 01/08/2017 06:31 AM, Paul Smith wrote:

Hi all.  I have a weird situation and I don't know what to try
next.

You also need to export _IO_stdin_used if it is defined by
libc_nonshared.a.  I have not yet found a good way to clean this up
on the glibc side.

I'm not familiar with that, but I looked at my libc_nonshared.a (from
GNU C Library 2.12 on Red Hat Enterprise Linux 6.3) and that symbol is
not present (according to nm) so I guess it's not an issue for me.

Sorry, I misremembered. As Andreas pointed out, the symbol is in fact defined by the startup code.

FYI, Here's my link line:

g++ -fPIC -fvisibility=hidden -fno-omit-frame-pointer -std=c++14 \
  -z noexecstack -Wl,--version-script=my-script -Wl,symbolic-functions \
  -pthread -static-libgcc -static-libstdc++ -g -shared \
  -Wl,-soname,libfoo.so -o libfoo.so foo.o ... ../util/libutil.a ... \
  -latomic -lrt -lnsl -lm -ldl -Wl,-rpath,'$ORIGIN/../lib64'

The elided bits are more .o files and more .a files all for my
code.  One of the .a files is my memory manager replacement (I'm using
jemalloc).

g++ will call the linker with additional arguments (just to be clear).

It all works great, except for one thing.  In my shared library I'm also
linking a memory management library (linked as a .a) which replaces all
the standard memory functions: malloc, calloc, realloc, free.  I don't
want these to be published by my .so because I want only my library to
be able to access them, not a program that links my library.

This happens automatically to enable symbol interposition.

So, you're saying that ld is hardcoded to always mark those four
symbols as global, if they're defined, regardless of what the linker
script may say?

No, ld links against -lc (in the form of the libc.so script) and notices that the shared object which is being created intends to interpose malloc/free/… because both the object being created and libc.so.6 (referenced from libc.so) define these symbols. To enable that, the symbols are automatically exported. There is nothing magic about the symbols themselves, it's just how ELF interposition works.

I don't know if there is a way to disable this from the version script directly, or if there is some other linker script/ld feature to achieve this more directly.

The best way to deal with this is to rename the allocator functions in
the source code.  If that's not possible, maybe you can use a partial
link (ld -r) with --wrap or some other ld functionality which renames
the symbols.

Unfortunately renaming the allocator is problematic because it means I
have to recompile all the third party code and force it to use my
allocator functions instead of malloc (I have the source, but most of
these libraries don't have any facility to allow use of a different
allocator function).

I didn't understand the need for using -r / partial link?

My idea (again, no binutils expert) is to do a partial link first, to get rid of the malloc/free/… symbols by renaming them, and then link against -lc in the final link only. This way, no interposition happens, and the symbols are not exported.

As for --wrap... are you saying that if I arrange for my replacement
allocator to define __wrap_malloc() (etc.) rather than malloc(), then
link with --wrap=malloc, all "malloc" calls in my code will be remapped
to __wrap_malloc(), which can be localized?

Yes, that's what I would expect.

Thanks,
Florian



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]