[lld] r201129 - [Mips] Handle R_MIPS_COPY relocation.

Simon Atanasyan simon at atanasyan.com
Mon Feb 10 21:34:02 PST 2014


Author: atanasyan
Date: Mon Feb 10 23:34:02 2014
New Revision: 201129

URL: http://llvm.org/viewvc/llvm-project?rev=201129&view=rev
Log:
[Mips] Handle R_MIPS_COPY relocation.

Added:
    lld/trunk/test/elf/Mips/rcopy.test
Modified:
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
    lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=201129&r1=201128&r2=201129&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Mon Feb 10 23:34:02 2014
@@ -46,6 +46,19 @@ void MipsLinkingContext::addPasses(PassM
   ELFLinkingContext::addPasses(pm);
 }
 
+bool MipsLinkingContext::isDynamicRelocation(const DefinedAtom &,
+                                             const Reference &r) const {
+  if (r.kindNamespace() != Reference::KindNamespace::ELF)
+    return false;
+
+  switch (r.kindValue()) {
+  case llvm::ELF::R_MIPS_COPY:
+    return true;
+  default:
+    return false;
+  }
+}
+
 bool MipsLinkingContext::isPLTRelocation(const DefinedAtom &,
                                          const Reference &r) const {
   if (r.kindNamespace() != Reference::KindNamespace::ELF)

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=201129&r1=201128&r2=201129&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h Mon Feb 10 23:34:02 2014
@@ -46,6 +46,8 @@ public:
   virtual StringRef getDefaultInterpreter() const;
   virtual void addPasses(PassManager &pm);
   virtual bool isRelaOutputFormat() const { return false; }
+  virtual bool isDynamicRelocation(const DefinedAtom &,
+                                   const Reference &r) const;
   virtual bool isPLTRelocation(const DefinedAtom &, const Reference &r) const;
 };
 

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=201129&r1=201128&r2=201129&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Mon Feb 10 23:34:02 2014
@@ -155,6 +155,11 @@ public:
       gotplt->setOrdinal(ordinal++);
       mf->addAtom(*gotplt);
     }
+
+    for (auto obj : _objectVector) {
+      obj->setOrdinal(ordinal++);
+      mf->addAtom(*obj);
+    }
   }
 
 private:
@@ -176,18 +181,30 @@ private:
   /// \brief Map Atoms to their PLT entries.
   llvm::DenseMap<const Atom *, PLTAtom *> _pltMap;
 
+  /// \brief Map Atoms to their Object entries.
+  llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
+
   /// \brief the list of PLT atoms.
   std::vector<PLTAtom *> _pltVector;
 
   /// \brief the list of GOTPLT atoms.
   std::vector<GOTAtom *> _gotpltVector;
 
+  /// \brief the list of Object entries.
+  std::vector<ObjectAtom *> _objectVector;
+
   /// \brief Handle a specific reference.
   void handleReference(const DefinedAtom &atom, const Reference &ref) {
     if (ref.kindNamespace() != lld::Reference::KindNamespace::ELF)
       return;
     assert(ref.kindArch() == Reference::KindArch::Mips);
     switch (ref.kindValue()) {
+    case R_MIPS_32:
+    case R_MIPS_HI16:
+    case R_MIPS_LO16:
+      // FIXME (simon): Handle dynamic/static linking differently.
+      handlePlain(ref);
+      break;
     case R_MIPS_26:
       handlePLT(ref);
       break;
@@ -204,6 +221,14 @@ private:
     return false;
   }
 
+  void handlePlain(const Reference &ref) {
+    if (!ref.target())
+      return;
+    auto sla = dyn_cast<SharedLibraryAtom>(ref.target());
+    if (sla && sla->type() == SharedLibraryAtom::Type::Data)
+      const_cast<Reference &>(ref).setTarget(getObjectEntry(sla));
+  }
+
   void handlePLT(const Reference &ref) {
     if (ref.kindValue() == R_MIPS_26 && !isLocal(ref.target()))
       const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_26);
@@ -332,6 +357,22 @@ private:
 
     return pa;
   }
+
+  const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a) {
+    auto obj = _objectMap.find(a);
+    if (obj != _objectMap.end())
+      return obj->second;
+
+    auto oa = new (_file._alloc) ObjectAtom(_file);
+    oa->addReferenceELF_Mips(R_MIPS_COPY, 0, oa, 0);
+    oa->_name = a->name();
+    oa->_size = a->size();
+
+    _objectMap[a] = oa;
+    _objectVector.push_back(oa);
+
+    return oa;
+  }
 };
 
 } // end anon namespace

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=201129&r1=201128&r2=201129&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Mon Feb 10 23:34:02 2014
@@ -56,6 +56,7 @@ const Registry::KindStrings MipsTargetHa
   LLD_KIND_STRING_ENTRY(R_MIPS_GOT16),
   LLD_KIND_STRING_ENTRY(R_MIPS_CALL16),
   LLD_KIND_STRING_ENTRY(R_MIPS_JALR),
+  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_GLOBAL_GOT16),

Added: lld/trunk/test/elf/Mips/rcopy.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Mips/rcopy.test?rev=201129&view=auto
==============================================================================
--- lld/trunk/test/elf/Mips/rcopy.test (added)
+++ lld/trunk/test/elf/Mips/rcopy.test Mon Feb 10 23:34:02 2014
@@ -0,0 +1,42 @@
+# Check handling of R_MIPS_COPY relocation
+
+# Build shared library
+# RUN: llvm-mc -triple=mipsel -filetype=obj -relocation-model=pic \
+# RUN:         -o=%t-obj %p/Inputs/ext.s
+# RUN: lld -flavor gnu -target mipsel -shared -o %t-so %t-obj
+
+# Build executable
+# RUN: llvm-mc -triple=mipsel -filetype=obj -o=%t-obj %s
+# RUN: lld -flavor gnu -target mipsel -e glob -o %t %t-obj %t-so
+# RUN: llvm-readobj -relocations -symbols -dyn-symbols %t | FileCheck %s
+
+# CHECK:       Relocations [
+# CHECK-NEXT:    Section ({{[0-9]+}}) .rel.dyn {
+# CHECK-NEXT:      0x{{[1-9A-F][0-9A-F]*}} R_MIPS_COPY data1 0x0
+# CHECK-NEXT:    }
+# CHECK-NEXT:  ]
+
+# CHECK:         Name: data1 ({{[0-9]+}}
+# CHECK-NEXT:    Value: 0x{{[1-9A-F][0-9A-F]*}}
+# CHECK-NEXT:    Size: 4
+# CHECK-NEXT:    Binding: Global (0x1)
+# CHECK-NEXT:    Type: Object (0x1)
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .bss (0x{{[1-9A-F][0-9A-F]*}})
+
+# CHECK:         Name: data1@ ({{[0-9]+}}
+# CHECK-NEXT:    Value: 0x{{[1-9A-F][0-9A-F]*}}
+# CHECK-NEXT:    Size: 4
+# CHECK-NEXT:    Binding: Global (0x1)
+# CHECK-NEXT:    Type: Object (0x1)
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .bss (0x{{[1-9A-F][0-9A-F]*}})
+
+    .abicalls
+    .option pic0
+    .global glob
+    .ent    glob
+glob:
+    lui     $2,%hi(data1)
+    lw      $2,%lo(data1)($2)
+    .end    glob





More information about the llvm-commits mailing list