[lld] r233277 - [ARM] Implementation of PLT: handling of IFUNC calls (gnu_indirect_function)

Leny Kholodov lkholodov at accesssoftek.com
Thu Mar 26 07:57:51 PDT 2015


Author: lkholodov
Date: Thu Mar 26 09:57:50 2015
New Revision: 233277

URL: http://llvm.org/viewvc/llvm-project?rev=233277&view=rev
Log:
[ARM] Implementation of PLT: handling of IFUNC calls (gnu_indirect_function)

This diff includes implementation of linking calls to ifunc functions.
It provides ifunc entries in PLT and corresponding relocations (R_ARM_ALU_PC_G0_NC,
R_ARM_ALU_PC_G1_NC, R_ARM_LDR_PC_G2 for link-time and R_ARM_IRELATIVE for run-time).

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


Added:
    lld/trunk/test/elf/ARM/rel-group-relocs.test
    lld/trunk/test/elf/ARM/rel-ifunc.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
    lld/trunk/test/elf/ARM/undef-lazy-symbol.test

Modified: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h?rev=233277&r1=233276&r2=233277&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMELFFile.h Thu Mar 26 09:57:50 2015
@@ -54,6 +54,8 @@ public:
 };
 
 template <class ELFT> class ARMELFFile : public ELFFile<ELFT> {
+  typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
+
 public:
   ARMELFFile(std::unique_ptr<MemoryBuffer> mb, ARMLinkingContext &ctx)
       : ELFFile<ELFT>(std::move(mb), ctx) {}
@@ -64,6 +66,15 @@ public:
         new ARMELFFile<ELFT>(std::move(mb), ctx));
   }
 
+protected:
+  /// Returns initial addend; for ARM it is 0, because it is read
+  /// during the relocations applying
+  Reference::Addend getInitialAddend(ArrayRef<uint8_t>,
+                                     uint64_t,
+                                     const Elf_Rel&) const override {
+    return 0;
+  }
+
 private:
   typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
   typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;

Modified: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h?rev=233277&r1=233276&r2=233277&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h Thu Mar 26 09:57:50 2015
@@ -22,6 +22,8 @@ public:
   static std::unique_ptr<ELFLinkingContext> create(llvm::Triple);
   ARMLinkingContext(llvm::Triple);
 
+  bool isRelaOutputFormat() const override { return false; }
+
   void addPasses(PassManager &) override;
 
   uint64_t getBaseAddress() const override {
@@ -29,6 +31,19 @@ public:
       return 0x400000;
     return _baseAddress;
   }
+
+  bool isPLTRelocation(const Reference &r) const override {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    assert(r.kindArch() == Reference::KindArch::ARM);
+    switch (r.kindValue()) {
+    case llvm::ELF::R_ARM_JUMP_SLOT:
+    case llvm::ELF::R_ARM_IRELATIVE:
+      return true;
+    default:
+      return false;
+    }
+  }
 };
 
 // Special methods to check code model of atoms.

Modified: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp?rev=233277&r1=233276&r2=233277&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp Thu Mar 26 09:57:50 2015
@@ -412,6 +412,75 @@ static void relocR_ARM_TLS_LE32(uint8_t
   applyArmReloc(location, result);
 }
 
+template <uint32_t lshift>
+static void relocR_ARM_ALU_PC_GN_NC(uint8_t *location, uint32_t result) {
+  static_assert(lshift < 32 && lshift % 2 == 0,
+                "lshift must be even and less than word size");
+
+  const uint32_t rshift = 32 - lshift;
+  result = ((result >> lshift) & 0xFF) | ((rshift / 2) << 8);
+
+  applyArmReloc(location, result, 0xFFF);
+}
+
+/// \brief R_ARM_ALU_PC_G0_NC - ((S + A) | T) - P => S + A - P
+static void relocR_ARM_ALU_PC_G0_NC(uint8_t *location, uint64_t P, uint64_t S,
+                                    int64_t A) {
+  int32_t result = (int32_t)((S + A) - P);
+
+  if (result < 0)
+    llvm_unreachable(
+        "Negative offsets for group relocations has not been implemented");
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result) << "\n");
+
+  relocR_ARM_ALU_PC_GN_NC<20>(location, (uint32_t)result);
+}
+
+/// \brief R_ARM_ALU_PC_G1_NC - ((S + A) | T) - P => S + A - P
+static void relocR_ARM_ALU_PC_G1_NC(uint8_t *location, uint64_t P, uint64_t S,
+                                    int64_t A) {
+  int32_t result = (int32_t)((S + A) - P);
+
+  if (result < 0)
+    llvm_unreachable(
+        "Negative offsets for group relocations has not been implemented");
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result) << "\n");
+
+  relocR_ARM_ALU_PC_GN_NC<12>(location, (uint32_t)result);
+}
+
+/// \brief R_ARM_LDR_PC_G2 - S + A - P
+static void relocR_ARM_LDR_PC_G2(uint8_t *location, uint64_t P, uint64_t S,
+                                 int64_t A) {
+  int32_t result = (int32_t)((S + A) - P);
+
+  if (result < 0)
+    llvm_unreachable(
+        "Negative offsets for group relocations has not been implemented");
+
+  DEBUG_WITH_TYPE(
+      "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+      llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+      llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+      llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+      llvm::dbgs() << " result: 0x" << Twine::utohexstr((uint32_t)result) << "\n");
+
+  const uint32_t mask = 0xFFF;
+  applyArmReloc(location, (uint32_t)result & mask, mask);
+}
+
 std::error_code ARMTargetRelocationHandler::applyRelocation(
     ELFWriter &writer, llvm::FileOutputBuffer &buf, const lld::AtomLayout &atom,
     const Reference &ref) const {
@@ -426,7 +495,7 @@ std::error_code ARMTargetRelocationHandl
 
   // Calculate proper initial addend for the relocation
   const Reference::Addend addend =
-      readAddend(location, ref.kindValue());
+      readAddend(location, ref.kindValue()) + ref.addend();
 
   // Flags that the relocation addresses Thumb instruction
   bool addressesThumb = false;
@@ -492,6 +561,18 @@ std::error_code ARMTargetRelocationHandl
     relocR_ARM_TLS_LE32(location, relocVAddress, targetVAddress, addend,
                         _armLayout.getTPOffset());
     break;
+  case R_ARM_ALU_PC_G0_NC:
+    relocR_ARM_ALU_PC_G0_NC(location, relocVAddress, targetVAddress, addend);
+    break;
+  case R_ARM_ALU_PC_G1_NC:
+    relocR_ARM_ALU_PC_G1_NC(location, relocVAddress, targetVAddress, addend);
+    break;
+  case R_ARM_LDR_PC_G2:
+    relocR_ARM_LDR_PC_G2(location, relocVAddress, targetVAddress, addend);
+    break;
+  case R_ARM_IRELATIVE:
+    // Runtime only relocations. Ignore here.
+    break;
   default:
     return make_unhandled_reloc_error();
   }

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=233277&r1=233276&r2=233277&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp Thu Mar 26 09:57:50 2015
@@ -28,6 +28,7 @@ using namespace lld;
 using namespace lld::elf;
 using namespace llvm::ELF;
 
+namespace {
 // ARM B/BL instructions of static relocation veneer.
 // TODO: consider different instruction set for archs below ARMv5
 // (one as for Thumb may be used though it's less optimal).
@@ -48,7 +49,17 @@ static const uint8_t Veneer_THM_B_BL_Sta
 // .got values
 static const uint8_t ARMGotAtomContent[4] = {0};
 
-namespace {
+// .plt values (other entries)
+static const uint8_t ARMPltAtomContent[12] = {
+    0x00, 0xc0, 0x8f,
+    0xe2, // add    ip, pc, #offset[G0]
+    0x00, 0xc0, 0x8c,
+    0xe2, // add    ip, ip, #offset[G1]
+
+    0x00, 0xf0, 0xbc,
+    0xe5, // ldr    pc, [ip, #offset[G2]]!
+};
+
 /// \brief Atoms that hold veneer code.
 class VeneerAtom : public SimpleELFDefinedAtom {
   StringRef _section;
@@ -119,6 +130,15 @@ public:
   Alignment alignment() const override { return 4; }
 };
 
+class ARMPLTAtom : public PLTAtom {
+public:
+  ARMPLTAtom(const File &f, StringRef secName) : PLTAtom(f, secName) {}
+
+  ArrayRef<uint8_t> rawContent() const override {
+    return llvm::makeArrayRef(ARMPltAtomContent);
+  }
+};
+
 class ELFPassFile : public SimpleFile {
 public:
   ELFPassFile(const ELFLinkingContext &eti) : SimpleFile("ELFPassFile") {
@@ -140,8 +160,16 @@ template <class Derived> class ARMReloca
       return;
     assert(ref.kindArch() == Reference::KindArch::ARM);
     switch (ref.kindValue()) {
+    case R_ARM_ABS32:
+    case R_ARM_REL32:
+    case R_ARM_TARGET1:
+    case R_ARM_THM_MOVW_ABS_NC:
+    case R_ARM_THM_MOVT_ABS:
+    case R_ARM_THM_CALL:
+    case R_ARM_CALL:
     case R_ARM_JUMP24:
     case R_ARM_THM_JUMP24:
+      static_cast<Derived *>(this)->handleIFUNC(ref);
       static_cast<Derived *>(this)->handleVeneer(atom, ref);
       break;
     case R_ARM_TLS_IE32:
@@ -152,6 +180,15 @@ template <class Derived> class ARMReloca
 
 protected:
   std::error_code handleVeneer(const DefinedAtom &atom, const Reference &ref) {
+    const auto kindValue = ref.kindValue();
+    switch (kindValue) {
+    case R_ARM_JUMP24:
+    case R_ARM_THM_JUMP24:
+      break;
+    default:
+      return std::error_code();
+    }
+
     // Target symbol and relocated place should have different
     // instruction sets in order a veneer to be generated in between.
     const auto *target = dyn_cast<DefinedAtom>(ref.target());
@@ -163,7 +200,6 @@ protected:
 
     // Veneers may only be generated for STT_FUNC target symbols
     // or for symbols located in sections different to the place of relocation.
-    const auto kindValue = ref.kindValue();
     StringRef secName = atom.customSectionName();
     if (DefinedAtom::typeCode != target->contentType() &&
         !target->customSectionName().equals(secName)) {
@@ -227,6 +263,65 @@ protected:
     return g;
   }
 
+  /// \brief Create a PLT entry referencing PLTGOT entry.
+  ///
+  /// The function creates the PLT entry object and passes ownership
+  /// over it to the caller.
+  PLTAtom *createPLTforGOT(const GOTAtom *ga) {
+    auto pa = new (_file._alloc) ARMPLTAtom(_file, ".plt");
+    pa->addReferenceELF_ARM(R_ARM_ALU_PC_G0_NC, 0, ga, -8);
+    pa->addReferenceELF_ARM(R_ARM_ALU_PC_G1_NC, 4, ga, -4);
+    pa->addReferenceELF_ARM(R_ARM_LDR_PC_G2, 8, ga, 0);
+    return pa;
+  }
+
+  /// \brief get the PLT entry for a given IFUNC Atom.
+  ///
+  /// If the entry does not exist. Both the GOT and PLT entry is created.
+  const PLTAtom *getIFUNCPLTEntry(const DefinedAtom *da) {
+    auto plt = _pltMap.find(da);
+    if (plt != _pltMap.end())
+      return plt->second;
+    auto ga = new (_file._alloc) ARMGOTAtom(_file, ".got.plt");
+    ga->addReferenceELF_ARM(R_ARM_ABS32, 0, da, 0);
+    ga->addReferenceELF_ARM(R_ARM_IRELATIVE, 0, da, 0);
+    auto pa = createPLTforGOT(ga);
+
+#ifndef NDEBUG
+    ga->_name = "__got_ifunc_";
+    ga->_name += da->name();
+    pa->_name = "__plt_ifunc_";
+    pa->_name += da->name();
+#endif
+
+    _gotMap[da] = ga;
+    _pltMap[da] = pa;
+    _gotVector.push_back(ga);
+    _pltVector.push_back(pa);
+    return pa;
+  }
+
+  /// \brief Handle adding of PLT entry by marking the reference
+  /// as requiring veneer generation.
+  std::error_code handlePLTEntry(Reference &ref, const PLTAtom *pa) {
+    ref.setTarget(pa);
+
+    return std::error_code();
+  }
+
+  /// \brief Redirect the call to the PLT stub for the target IFUNC.
+  ///
+  /// This create a PLT and GOT entry for the IFUNC if one does not exist. The
+  /// GOT entry and a IRELATIVE relocation to the original target resolver.
+  std::error_code handleIFUNC(const Reference &ref) {
+    auto target = dyn_cast<const DefinedAtom>(ref.target());
+    if (target && target->contentType() == DefinedAtom::typeResolver) {
+      return handlePLTEntry(const_cast<Reference &>(ref),
+                            getIFUNCPLTEntry(target));
+    }
+    return std::error_code();
+  }
+
 public:
   ARMRelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx) {}
 
@@ -278,6 +373,10 @@ public:
       got->setOrdinal(ordinal++);
       mf->addAtom(*got);
     }
+    for (auto &plt : _pltVector) {
+      plt->setOrdinal(ordinal++);
+      mf->addAtom(*plt);
+    }
     for (auto &veneer : _veneerVector) {
       veneer->setOrdinal(ordinal++);
       mf->addAtom(*veneer);
@@ -292,11 +391,15 @@ protected:
   /// \brief Map Atoms to their GOT entries.
   llvm::DenseMap<const Atom *, GOTAtom *> _gotMap;
 
+  /// \brief Map Atoms to their PLT entries.
+  llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
+
   /// \brief Map Atoms to their veneers.
   llvm::DenseMap<const Atom *, VeneerAtom *> _veneerMap;
 
   /// \brief the list of GOT/PLT atoms
   std::vector<GOTAtom *> _gotVector;
+  std::vector<PLTAtom *> _pltVector;
 
   /// \brief the list of veneer atoms.
   std::vector<VeneerAtom *> _veneerVector;

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFFile.h?rev=233277&r1=233276&r2=233277&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFFile.h Thu Mar 26 09:57:50 2015
@@ -316,6 +316,13 @@ protected:
     return symbol->st_value;
   }
 
+  /// Returns initial addend
+  virtual Reference::Addend getInitialAddend(ArrayRef<uint8_t> symContent,
+                                  uint64_t symbolValue,
+                                  const Elf_Rel& reference) const {
+    return *(symContent.data() + reference.r_offset - symbolValue);
+  }
+
   /// Process the common symbol and create an atom for it.
   virtual ErrorOr<ELFCommonAtom<ELFT> *>
   handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
@@ -1030,7 +1037,7 @@ void ELFFile<ELFT>::createRelocationRefe
     auto elfRelocation = new (_readerStorage)
         ELFReference<ELFT>(rel.r_offset - symValue, kindArch(),
                            rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
-    int32_t addend = *(symContent.data() + rel.r_offset - symValue);
+    Reference::Addend addend = getInitialAddend(symContent, symValue, rel);
     elfRelocation->setAddend(addend);
     addReferenceToSymbol(elfRelocation, symbol);
     _references.push_back(elfRelocation);

Added: lld/trunk/test/elf/ARM/rel-group-relocs.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-group-relocs.test?rev=233277&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-group-relocs.test (added)
+++ lld/trunk/test/elf/ARM/rel-group-relocs.test Thu Mar 26 09:57:50 2015
@@ -0,0 +1,69 @@
+# Check handling of group relocations (R_ARM_ALU_PC_G0_NC, R_ARM_ALU_PC_G1_NC,
+# R_ARM_LDR_PC_G2).
+# 
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: -e plt_func %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t -disassemble | FileCheck %s
+
+# CHECK: Disassembly of section .text:
+# CHECK: plt_func:
+# CHECK:   400074:	00 c6 8f e2                                  	add	r12, pc, #0, #12
+#                         ^ after execution: r12=0x40007c
+# CHECK:   400078:	00 ca 8c e2                                  	add	r12, r12, #0, #20
+#                         ^ after execution: r12=0x40007C
+# CHECK:   40007c:	84 ff bc e5                                  	ldr	pc, [r12, #3972]!
+#                         ^ referenced address is 0x401000, after execution pc=0x400074
+# CHECK: Contents of section .data:
+# CHECK:  401000 74004000
+#                  ^ this value is written to pc after execution of comand 0x40007c
+#          ^ this address is referenced by command at 0x40007c
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400074 g     F .text	0000000c plt_func
+# CHECK: 00401000 g       .data	00000004 got_func
+
+---
+FileHeader:      
+  Class:           ELFCLASS32
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_ARM
+Sections:        
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    AddressAlign:    0x4
+    Content:         00C08FE200C08CE200F0BCE5
+  - Name:            .rela.text
+    Type:            SHT_RELA
+    Link:            .symtab
+    Info:            .text
+    AddressAlign:    0x4
+    Relocations:     
+      - Offset:          0
+        Symbol:          got_func
+        Type:            R_ARM_ALU_PC_G0_NC
+        Addend:          -8
+      - Offset:          0x4
+        Symbol:          got_func
+        Type:            R_ARM_ALU_PC_G1_NC
+        Addend:          -4
+      - Offset:          0x8
+        Symbol:          got_func
+        Type:            R_ARM_LDR_PC_G2
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    AddressAlign:    0x4
+    Content:         74004000
+Symbols:         
+  Local:           
+  Global:          
+    - Name:            plt_func
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0xC
+    - Name:            got_func
+      Section:         .data
+      Size:            0x4
+...

Added: lld/trunk/test/elf/ARM/rel-ifunc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-ifunc.test?rev=233277&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-ifunc.test (added)
+++ lld/trunk/test/elf/ARM/rel-ifunc.test Thu Mar 26 09:57:50 2015
@@ -0,0 +1,102 @@
+# Check handling of IFUNC (gnu_indirect_function).
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .rel.plt:
+# CHECK: 400074 00104000
+# CHECK: Contents of section .plt:
+# CHECK: 400080 00c68fe2 00ca8ce2 78ffbce5
+# CHECK: Contents of section .text:
+# CHECK: 4001ac 00482de9 04b08de2 d4ffffeb b0ffffeb
+#                                             ^ bl #-320 (to address 0x400080=__plt_ifunc_myfunc)
+# CHECK: Contents of section .got.plt:
+# CHECK: 401000 c4004000
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400080 l     F .plt	0000000c __plt_ifunc_myfunc
+# CHECK: 004000c4 g       .text	00000020 myfunc
+# CHECK: 00400074 g       *ABS*	00000000 __rel_iplt_start
+# CHECK: 0040007c g       *ABS*	00000000 __rel_iplt_end
+
+---
+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:         04B02DE500B08DE20130A0E30300A0E100D04BE204B09DE41EFF2FE104B02DE500B08DE20230A0E30300A0E100D04BE204B09DE41EFF2FE104B02DE500B08DE2003000E3003040E30300A0E100D04BE204B09DE41EFF2FE100482DE904B08DE208D04DE208000BE508301BE533FF2FE10030A0E10300A0E104D04BE20088BDE800482DE904B08DE210D04DE2003000E3003040E308300BE5190000EA08301BE50C300BE50C301BE5003093E510300BE50C301BE5043093E57330EFE614300BE514301BE5A00053E30130A0030030A0137330EFE6000053E30600000A10301BE5003093E50300A0E1DAFFFFEB0020A0E110301BE5002083E508301BE5083083E208300BE508201BE5003000E3003040E3030052E1E0FFFF3A04D04BE20088BDE800482DE904B08DE2D4FFFFEBFEFFFFEB0030A0E30300A0E10088BDE8
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:     
+      - Offset:          0x0000000000000040
+        Symbol:          myfunc1
+        Type:            R_ARM_MOVW_ABS_NC
+      - Offset:          0x0000000000000044
+        Symbol:          myfunc1
+        Type:            R_ARM_MOVT_ABS
+      - Offset:          0x000000000000008C
+        Symbol:          __rel_iplt_start
+        Type:            R_ARM_MOVW_ABS_NC
+      - Offset:          0x0000000000000090
+        Symbol:          __rel_iplt_start
+        Type:            R_ARM_MOVT_ABS
+      - Offset:          0x0000000000000108
+        Symbol:          __rel_iplt_end
+        Type:            R_ARM_MOVW_ABS_NC
+      - Offset:          0x000000000000010C
+        Symbol:          __rel_iplt_end
+        Type:            R_ARM_MOVT_ABS
+      - Offset:          0x000000000000012C
+        Symbol:          myfunc
+        Type:            R_ARM_CALL
+Symbols:         
+  Local:           
+    - Name:            .text
+      Type:            STT_SECTION
+      Section:         .text
+    - Name:            '$a'
+      Section:         .text
+    - Name:            elf_ifunc_invoke
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000058
+      Size:            0x0000000000000028
+    - Name:            apply_irel
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000080
+      Size:            0x00000000000000A0
+  Global:          
+    - Name:            myfunc1
+      Type:            STT_FUNC
+      Section:         .text
+      Size:            0x000000000000001C
+    - Name:            myfunc2
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x000000000000001C
+      Size:            0x000000000000001C
+    - Name:            myfunc
+      Type:            STT_GNU_IFUNC
+      Section:         .text
+      Value:           0x0000000000000038
+      Size:            0x0000000000000020
+    - Name:            _start
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000120
+      Size:            0x000000000000001C
+  Weak:            
+    - Name:            __rel_iplt_start
+    - Name:            __rel_iplt_end
+...

Modified: lld/trunk/test/elf/ARM/undef-lazy-symbol.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/undef-lazy-symbol.test?rev=233277&r1=233276&r2=233277&view=diff
==============================================================================
--- lld/trunk/test/elf/ARM/undef-lazy-symbol.test (original)
+++ lld/trunk/test/elf/ARM/undef-lazy-symbol.test Thu Mar 26 09:57:50 2015
@@ -5,7 +5,7 @@
 # RUN: --noinhibit-exec %t-got.o -o %t
 # RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=GOT %s
 
-# GOT:   Name: _GLOBAL_OFFSET_TABLE_ (185)
+# GOT:   Name: _GLOBAL_OFFSET_TABLE_ (183)
 # GOT-NEXT:   Value: {{[0-9]+}}
 # GOT-NEXT:   Size: 0
 # GOT-NEXT:   Binding: Global (0x1)
@@ -20,7 +20,7 @@
 # RUN: --defsym=main=fn --noinhibit-exec %t-exidx.o -o %t
 # RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=EXIDX %s
 
-# EXIDX:   Name: __exidx_start (188)
+# EXIDX:   Name: __exidx_start (186)
 # EXIDX-NEXT:   Value: {{[0-9]+}}
 # EXIDX-NEXT:   Size: 0
 # EXIDX-NEXT:   Binding: Global (0x1)
@@ -28,7 +28,7 @@
 # EXIDX-NEXT:   Other: 0
 # EXIDX-NEXT:   Section: Absolute (0xFFF1)
 #
-# EXIDX:   Name: __exidx_end (202)
+# EXIDX:   Name: __exidx_end (200)
 # EXIDX-NEXT:   Value: {{[0-9]+}}
 # EXIDX-NEXT:   Size: 0
 # EXIDX-NEXT:   Binding: Global (0x1)
@@ -44,7 +44,7 @@
 # RUN: --noinhibit-exec %t-got.o %t-exidx.o -o %t
 # RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=SYMS %s
 
-# SYMS:   Name: _GLOBAL_OFFSET_TABLE_ (188)
+# SYMS:   Name: _GLOBAL_OFFSET_TABLE_ (186)
 # SYMS-NEXT:   Value: {{[0-9]+}}
 # SYMS-NEXT:   Size: 0
 # SYMS-NEXT:   Binding: Global (0x1)
@@ -52,7 +52,7 @@
 # SYMS-NEXT:   Other: 0
 # SYMS-NEXT:   Section: Absolute (0xFFF1)
 #
-# SYMS:   Name: __exidx_start (210)
+# SYMS:   Name: __exidx_start (208)
 # SYMS-NEXT:   Value: {{[0-9]+}}
 # SYMS-NEXT:   Size: 0
 # SYMS-NEXT:   Binding: Global (0x1)
@@ -60,7 +60,7 @@
 # SYMS-NEXT:   Other: 0
 # SYMS-NEXT:   Section: Absolute (0xFFF1)
 #
-# SYMS:   Name: __exidx_end (224)
+# SYMS:   Name: __exidx_end (222)
 # SYMS-NEXT:   Value: {{[0-9]+}}
 # SYMS-NEXT:   Size: 0
 # SYMS-NEXT:   Binding: Global (0x1)





More information about the llvm-commits mailing list