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: Understanding multiple definitions in C program


Greetings,

When linking your application, the linker sees that malloc() is an
external symbol and generates a PLT entry for it in your application. It
also generates the necessary GOT entry to match the PLT entry. The
function malloc() does not get added to your program.

At runtime, if using lazy binding (default in most systems/binaries),
upon the first call to malloc(), the GOT for malloc() entry points to
the first PLT entry (this is done at load time). When the call is
executed, the PLT entry for malloc() takes the address on the
corresponding GOT entry and jumps to the first PLT entry. This entry is
tasked with jumping into the dynamic resolver, which resolves the symbol
malloc(), updates the GOT entry for it and proceeds to jump into the
actual function.

To answer your questions then:

- Resolution of malloc() is done by the resolver. How it does it is
documented in its manual. If you have it available you can access it
with the command 'man ld.so'. Of importance here is the following:

       If  a  shared  object  dependency  does not contain a slash,
       then it is searched for in the following order:

       o  (ELF only) Using the directories specified in the  DT_RPATH
       dynamic section  attribute of the binary if present and
       DT_RUNPATH attribute does not exist.  Use of DT_RPATH is
       deprecated.

       o  Using the environment  variable  LD_LIBRARY_PATH  (unless
       the  executable is being run in secure-execution mode; see
       below).  in which case it is ignored.


You explicitly set LD_LIBRARY_PATH to the current directory where the
libmalloc.so shared object happens to reside. The resolver picks this
one up over the one in libc.so.

- This is a runtime behaviour which is documented. GCC does not need to
report any multiple definitions on the grounds that (1) GCC is a
compiler collection and not a linker, and (2) The symbols are being
dynamically resolved on the application (shared objects), as opposed to
statically linking (at which point, ld will complain that you DO have
duplicate symbols, unless one of them is flagged as weak).

- This is standard UNIX behaviour. You can use this behaviour to
dynamically replace functions, have multiple versions of the same
function and the such. For more information, refer to the corresponding
manual page and the book "UNIX System V Release 4 Programmer's Guide:
ANSI C and Programming Support Tools".

Cheers,
Orlando.

On 07/17/2016 11:30 PM, linu cherian wrote:
> Hi,
> 
> Recently observed that, gcc doesnt warns/give error when i had a
> private malloc definition in my C program, though it had dependency on
> the libc. 
> 
> main.c
> ----------
> #include <stdio.h>
> #include <stdlib.h>
> 
> 
> int main()
> {
> 
>   printf("Calling malloc\n");
> 
>   malloc(100);
> }
> 
> malloc.c
> -------------
>  #include <stdio.h>
> #include <stdlib.h>
> 
> 
> void *malloc(size_t x)
> {
>   printf("hello my malloc %lu \n", x);
>   /* do nothing */
> }
> 
> Makefile
> -------------
> all: malloc
> 
> 
> libmalloc.so:libmalloc.o
>         gcc -shared  malloc.o -o libmalloc.so
> 
> libmalloc.o: malloc.c
>         gcc -fpic -c malloc.c
> 
> 
> 
> malloc: main.c libmalloc.so
>         gcc  malloc.c main.c -L. -lfoo -o malloc
> 
> 
> clean:
>         rm -f *.a *.o
> 
> 
> When i compiled and ran the above code, the output was,
> # export LD_LIBRARY_PATH=.
> #./malloc
> Calling malloc
> hello my malloc 100
> 
> #gcc --version
> gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
> Copyright (C) 2011 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> 
> 
> 1. On what criteria, does the  malloc symbol get resolved, since we
>    have multiple  definitions, one in libmalloc and other libc. 
> 
> 2. Wont it be better if gcc reports multiple definitions as error, since
>     - allowing multiple definitions is error prone
>     - there is inconsistency on  how gcc handles multiple definitions
>       with regard to -static and without -static.
>       (ie. with -static gcc reports error for this)
> 
> 3. Could someone please help me understand why multiple definitions
>    are desired in dynamic linked case ? 
> 
> Appreciate your help.
> 
> Thanks.
> 

Attachment: signature.asc
Description: OpenPGP digital signature


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