This is the mail archive of the
mailing list for the binutils project.
Re: gold: Something special about malloc/calloc/realloc/free symbols?
- From: Paul Smith <paul at mad-scientist dot net>
- To: Florian Weimer <fweimer at redhat dot com>, binutils <binutils at sourceware dot org>
- Date: Tue, 10 Jan 2017 16:44:57 -0500
- Subject: Re: gold: Something special about malloc/calloc/realloc/free symbols?
- Authentication-results: sourceware.org; auth=none
- References: <firstname.lastname@example.org> <email@example.com>
- Reply-to: paul at mad-scientist dot net
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.
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
> > 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?
If so I find that behavior surprising for a low-level tool like ld; I expect tools at that level to do what I tell them, even if I'm aiming the gun at my own foot and telling them to pull the trigger... :)
Is there any way to stop that from happening? Some option to ld or in the script file that I can use to say "yes I know, but just do it"?
> If you avoid symbol interposition, you will not be able to use quite a
> few glibc functions (strdup, getline, asprintf, realpath with a NULL
> argument, to name a few examples), and you must make sure that your
> library does not call realloc or free on a pointer supplied by the
> application (or the application does not call realloc or free on a
> pointer obtained from the library).
For the latter issue, we are already very careful about that: for any
memory we allocate and pass through the shared API, we provide methods
that free that memory as well. And for any memory we accept through
the shared API, we expect the caller to free it, we don't ever invoke
free on that memory. Not only for this reason but also the code is
compiled into a Windows DLL and memory management is less flexible
there, so this is a requirement.
For the former issue, I see what you're saying. We are actually not
using C runtime functions that return allocated memory that we're
expected to free; the only one I think we use is strdup(), and we just
wrote our own strdup() method that calls our own malloc(), hiding the C
So I *think* we're OK, although I understand that this stuff can get
hairy. I should be double-check all the third party code we use just
to be sure there are not issues there.
> 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
I didn't understand the need for using -r / partial link?
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?