symbol resolution on shard library. - Unix

This is a discussion on symbol resolution on shard library. - Unix ; While learning about the mechaism of symbol resolution of a linker, I found difficulty to undestand one thing. (Forgive me to explain verbosely. I cannot write it concisely.) A. In static linking, a linker try to resolve unresolved symbol reference ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: symbol resolution on shard library.

  1. symbol resolution on shard library.

    While learning about the mechaism of symbol resolution of a linker, I
    found difficulty to undestand one thing. (Forgive me to explain
    verbosely. I cannot write it concisely.)


    A. In static linking, a linker try to resolve unresolved symbol
    reference by searching .o files, then archives in given order, and
    if the symbol's definition is found in the archive, it resolve in
    by including the module from the archives to the
    executable. Correct?


    If I made libmal.a that contains only mal.o that defines only one
    function, malloc() like this:

    mal.c:
    #include

    void *malloc(size_t size)
    {
    return 0;
    }

    $ gcc -c mal.c
    $ ar rc libmal.a mal.o

    And the main code is in main.c like this:

    main.c:

    #include

    int main(void)
    {
    malloc(1);
    calloc(1, 1);
    return 0;
    }

    $ gcc -static -L. main.c -lmal
    ..../libc.a(malloc.o): In function `malloc':
    (.text+....): multiple definition of `malloc'
    ../libmal.a(mal.o):mal.ctext+0x0): first defined here
    collect2: ld returned 1 exit status
    $ _

    Ok, I understand why above gcc excution failed. But If I run without
    '-static' option, (I assume that without '-static', gcc will try to
    link the libc.so)

    $ gcc -L. main.c -lmal
    $ ./a.out # succeeded.
    $ _

    There's no error. What I guessed, if the main() calls calloc(), the
    dynamic linker/loader will load malloc.o in libc.so into the current
    address space. I'm sure that the module malloc.o have a definition of
    malloc() and calloc(), etc. So I guess it will fail because there are
    two definitions of malloc(); one from my mal.o, and one from the
    malloc.o in libc.so. But as you see in above example, the compiling
    "gcc -L. main.c -lmal" gives no error.


    B. I suspect at least either the build or the excution will fail. but
    they didn't. Could you explain why?


    C. Is there any specification or a standard document describing the
    mechanism/structure of ld.so? If so, please let me know.


    Thanks in advance.

  2. Re: symbol resolution on shard library.

    cinsky@gmail.com writes:

    > A. In static linking, a linker try to resolve unresolved symbol
    > reference by searching .o files, then archives in given order, and
    > if the symbol's definition is found in the archive, it resolve in
    > by including the module from the archives to the
    > executable. Correct?


    Mostly correct. You could list archive libraries before objects (so
    the order of searching isn't necessarily "objects then archives";
    it's "in whatever order they are on command line").

    > $ gcc -L. main.c -lmal
    > $ ./a.out # succeeded.
    >
    > There's no error. What I guessed, if the main() calls calloc(), the
    > dynamic linker/loader will load malloc.o in libc.so into the current
    > address space.


    That is incorrect.

    First, there is no separate 'malloc.o' in libc.so. Shared library is
    fully linked (just like an executable), and all boundaries between
    objects are gone.

    Second, libc.so will be loaded by the dynamic linker long before
    you call calloc(), and in fact long before your main() is called.

    > I'm sure that the module malloc.o have a definition of
    > malloc() and calloc(), etc.


    libc.so does have definitions of malloc(), calloc(), etc.

    > So I guess it will fail because there are
    > two definitions of malloc(); one from my mal.o, and one from the
    > malloc.o in libc.so.


    It does *not* fail, because dynamic linking tries to emulate what
    happens at static linking; namely, ld.so will normally use the first
    definition it finds, and ignore all subsequent ones.

    On Linux, you can observe this by running:

    LD_DEBUG=bindings ./a.out

    > C. Is there any specification or a standard document describing the
    > mechanism/structure of ld.so? If so, please let me know.


    Not really. But you can gain much understanding about linking an
    runtime loader from the "Linkers and Loaders" book:
    http://www.iecc.com/linker

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

+ Reply to Thread