[llvm-dev] [lld] R_MIPS_HI16 / R_MIPS_LO16 calculation

Simon Atanasyan via llvm-dev llvm-dev at lists.llvm.org
Fri Nov 20 23:02:44 PST 2015


On Sat, Nov 21, 2015 at 9:28 AM, Rui Ueyama <ruiu at google.com> wrote:
> On Fri, Nov 20, 2015 at 10:13 PM, Simon Atanasyan <simon at atanasyan.com>
> wrote:
>>
>> In case of MIPS O32 ABI we have to find a matching R_MIPS_LO16
>> relocation to calculate R_MIPS_HI16 one because R_MIPS_HI16 uses
>> combined addend (AHI << 16) + (short)ALO where AHI is original
>> R_MIPS_HI16 addend and ALO is addend of the matching R_MIPS_LO16
>> relocation [1]. There are two methods to do matching and R_MIPS_HI16
>> calculation.
>>
>> Method A:
>> 1. Postpone R_MIPS_HI16 relocation calculation and record its arguments.
>> 2. When R_MIPS_LO16 is found, iterate over recorded R_MIPS_HI16
>> relocations, calculate combined addend and apply relocations.
>> 3. At the end check orphaned (without R_MIPS_LO16 pair) R_MIPS_HI16
>> relocations, show warnings and apply them with zero addend.
>>
>> Method B:
>> 1. Each time we have found R_MIPS_HI16 relocation, iterate remaining
>> relocations list to find matching R_MIPS_LO16.
>> 2. Calculate combined adddend and apply relocation or show warning if
>> the R_MIPS_LO16 is not found.
>>
>> Method A requires some sort of container to keep postponed HI16
>> relocations. If we add the container to the `MipsTargetInfo` class we
>> will be able to hide all this unusual scheme inside MIPS specific code
>> and will not need to perform LO16 lookups. But the `MipsTargetInfo`
>> becomes stateful.
>>
>> Method B keeps the `MipsTargetInfo` stateless but requires forward
>> LO16 lookup for each HI16 relocation and requires to provide an
>> interface for such lookup to the `MipsTargetInfo`.
>>
>> Sure we can implement each of these methods somewhere in the
>> `InputSectionBase` class under `if (MIPS)` statements.
>>
>> Any opinions about the best method / approach?
>
>
> If I understand that spec correctly, an R_MIPS_HI16 should immediately be
> followed by an R_MIPS_LO16. Can't you use that property? It doesn't seem to
> me that you really have to search and pair up HI16 and LO16 relocations.

It is a question what the ABI authors did mean by the "R_MIPS_HI16
must have an associated R_MIPS_LO16 entry immediately following it"
phrase. In fact you can get from a compiler this code:

lui    $t0,%hi(sym1+4)      # R_MIPS_HI16
lui    $t0,%hi(sym1+8)      # R_MIPS_HI16
lui    $t0,%hi(sym1+12)     # R_MIPS_HI16
addi   $t0,$t0,%lo(sym1+16) # R_MIPS_LO16

and even such code:

lui    $t0,%hi(sym1)     # R_MIPS_HI16 on sym1
lui    $t0,%hi(sym2)     # R_MIPS_HI16 on sym2
addi   $t0,$t0,%lo(sym1) # R_MIPS_LO16 on sym1
addi   $t0,$t0,%lo(sym2) # R_MIPS_LO16 on sym2

fortunately I have never seen such code:

lui    $t0,%hi(sym1+12)     # R_MIPS_HI16
... other type (except HI16 / LO16) of relocation here
addi   $t0,$t0,%lo(sym1+16) # R_MIPS_LO16

-- 
Simon Atanasyan


More information about the llvm-dev mailing list