Question related to -fPIC behaviour across architectures

vincent Dupaquis v.dupaquis@trusted-objects.com
Tue May 3 13:29:30 GMT 2022


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>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <https://gcc.gnu.org/pipermail/gcc-help/attachments/20220503/a87f9091/attachment-0001.sig>


More information about the Gcc-help mailing list