summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/ELF
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2015-07-13 09:11:35 +0000
committerSimon Atanasyan <simon@atanasyan.com>2015-07-13 09:11:35 +0000
commitb34a080701942dc6e9ab3dac7e9eb220022bad46 (patch)
treec212d81aff47096b24d8fb535e13a565fecf2241 /lld/lib/ReaderWriter/ELF
parentf8f780ccc5ad5f26e6473ffbbca71b4d7f98d255 (diff)
downloadbcm5719-llvm-b34a080701942dc6e9ab3dac7e9eb220022bad46.tar.gz
bcm5719-llvm-b34a080701942dc6e9ab3dac7e9eb220022bad46.zip
[Mips] Support MIPS big-endian 32/64-bits targets
llvm-svn: 242014
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
-rw-r--r--lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp2
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp2
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp9
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp4
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp8
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp65
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h1
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp227
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp12
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp6
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp2
11 files changed, 278 insertions, 60 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
index 361bd509fa8..70ed30a12ed 100644
--- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
@@ -52,7 +52,9 @@ uint16_t ELFLinkingContext::getOutputMachine() const {
return llvm::ELF::EM_X86_64;
case llvm::Triple::hexagon:
return llvm::ELF::EM_HEXAGON;
+ case llvm::Triple::mips:
case llvm::Triple::mipsel:
+ case llvm::Triple::mips64:
case llvm::Triple::mips64el:
return llvm::ELF::EM_MIPS;
case llvm::Triple::aarch64:
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
index fac238ac952..2c2f528f8a0 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsAbiInfoHandler.cpp
@@ -643,7 +643,9 @@ MipsAbiInfoHandler<ELFT>::createAbiFromSection(const Elf_Mips_ABIFlags &sec) {
return abi;
}
+template class MipsAbiInfoHandler<ELF32BE>;
template class MipsAbiInfoHandler<ELF32LE>;
+template class MipsAbiInfoHandler<ELF64BE>;
template class MipsAbiInfoHandler<ELF64LE>;
}
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
index 51d366479d8..398d302d29b 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
@@ -50,7 +50,9 @@ template <class ELFT> bool MipsELFDefinedAtom<ELFT>::isPIC() const {
codeModel() == DefinedAtom::codeMipsPIC;
}
+template class MipsELFDefinedAtom<ELF32BE>;
template class MipsELFDefinedAtom<ELF32LE>;
+template class MipsELFDefinedAtom<ELF64BE>;
template class MipsELFDefinedAtom<ELF64LE>;
template <class ELFT> static bool isMips64EL() {
@@ -78,7 +80,9 @@ MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rel &rel)
rel.getSymbol(isMips64EL<ELFT>())),
_tag(extractTag(rel)) {}
+template class MipsELFReference<ELF32BE>;
template class MipsELFReference<ELF32LE>;
+template class MipsELFReference<ELF64BE>;
template class MipsELFReference<ELF64LE>;
template <class ELFT>
@@ -270,7 +274,8 @@ template <class ELFT>
Reference::Addend
MipsELFFile<ELFT>::readAddend(const Elf_Rel &ri,
const ArrayRef<uint8_t> content) const {
- return readMipsRelocAddend(getPrimaryType(ri), content.data() + ri.r_offset);
+ return readMipsRelocAddend<ELFT>(getPrimaryType(ri),
+ content.data() + ri.r_offset);
}
template <class ELFT>
@@ -315,7 +320,9 @@ bool MipsELFFile<ELFT>::isLocalBinding(const Elf_Rel &rel) const {
->getBinding() == llvm::ELF::STB_LOCAL;
}
+template class MipsELFFile<ELF32BE>;
template class MipsELFFile<ELF32LE>;
+template class MipsELFFile<ELF64BE>;
template class MipsELFFile<ELF64LE>;
} // elf
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
index 9d17e4f2d06..1abb763e3a0 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
@@ -159,7 +159,9 @@ MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
}
+template class MipsDynamicLibraryWriter<ELF32BE>;
template class MipsDynamicLibraryWriter<ELF32LE>;
+template class MipsDynamicLibraryWriter<ELF64BE>;
template class MipsDynamicLibraryWriter<ELF64LE>;
template <class ELFT>
@@ -275,7 +277,9 @@ MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
}
+template class MipsExecutableWriter<ELF32BE>;
template class MipsExecutableWriter<ELF32LE>;
+template class MipsExecutableWriter<ELF64BE>;
template class MipsExecutableWriter<ELF64LE>;
} // elf
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
index 0124b7b737c..b905fa5f3ab 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
@@ -18,7 +18,9 @@ using namespace lld::elf;
std::unique_ptr<ELFLinkingContext>
elf::createMipsLinkingContext(llvm::Triple triple) {
- if (triple.getArch() == llvm::Triple::mipsel ||
+ if (triple.getArch() == llvm::Triple::mips ||
+ triple.getArch() == llvm::Triple::mipsel ||
+ triple.getArch() == llvm::Triple::mips64 ||
triple.getArch() == llvm::Triple::mips64el)
return llvm::make_unique<MipsLinkingContext>(triple);
return nullptr;
@@ -27,8 +29,12 @@ elf::createMipsLinkingContext(llvm::Triple triple) {
static std::unique_ptr<TargetHandler> createTarget(llvm::Triple triple,
MipsLinkingContext &ctx) {
switch (triple.getArch()) {
+ case llvm::Triple::mips:
+ return llvm::make_unique<MipsTargetHandler<ELF32BE>>(ctx);
case llvm::Triple::mipsel:
return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx);
+ case llvm::Triple::mips64:
+ return llvm::make_unique<MipsTargetHandler<ELF64BE>>(ctx);
case llvm::Triple::mips64el:
return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx);
default:
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
index 49e6ea00cd1..3e9619f9f19 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.cpp
@@ -356,11 +356,6 @@ static CrossJumpMode getCrossJumpMode(const Reference &ref) {
}
}
-static uint64_t microShuffle(uint64_t ins) {
- return (ins & 0xffffffff00000000ull) | ((ins & 0xffff) << 16) |
- ((ins & 0xffff0000) >> 16);
-}
-
static ErrorOr<int64_t> calculateRelocation(Reference::KindValue kind,
Reference::Addend addend,
uint64_t tgtAddr, uint64_t relAddr,
@@ -502,29 +497,32 @@ static ErrorOr<int64_t> calculateRelocation(Reference::KindValue kind,
}
}
+template <class ELFT>
static uint64_t relocRead(const MipsRelocationParams &params,
const uint8_t *loc) {
+ assert((params._size == 4 || params._size == 8) && "Unexpected size");
uint64_t data;
+ memcpy(&data, loc, params._size);
+ if (params._shuffle) {
+ using namespace endian;
+ auto p = reinterpret_cast<const uint8_t *>(&data);
+ uint32_t a = readNext<uint16_t, ELFT::TargetEndianness, unaligned>(p);
+ uint32_t b = read<uint16_t, ELFT::TargetEndianness, unaligned>(p);
+ write<uint32_t, ELFT::TargetEndianness, unaligned>(&data, a << 16 | b);
+ }
switch (params._size) {
case 4:
- data = endian::read32le(loc);
- break;
+ return endian::read<uint32_t, ELFT::TargetEndianness, unaligned>(&data);
case 8:
- data = endian::read64le(loc);
- break;
+ return endian::read<uint64_t, ELFT::TargetEndianness, unaligned>(&data);
default:
llvm_unreachable("Unexpected size");
}
- if (params._shuffle)
- data = microShuffle(data);
- return data;
}
template <class ELFT>
static void relocWrite(uint64_t data, const MipsRelocationParams &params,
uint8_t *loc) {
- if (params._shuffle)
- data = microShuffle(data);
switch (params._size) {
case 4:
endian::write<uint32_t, ELFT::TargetEndianness, unaligned>(loc, data);
@@ -535,6 +533,13 @@ static void relocWrite(uint64_t data, const MipsRelocationParams &params,
default:
llvm_unreachable("Unexpected size");
}
+ if (params._shuffle) {
+ uint32_t v = endian::read<uint32_t, ELFT::TargetEndianness, unaligned>(loc);
+ uint16_t a = v >> 16;
+ uint16_t b = v & 0xffff;
+ endian::write<uint16_t, ELFT::TargetEndianness, unaligned>(loc, a);
+ endian::write<uint16_t, ELFT::TargetEndianness, unaligned>(loc + 2, b);
+ }
}
static uint32_t getRelKind(const Reference &ref, size_t num) {
@@ -604,7 +609,7 @@ std::error_code RelocationHandler<ELFT>::applyRelocation(
}
auto params = getRelocationParams(lastRel);
- uint64_t ins = relocRead(params, location);
+ uint64_t ins = relocRead<ELFT>(params, location);
if (auto ec = adjustJumpOpCode(ins, tgtAddr, jumpMode))
return ec;
@@ -619,6 +624,13 @@ namespace elf {
template <>
std::unique_ptr<TargetRelocationHandler>
+createMipsRelocationHandler<ELF32BE>(MipsLinkingContext &ctx,
+ MipsTargetLayout<ELF32BE> &layout) {
+ return llvm::make_unique<RelocationHandler<ELF32BE>>(ctx, layout);
+}
+
+template <>
+std::unique_ptr<TargetRelocationHandler>
createMipsRelocationHandler<ELF32LE>(MipsLinkingContext &ctx,
MipsTargetLayout<ELF32LE> &layout) {
return llvm::make_unique<RelocationHandler<ELF32LE>>(ctx, layout);
@@ -626,15 +638,23 @@ createMipsRelocationHandler<ELF32LE>(MipsLinkingContext &ctx,
template <>
std::unique_ptr<TargetRelocationHandler>
+createMipsRelocationHandler<ELF64BE>(MipsLinkingContext &ctx,
+ MipsTargetLayout<ELF64BE> &layout) {
+ return llvm::make_unique<RelocationHandler<ELF64BE>>(ctx, layout);
+}
+
+template <>
+std::unique_ptr<TargetRelocationHandler>
createMipsRelocationHandler<ELF64LE>(MipsLinkingContext &ctx,
MipsTargetLayout<ELF64LE> &layout) {
return llvm::make_unique<RelocationHandler<ELF64LE>>(ctx, layout);
}
+template <class ELFT>
Reference::Addend readMipsRelocAddend(Reference::KindValue kind,
const uint8_t *content) {
auto params = getRelocationParams(kind);
- uint64_t ins = relocRead(params, content);
+ uint64_t ins = relocRead<ELFT>(params, content);
int64_t res = (ins & params._mask) << params._shift;
switch (kind) {
case R_MIPS_GPREL16:
@@ -660,5 +680,18 @@ Reference::Addend readMipsRelocAddend(Reference::KindValue kind,
return res;
}
+template
+Reference::Addend readMipsRelocAddend<ELF32BE>(Reference::KindValue kind,
+ const uint8_t *content);
+template
+Reference::Addend readMipsRelocAddend<ELF32LE>(Reference::KindValue kind,
+ const uint8_t *content);
+template
+Reference::Addend readMipsRelocAddend<ELF64BE>(Reference::KindValue kind,
+ const uint8_t *content);
+template
+Reference::Addend readMipsRelocAddend<ELF64LE>(Reference::KindValue kind,
+ const uint8_t *content);
+
} // elf
} // lld
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
index d136be837f9..62a7aee3449 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationHandler.h
@@ -22,6 +22,7 @@ std::unique_ptr<TargetRelocationHandler>
createMipsRelocationHandler(MipsLinkingContext &ctx,
MipsTargetLayout<ELFT> &layout);
+template <class ELFT>
Reference::Addend readMipsRelocAddend(Reference::KindValue kind,
const uint8_t *content);
} // elf
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
index 38e31af2183..d9be544b681 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp
@@ -37,8 +37,20 @@ static const uint8_t mipsGotTlsGdAtomContent[] = {
0x00, 0x00, 0x00, 0x00
};
-// Regular PLT0 entry
-static const uint8_t mipsPlt0AtomContent[] = {
+// Regular big-endian PLT0 entry
+static const uint8_t mipsBePlt0AtomContent[] = {
+ 0x3c, 0x1c, 0x00, 0x00, // lui $28, %hi(&GOTPLT[0])
+ 0x8f, 0x99, 0x00, 0x00, // lw $25, %lo(&GOTPLT[0])($28)
+ 0x27, 0x9c, 0x00, 0x00, // addiu $28, $28, %lo(&GOTPLT[0])
+ 0x03, 0x1c, 0xc0, 0x23, // subu $24, $24, $28
+ 0x03, 0xe0, 0x78, 0x21, // move $15, $31
+ 0x00, 0x18, 0xc0, 0x82, // srl $24, $24, 2
+ 0x03, 0x20, 0xf8, 0x09, // jalr $25
+ 0x27, 0x18, 0xff, 0xfe // subu $24, $24, 2
+};
+
+// Regular little-endian PLT0 entry
+static const uint8_t mipsLePlt0AtomContent[] = {
0x00, 0x00, 0x1c, 0x3c, // lui $28, %hi(&GOTPLT[0])
0x00, 0x00, 0x99, 0x8f, // lw $25, %lo(&GOTPLT[0])($28)
0x00, 0x00, 0x9c, 0x27, // addiu $28, $28, %lo(&GOTPLT[0])
@@ -49,8 +61,21 @@ static const uint8_t mipsPlt0AtomContent[] = {
0xfe, 0xff, 0x18, 0x27 // subu $24, $24, 2
};
-// microMIPS PLT0 entry
-static const uint8_t micromipsPlt0AtomContent[] = {
+// microMIPS big-endian PLT0 entry
+static const uint8_t microMipsBePlt0AtomContent[] = {
+ 0x79, 0x80, 0x00, 0x00, // addiupc $3, (&GOTPLT[0]) - .
+ 0xff, 0x23, 0x00, 0x00, // lw $25, 0($3)
+ 0x05, 0x35, // subu $2, $2, $3
+ 0x25, 0x25, // srl $2, $2, 2
+ 0x33, 0x02, 0xff, 0xfe, // subu $24, $2, 2
+ 0x0d, 0xff, // move $15, $31
+ 0x45, 0xf9, // jalrs $25
+ 0x0f, 0x83, // move $28, $3
+ 0x0c, 0x00 // nop
+};
+
+// microMIPS little-endian PLT0 entry
+static const uint8_t microMipsLePlt0AtomContent[] = {
0x80, 0x79, 0x00, 0x00, // addiupc $3, (&GOTPLT[0]) - .
0x23, 0xff, 0x00, 0x00, // lw $25, 0($3)
0x35, 0x05, // subu $2, $2, $3
@@ -62,40 +87,80 @@ static const uint8_t micromipsPlt0AtomContent[] = {
0x00, 0x0c // nop
};
-// Regular PLT entry
-static const uint8_t mipsPltAAtomContent[] = {
+// Regular big-endian PLT entry
+static const uint8_t mipsBePltAAtomContent[] = {
+ 0x3c, 0x0f, 0x00, 0x00, // lui $15, %hi(.got.plt entry)
+ 0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15)
+ 0x03, 0x20, 0x00, 0x08, // jr $25
+ 0x25, 0xf8, 0x00, 0x00 // addiu $24, $15, %lo(.got.plt entry)
+};
+
+// Regular little-endian PLT entry
+static const uint8_t mipsLePltAAtomContent[] = {
0x00, 0x00, 0x0f, 0x3c, // lui $15, %hi(.got.plt entry)
0x00, 0x00, 0xf9, 0x8d, // l[wd] $25, %lo(.got.plt entry)($15)
0x08, 0x00, 0x20, 0x03, // jr $25
0x00, 0x00, 0xf8, 0x25 // addiu $24, $15, %lo(.got.plt entry)
};
-// microMIPS PLT entry
-static const uint8_t micromipsPltAtomContent[] = {
+// microMIPS big-endian PLT entry
+static const uint8_t microMipsBePltAAtomContent[] = {
+ 0x79, 0x00, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
+ 0xff, 0x22, 0x00, 0x00, // lw $25, 0($2)
+ 0x45, 0x99, // jr $25
+ 0x0f, 0x02 // move $24, $2
+};
+
+// microMIPS little-endian PLT entry
+static const uint8_t microMipsLePltAAtomContent[] = {
0x00, 0x79, 0x00, 0x00, // addiupc $2, (.got.plt entry) - .
0x22, 0xff, 0x00, 0x00, // lw $25, 0($2)
0x99, 0x45, // jr $25
0x02, 0x0f // move $24, $2
};
-// R6 PLT entry
-static const uint8_t mipsR6PltAAtomContent[] = {
+// R6 big-endian PLT entry
+static const uint8_t mipsR6BePltAAtomContent[] = {
+ 0x3c, 0x0f, 0x00, 0x00, // lui $15, %hi(.got.plt entry)
+ 0x8d, 0xf9, 0x00, 0x00, // l[wd] $25, %lo(.got.plt entry)($15)
+ 0x03, 0x20, 0x00, 0x09, // jr $25
+ 0x25, 0xf8, 0x00, 0x00 // addiu $24, $15, %lo(.got.plt entry)
+};
+
+// R6 little-endian PLT entry
+static const uint8_t mipsR6LePltAAtomContent[] = {
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[] = {
+// LA25 big-endian stub entry
+static const uint8_t mipsBeLA25AtomContent[] = {
+ 0x3c, 0x19, 0x00, 0x00, // lui $25, %hi(func)
+ 0x08, 0x00, 0x00, 0x00, // j func
+ 0x27, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func)
+ 0x00, 0x00, 0x00, 0x00 // nop
+};
+
+// LA25 little-endian stub entry
+static const uint8_t mipsLeLA25AtomContent[] = {
0x00, 0x00, 0x19, 0x3c, // lui $25, %hi(func)
0x00, 0x00, 0x00, 0x08, // j func
0x00, 0x00, 0x39, 0x27, // addiu $25, $25, %lo(func)
0x00, 0x00, 0x00, 0x00 // nop
};
-// microMIPS LA25 stub entry
-static const uint8_t micromipsLA25AtomContent[] = {
+// microMIPS LA25 big-endian stub entry
+static const uint8_t microMipsBeLA25AtomContent[] = {
+ 0x41, 0xbe, 0x00, 0x00, // lui $25, %hi(func)
+ 0xd4, 0x00, 0x00, 0x00, // j func
+ 0x33, 0x39, 0x00, 0x00, // addiu $25, $25, %lo(func)
+ 0x00, 0x00, 0x00, 0x00 // nop
+};
+
+// microMIPS LA25 little-endian stub entry
+static const uint8_t microMipsLeLA25AtomContent[] = {
0xb9, 0x41, 0x00, 0x00, // lui $25, %hi(func)
0x00, 0xd4, 0x00, 0x00, // j func
0x39, 0x33, 0x00, 0x00, // addiu $25, $25, %lo(func)
@@ -120,9 +185,15 @@ public:
ArrayRef<uint8_t> rawContent() const override;
};
+template <> ArrayRef<uint8_t> GOT0Atom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
+}
template <> ArrayRef<uint8_t> GOT0Atom<ELF32LE>::rawContent() const {
return llvm::makeArrayRef(mipsGot0AtomContent).slice(4);
}
+template <> ArrayRef<uint8_t> GOT0Atom<ELF64BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsGot0AtomContent);
+}
template <> ArrayRef<uint8_t> GOT0Atom<ELF64LE>::rawContent() const {
return llvm::makeArrayRef(mipsGot0AtomContent);
}
@@ -136,10 +207,18 @@ public:
};
template <>
+ArrayRef<uint8_t> GOTModulePointerAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4);
+}
+template <>
ArrayRef<uint8_t> GOTModulePointerAtom<ELF32LE>::rawContent() const {
return llvm::makeArrayRef(mipsGotModulePointerAtomContent).slice(4);
}
template <>
+ArrayRef<uint8_t> GOTModulePointerAtom<ELF64BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsGotModulePointerAtomContent);
+}
+template <>
ArrayRef<uint8_t> GOTModulePointerAtom<ELF64LE>::rawContent() const {
return llvm::makeArrayRef(mipsGotModulePointerAtomContent);
}
@@ -152,12 +231,17 @@ public:
ArrayRef<uint8_t> rawContent() const override;
};
+template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
+}
template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF32LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
+ return llvm::makeArrayRef(mipsGotTlsGdAtomContent).slice(8);
+}
+template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
}
-
template <> ArrayRef<uint8_t> GOTTLSGdAtom<ELF64LE>::rawContent() const {
- return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
+ return llvm::makeArrayRef(mipsGotTlsGdAtomContent);
}
class GOTPLTAtom : public GOTAtom {
@@ -180,7 +264,7 @@ public:
}
};
-class PLT0Atom : public PLTAtom {
+template <class ELFT> class PLT0Atom : public PLTAtom {
public:
PLT0Atom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
// Setup reference to fixup the PLT0 entry.
@@ -190,11 +274,18 @@ public:
}
ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(mipsPlt0AtomContent);
+ llvm_unreachable("PLT0 is not applicable for this target");
}
};
-class PLT0MicroAtom : public PLTAtom {
+template <> ArrayRef<uint8_t> PLT0Atom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsBePlt0AtomContent);
+}
+template <> ArrayRef<uint8_t> PLT0Atom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(mipsLePlt0AtomContent);
+}
+
+template <class ELFT> class PLT0MicroAtom : public PLTAtom {
public:
PLT0MicroAtom(const Atom *got, const File &f) : PLTAtom(f, ".plt") {
// Setup reference to fixup the PLT0 entry.
@@ -204,10 +295,17 @@ public:
CodeModel codeModel() const override { return codeMipsMicro; }
ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(micromipsPlt0AtomContent);
+ llvm_unreachable("PLT0 is not applicable for this target");
}
};
+template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(microMipsBePlt0AtomContent);
+}
+template <> ArrayRef<uint8_t> PLT0MicroAtom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(microMipsLePlt0AtomContent);
+}
+
class PLTAAtom : public PLTAtom {
public:
PLTAAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
@@ -216,22 +314,41 @@ public:
addReferenceELF_Mips(R_MIPS_LO16, 4, got, 0);
addReferenceELF_Mips(R_MIPS_LO16, 12, got, 0);
}
+};
+
+template <class ELFT> class PLTARegAtom : public PLTAAtom {
+public:
+ PLTARegAtom(const GOTPLTAtom *got, const File &f) : PLTAAtom(got, f) {}
ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(mipsPltAAtomContent);
+ llvm_unreachable("PLT is not applicable for this target");
}
};
-class PLTR6Atom : public PLTAAtom {
+template <> ArrayRef<uint8_t> PLTARegAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsBePltAAtomContent);
+}
+template <> ArrayRef<uint8_t> PLTARegAtom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(mipsLePltAAtomContent);
+}
+
+template <class ELFT> 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);
+ llvm_unreachable("PLT is not applicable for this target");
}
};
-class PLTMicroAtom : public PLTAtom {
+template <> ArrayRef<uint8_t> PLTR6Atom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsR6BePltAAtomContent);
+}
+template <> ArrayRef<uint8_t> PLTR6Atom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(mipsR6LePltAAtomContent);
+}
+
+template <class ELFT> class PLTMicroAtom : public PLTAtom {
public:
PLTMicroAtom(const GOTPLTAtom *got, const File &f) : PLTAtom(f, ".plt") {
// Setup reference to fixup the microMIPS PLT entry.
@@ -242,16 +359,23 @@ public:
CodeModel codeModel() const override { return codeMipsMicro; }
ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(micromipsPltAtomContent);
+ llvm_unreachable("PLT is not applicable for this target");
}
};
+template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(microMipsBePltAAtomContent);
+}
+template <> ArrayRef<uint8_t> PLTMicroAtom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(microMipsLePltAAtomContent);
+}
+
class LA25Atom : public PLTAtom {
public:
LA25Atom(const File &f) : PLTAtom(f, ".text") {}
};
-class LA25RegAtom : public LA25Atom {
+template <typename ELFT> class LA25RegAtom : public LA25Atom {
public:
LA25RegAtom(const Atom *a, const File &f) : LA25Atom(f) {
// Setup reference to fixup the LA25 stub entry.
@@ -261,11 +385,18 @@ public:
}
ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(mipsLA25AtomContent);
+ llvm_unreachable("LA25 stubs are not applicable for this target");
}
};
-class LA25MicroAtom : public LA25Atom {
+template <> ArrayRef<uint8_t> LA25RegAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(mipsBeLA25AtomContent);
+}
+template <> ArrayRef<uint8_t> LA25RegAtom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(mipsLeLA25AtomContent);
+}
+
+template <typename ELFT> class LA25MicroAtom : public LA25Atom {
public:
LA25MicroAtom(const Atom *a, const File &f) : LA25Atom(f) {
// Setup reference to fixup the microMIPS LA25 stub entry.
@@ -277,10 +408,17 @@ public:
CodeModel codeModel() const override { return codeMipsMicro; }
ArrayRef<uint8_t> rawContent() const override {
- return llvm::makeArrayRef(micromipsLA25AtomContent);
+ llvm_unreachable("LA25 stubs are not applicable for this target");
}
};
+template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32BE>::rawContent() const {
+ return llvm::makeArrayRef(microMipsBeLA25AtomContent);
+}
+template <> ArrayRef<uint8_t> LA25MicroAtom<ELF32LE>::rawContent() const {
+ return llvm::makeArrayRef(microMipsLeLA25AtomContent);
+}
+
class MipsGlobalOffsetTableAtom : public GlobalOffsetTableAtom {
public:
MipsGlobalOffsetTableAtom(const File &f) : GlobalOffsetTableAtom(f) {}
@@ -342,14 +480,14 @@ private:
/// \brief Map Atoms to their PLT entries.
llvm::DenseMap<const Atom *, PLTAAtom *> _pltRegMap;
- llvm::DenseMap<const Atom *, PLTMicroAtom *> _pltMicroMap;
+ llvm::DenseMap<const Atom *, PLTMicroAtom<ELFT> *> _pltMicroMap;
/// \brief Map Atoms to their Object entries.
llvm::DenseMap<const Atom *, ObjectAtom *> _objectMap;
/// \brief Map Atoms to their LA25 entries.
- llvm::DenseMap<const Atom *, LA25RegAtom *> _la25RegMap;
- llvm::DenseMap<const Atom *, LA25MicroAtom *> _la25MicroMap;
+ llvm::DenseMap<const Atom *, LA25Atom *> _la25RegMap;
+ llvm::DenseMap<const Atom *, LA25Atom *> _la25MicroMap;
/// \brief Atoms referenced by static relocations.
llvm::DenseSet<const Atom *> _hasStaticRelocations;
@@ -1085,9 +1223,8 @@ PLTAtom *RelocationPass<ELFT>::createPLTHeader(bool isMicroMips) {
_gotpltVector.insert(_gotpltVector.begin(), ga0);
if (isMicroMips)
- return new (_file._alloc) PLT0MicroAtom(ga0, _file);
- else
- return new (_file._alloc) PLT0Atom(ga0, _file);
+ return new (_file._alloc) PLT0MicroAtom<ELFT>(ga0, _file);
+ return new (_file._alloc) PLT0Atom<ELFT>(ga0, _file);
}
template <typename ELFT>
@@ -1108,9 +1245,11 @@ const PLTAtom *RelocationPass<ELFT>::getPLTRegEntry(const Atom *a) {
if (plt != _pltRegMap.end())
return plt->second;
- PLTAAtom *pa = isMipsR6()
- ? new (_file._alloc) PLTR6Atom(getGOTPLTEntry(a), _file)
- : new (_file._alloc) PLTAAtom(getGOTPLTEntry(a), _file);
+ PLTAAtom *pa = nullptr;
+ if (isMipsR6())
+ pa = new (_file._alloc) PLTR6Atom<ELFT>(getGOTPLTEntry(a), _file);
+ else
+ pa = new (_file._alloc) PLTARegAtom<ELFT>(getGOTPLTEntry(a), _file);
_pltRegMap[a] = pa;
_pltRegVector.push_back(pa);
@@ -1127,7 +1266,7 @@ const PLTAtom *RelocationPass<ELFT>::getPLTMicroEntry(const Atom *a) {
if (plt != _pltMicroMap.end())
return plt->second;
- auto pa = new (_file._alloc) PLTMicroAtom(getGOTPLTEntry(a), _file);
+ auto pa = new (_file._alloc) PLTMicroAtom<ELFT>(getGOTPLTEntry(a), _file);
_pltMicroMap[a] = pa;
_pltMicroVector.push_back(pa);
@@ -1144,7 +1283,7 @@ const LA25Atom *RelocationPass<ELFT>::getLA25RegEntry(const Atom *a) {
if (la25 != _la25RegMap.end())
return la25->second;
- auto sa = new (_file._alloc) LA25RegAtom(a, _file);
+ auto sa = new (_file._alloc) LA25RegAtom<ELFT>(a, _file);
_la25RegMap[a] = sa;
_la25Vector.push_back(sa);
@@ -1157,7 +1296,7 @@ const LA25Atom *RelocationPass<ELFT>::getLA25MicroEntry(const Atom *a) {
if (la25 != _la25MicroMap.end())
return la25->second;
- auto sa = new (_file._alloc) LA25MicroAtom(a, _file);
+ auto sa = new (_file._alloc) LA25MicroAtom<ELFT>(a, _file);
_la25MicroMap[a] = sa;
_la25Vector.push_back(sa);
@@ -1186,8 +1325,12 @@ RelocationPass<ELFT>::getObjectEntry(const SharedLibraryAtom *a) {
static std::unique_ptr<Pass> createPass(MipsLinkingContext &ctx) {
switch (ctx.getTriple().getArch()) {
+ case llvm::Triple::mips:
+ return llvm::make_unique<RelocationPass<ELF32BE>>(ctx);
case llvm::Triple::mipsel:
return llvm::make_unique<RelocationPass<ELF32LE>>(ctx);
+ case llvm::Triple::mips64:
+ return llvm::make_unique<RelocationPass<ELF64BE>>(ctx);
case llvm::Triple::mips64el:
return llvm::make_unique<RelocationPass<ELF64LE>>(ctx);
default:
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
index d6318cbee04..98cc059787e 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
@@ -44,7 +44,9 @@ template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
this->_outputSection->setType(this->_type);
}
+template class MipsReginfoSection<ELF32BE>;
template class MipsReginfoSection<ELF32LE>;
+template class MipsReginfoSection<ELF64BE>;
template class MipsReginfoSection<ELF64LE>;
template <class ELFT>
@@ -85,7 +87,9 @@ template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
this->_outputSection->setType(this->_type);
}
+template class MipsOptionsSection<ELF32BE>;
template class MipsOptionsSection<ELF32LE>;
+template class MipsOptionsSection<ELF64BE>;
template class MipsOptionsSection<ELF64LE>;
template <class ELFT>
@@ -116,7 +120,9 @@ template <class ELFT> void MipsAbiFlagsSection<ELFT>::finalize() {
this->_outputSection->setType(this->_type);
}
+template class MipsAbiFlagsSection<ELF32BE>;
template class MipsAbiFlagsSection<ELF32LE>;
+template class MipsAbiFlagsSection<ELF64BE>;
template class MipsAbiFlagsSection<ELF64LE>;
template <class ELFT>
@@ -175,7 +181,9 @@ const AtomLayout *MipsGOTSection<ELFT>::appendAtom(const Atom *atom) {
return AtomSection<ELFT>::appendAtom(atom);
}
+template class MipsGOTSection<ELF32BE>;
template class MipsGOTSection<ELF32LE>;
+template class MipsGOTSection<ELF64BE>;
template class MipsGOTSection<ELF64LE>;
template <class ELFT>
@@ -208,7 +216,9 @@ const AtomLayout *MipsPLTSection<ELFT>::appendAtom(const Atom *atom) {
return layout;
}
+template class MipsPLTSection<ELF32BE>;
template class MipsPLTSection<ELF32LE>;
+template class MipsPLTSection<ELF64BE>;
template class MipsPLTSection<ELF64LE>;
template <class ELFT> static bool isMips64EL() {
@@ -245,7 +255,9 @@ void MipsRelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r,
r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
}
+template class MipsRelocationTable<ELF32BE>;
template class MipsRelocationTable<ELF32LE>;
+template class MipsRelocationTable<ELF64BE>;
template class MipsRelocationTable<ELF64LE>;
} // elf
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
index 2afc2c1fdcf..d78fc466b4d 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
@@ -53,7 +53,9 @@ std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() {
}
}
+template class MipsTargetHandler<ELF32BE>;
template class MipsTargetHandler<ELF32LE>;
+template class MipsTargetHandler<ELF64BE>;
template class MipsTargetHandler<ELF64LE>;
template <class ELFT>
@@ -95,7 +97,9 @@ template <class ELFT> void MipsSymbolTable<ELFT>::finalize(bool sort) {
}
}
+template class MipsSymbolTable<ELF32BE>;
template class MipsSymbolTable<ELF32LE>;
+template class MipsSymbolTable<ELF64BE>;
template class MipsSymbolTable<ELF64LE>;
template <class ELFT>
@@ -149,7 +153,9 @@ template <class ELFT> void MipsDynamicSymbolTable<ELFT>::finalize() {
}
}
+template class MipsDynamicSymbolTable<ELF32BE>;
template class MipsDynamicSymbolTable<ELF32LE>;
+template class MipsDynamicSymbolTable<ELF64BE>;
template class MipsDynamicSymbolTable<ELF64LE>;
}
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
index 78ea33d7d41..cb06d5d21ce 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
@@ -102,7 +102,9 @@ template <class ELFT> void MipsTargetLayout<ELFT>::sortSegments() {
this->_segments.insert(outIt, abiSeg);
}
+template class MipsTargetLayout<ELF32BE>;
template class MipsTargetLayout<ELF32LE>;
+template class MipsTargetLayout<ELF64BE>;
template class MipsTargetLayout<ELF64LE>;
} // end namespace elf
OpenPOWER on IntegriCloud