summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF/Mips
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2015-03-20 11:28:22 +0000
committerSimon Atanasyan <simon@atanasyan.com>2015-03-20 11:28:22 +0000
commit12e9f8cd1156914eebfc1848742e911fa94eca3f (patch)
tree89f18ecd91fa5d26c3818d3d6c521416b2df493e /lld/lib/ReaderWriter/ELF/Mips
parent98236e0510de57b1d10d9e16d5c4a911a4ed7d88 (diff)
downloadbcm5719-llvm-12e9f8cd1156914eebfc1848742e911fa94eca3f.tar.gz
bcm5719-llvm-12e9f8cd1156914eebfc1848742e911fa94eca3f.zip
[Mips] Create special PLT entry in case of MIPS R6 ABI
llvm-svn: 232806
Diffstat (limited to 'lld/lib/ReaderWriter/ELF/Mips')
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp33
1 files changed, 32 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
index 81d7a3d94a6..bf69b14f0ab 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
@@ -78,6 +78,14 @@ static const uint8_t micromipsPltAtomContent[] = {
0x02, 0x0f // move $24, $2
};
+// R6 PLT entry
+static const uint8_t mipsR6PltAAtomContent[] = {
+ 0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry)
+ 0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
+ 0x09, 0x00, 0x20, 0x03, // jr $25
+ 0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry)
+};
+
// LA25 stub entry
static const uint8_t mipsLA25AtomContent[] = {
0x00, 0x00, 0x19, 0x3c, // lui $25, %hi(func)
@@ -214,6 +222,15 @@ public:
}
};
+class PLTR6Atom : public PLTAAtom {
+public:
+ PLTR6Atom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {}
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return llvm::makeArrayRef(mipsR6PltAAtomContent);
+ }
+};
+
class PLTMicroAtom : public PLTAtom {
public:
PLTMicroAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
@@ -388,6 +405,8 @@ private:
bool mightBeDynamic(const MipsELFDefinedAtom<ELFT> &atom,
Reference::KindValue refKind) const;
bool hasPLTEntry(const Atom *atom) const;
+
+ bool isR6Target() const;
};
template <typename ELFT>
@@ -638,6 +657,16 @@ bool RelocationPass<ELFT>::hasPLTEntry(const Atom *atom) const {
return _pltRegMap.count(atom) || _pltMicroMap.count(atom);
}
+template <typename ELFT> bool RelocationPass<ELFT>::isR6Target() const {
+ switch (_ctx.getMergedELFFlags() & EF_MIPS_ARCH) {
+ case EF_MIPS_ARCH_32R6:
+ case EF_MIPS_ARCH_64R6:
+ return true;
+ default:
+ return false;
+ }
+}
+
template <typename ELFT>
bool RelocationPass<ELFT>::requirePLTEntry(const Atom *a) const {
if (!_hasStaticRelocations.count(a))
@@ -938,7 +967,9 @@ const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) {
if (plt != _pltRegMap.end())
return plt->second;
- auto pa = new (_file._alloc) PLTAAtom(getGOTPLTEntry(a), _file);
+ PLTAAtom *pa = isR6Target()
+ ? new (_file._alloc) PLTR6Atom(getGOTPLTEntry(a), _file)
+ : new (_file._alloc) PLTAAtom(getGOTPLTEntry(a), _file);
_pltRegMap[a] = pa;
_pltRegVector.push_back(pa);
OpenPOWER on IntegriCloud