[lld] r238015 - [ARM] Ability to add GOT and PLTGOT entries for same symbol

Denis Protivensky dprotivensky at accesssoftek.com
Fri May 22 04:23:40 PDT 2015


Author: denis-protivensky
Date: Fri May 22 06:23:39 2015
New Revision: 238015

URL: http://llvm.org/viewvc/llvm-project?rev=238015&view=rev
Log:
[ARM] Ability to add GOT and PLTGOT entries for same symbol

These two serve different purpose:
PLTGOT entries are (usually) lazily resolved and serve as trampolines
to correctly call dynamically linked functions. They often have
R_*_JUMP_SLOT dynamic relocation type used.
Simple GOT entries hold other things, one of them may be
R_*_GLOB_DAT to correctly reference global and static data. This
is also used to hold dynamically linked function's address.

To properly handle cases when shared object's function is called
and at the same time its address is taken, we need to be able to have
both GOT and PLTGOT entries bearing different dynamic relocation types
for the same symbol.

Added:
    lld/trunk/test/elf/ARM/two-got-for-symbol.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp?rev=238015&r1=238014&r2=238015&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp Fri May 22 06:23:39 2015
@@ -566,8 +566,8 @@ protected:
 
     // Create specific GOT entry.
     const auto *ga = (static_cast<Derived *>(this)->*gotFactory)(da);
-    assert(_gotAtoms.lookup(da) == ga &&
-           "GOT entry should be added to the map");
+    assert(_gotpltAtoms.lookup(da) == ga &&
+           "GOT entry should be added to the PLTGOT map");
     assert(ga->customSectionName() == ".got.plt" &&
            "GOT entry should be in a special section");
 
@@ -592,7 +592,7 @@ protected:
 
   /// \brief Create the GOT entry for a given IFUNC Atom.
   const GOTAtom *createIFUNCGOT(const Atom *da) {
-    assert(!_gotAtoms.lookup(da) && "IFUNC GOT entry already exists");
+    assert(!_gotpltAtoms.lookup(da) && "IFUNC GOT entry already exists");
     auto g = new (_file._alloc) ARMGOTPLTAtom(_file);
     g->addReferenceELF_ARM(R_ARM_ABS32, 0, da, 0);
     g->addReferenceELF_ARM(R_ARM_IRELATIVE, 0, da, 0);
@@ -600,7 +600,7 @@ protected:
     g->_name = "__got_ifunc_";
     g->_name += da->name();
 #endif
-    _gotAtoms[da] = g;
+    _gotpltAtoms[da] = g;
     return g;
   }
 
@@ -740,6 +740,11 @@ public:
       got->setOrdinal(ordinal++);
       mf->addAtom(*got);
     }
+    for (auto &gotKV : _gotpltAtoms) {
+      auto &got = gotKV.second;
+      got->setOrdinal(ordinal++);
+      mf->addAtom(*got);
+    }
     for (auto &objectKV : _objectAtoms) {
       auto &obj = objectKV.second;
       obj->setOrdinal(ordinal++);
@@ -764,6 +769,9 @@ protected:
   /// \brief Map Atoms to their GOT entries.
   llvm::MapVector<const Atom *, GOTAtom *> _gotAtoms;
 
+  /// \brief Map Atoms to their PLTGOT entries.
+  llvm::MapVector<const Atom *, GOTAtom *> _gotpltAtoms;
+
   /// \brief Map Atoms to their Object entries.
   llvm::MapVector<const Atom *, ObjectAtom *> _objectAtoms;
 
@@ -861,7 +869,7 @@ public:
 
   /// \brief Create the GOT entry for a given atom.
   const GOTAtom *createPLTGOT(const Atom *da) {
-    assert(!_gotAtoms.lookup(da) && "PLTGOT entry already exists");
+    assert(!_gotpltAtoms.lookup(da) && "PLTGOT entry already exists");
     auto g = new (_file._alloc) ARMGOTPLTAtom(_file);
     g->addReferenceELF_ARM(R_ARM_ABS32, 0, getPLT0(), 0);
     g->addReferenceELF_ARM(R_ARM_JUMP_SLOT, 0, da, 0);
@@ -869,7 +877,7 @@ public:
     g->_name = "__got_plt0_";
     g->_name += da->name();
 #endif
-    _gotAtoms[da] = g;
+    _gotpltAtoms[da] = g;
     return g;
   }
 

Added: lld/trunk/test/elf/ARM/two-got-for-symbol.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/two-got-for-symbol.test?rev=238015&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/two-got-for-symbol.test (added)
+++ lld/trunk/test/elf/ARM/two-got-for-symbol.test Fri May 22 06:23:39 2015
@@ -0,0 +1,63 @@
+# Check that two GOT entries containing R_ARM_JUMP_SLOT and
+# R_ARM_GLOB_DAT may be present for the same symbol in the linked binary.
+
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -shared \
+# RUN: --noinhibit-exec %t-o.o -lfn -L%p/Inputs -o %t
+# RUN: llvm-readobj -relocations %t | FileCheck %s
+
+# CHECK: 0x401000 R_ARM_GLOB_DAT fn 0x0
+# CHECK: 0x401010 R_ARM_JUMP_SLOT fn 0x0
+
+---
+FileHeader:
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+  Flags:           [ EF_ARM_EABI_VER5 ]
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x0000000000000004
+    Content:         10482DE908B08DE20CD04DE230209FE502208FE02C309FE5033092E710300BE5FEFFFFEB0040A0E110301BE533FF2FE10030A0E1033084E00300A0E108D04BE21088BDE82C00000000000000
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000020
+        Symbol:          fn
+        Type:            R_ARM_CALL
+      - Offset:          0x0000000000000044
+        Symbol:          _GLOBAL_OFFSET_TABLE_
+        Type:            R_ARM_BASE_PREL
+      - Offset:          0x0000000000000048
+        Symbol:          fn
+        Type:            R_ARM_GOT_BREL
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+  - Name:            .bss
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x0000000000000001
+    Content:         ''
+Symbols:
+  Local:
+    - Name:            '$a'
+      Section:         .text
+    - Name:            '$d'
+      Section:         .text
+      Value:           0x0000000000000044
+  Global:
+    - Name:            f
+      Type:            STT_FUNC
+      Section:         .text
+    - Name:            fn
+    - Name:            _GLOBAL_OFFSET_TABLE_
+...





More information about the llvm-commits mailing list