BSD

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Text relocations in shared libs

    7 answers - 2303 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    [Thanks to Nick Hudson for discovering this]
    For sh3 a few shared libraries in the base system has text
    relocations. This means that ld.so needs to perform relocations
    during startup. E.g.
    nada# ktruss echo
    600 1 echo open("/lib/libc.so.12", 0, 0xfffff804) = 3, 6214
    600 1 echo __fstat30(0x3, 0x7fffd82c) = 0, 6214
    600 1 echo mmap(0, 0x1000, 0x1, 0x1, 0x3, 0, 0, 0) = 0x20434000
    600 1 echo munmap(0x20434000, 0x1000) = 0, 541254268
    600 1 echo mmap(0, 0xdc000, 0x5, 0x10000002, 0x3, 0, 0, 0) = 0x20440000
    600 1 echo mmap(0x20505000, 0x8000, 0x3, 0x12, 0x3, 0, 0xb5000, 0) = 0x20505000
    600 1 echo mmap(0x2050d000, 0xf000, 0x3, 0x1012, 0xffffffff, 0, 0, 0) = 0x2050d000
    600 1 echo mprotect(0x204f6000, 0xf000, 0) = 0
    600 1 echo close(0x3) = 0, 831372
    !->600 1 echo mprotect(0x20440000, 0xb6000, 0x7) = 0
    !->600 1 echo mprotect(0x20440000, 0xb6000, 0x5) = 0
    This also means that the pages are no longer shared.
    libraries are libc, libposix, and libpthread. Text
    relocations come from the handwritten asm files. libc and libposix
    (that borrows SYS.h code from libc) has a lot of relocs for cerror:
    #define _SYSCALL(x,y)\
    .text;\
    911:mov.l912f, r3;\
    brafr3;\
    nop;\
    .align2;\
    912:.longcerror-(911b+6);\
    ^^^^^^^^^^^^^^^^^^^^^^^
    _SYSCALL_NERRR(x,y);\
    bf911b;\
    nop
    A proper PIC call would be to set up r12 and do the call via plt, but
    that raises a number of questions.
    plt destroys r0, where syscall code passes errno, so that would either
    cause a flag day, or we will need to introduce a flag or'ed into the
    syscall number, that would tell the kernel to use a different return
    convention.
    The benefits of calling cerror via plt are not clear, b/c there's
    little point in allowing cerror to be overridden, after all it's just
    the error path factored out of all the syscalls. I'm really inclined
    to think that making cerror .protected or even .hidden is the right
    thing to do.
    libposix will need a copy of cerror to compensate for that change.
    Another possible solution is to change libposix to (tail)call into
    libc instead of duplicating the actual syscall code in libposix.
    Ideas?
    SY, Uwe
  • No.1 | | 1135 bytes | |

    Quoting "Valeriy E. Ushakov" <uwe (AT) ptc (DOT) spbu.ru>:

    #define _SYSCALL(x,y) \
    .text; \
    911: mov.l 912f, r3; \
    braf r3; \
    nop; \
    .align 2; \
    912: .long cerror-(911b+6); \
    ^^^^^^^^^^^^^^^^^^^^^^^
    _SYSCALL_NERRR(x,y); \
    bf 911b; \
    nop

    A proper PIC call would be to set up r12 and do the call via plt, but
    that raises a number of questions.

    plt destroys r0, where syscall code passes errno, so that would either
    cause a flag day,

    What prevents you from just moving errno to a different register before
    executing the PLT? Surely you have another callee-saved register you
    can destroy. You can probably even put the move instruction in one of
    the branch delay slots, so it doesn't cost you anything.

    It would cause a flag day only in the sense that libposix and libpthread
    would have to be updated in sync with libc, because of the new cerror
    calling convention, but I think this is minor -- owing both to a limited
    number of users, and the fact that nothing in the build or install
    process uses either of those libraries.
  • No.2 | | 645 bytes | |

    Sun, Dec 25, 2005 at 13:54:13 -0500, Charles M. Hannum wrote:

    What prevents you from just moving errno to a different register before
    executing the PLT? Surely you have another callee-saved register you
    can destroy. You can probably even put the move instruction in one of
    the branch delay slots, so it doesn't cost you anything.

    Right, but that kinda reinforces my other point. If the interface
    between syscall code and cerror is private, why do we need to bother
    with exporting cerror at all? We can just make it .hidden and make
    the call to go directly to cerror, instead of going via PLT.

    SY, Uwe
  • No.3 | | 852 bytes | |

    Valeriy E. Ushakov wrote:
    Sun, Dec 25, 2005 at 13:54:13 -0500, Charles M. Hannum wrote:


    >>What prevents you from just moving errno to a different register before
    >>executing the PLT? Surely you have another callee-saved register you
    >>can destroy. You can probably even put the move instruction in one of
    >>the branch delay slots, so it doesn't cost you anything.


    Right, but that kinda reinforces my other point. If the interface
    between syscall code and cerror is private, why do we need to bother
    with exporting cerror at all? We can just make it .hidden and make
    the call to go directly to cerror, instead of going via PLT.

    cerror is also used by libposix. So either posix will need its own or
    able to use libc's.
  • No.4 | | 1474 bytes | |

    Mon, Dec 26, 2005 at 19:32:26 -0800, Matt Thomas wrote:

    Sun, Dec 25, 2005 at 13:54:13 -0500, Charles M. Hannum wrote:

    What prevents you from just moving errno to a different register
    before executing the PLT? Surely you have another callee-saved
    register you can destroy. You can probably even put the move
    instruction in one of the branch delay slots, so it doesn't cost
    you anything.

    Right, but that kinda reinforces my other point. If the interface
    between syscall code and cerror is private, why do we need to
    bother with exporting cerror at all? We can just make it .hidden
    and make the call to go directly to cerror, instead of going via
    PLT.

    cerror is also used by libposix. So either posix will need its own
    or able to use libc's.

    I know. As I said in my original mail:

    | libposix will need a copy of cerror to compensate for that change.
    | Another possible solution is to change libposix to (tail)call into
    | libc instead of duplicating the actual syscall code in libposix.

    and I think calling libc is a cleaner option, with code like the
    following:

    #include <sys/cdefs.h>

    extern int __posix_rename(const char *, const char *);

    #ifdef __weak_alias
    #define rename _rename
    __weak_alias(rename,_rename)
    #endif

    int
    rename(const char *from, const char *to)
    {
    return __posix_rename(from, to);
    }

    SY, Uwe
  • No.5 | | 562 bytes | |

    Sunday 25 December 2005 13:02, Valeriy E. Ushakov wrote:
    []
    The benefits of calling cerror via plt are not clear, b/c there's
    little point in allowing cerror to be overridden, after all it's just
    the error path factored out of all the syscalls. I'm really inclined
    to think that making cerror .protected or even .hidden is the right
    thing to do.

    Aren't there *lots* of symbols in libc that don't need to be exposed? Why
    special case cerror and the others with text relocations in libc?

    Nick
  • No.6 | | 1187 bytes | |

    Tue, Dec 27, 2005 at 08:51:33 +0000, Nick Hudson wrote:

    Sunday 25 December 2005 13:02, Valeriy E. Ushakov wrote:
    []
    The benefits of calling cerror via plt are not clear, b/c there's
    little point in allowing cerror to be overridden, after all it's just
    the error path factored out of all the syscalls. I'm really inclined
    to think that making cerror .protected or even .hidden is the right
    thing to do.

    Aren't there *lots* of symbols in libc that don't need to be
    exposed? Why special case cerror and the others with text
    relocations in libc?

    Well, ideally we should use version script to only export from libc.so
    (and other shared libs) what's meant to be exported, but that's a
    topic for another thread.

    cerror is "special" in that it does not even have a defined interface,
    except a private one between it and SYSCALL macros. It's really just
    a common error path factored out of syscall functions. Pretending
    that it is really exported and thus forthing all *jumps* (not even
    calls) to it from the syscall functions go via PLT seems just
    counterproductive.

    SY, Uwe
  • No.7 | | 571 bytes | |

    Tue, 27 Dec 2005 12:00:39 +0300,
    "Valeriy E. Ushakov" <uwe (AT) ptc (DOT) spbu.rusaid:

    Well, ideally we should use version script to only export from libc.so
    (and other shared libs) what's meant to be exported, but that's a
    topic for another thread.

    topic note:
    Sometimes it's difficult to decide what should be exported.
    For example, someone might think we shouldn't export "_open",
    but some HPC frameworks (e.g. checkpointing package) need to
    override "_open" and other internal entry points of system calls.

Re: Text relocations in shared libs


max 4000 letters.
Your nickname that display:
In order to stop the spam: 1 + 0 =
QUESTION ON "BSD"

EMSDN.COM