This is the mail archive of the
mailing list for the binutils project.
Re: Understanding multiple definitions in C program
- From: Linu Cherian <linuc dot decode at gmail dot com>
- To: binutils at sourceware dot org
- Date: Tue, 19 Jul 2016 07:11:13 +0530
- Subject: Re: Understanding multiple definitions in C program
- Authentication-results: sourceware.org; auth=none
- References: <20160718033036.GA4337@linu-ThinkPad-T61> <email@example.com>
Thanks for the detailed answer and also for the document references.
On Mon, Jul 18, 2016 at 8:36 PM, Orlando Arias <firstname.lastname@example.org> wrote:
> 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
> 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".
> On 07/17/2016 11:30 PM, linu cherian wrote:
>> 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.
>> #include <stdio.h>
>> #include <stdlib.h>
>> int main()
>> printf("Calling malloc\n");
>> #include <stdio.h>
>> #include <stdlib.h>
>> void *malloc(size_t x)
>> printf("hello my malloc %lu \n", x);
>> /* do nothing */
>> all: malloc
>> 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
>> rm -f *.a *.o
>> When i compiled and ran the above code, the output was,
>> # export LD_LIBRARY_PATH=.
>> 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.