Simon Atanasyan via llvm-dev
2015-Nov-21 06:13 UTC
[llvm-dev] [lld] R_MIPS_HI16 / R_MIPS_LO16 calculation
Hi, I am working on support R_MIPS_HI16 / R_MIPS_LO16 in the new LLD and have a couple of questions. == Q1 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? == Q2 R_MIPS_HI16 and R_MIPS_LO16 relocations perform a special calculation if a target symbol's name is `_gp_disp` [2]. AFAIK now in the target `relocateOne` method there is no chance to get the traget symbol name. Is it okay to pass the target symbol index and provide `MipsTargetInfo` access to the symbol table of the processing input file? [1] ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf page 4-18 [2] ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf page 4-19 -- Simon Atanasyan
Rui Ueyama via llvm-dev
2015-Nov-21 06:28 UTC
[llvm-dev] [lld] R_MIPS_HI16 / R_MIPS_LO16 calculation
On Fri, Nov 20, 2015 at 10:13 PM, Simon Atanasyan <simon at atanasyan.com> wrote:> Hi, > > I am working on support R_MIPS_HI16 / R_MIPS_LO16 in the new LLD and > have a couple of questions. > > == Q1 > 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. == Q2> > R_MIPS_HI16 and R_MIPS_LO16 relocations perform a special calculation > if a target symbol's name is `_gp_disp` [2]. AFAIK now in the target > `relocateOne` method there is no chance to get the traget symbol name. > Is it okay to pass the target symbol index and provide > `MipsTargetInfo` access to the symbol table of the processing input > file? >One way is to add a SymbolBody* field to Out<ELFT> struct, and let it have a pointer to _gp_disp symbol. And do pointer comparison to check if a relocation target is _gp_disp or not. [1] ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf page 4-18> [2] ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf page 4-19 > > -- > Simon Atanasyan >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151120/e6a0de17/attachment.html>
Simon Atanasyan via llvm-dev
2015-Nov-21 07:02 UTC
[llvm-dev] [lld] R_MIPS_HI16 / R_MIPS_LO16 calculation
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