reed kotler <rkot...@mips.com> writes:
> Consider the following function:
> void floatvf(float x) {
> }
>
> The compiled with:
> mips-linux-gnu-gcc -mips16 mips16_fpcall.c  -S -fPIC -EL
>
>
> The stub looks like this:
>
> __fn_stub_floatvf:
>      .set    noreorder
>      .cpload    $25
>      .set    reorder
>      .reloc    0,R_MIPS_NONE,floatvf
>      la    $25,__fn_local_floatvf
>      mfc1    $4,$f12
>      jr    $25
>      .end    __fn_stub_floatvf
>      __fn_local_floatvf = floatvf
>
>
> What is the purpose of this .reloc and this __fn_local_floatvf = floatvf ?

__fn_local_floatvf = floatvf creates a local symbol alias for a
locally-defined global function.  The idea is that:

      la $25, __fn_local_floatvf

then uses a page GOT access, ensuring the stub does not force the
creation of stub-specific GOT entries.

The difficulty with:

      la $25, floatvf

is that it would appear to the assembler and linker as a global GOT
reference (because floatvf is global).  However, the relocation actually
resolves to the MIPS16 function, whereas other non-stub instances of:

      la $25, floatvf

should resolve to the stub.  So we would have the strange (and currently
unsupported) situation that the same symbol could need two GOT entries,
one local entry pointing to the MIPS16 address and one global entry
containing the canonical function address (i.e. the stub).  Or,
if floatvf is hidden, we could end up with two different local GOT
entries for the same symbol.

The .reloc ensures that the first relocation in the stub section points
to the stubbed function (rather than its alias).  That's how the linker
works out which function is being stubbed.

Thanks,
Richard
  • mips16 stubs reed kotler
    • Re: mips16 stubs Richard Sandiford

Reply via email to