summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2014-02-11 05:34:02 +0000
committerSimon Atanasyan <simon@atanasyan.com>2014-02-11 05:34:02 +0000
commitbf987c2dae19ff8bf4818292fb7f424c611592af (patch)
tree1ce8ccc681420a52e4e282a86d593062c9752d3b /lld/lib/ReaderWriter/ELF
parentceb0b86822b0907db6aa0347fcfa4643ee62b80d (diff)
downloadbcm5719-llvm-bf987c2dae19ff8bf4818292fb7f424c611592af.tar.gz
bcm5719-llvm-bf987c2dae19ff8bf4818292fb7f424c611592af.zip
[Mips] Handle R_MIPS_COPY relocation.
llvm-svn: 201129
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp13
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h2
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp41
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp1
4 files changed, 57 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
index 43578d5b4b0..80343ff8bef 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
@@ -46,6 +46,19 @@ void MipsLinkingContext::addPasses(PassManager &pm) {
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)
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
index 17b42194965..f44ff7ff979 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.h
@@ -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;
};
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
index 3ec98c6930a..78c879fce9d 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
@@ -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
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
index be3d1e466cb..84ee9636a0c 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
@@ -56,6 +56,7 @@ const Registry::KindStrings MipsTargetHandler::kindStrings[] = {
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),
OpenPOWER on IntegriCloud