[PATCH] D19115: [ELF][MIPS] Make R_MIPS_LO16 a relative relocation if it references _gp_disp symbol

Rafael Espíndola via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 14 12:03:28 PDT 2016


LGTM, thanks.

On 14 April 2016 at 11:03, Simon Atanasyan <simon at atanasyan.com> wrote:
> atanasyan created this revision.
> atanasyan added a reviewer: rafael.
> atanasyan added a subscriber: llvm-commits.
> atanasyan set the repository for this revision to rL LLVM.
> atanasyan added a project: lld.
> Herald added a subscriber: sdardis.
>
> The _gp_disp symbol designates offset between start of function and 'gp' pointer into GOT. The following code is a typical MIPS function preamble used to setup $gp register:
> ```
> lui    $gp, %hi(_gp_disp)
> addi   $gp, $gp, %lo(_gp_disp)
> ```
> To calculate R_MIPS_HI16 / R_MIPS_LO16 relocations results we use the following formulas:
> ```
> %hi(_gp - P + A)
> %lo(_gp - P + A + 4),
> ```
> where _gp is a value of _gp symbol, A is addend, and P current address.
>
> The R_MIPS_LO16 relocation references _gp_disp symbol is always the second instruction. That is why we need four byte adjustments. The patch assigns R_PC type for R_MIPS_LO16 relocation and adjusts its addend by 4. That fix R_MIPS_LO16 calculation.
>
> For details see p. 4-19 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
>
> Repository:
>   rL LLVM
>
> http://reviews.llvm.org/D19115
>
> Files:
>   ELF/Target.cpp
>   ELF/Writer.cpp
>   test/ELF/mips-hilo-gp-disp.s
>
> Index: test/ELF/mips-hilo-gp-disp.s
> ===================================================================
> --- test/ELF/mips-hilo-gp-disp.s
> +++ test/ELF/mips-hilo-gp-disp.s
> @@ -16,27 +16,40 @@
>    lui    $t0,%hi(_gp_disp)
>    addi   $t0,$t0,%lo(_gp_disp)
>    lw     $v0,%call16(_foo)($gp)
> +bar:
> +  lui    $t0,%hi(_gp_disp)
> +  addi   $t0,$t0,%lo(_gp_disp)
>
>  # EXE:      Disassembly of section .text:
>  # EXE-NEXT: __start:
>  # EXE-NEXT:  20000:   3c 08 00 01   lui    $8, 1
>  #                                              ^-- %hi(0x37ff0-0x20000)
>  # EXE-NEXT:  20004:   21 08 7f f0   addi   $8, $8, 32752
>  #                                                  ^-- %lo(0x37ff0-0x20004+4)
> +# EXE:      bar:
> +# EXE-NEXT:  2000c:   3c 08 00 01   lui    $8, 1
> +#                                              ^-- %hi(0x37ff0-0x2000c)
> +# EXE-NEXT:  20010:   21 08 7f e4   addi   $8, $8, 32740
> +#                                                  ^-- %lo(0x37ff0-0x20010+4)
>
>  # EXE: SYMBOL TABLE:
> +# EXE: 0002000c     .text   00000000 bar
>  # EXE: 00037ff0     .got    00000000 .hidden _gp
>  # EXE: 00020000     .text   00000000 __start
> -# EXE: 00020010     .text   00000000 _foo
>
>  # SO:      Disassembly of section .text:
>  # SO-NEXT: __start:
>  # SO-NEXT:  10000:   3c 08 00 01   lui    $8, 1
>  #                                             ^-- %hi(0x27ff0-0x10000)
>  # SO-NEXT:  10004:   21 08 7f f0   addi   $8, $8, 32752
>  #                                                 ^-- %lo(0x27ff0-0x10004+4)
> +# SO:       bar:
> +# SO-NEXT:   1000c:   3c 08 00 01   lui    $8, 1
> +#                                              ^-- %hi(0x27ff0-0x1000c)
> +# SO-NEXT:   10010:   21 08 7f e4   addi   $8, $8, 32740
> +#                                                  ^-- %lo(0x27ff0-0x10010+4)
>
>  # SO: SYMBOL TABLE:
> +# SO: 0001000c     .text   00000000 bar
>  # SO: 00027ff0     .got    00000000 .hidden _gp
>  # SO: 00010000     .text   00000000 __start
> -# SO: 00010010     .text   00000000 _foo
> Index: ELF/Writer.cpp
> ===================================================================
> --- ELF/Writer.cpp
> +++ ELF/Writer.cpp
> @@ -468,8 +468,16 @@
>      const uint8_t *BufLoc = Buf + RI.r_offset;
>      if (!RelTy::IsRela)
>        Addend += Target->getImplicitAddend(BufLoc, Type);
> -    if (Config->EMachine == EM_MIPS)
> +    if (Config->EMachine == EM_MIPS) {
>        Addend += findMipsPairedAddend<ELFT>(Buf, BufLoc, Body, &RI, E);
> +      if (Type == R_MIPS_LO16 && Expr == R_PC)
> +        // R_MIPS_LO16 expression has R_PC type iif the target is _gp_disp
> +        // symbol. In that case we should use the following formula for
> +        // calculation "AHL + GP – P + 4". Let's add 4 right here.
> +        // For details see p. 4-19 at
> +        // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
> +        Addend += 4;
> +    }
>
>      bool Preemptible = Body.isPreemptible();
>      if (unsigned Processed =
> Index: ELF/Target.cpp
> ===================================================================
> --- ELF/Target.cpp
> +++ ELF/Target.cpp
> @@ -1589,6 +1589,7 @@
>    default:
>      return R_ABS;
>    case R_MIPS_HI16:
> +  case R_MIPS_LO16:
>      // MIPS _gp_disp designates offset between start of function and 'gp'
>      // pointer into GOT. __gnu_local_gp is equal to the current value of
>      // the 'gp'. Therefore any relocations against them do not require
>
>


More information about the llvm-commits mailing list