[lld] r204242 - [Mips] Move RelocationPass class member function definitions out of the
Simon Atanasyan
simon at atanasyan.com
Wed Mar 19 08:45:49 PDT 2014
Author: atanasyan
Date: Wed Mar 19 10:45:49 2014
New Revision: 204242
URL: http://llvm.org/viewvc/llvm-project?rev=204242&view=rev
Log:
[Mips] Move RelocationPass class member function definitions out of the
class.
Modified:
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
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=204242&r1=204241&r2=204242&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp Wed Mar 19 10:45:49 2014
@@ -114,53 +114,9 @@ public:
class RelocationPass : public Pass {
public:
- RelocationPass(MipsLinkingContext &context)
- : _context(context), _file(context) {
- _localGotVector.push_back(new (_file._alloc) GOT0Atom(_file));
- _localGotVector.push_back(new (_file._alloc) GOTModulePointerAtom(_file));
- }
+ RelocationPass(MipsLinkingContext &context);
- void perform(std::unique_ptr<MutableFile> &mf) override {
- // Process all references.
- for (const auto &atom : mf->defined())
- for (const auto &ref : *atom)
- handleReference(*atom, *ref);
-
- uint64_t ordinal = 0;
-
- for (auto &got : _localGotVector) {
- DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOT ] Adding L "
- << got->name() << "\n");
- got->setOrdinal(ordinal++);
- mf->addAtom(*got);
- }
-
- for (auto &got : _globalGotVector) {
- DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOT ] Adding G "
- << got->name() << "\n");
- got->setOrdinal(ordinal++);
- mf->addAtom(*got);
- }
-
- for (auto &plt : _pltVector) {
- DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ PLT ] Adding "
- << plt->name() << "\n");
- plt->setOrdinal(ordinal++);
- mf->addAtom(*plt);
- }
-
- for (auto &gotplt : _gotpltVector) {
- DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOTPLT ] Adding "
- << gotplt->name() << "\n");
- gotplt->setOrdinal(ordinal++);
- mf->addAtom(*gotplt);
- }
-
- for (auto obj : _objectVector) {
- obj->setOrdinal(ordinal++);
- mf->addAtom(*obj);
- }
- }
+ void perform(std::unique_ptr<MutableFile> &mf) override;
private:
/// \brief Reference to the linking context.
@@ -194,186 +150,248 @@ private:
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;
- case R_MIPS_GOT16:
- case R_MIPS_CALL16:
- handleGOT(ref);
- break;
- }
- }
-
- bool isLocal(const Atom *a) {
- if (auto *da = dyn_cast<DefinedAtom>(a))
- return da->scope() == Atom::scopeTranslationUnit;
- 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);
-
- if (isa<SharedLibraryAtom>(ref.target()))
- const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
- }
-
- void handleGOT(const Reference &ref) {
- if (ref.kindValue() == R_MIPS_GOT16 && !isLocal(ref.target()))
- const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_GOT16);
-
- const_cast<Reference &>(ref).setTarget(getGOTEntry(ref.target()));
- }
+ void handleReference(const DefinedAtom &atom, const Reference &ref);
- bool requireLocalGOT(const Atom *a) {
- Atom::Scope scope;
- if (auto *da = dyn_cast<DefinedAtom>(a))
- scope = da->scope();
- else if (auto *aa = dyn_cast<AbsoluteAtom>(a))
- scope = aa->scope();
- else
- return false;
-
- // Local and hidden symbols must be local.
- if (scope == Atom::scopeTranslationUnit ||
- scope == Atom::scopeLinkageUnit)
- return true;
-
- // External symbol defined in an executable file requires a local GOT entry.
- if (_context.getOutputELFType() == llvm::ELF::ET_EXEC)
- return true;
+ void handlePlain(const Reference &ref);
+ void handlePLT(const Reference &ref);
+ void handleGOT(const Reference &ref);
+
+ const GOTAtom *getGOTEntry(const Atom *a);
+ const PLTAtom *getPLTEntry(const Atom *a);
+ const ObjectAtom *getObjectEntry(const SharedLibraryAtom *a);
+
+ bool isLocal(const Atom *a);
+ bool requireLocalGOT(const Atom *a);
+ void createPLTHeader();
+};
+RelocationPass::RelocationPass(MipsLinkingContext &context)
+ : _context(context), _file(context) {
+ _localGotVector.push_back(new (_file._alloc) GOT0Atom(_file));
+ _localGotVector.push_back(new (_file._alloc) GOTModulePointerAtom(_file));
+}
+
+void RelocationPass::perform(std::unique_ptr<MutableFile> &mf) {
+ // Process all references.
+ for (const auto &atom : mf->defined())
+ for (const auto &ref : *atom)
+ handleReference(*atom, *ref);
+
+ uint64_t ordinal = 0;
+
+ for (auto &got : _localGotVector) {
+ DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOT ] Adding L "
+ << got->name() << "\n");
+ got->setOrdinal(ordinal++);
+ mf->addAtom(*got);
+ }
+
+ for (auto &got : _globalGotVector) {
+ DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOT ] Adding G "
+ << got->name() << "\n");
+ got->setOrdinal(ordinal++);
+ mf->addAtom(*got);
+ }
+
+ for (auto &plt : _pltVector) {
+ DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ PLT ] Adding " << plt->name()
+ << "\n");
+ plt->setOrdinal(ordinal++);
+ mf->addAtom(*plt);
+ }
+
+ for (auto &gotplt : _gotpltVector) {
+ DEBUG_WITH_TYPE("MipsGOT", llvm::dbgs() << "[ GOTPLT ] Adding "
+ << gotplt->name() << "\n");
+ gotplt->setOrdinal(ordinal++);
+ mf->addAtom(*gotplt);
+ }
+
+ for (auto obj : _objectVector) {
+ obj->setOrdinal(ordinal++);
+ mf->addAtom(*obj);
+ }
+}
+
+void RelocationPass::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;
+ case R_MIPS_GOT16:
+ case R_MIPS_CALL16:
+ handleGOT(ref);
+ break;
+ }
+}
+
+bool RelocationPass::isLocal(const Atom *a) {
+ if (auto *da = dyn_cast<DefinedAtom>(a))
+ return da->scope() == Atom::scopeTranslationUnit;
+ return false;
+}
+
+void RelocationPass::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 RelocationPass::handlePLT(const Reference &ref) {
+ if (ref.kindValue() == R_MIPS_26 && !isLocal(ref.target()))
+ const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_26);
+
+ if (isa<SharedLibraryAtom>(ref.target()))
+ const_cast<Reference &>(ref).setTarget(getPLTEntry(ref.target()));
+}
+
+void RelocationPass::handleGOT(const Reference &ref) {
+ if (ref.kindValue() == R_MIPS_GOT16 && !isLocal(ref.target()))
+ const_cast<Reference &>(ref).setKindValue(LLD_R_MIPS_GLOBAL_GOT16);
+
+ const_cast<Reference &>(ref).setTarget(getGOTEntry(ref.target()));
+}
+
+bool RelocationPass::requireLocalGOT(const Atom *a) {
+ Atom::Scope scope;
+ if (auto *da = dyn_cast<DefinedAtom>(a))
+ scope = da->scope();
+ else if (auto *aa = dyn_cast<AbsoluteAtom>(a))
+ scope = aa->scope();
+ else
return false;
- }
-
- const GOTAtom *getGOTEntry(const Atom *a) {
- auto got = _gotMap.find(a);
- if (got != _gotMap.end())
- return got->second;
-
- auto ga = new (_file._alloc) GOT0Atom(_file);
- _gotMap[a] = ga;
-
- bool localGOT = requireLocalGOT(a);
-
- if (localGOT)
- _localGotVector.push_back(ga);
- else {
- _globalGotVector.push_back(ga);
- ga->addReferenceELF_Mips(LLD_R_MIPS_GLOBAL_GOT, 0, a, 0);
- }
-
- if (const DefinedAtom *da = dyn_cast<DefinedAtom>(a))
- ga->addReferenceELF_Mips(R_MIPS_32, 0, da, 0);
-
- DEBUG_WITH_TYPE("MipsGOT", {
- ga->_name = "__got_";
- ga->_name += a->name();
- llvm::dbgs() << "[ GOT ] Create " << (localGOT ? "L " : "G ") << a->name()
- << "\n";
- });
-
- return ga;
- }
-
- void createPLTHeader() {
- assert(_pltVector.empty() && _gotpltVector.empty());
-
- auto pa = new (_file._alloc) PLT0Atom(_file);
- _pltVector.push_back(pa);
- auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
- _gotpltVector.push_back(ga0);
- auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
- _gotpltVector.push_back(ga1);
-
- // Setup reference to fixup the PLT0 entry.
- pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga0, 0);
- pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga0, 0);
- pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 8, ga0, 0);
-
- DEBUG_WITH_TYPE("MipsGOT", {
- pa->_name = "__plt0";
- llvm::dbgs() << "[ PLT ] Create PLT0\n";
- ga0->_name = "__gotplt0";
- llvm::dbgs() << "[ GOTPLT ] Create GOTPLT0\n";
- ga1->_name = "__gotplt1";
- llvm::dbgs() << "[ GOTPLT ] Create GOTPLT1\n";
- });
- }
-
- const PLTAtom *getPLTEntry(const Atom *a) {
- auto plt = _pltMap.find(a);
- if (plt != _pltMap.end())
- return plt->second;
-
- if (_pltVector.empty())
- createPLTHeader();
-
- auto pa = new (_file._alloc) PLTAAtom(_file);
- _pltMap[a] = pa;
- _pltVector.push_back(pa);
-
- auto ga = new (_file._alloc) GOTPLTAtom(_file);
- _gotpltVector.push_back(ga);
-
- // Setup reference to fixup the PLT entry.
- pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga, 0);
- pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga, 0);
- pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 12, ga, 0);
-
- // Setup reference to assign initial value to the .got.plt entry.
- ga->addReferenceELF_Mips(R_MIPS_32, 0, _pltVector.front(), 0);
- // Create dynamic relocation to adjust the .got.plt entry at runtime.
- ga->addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
-
- DEBUG_WITH_TYPE("MipsGOT", {
- pa->_name = "__plt_";
- pa->_name += a->name();
- llvm::dbgs() << "[ PLT ] Create " << a->name() << "\n";
- ga->_name = "__got_plt_";
- ga->_name += a->name();
- llvm::dbgs() << "[ GOTPLT ] Create " << a->name() << "\n";
- });
-
- return pa;
- }
+ // Local and hidden symbols must be local.
+ if (scope == Atom::scopeTranslationUnit || scope == Atom::scopeLinkageUnit)
+ return true;
+
+ // External symbol defined in an executable file requires a local GOT entry.
+ if (_context.getOutputELFType() == llvm::ELF::ET_EXEC)
+ return true;
+
+ return false;
+}
+
+const GOTAtom *RelocationPass::getGOTEntry(const Atom *a) {
+ auto got = _gotMap.find(a);
+ if (got != _gotMap.end())
+ return got->second;
+
+ auto ga = new (_file._alloc) GOT0Atom(_file);
+ _gotMap[a] = ga;
+
+ bool localGOT = requireLocalGOT(a);
+
+ if (localGOT)
+ _localGotVector.push_back(ga);
+ else {
+ _globalGotVector.push_back(ga);
+ ga->addReferenceELF_Mips(LLD_R_MIPS_GLOBAL_GOT, 0, a, 0);
+ }
+
+ if (const DefinedAtom *da = dyn_cast<DefinedAtom>(a))
+ ga->addReferenceELF_Mips(R_MIPS_32, 0, da, 0);
+
+ DEBUG_WITH_TYPE("MipsGOT", {
+ ga->_name = "__got_";
+ ga->_name += a->name();
+ llvm::dbgs() << "[ GOT ] Create " << (localGOT ? "L " : "G ") << a->name()
+ << "\n";
+ });
+
+ return ga;
+}
+
+void RelocationPass::createPLTHeader() {
+ assert(_pltVector.empty() && _gotpltVector.empty());
+
+ auto pa = new (_file._alloc) PLT0Atom(_file);
+ _pltVector.push_back(pa);
+
+ auto ga0 = new (_file._alloc) GOTPLTAtom(_file);
+ _gotpltVector.push_back(ga0);
+ auto ga1 = new (_file._alloc) GOTPLTAtom(_file);
+ _gotpltVector.push_back(ga1);
+
+ // Setup reference to fixup the PLT0 entry.
+ pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga0, 0);
+ pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga0, 0);
+ pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 8, ga0, 0);
+
+ DEBUG_WITH_TYPE("MipsGOT", {
+ pa->_name = "__plt0";
+ llvm::dbgs() << "[ PLT ] Create PLT0\n";
+ ga0->_name = "__gotplt0";
+ llvm::dbgs() << "[ GOTPLT ] Create GOTPLT0\n";
+ ga1->_name = "__gotplt1";
+ llvm::dbgs() << "[ GOTPLT ] Create GOTPLT1\n";
+ });
+}
+
+const PLTAtom *RelocationPass::getPLTEntry(const Atom *a) {
+ auto plt = _pltMap.find(a);
+ if (plt != _pltMap.end())
+ return plt->second;
+
+ if (_pltVector.empty())
+ createPLTHeader();
+
+ auto pa = new (_file._alloc) PLTAAtom(_file);
+ _pltMap[a] = pa;
+ _pltVector.push_back(pa);
+
+ auto ga = new (_file._alloc) GOTPLTAtom(_file);
+ _gotpltVector.push_back(ga);
+
+ // Setup reference to fixup the PLT entry.
+ pa->addReferenceELF_Mips(LLD_R_MIPS_HI16, 0, ga, 0);
+ pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 4, ga, 0);
+ pa->addReferenceELF_Mips(LLD_R_MIPS_LO16, 12, ga, 0);
+
+ // Setup reference to assign initial value to the .got.plt entry.
+ ga->addReferenceELF_Mips(R_MIPS_32, 0, _pltVector.front(), 0);
+ // Create dynamic relocation to adjust the .got.plt entry at runtime.
+ ga->addReferenceELF_Mips(R_MIPS_JUMP_SLOT, 0, a, 0);
+
+ DEBUG_WITH_TYPE("MipsGOT", {
+ pa->_name = "__plt_";
+ pa->_name += a->name();
+ llvm::dbgs() << "[ PLT ] Create " << a->name() << "\n";
+ ga->_name = "__got_plt_";
+ ga->_name += a->name();
+ llvm::dbgs() << "[ GOTPLT ] Create " << a->name() << "\n";
+ });
+
+ return pa;
+}
+
+const ObjectAtom *RelocationPass::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();
- 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);
- _objectMap[a] = oa;
- _objectVector.push_back(oa);
-
- return oa;
- }
-};
+ return oa;
+}
} // end anon namespace
More information about the llvm-commits
mailing list