Re: Question related to -fPIC behaviour across architectures

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

 



Thanks for your response !

Ok, it makes sense in the context of dynamic libraries.

But in the case of embedded code, not running on a OS like linux (which is the case of Cortex-Mx and a lot of xtensa devices), the definition of Position Independant Code is quite different, and in this case, only relative jumps/calls and relative access to constants should be allowed.

I have the feeling that because some xtensa chips are able to run linux, there may be some confusion there.

Regards,

Vincent.

Le 03/05/2022 à 12:24, Xi Ruoyao a écrit :
On Tue, 2022-05-03 at 10:26 +0200, vincent Dupaquis wrote:


- Is there somewhere a common definition of what mean PIC for the
different architectures ?
Generally -fpic/-fPIC does not means only position-independant code, but
position-independant code **suitable for dynamic linking**.

Consider the code:

void callee(void)
{
   /* ... */
}

void caller(void)
{
   callee();
}

Without -fPIC caller may call callee with a PC-relative call
instruction.  But with -fPIC it's not allowed because the symbol callee
may be interposed.  For more info:
https://maskray.me/blog/2021-05-16-elf-interposition-and-bsymbolic

(You may argue that the ELF interposition rule is strange and known to
slow down programs, but there are still many programs depending on the
rule in 2022.)

So my guess is w/o -fPIC the compiler just calls callee with a PC-rel
call, but with -fPIC it needs to either:

(1) Load the address of callee from GOT.

or

(2) Call the PLT stub ("callee@PLT") which is resolved to "jump callee"
at runtime.

For (1), the address of the callee is loaded into a register then a
"call register" instruction is used.  It seems callx8 is such an
instruction on Xtensa (I know nothing about Xtensa so it's from Google).
For (2), the compiler and the assembler cannot determine if the PLT stub
is out-of-range for the PC-rel call instruction (as the PLT stubs are
generated by the linker).  So the only approach legal for the worst case
is to assume the PLT stub may be far away from the call site.  Then a
PC-relative address load instruction will be used to load the address of
the PLT stub into a register, then callx8 is used to perform the call.


For some of other targets, a code model is defined to guarantee the PLT
stubs to be in-range of the PC-rel call instruction.  Those targets can
simply use PC-rel call to invoke callee@PLT.  But again I know nothing
about Xtensa and I can't reproduce the behavior you mentioned with GCC
trunk.  It seems always generating "l32r/callx8" pairs for calls on
xtensa-linux-gnu, unless the callee is `static`.  And it makes sense to
me: "l32r", as a PC-relative address loading instruction, will load the
address of callee@PLT correctly.
--

*Vincent Dupaquis*
Software security & Cryptography expert
06 24 58 17 05
/Europarc de Pichaury Bâtiment B8 1330 rue Guillibert Gautier de la Lauzière 13290 Aix-en-Provence/

www.trusted-objects.com <http://www.trusted-objects.com>

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux