[lld] r227244 - [Mips] Support R_MIPS_GPREL16 relocation

Simon Atanasyan simon at atanasyan.com
Tue Jan 27 13:11:11 PST 2015


Author: atanasyan
Date: Tue Jan 27 15:11:11 2015
New Revision: 227244

URL: http://llvm.org/viewvc/llvm-project?rev=227244&view=rev
Log:
[Mips] Support R_MIPS_GPREL16 relocation

Added:
    lld/trunk/test/elf/Mips/rel-gprel16.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=227244&r1=227243&r2=227244&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Tue Jan 27 15:11:11 2015
@@ -94,7 +94,7 @@ public:
   }
 
   /// \brief gp register value stored in the .reginfo section.
-  int64_t getGP0() const { return *_gp0; }
+  int64_t getGP0() const { return _gp0 ? *_gp0 : 0; }
 
   /// \brief .tdata section address plus fixed offset.
   uint64_t getTPOffset() const { return *_tpOff; }
@@ -204,6 +204,7 @@ private:
       return readAddend(ap, 0x3ffffff, false) << 2;
     case llvm::ELF::R_MIPS_HI16:
     case llvm::ELF::R_MIPS_LO16:
+    case llvm::ELF::R_MIPS_GPREL16:
     case llvm::ELF::R_MIPS_GOT16:
     case llvm::ELF::R_MIPS_TLS_DTPREL_HI16:
     case llvm::ELF::R_MIPS_TLS_DTPREL_LO16:

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp?rev=227244&r1=227243&r2=227244&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Tue Jan 27 15:11:11 2015
@@ -84,6 +84,15 @@ static void relocGOT(uint32_t &ins, uint
   applyReloc(ins, G, 0xffff);
 }
 
+/// \brief R_MIPS_GPREL16
+/// local: sign-extend(A) + S + GP0 - GP
+/// external: sign-extend(A) + S - GP
+static void relocGPRel16(uint32_t &ins, uint64_t S, int64_t A, uint64_t GP) {
+  // We added GP0 to addendum for a local symbol during a Relocation pass.
+  int32_t result = signExtend<16>(A) + S - GP;
+  applyReloc(ins, result, 0xffff);
+}
+
 /// \brief R_MIPS_GPREL32
 /// local: rel32 A + S + GP0 - GP (truncate)
 static void relocGPRel32(uint32_t &ins, uint64_t P, uint64_t S, int64_t A,
@@ -321,6 +330,9 @@ std::error_code RelocationHandler<ELFT>:
   case R_MICROMIPS_TLS_TPREL_LO16:
     relocLo16(ins, 0, targetVAddress, ref.addend(), false, true);
     break;
+  case R_MIPS_GPREL16:
+    relocGPRel16(ins, targetVAddress, ref.addend(), gpAddr);
+    break;
   case R_MIPS_GPREL32:
     relocGPRel32(ins, relocVAddress, targetVAddress, ref.addend(), gpAddr);
     break;

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp?rev=227244&r1=227243&r2=227244&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Tue Jan 27 15:11:11 2015
@@ -338,7 +338,6 @@ private:
   void handlePlain(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
   void handle26(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
   void handleGOT(Reference &ref);
-  void handleGPRel(const MipsELFDefinedAtom<ELFT> &atom, Reference &ref);
 
   const GOTAtom *getLocalGOTEntry(const Reference &ref);
   const GOTAtom *getGlobalGOTEntry(const Atom *a);
@@ -486,8 +485,12 @@ void RelocationPass<ELFT>::handleReferen
   case R_MICROMIPS_CALL16:
     handleGOT(ref);
     break;
+  case R_MIPS_GPREL16:
+    if (isLocal(ref.target()))
+      ref.setAddend(ref.addend() + atom.file().getGP0());
+    break;
   case R_MIPS_GPREL32:
-    handleGPRel(atom, ref);
+    ref.setAddend(ref.addend() + atom.file().getGP0());
     break;
   case R_MIPS_TLS_DTPREL_HI16:
   case R_MIPS_TLS_DTPREL_LO16:
@@ -524,6 +527,7 @@ static bool isConstrainSym(const MipsELF
   case R_MIPS_NONE:
   case R_MIPS_JALR:
   case R_MICROMIPS_JALR:
+  case R_MIPS_GPREL16:
   case R_MIPS_GPREL32:
     return false;
   default:
@@ -725,13 +729,6 @@ template <typename ELFT> void Relocation
 }
 
 template <typename ELFT>
-void RelocationPass<ELFT>::handleGPRel(const MipsELFDefinedAtom<ELFT> &atom,
-                                       Reference &ref) {
-  assert(ref.kindValue() == R_MIPS_GPREL32);
-  ref.setAddend(ref.addend() + atom.file().getGP0());
-}
-
-template <typename ELFT>
 bool RelocationPass<ELFT>::isLocalCall(const Atom *a) const {
   Atom::Scope scope;
   if (auto *da = dyn_cast<DefinedAtom>(a))

Added: lld/trunk/test/elf/Mips/rel-gprel16.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rel-gprel16.test?rev=227244&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rel-gprel16.test (added)
+++ lld/trunk/test/elf/Mips/rel-gprel16.test Tue Jan 27 15:11:11 2015
@@ -0,0 +1,104 @@
+# Check R_MIPS_GPREL16 relocation handling.
+#
+# RUN: yaml2obj -format=elf %s > %t-obj
+# RUN: lld -flavor gnu -target mipsel -e G1 -shared -o %t.so %t-obj
+# RUN: llvm-readobj -symbols %t.so | FileCheck -check-prefix=SYM %s
+# RUN: llvm-objdump -s %t.so | FileCheck -check-prefix=SEC %s
+
+# SYM:      Name: L1 (1)
+# SYM-NEXT: Value: 0xCC
+# SYM-NEXT: Size: 4
+# SYM-NEXT: Binding: Local (0x0)
+# SYM-NEXT: Type: Function (0x2)
+# SYM-NEXT: Other: 0
+# SYM-NEXT: Section: .text (0x4)
+
+# SYM:      Name: G1 (4)
+# SYM-NEXT: Value: 0xD0
+# SYM-NEXT: Size: 4
+# SYM-NEXT: Binding: Global (0x1)
+# SYM-NEXT: Type: Function (0x2)
+# SYM-NEXT: Other: 0
+# SYM-NEXT: Section: .text (0x4)
+
+# SYM:      Name: _gp (34)
+# SYM-NEXT: Value: 0x8FF0
+# SYM-NEXT: Size: 0
+# SYM-NEXT: Binding: Global (0x1)
+# SYM-NEXT: Type: Object (0x1)
+# SYM-NEXT: Other: 0
+# SYM-NEXT: Section: Absolute (0xFFF1)
+
+# 0x160db == 0xffff (addend) + 0x00cc (L1) + 0x01f000 (GP0) - 0x8ff0 (_gp)
+# SEC:      Contents of section .rodata:
+# SEC-NEXT:  00d4 db600008 00000000 00000000 00000000  .`..............
+
+!ELF
+FileHeader:
+  Class:    ELFCLASS32
+  Data:     ELFDATA2LSB
+  Type:     ET_REL
+  Machine:  EM_MIPS
+  Flags:    [ EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC,
+              EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2 ]
+Sections:
+- Type:         SHT_PROGBITS
+  Name:         .text
+  Type:         SHT_PROGBITS
+  Flags:        [ SHF_ALLOC, SHF_EXECINSTR ]
+  AddressAlign: 0x04
+  Size:         0x08
+
+- Type:         SHT_REL
+  Name:         .rel.text
+  Type:         SHT_REL
+  Link:         .symtab
+  Info:         .text
+  AddressAlign: 0x04
+  Relocations:
+    - Offset:      0
+      Symbol:      .rodata
+      Type:        R_MIPS_GOT16
+    - Offset:      4
+      Symbol:      .rodata
+      Type:        R_MIPS_LO16
+
+- Type:         SHT_PROGBITS
+  Name:         .rodata
+  Type:         SHT_PROGBITS
+  Flags:        [ SHF_ALLOC ]
+  AddressAlign: 0x04
+  Content:      ffff0008000000000000000000000000
+
+- Type:         SHT_REL
+  Name:         .rel.rodata
+  Type:         SHT_REL
+  Link:         .symtab
+  Info:         .rodata
+  AddressAlign: 0x04
+  Relocations:
+    - Offset:      0
+      Symbol:      L1
+      Type:        R_MIPS_GPREL16
+
+- Type:         SHT_MIPS_REGINFO
+  Name:         .reginfo
+  Type:         SHT_MIPS_REGINFO
+  Flags:        [ SHF_ALLOC ]
+  AddressAlign: 0x01
+  Content:      000000000000000000000000000000000000000000f00100
+
+Symbols:
+  Local:
+    - Name:     L1
+      Section:  .text
+      Value:    0x00
+      Size:     0x04
+    - Name:     .rodata
+      Type:     STT_SECTION
+      Section:  .rodata
+  Global:
+    - Name:     G1
+      Section:  .text
+      Value:    0x04
+      Size:     0x04





More information about the llvm-commits mailing list