[lld] r235705 - [ARM] Implement R_ARM_COPY relocation

Denis Protivensky dprotivensky at accesssoftek.com
Fri Apr 24 01:53:02 PDT 2015


Author: denis-protivensky
Date: Fri Apr 24 03:53:02 2015
New Revision: 235705

URL: http://llvm.org/viewvc/llvm-project?rev=235705&view=rev
Log:
[ARM] Implement R_ARM_COPY relocation

This adds support of copying objects from shared libraries.

Added:
    lld/trunk/test/elf/ARM/Inputs/libobj.so   (with props)
    lld/trunk/test/elf/ARM/Inputs/obj.c
    lld/trunk/test/elf/ARM/rel-copy.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp

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=235705&r1=235704&r2=235705&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h Fri Apr 24 03:53:02 2015
@@ -39,12 +39,20 @@ public:
     assert(r.kindArch() == Reference::KindArch::ARM);
     switch (r.kindValue()) {
     case llvm::ELF::R_ARM_TLS_TPOFF32:
+    case llvm::ELF::R_ARM_COPY:
       return true;
     default:
       return false;
     }
   }
 
+  bool isCopyRelocation(const Reference &r) const override {
+    if (r.kindNamespace() != Reference::KindNamespace::ELF)
+      return false;
+    assert(r.kindArch() == Reference::KindArch::ARM);
+    return r.kindValue() == llvm::ELF::R_ARM_COPY;
+  }
+
   bool isPLTRelocation(const Reference &r) const override {
     if (r.kindNamespace() != Reference::KindNamespace::ELF)
       return false;

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=235705&r1=235704&r2=235705&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationPass.cpp Fri Apr 24 03:53:02 2015
@@ -304,6 +304,14 @@ public:
   Alignment alignment() const override { return 4; }
 };
 
+/// \brief Atom which represents an object for which a COPY relocation will
+/// be generated.
+class ARMObjectAtom : public ObjectAtom {
+public:
+  ARMObjectAtom(const File &f) : ObjectAtom(f) {}
+  Alignment alignment() const override { return 4; }
+};
+
 class ELFPassFile : public SimpleFile {
 public:
   ELFPassFile(const ELFLinkingContext &eti) : SimpleFile("ELFPassFile") {
@@ -732,6 +740,11 @@ public:
       got->setOrdinal(ordinal++);
       mf->addAtom(*got);
     }
+    for (auto &objectKV : _objectAtoms) {
+      auto &obj = objectKV.second;
+      obj->setOrdinal(ordinal++);
+      mf->addAtom(*obj);
+    }
     for (auto &veneerKV : _veneerAtoms) {
       auto &veneer = veneerKV.second;
       auto *m = veneer._mapping;
@@ -751,6 +764,9 @@ protected:
   /// \brief Map Atoms to their GOT entries.
   llvm::MapVector<const Atom *, GOTAtom *> _gotAtoms;
 
+  /// \brief Map Atoms to their Object entries.
+  llvm::MapVector<const Atom *, ObjectAtom *> _objectAtoms;
+
   /// \brief Map Atoms to their PLT entries depending on the code model.
   struct PLTWithVeneer {
     PLTWithVeneer(PLTAtom *p = nullptr, PLTAtom *v = nullptr)
@@ -857,11 +873,26 @@ public:
     return g;
   }
 
+  const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
+    if (auto obj = _objectAtoms.lookup(a))
+      return obj;
+
+    auto oa = new (_file._alloc) ARMObjectAtom(_file);
+    oa->addReferenceELF_ARM(R_ARM_COPY, 0, oa, 0);
+
+    oa->_name = a->name();
+    oa->_size = a->size();
+
+    _objectAtoms[a] = oa;
+    return oa;
+  }
+
   /// \brief Handle ordinary relocation references.
   std::error_code handlePlain(bool fromThumb, const Reference &ref) {
     if (auto sla = dyn_cast<SharedLibraryAtom>(ref.target())) {
-      if (sla->type() == SharedLibraryAtom::Type::Data) {
-        llvm_unreachable("Handle object entries");
+      if (sla->type() == SharedLibraryAtom::Type::Data &&
+          _ctx.getOutputELFType() == llvm::ELF::ET_EXEC) {
+        const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
       } else if (sla->type() == SharedLibraryAtom::Type::Code) {
         const_cast<Reference &>(ref).setTarget(getPLTEntry(sla, fromThumb));
       }

Added: lld/trunk/test/elf/ARM/Inputs/libobj.so
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/Inputs/libobj.so?rev=235705&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/ARM/Inputs/libobj.so
------------------------------------------------------------------------------
    svn:executable = *

Propchange: lld/trunk/test/elf/ARM/Inputs/libobj.so
------------------------------------------------------------------------------
    svn:mime-type = application/x-sharedlib

Added: lld/trunk/test/elf/ARM/Inputs/obj.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/Inputs/obj.c?rev=235705&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/Inputs/obj.c (added)
+++ lld/trunk/test/elf/ARM/Inputs/obj.c Fri Apr 24 03:53:02 2015
@@ -0,0 +1,4 @@
+static struct S {
+} s;
+
+struct S *const object = &s;

Added: lld/trunk/test/elf/ARM/rel-copy.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-copy.test?rev=235705&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-copy.test (added)
+++ lld/trunk/test/elf/ARM/rel-copy.test Fri Apr 24 03:53:02 2015
@@ -0,0 +1,61 @@
+# Check handling of R_ARM_COPY relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi \
+# RUN: --noinhibit-exec %t-o.o -lobj -L%p/Inputs -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+# RUN: llvm-readobj -relocations %t | FileCheck -check-prefix=READOBJ %s
+
+# CHECK: Contents of section .rel.dyn:
+# CHECK-NEXT: 400138 00104000 14010000
+#       addr = 0x401000 ^^       ^^ rel_type = 0x14 => R_ARM_COPY
+# CHECK: SYMBOL TABLE:
+# CHECK: 00401000 g       .bss   00000004 object
+#
+# READOBJ: 0x401000 R_ARM_COPY object
+
+---
+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:         80B483B000AF40F20003C0F200031B687B60002318460C37BD465DF8047B7047
+  - Name:            .rel.text
+    Type:            SHT_REL
+    Link:            .symtab
+    AddressAlign:    0x0000000000000004
+    Info:            .text
+    Relocations:
+      - Offset:          0x0000000000000006
+        Symbol:          object
+        Type:            R_ARM_THM_MOVW_ABS_NC
+      - Offset:          0x000000000000000A
+        Symbol:          object
+        Type:            R_ARM_THM_MOVT_ABS
+  - 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:            '$t'
+      Section:         .text
+  Global:
+    - Name:            main
+      Type:            STT_FUNC
+      Section:         .text
+      Value:           0x0000000000000001
+    - Name:            object
+...





More information about the llvm-commits mailing list