Search code examples
linuxgccdebianpowerpc

How to check which symbols on my shared library have non-position independent code (PIC)?


I'm trying to build a .deb package with debuild -i -us -uc -b and in the end I see:

Now running lintian...
warning: the authors of lintian do not recommend running it with root     privileges!
W: libluajit-5.1-2: hardening-no-relro usr/lib/powerpc64le-linux-gnu/libluajit-5.1.so.2.1.0
E: libluajit-5.1-2: shlib-with-non-pic-code usr/lib/powerpc64le-linux-gnu/libluajit-5.1.so.2.1.0
W: luajit: hardening-no-relro usr/bin/luajit-2.1.0-alpha
W: luajit: binary-without-manpage usr/bin/luajit-2.1.0-alpha
Finished running lintian.

I have a hunch that I failed to define a "PIC code setup", which must be at the beginning of each external function:

The following code might appear in a PIC code setup sequence to compute
the distance from a function entry point to the TOC base:
addis 2,12,.TOC.-func@ha
addi 2,2,.TOC.-func@l

as specified by the ABI, page 99.

However I couldn't find the symbols which were non-PIC. Or maybe some relevant file that was not compiled with -fPIC?

Info:

system architecture: ppc64le

compiling .so library with: gcc -shared -fPIC


Solution

  • To find which symbols made your elf non-PIC/PIE (Position Independent Code/Executable), use scanelf from pax-utils package (on ubuntu, install it with sudo apt-get install pax-utils):

    $ scanelf -qT /usr/local/lib/libluajit-5.1.so.2.1.0 | head -n 3
      libluajit-5.1.so.2.1.0: buf_grow [0x7694] in (optimized out: previous lj_BC_MODVN) [0x7600]
      libluajit-5.1.so.2.1.0: buf_grow [0x769C] in (optimized out: previous lj_BC_MODVN) [0x7600]
      libluajit-5.1.so.2.1.0: buf_grow [0x76A0] in (optimized out: previous lj_BC_MODVN) [0x7600]
    $ objdump -Sa /usr/local/lib/libluajit-5.1.so.2.1.0 | grep -A5 \ 7694:
        7694:       00 00 80 39     li      r12,0
        7698:       c6 07 8c 79     rldicr  r12,r12,32,31
        769c:       00 00 8c 65     oris    r12,r12,0
        76a0:       00 00 8c 61     ori     r12,r12,0
        76a4:       a6 03 89 7d     mtctr   r12
        76a8:       21 04 80 4e     bctrl
    

    On my case an absolute address was meant to be load on r12, but that's not possible for a dynamic library, so the linker used 0 for that parameter (I had to use @GOT operator, but that's the particular solution to my case).

    On the luajit program, it's possible to define the address on linking time and it looks like this:

        1003d0d4:   00 00 80 39     li      r12,0
        1003d0d8:   c6 07 8c 79     rldicr  r12,r12,32,31
        1003d0dc:   07 10 8c 65     oris    r12,r12,4103
        1003d0e0:   30 ca 8c 61     ori     r12,r12,51760
        1003d0e4:   a6 03 89 7d     mtctr   r12
    

    Quite different right?

    a much detailed explanation can be found on this wonderful Gentoo wiki page.