[lld] r204247 - [Mips] Fix handling of R_MIPS_GOT16 relocation and building local part

Simon Atanasyan simon at atanasyan.com
Wed Mar 19 08:46:25 PDT 2014


Author: atanasyan
Date: Wed Mar 19 10:46:25 2014
New Revision: 204247

URL: http://llvm.org/viewvc/llvm-project?rev=204247&view=rev
Log:
[Mips] Fix handling of R_MIPS_GOT16 relocation and building local part
of GOT.
 * Read addend for R_MIPS_GOT16 relocation.
 * Put only high 16 bits of symbol + addend into GOT entries for
   locally visible symbols.

Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
    lld/trunk/test/elf/Mips/dynlib-dynsym.test
    lld/trunk/test/elf/Mips/got16.test

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=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Wed Mar 19 10:46:25 2014
@@ -78,6 +78,7 @@ private:
       break;
     case R_MIPS_HI16:
     case R_MIPS_LO16:
+    case R_MIPS_GOT16:
       ref->setAddend(*(int16_t *)ap);
       break;
     }

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Wed Mar 19 10:46:25 2014
@@ -18,6 +18,8 @@ namespace elf {
 enum {
   /// \brief Do nothing but mark GOT entry as a global one.
   LLD_R_MIPS_GLOBAL_GOT = 1024,
+  /// \brief Apply high 16 bits of symbol + addend.
+  LLD_R_MIPS_32_HI16 = 1025,
   /// \brief The same as R_MIPS_26 but for global symbols.
   LLD_R_MIPS_GLOBAL_26 = 1026,
   /// \brief Setup hi 16 bits using the symbol this reference refers to.

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=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp Wed Mar 19 10:46:25 2014
@@ -105,6 +105,11 @@ void relocCall16(uint8_t *location, uint
   applyReloc(location, G, 0xffff);
 }
 
+/// \brief LLD_R_MIPS_32_HI16
+void reloc32hi16(uint8_t *location, uint64_t S, int64_t A) {
+  applyReloc(location, (S + A) & 0xffff0000, 0xffffffff);
+}
+
 /// \brief LLD_R_MIPS_HI16
 void relocLldHi16(uint8_t *location, uint64_t S) {
   applyReloc(location, (S + 0x8000) >> 16, 0xffff);
@@ -164,6 +169,9 @@ error_code MipsTargetRelocationHandler::
   case LLD_R_MIPS_GLOBAL_GOT:
     // Do nothing.
     break;
+  case LLD_R_MIPS_32_HI16:
+    reloc32hi16(location, targetVAddress, ref.addend());
+    break;
   case LLD_R_MIPS_GLOBAL_26:
     reloc26ext(location, targetVAddress, ref.addend());
     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=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Wed Mar 19 10:46:25 2014
@@ -125,8 +125,11 @@ private:
   /// \brief Owner of all the Atoms created by this pass.
   RelocationPassFile _file;
 
-  /// \brief Map Atoms to their GOT entries.
-  llvm::DenseMap<const Atom *, GOTAtom *> _gotLocalMap;
+  /// \brief Map Atoms and addend to local GOT entries.
+  typedef std::pair<const Atom *, int64_t> LocalGotMapKeyT;
+  llvm::DenseMap<LocalGotMapKeyT, GOTAtom *> _gotLocalMap;
+
+  /// \brief Map Atoms to global GOT entries.
   llvm::DenseMap<const Atom *, GOTAtom *> _gotGlobalMap;
 
   /// \brief the list of local GOT atoms.
@@ -160,7 +163,7 @@ private:
   void handlePLT(const Reference &ref);
   void handleGOT(const Reference &ref);
 
-  const GOTAtom *getLocalGOTEntry(const Atom *a);
+  const GOTAtom *getLocalGOTEntry(const Reference &ref);
   const GOTAtom *getGlobalGOTEntry(const Atom *a);
   const PLTAtom *getPLTEntry(const Atom *a);
   const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);
@@ -302,7 +305,7 @@ void RelocationPass::handlePLT(const Ref
 
 void RelocationPass::handleGOT(const Reference &ref) {
   if (requireLocalGOT(ref.target()))
-    const_cast<Reference &>(ref).setTarget(getLocalGOTEntry(ref.target()));
+    const_cast<Reference &>(ref).setTarget(getLocalGOTEntry(ref));
   else
     const_cast<Reference &>(ref).setTarget(getGlobalGOTEntry(ref.target()));
 }
@@ -327,18 +330,23 @@ bool RelocationPass::requireLocalGOT(con
   return false;
 }
 
-const GOTAtom *RelocationPass::getLocalGOTEntry(const Atom *a) {
-  auto got = _gotLocalMap.find(a);
+const GOTAtom *RelocationPass::getLocalGOTEntry(const Reference &ref) {
+  const Atom *a = ref.target();
+  LocalGotMapKeyT key(a, ref.addend());
+
+  auto got = _gotLocalMap.find(key);
   if (got != _gotLocalMap.end())
     return got->second;
 
   auto ga = new (_file._alloc) GOT0Atom(_file);
-  _gotLocalMap[a] = ga;
+  _gotLocalMap[key] = ga;
 
   _localGotVector.push_back(ga);
 
-  if (const DefinedAtom *da = dyn_cast<DefinedAtom>(a))
-    ga->addReferenceELF_Mips(R_MIPS_32, 0, da, 0);
+  if (isLocal(a))
+    ga->addReferenceELF_Mips(LLD_R_MIPS_32_HI16, 0, a, ref.addend());
+  else
+    ga->addReferenceELF_Mips(R_MIPS_32, 0, a, 0);
 
   DEBUG_WITH_TYPE("MipsGOT", {
     ga->_name = "__got_";

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Wed Mar 19 10:46:25 2014
@@ -58,6 +58,7 @@ const Registry::KindStrings MipsTargetHa
   LLD_KIND_STRING_ENTRY(R_MIPS_COPY),
   LLD_KIND_STRING_ENTRY(R_MIPS_JUMP_SLOT),
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_GOT),
+  LLD_KIND_STRING_ENTRY(LLD_R_MIPS_32_HI16),
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_GLOBAL_26),
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_HI16),
   LLD_KIND_STRING_ENTRY(LLD_R_MIPS_LO16),

Modified: lld/trunk/test/elf/Mips/dynlib-dynsym.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/dynlib-dynsym.test?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/dynlib-dynsym.test (original)
+++ lld/trunk/test/elf/Mips/dynlib-dynsym.test Wed Mar 19 10:46:25 2014
@@ -83,7 +83,7 @@
 # CHECK-GOT:     section-name:    .got
 # CHECK-GOT:     permissions:     rw-
 # CHECK-GOT:     references:
-# CHECK-GOT:       - kind:            R_MIPS_32
+# CHECK-GOT:       - kind:            LLD_R_MIPS_32_HI16
 # CHECK-GOT:         offset:          0
 # CHECK-GOT:         target:          L003
 # CHECK-GOT:   - ref-name:        L004
@@ -94,7 +94,7 @@
 # CHECK-GOT:     section-name:    .got
 # CHECK-GOT:     permissions:     rw-
 # CHECK-GOT:     references:
-# CHECK-GOT:       - kind:            R_MIPS_32
+# CHECK-GOT:       - kind:            LLD_R_MIPS_32_HI16
 # CHECK-GOT:         offset:          0
 # CHECK-GOT:         target:          L005
 # CHECK-GOT:   - ref-name:        L006

Modified: lld/trunk/test/elf/Mips/got16.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/got16.test?rev=204247&r1=204246&r2=204247&view=diff
==============================================================================
--- lld/trunk/test/elf/Mips/got16.test (original)
+++ lld/trunk/test/elf/Mips/got16.test Wed Mar 19 10:46:25 2014
@@ -6,105 +6,141 @@
 # RUN: lld -flavor gnu -target mipsel -shared --noinhibit-exec -o %t2 %t1
 # RUN: llvm-objdump -t -disassemble %t2 | FileCheck -check-prefix RAW %s
 
-
-# YAML: - ref-name:        [[L002:[-a-zA-Z0-9_]+]]
-# YAML:   type:            got
-# YAML:   content:         [ 00, 00, 00, 00 ]
-# YAML:   alignment:       2^2
-# YAML:   section-choice:  custom-required
-# YAML:   section-name:    .got
-# YAML:   permissions:     rw-
-# YAML:   references:
-# YAML:     - kind:            R_MIPS_32
-# YAML:       offset:          0
-# YAML:       target:          [[L003:[-a-zA-Z0-9_]+]]
-# YAML: - ref-name:        [[L004:[-a-zA-Z0-9_]+]]
-# YAML:   type:            got
-# YAML:   content:         [ 00, 00, 00, 00 ]
-# YAML:   alignment:       2^2
-# YAML:   section-choice:  custom-required
-# YAML:   section-name:    .got
-# YAML:   permissions:     rw-
-# YAML:   references:
-# YAML:     - kind:            R_MIPS_32
-# YAML:       offset:          0
-# YAML:       target:          hidden
-# YAML: - ref-name:        [[L005:[-a-zA-Z0-9_]+]]
-# YAML:   type:            got
-# YAML:   content:         [ 00, 00, 00, 00 ]
-# YAML:   alignment:       2^2
-# YAML:   section-choice:  custom-required
-# YAML:   section-name:    .got
-# YAML:   permissions:     rw-
-# YAML:   references:
-# YAML:     - kind:            LLD_R_MIPS_GLOBAL_GOT
-# YAML:       offset:          0
-# YAML:       target:          glob
-# YAML:     - kind:            R_MIPS_32
-# YAML:       offset:          0
-# YAML:       target:          glob
-# YAML: - ref-name:        [[L006:[-a-zA-Z0-9_]+]]
-# YAML:   type:            got
-# YAML:   content:         [ 00, 00, 00, 00 ]
-# YAML:   alignment:       2^2
-# YAML:   section-choice:  custom-required
-# YAML:   section-name:    .got
-# YAML:   permissions:     rw-
-# YAML:   references:
-# YAML:     - kind:            LLD_R_MIPS_GLOBAL_GOT
-# YAML:       offset:          0
-# YAML:       target:          extern
-# YAML: - ref-name:        [[L007:[-a-zA-Z0-9_]+]]
-# YAML:   alignment:       2^2
-# YAML:   references:
-# YAML:     - kind:            layout-after
-# YAML:       offset:          0
-# YAML:       target:          glob
-# YAML: - name:            glob
-# YAML:   scope:           global
-# YAML:   content:         [ 00, 00, 84, 8F, 00, 00, 84, 24, 00, 00, 84, 8F,
-# YAML:                      00, 00, 84, 8F, 00, 00, 84, 8F ]
-# YAML:   alignment:       2^2
-# YAML:   references:
-# YAML:     - kind:            R_MIPS_LO16
-# YAML:       offset:          4
-# YAML:       target:          [[L003]]
-# YAML:     - kind:            R_MIPS_GOT16
-# YAML:       offset:          8
-# YAML:       target:          [[L004]]
-# YAML:     - kind:            R_MIPS_CALL16
-# YAML:       offset:          12
-# YAML:       target:          [[L005]]
-# YAML:     - kind:            R_MIPS_CALL16
-# YAML:       offset:          16
-# YAML:       target:          [[L006]]
+# Local GOT entries:
+# YAML:       - ref-name:        L003
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_32_HI16
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          L006
+# YAML-NEXT:  - ref-name:        L005
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_32_HI16
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          L006
+# YAML-NEXT:        addend:          66048
+# YAML-NEXT:  - ref-name:        L007
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            R_MIPS_32
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          hidden
+
+# Global GOT entries:
+# YAML-NEXT:  - ref-name:        L008
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_GLOBAL_GOT
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          glob
+# YAML-NEXT:      - kind:            R_MIPS_32
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          glob
+# YAML-NEXT:  - ref-name:        L009
+# YAML-NEXT:    type:            got
+# YAML-NEXT:    content:         [ 00, 00, 00, 00 ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    section-choice:  custom-required
+# YAML-NEXT:    section-name:    .got
+# YAML-NEXT:    permissions:     rw-
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            LLD_R_MIPS_GLOBAL_GOT
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          extern
+
+# Function glob
+# YAML:       - name:            glob
+# YAML-NEXT:    scope:           global
+# YAML-NEXT:    content:         [ 00, 00, 84, 8F, 00, 00, 84, 24, 01, 00, 84, 8F,
+# YAML-NEXT:                       00, 02, 84, 24, 00, 00, 84, 8F, 00, 00, 84, 8F,
+# YAML-NEXT:                       00, 00, 84, 8F ]
+# YAML-NEXT:    alignment:       2^2
+# YAML-NEXT:    references:
+# YAML-NEXT:      - kind:            R_MIPS_GOT16
+# YAML-NEXT:        offset:          0
+# YAML-NEXT:        target:          L003
+# YAML-NEXT:      - kind:            R_MIPS_LO16
+# YAML-NEXT:        offset:          4
+# YAML-NEXT:        target:          L006
+# YAML-NEXT:      - kind:            R_MIPS_GOT16
+# YAML-NEXT:        offset:          8
+# YAML-NEXT:        target:          L005
+# YAML-NEXT:        addend:          66048
+# YAML-NEXT:      - kind:            R_MIPS_LO16
+# YAML-NEXT:        offset:          12
+# YAML-NEXT:        target:          L006
+# YAML-NEXT:        addend:          512
+# YAML-NEXT:      - kind:            R_MIPS_GOT16
+# YAML-NEXT:        offset:          16
+# YAML-NEXT:        target:          L007
+# YAML-NEXT:      - kind:            R_MIPS_CALL16
+# YAML-NEXT:        offset:          20
+# YAML-NEXT:        target:          L008
+# YAML-NEXT:      - kind:            R_MIPS_CALL16
+# YAML-NEXT:        offset:          24
+# YAML-NEXT:        target:          L009
 
 # RAW: Disassembly of section .text:
 # RAW: glob:
-# RAW-NEXT:   148:  18 80 84 8f  lw      $4, -32744($gp)
-# RAW-NEXT:   14c:  00 20 84 24  addiu   $4, $4, 8192
-# RAW-NEXT:   150:  1c 80 84 8f  lw      $4, -32740($gp)
-# RAW-NEXT:   154:  20 80 84 8f  lw      $4, -32736($gp)
-# RAW-NEXT:   158:  24 80 84 8f  lw      $4, -32732($gp)
+# RAW-NEXT:   12c:  18 80 84 8f  lw      $4, -32744($gp)
+# RAW-NEXT:   130:  00 20 84 24  addiu   $4, $4, 8192
+# RAW-NEXT:   134:  1c 80 84 8f  lw      $4, -32740($gp)
+# RAW-NEXT:   138:  00 22 84 24  addiu   $4, $4, 8704
+# RAW-NEXT:   13c:  20 80 84 8f  lw      $4, -32736($gp)
+# RAW-NEXT:   140:  24 80 84 8f  lw      $4, -32732($gp)
+# RAW-NEXT:   144:  28 80 84 8f  lw      $4, -32728($gp)
 
 # RAW: SYMBOL TABLE:
 # RAW: 00000000       *UND*  00000000
-# RAW: 00002000 l     .data  00000000 local
+# RAW: 00002000 l     .data  00000000 str1
+# RAW: 00012200 l     .data  00000005 str2
+# RAW: 0000012c g   F .text  0000001c glob
+# RAW: 00012205 g     .data  00000004 hidden
 
     .global glob
     .ent    glob
 glob:
-    lw      $4,%got(local)($28)      # G(local)
-    addiu   $4,$4,%lo(local)         # local (0x2000)
+    lw      $4,%got(str1)($28)       # G(str1)
+    addiu   $4,$4,%lo(str1)          # str1
+    lw      $4,%got(str2)($28)       # G(str2)
+    addiu   $4,$4,%lo(str2)          # str2
     lw      $4,%got(hidden)($28)     # G(hidden)
     lw      $4,%call16(glob)($28)    # G(glob)
     lw      $4,%call16(extern)($28)  # G(extern)
     .end    glob
+
     .data
-    .type   local,%object
-    .size   local,4
-local:
-    .word   undef
+    .type   str1, %object
+    .size   str1, 0x10200
+str1:
+    .ascii  "str1\000"
+    .space  0x101fb
+
+    .type str2, @object
+    .size str2, 5
+str2:
+    .ascii  "str2\000"
 
     .globl  hidden
     .hidden hidden





More information about the llvm-commits mailing list