[lld] r255768 - [ELF][MIPS] Handle R_MIPS_HI16/LO16 relocations against _gp_disp symbol

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 16 06:45:10 PST 2015


Author: atanasyan
Date: Wed Dec 16 08:45:09 2015
New Revision: 255768

URL: http://llvm.org/viewvc/llvm-project?rev=255768&view=rev
Log:
[ELF][MIPS] Handle R_MIPS_HI16/LO16 relocations against _gp_disp symbol

The `_gp_disp` is a magic symbol designates offset between start of
function and gp pointer into GOT. Only `R_MIPS_HI16` and `R_MIPS_LO16`
relocations are permitted with `_gp_disp`. The patch adds the `_gp_disp`
as an ignored symbol and adjusts symbol value before call the `relocateOne`
for `R_MIPS_HI16/LO16` relocations.

Differential Revision: http://reviews.llvm.org/D15480

Added:
    lld/trunk/test/ELF/mips-hilo-gp-disp.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Dec 16 08:45:09 2015
@@ -32,6 +32,7 @@ enum ELFKind {
 
 struct Configuration {
   SymbolBody *EntrySym = nullptr;
+  SymbolBody *MipsGpDisp = nullptr;
   InputFile *FirstElf = nullptr;
   llvm::StringRef DynamicLinker;
   llvm::StringRef Entry;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Dec 16 08:45:09 2015
@@ -263,6 +263,11 @@ template <class ELFT> void LinkerDriver:
     Symtab.addIgnoredSym("_GLOBAL_OFFSET_TABLE_");
   }
 
+  // On MIPS O32 ABI _gp_disp is a magic symbol designates offset between
+  // start of function and gp pointer into GOT.
+  if (Config->EMachine == EM_MIPS)
+    Config->MipsGpDisp = Symtab.addIgnoredSym("_gp_disp");
+
   if (!Config->Entry.empty()) {
     // Set either EntryAddr (if S is a number) or EntrySym (otherwise).
     StringRef S = Config->Entry;

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Dec 16 08:45:09 2015
@@ -205,6 +205,11 @@ void InputSectionBase<ELFT>::relocate(ui
     } else if (Target->isTlsDynReloc(Type) ||
                Target->isSizeDynReloc(Type, Body)) {
       continue;
+    } else if (Config->EMachine == EM_MIPS) {
+      if (Type == R_MIPS_HI16 && &Body == Config->MipsGpDisp)
+        SymVA = getMipsGpAddr<ELFT>() - AddrLoc;
+      else if (Type == R_MIPS_LO16 && &Body == Config->MipsGpDisp)
+        SymVA = getMipsGpAddr<ELFT>() - AddrLoc + 4;
     }
     uintX_t A = getAddend<ELFT>(RI);
     uintX_t Size = getSymSize<ELFT>(Body);

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Dec 16 08:45:09 2015
@@ -88,10 +88,12 @@ void SymbolTable<ELFT>::addSyntheticSym(
   resolve(Sym);
 }
 
-template <class ELFT> void SymbolTable<ELFT>::addIgnoredSym(StringRef Name) {
+template <class ELFT>
+SymbolBody *SymbolTable<ELFT>::addIgnoredSym(StringRef Name) {
   auto Sym = new (Alloc)
       DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef);
   resolve(Sym);
+  return Sym;
 }
 
 template <class ELFT> bool SymbolTable<ELFT>::isUndefined(StringRef Name) {

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=255768&r1=255767&r2=255768&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Dec 16 08:45:09 2015
@@ -54,7 +54,7 @@ public:
                       typename llvm::object::ELFFile<ELFT>::Elf_Sym &ESym);
   void addSyntheticSym(StringRef Name, OutputSectionBase<ELFT> &Section,
                        typename llvm::object::ELFFile<ELFT>::uintX_t Value);
-  void addIgnoredSym(StringRef Name);
+  SymbolBody *addIgnoredSym(StringRef Name);
   bool isUndefined(StringRef Name);
   void scanShlibUndefined();
   SymbolBody *find(StringRef Name);

Added: lld/trunk/test/ELF/mips-hilo-gp-disp.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-hilo-gp-disp.s?rev=255768&view=auto
==============================================================================
--- lld/trunk/test/ELF/mips-hilo-gp-disp.s (added)
+++ lld/trunk/test/ELF/mips-hilo-gp-disp.s Wed Dec 16 08:45:09 2015
@@ -0,0 +1,42 @@
+# Check R_MIPS_HI16 / LO16 relocations calculation against _gp_disp.
+
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
+# RUN:         %S/Inputs/mips-dynamic.s -o %t2.o
+# RUN: ld.lld %t1.o %t2.o -o %t.exe
+# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=EXE %s
+# RUN: ld.lld %t1.o %t2.o -shared -o %t.so
+# RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=SO %s
+
+# REQUIRES: mips
+
+  .text
+  .globl  __start
+__start:
+  lui    $t0,%hi(_gp_disp)
+  addi   $t0,$t0,%lo(_gp_disp)
+  lw     $v0,%call16(_foo)($gp)
+
+# 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: SYMBOL TABLE:
+# EXE: 00037ff0     *ABS*   00000000 _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: SYMBOL TABLE:
+# SO: 00027ff0     *ABS*   00000000 _gp
+# SO: 00010000     .text   00000000 __start
+# SO: 00010010     .text   00000000 _foo




More information about the llvm-commits mailing list