[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: how to solve a non pic code in an shlib due to assembly code



Picca Frédéric-Emmanuel skrev:
> Is someone on this mailing have the assembly skills to help me, and the
> upstream, solve this problem.
> 
> I already contact the main upstream but it does not know how to
> solve this.

The idea of position-independent code (PIC) is that no absolute memory
offsets should be assembled, everything should be made relative to a
known reference point, which can be the current program counter (or, as
Intel calls it, the instruction pointer).

The basic i386 instruction set does not inherently support PC-relative
addressing. Therefore, any instruction such as "movq mm1,
__jpmm_tg_2_16", "lea ebx,__jpmm_row_tab_frw", etc, that directly
reference a symbol will be given a text relocation (TEXTREL) entry.

When a compiler is given the -fPIC option, it usually solves this by
first using a call/pop combination on function entry to get the PC into
a register, then replacing the absolute reference with a relative one
using the known PC as a base. GCC uses the ebx register for this. (A
drawback of this technique is that performance is reduced slightly in
PIC code, since that means ebx can't be used for anything else.)

For example, instead of

 push ebx
 mov ecx, 8
 lea eax, __jpmm_row_tabs
 lea ebx, __jpmm_rounder
__mmx_idct_rows:

you might write something like this (if you decided to use edx as the
base register):

 call __mmx_idct_rows_base
__mmx_idct_rows_base:
 pop edx
 push ebx
 mov ecx, 8
 lea eax, [edx + __jpmm_row_tabs - __mmx_idct_rows_base]
 lea ebx, [edx + __jpmm_rounder - __mmx_idct_rows_base]

Here, instead of an absolute reference to __jpmm_row_tabs (whose address
won't be known at compile-time, and won't be known before the library is
loaded), we now have a relative offset, __jpmm_row_tabs -
__mmx_idct_rows_base, which *can* be computed at compile-time (since the
*difference* is always the same regardless of where in memory the
library is loaded), and therefore no absolute memory reference gets
assembled into the library. The memory reference is instead calculated
at runtime (using the absolute address loaded into edx as the base).

I'm not 100% sure whether amd64 code would also need a similar
treatment, but I think so. I don't exactly have time to do the job for
you, though. And ideally, it's upstream's job. They wrote the asm code...

However, if they can't or won't fix it, there's *some* good news. In
general, shared libraries must be compiled as PIC because on some
platforms, the library just won't work properly if you don't. However,
i386 and amd64 are not among those platforms. Since the MMX code is only
compiled for those, it might be safe to ignore the lintian error in this
particular case, if there's no other way.


Reply to: