Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -169,9 +169,7 @@ size_t Size = 0; }; -template class MipsGotSection final : public SyntheticSection { - typedef typename ELFT::uint uintX_t; - +class MipsGotSection final : public SyntheticSection { public: MipsGotSection(); void writeTo(uint8_t *Buf) override; @@ -182,9 +180,9 @@ void addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr); bool addDynTlsEntry(SymbolBody &Sym); bool addTlsIndex(); - uintX_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const; - uintX_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const; - uintX_t getGlobalDynOffset(const SymbolBody &B) const; + uint64_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const; + uint64_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const; + uint64_t getGlobalDynOffset(const SymbolBody &B) const; // Returns the symbol which corresponds to the first entry of the global part // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic @@ -198,11 +196,11 @@ // Returns offset of TLS part of the MIPS GOT table. This part goes // after 'local' and 'global' entries. - uintX_t getTlsOffset() const; + uint64_t getTlsOffset() const; uint32_t getTlsIndexOff() const { return TlsIndexOff; } - uintX_t getGp() const; + uint64_t getGp() const; private: // MIPS GOT consists of three parts: local, global and tls. Each part @@ -250,7 +248,7 @@ // to the first index of "Page" entries allocated for this section. llvm::SmallMapVector PageIndexMap; - typedef std::pair GotEntry; + typedef std::pair GotEntry; typedef std::vector GotEntries; // Map from Symbol-Addend pair to the GOT index. llvm::DenseMap EntryIndexMap; @@ -266,7 +264,7 @@ std::vector TlsEntries; uint32_t TlsIndexOff = -1; - uintX_t Size = 0; + uint64_t Size = 0; }; class GotPltSection final : public SyntheticSection { @@ -766,6 +764,7 @@ static InputSection *Interp; static GotPltSection *GotPlt; static IgotPltSection *IgotPlt; + static MipsGotSection *MipsGot; static MipsRldMapSection *MipsRldMap; static PltSection *Plt; static PltSection *Iplt; @@ -781,7 +780,6 @@ static GdbIndexSection *GdbIndex; static GotSection *Got; static EhFrameSection *EhFrame; - static MipsGotSection *MipsGot; static HashTableSection *HashTab; static RelocationSection *RelaDyn; static RelocationSection *RelaPlt; @@ -799,7 +797,6 @@ template GnuHashTableSection *In::GnuHashTab; template GotSection *In::Got; template EhFrameSection *In::EhFrame; -template MipsGotSection *In::MipsGot; template HashTableSection *In::HashTab; template RelocationSection *In::RelaDyn; template RelocationSection *In::RelaPlt; Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -665,14 +665,11 @@ this->template relocate(Buf, Buf + Size); } -template -MipsGotSection::MipsGotSection() +MipsGotSection::MipsGotSection() : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16, ".got") {} -template -void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, - RelExpr Expr) { +void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) { // For "true" local symbols which can be referenced from the same module // only compiler creates two instructions for address loading: // @@ -715,7 +712,7 @@ TlsEntries.push_back(&Sym); return; } - auto AddEntry = [&](SymbolBody &S, uintX_t A, GotEntries &Items) { + auto AddEntry = [&](SymbolBody &S, uint64_t A, GotEntries &Items) { if (S.isInGot() && !A) return; size_t NewIndex = Items.size(); @@ -740,8 +737,7 @@ } } -template -bool MipsGotSection::addDynTlsEntry(SymbolBody &Sym) { +bool MipsGotSection::addDynTlsEntry(SymbolBody &Sym) { if (Sym.GlobalDynIndex != -1U) return false; Sym.GlobalDynIndex = TlsEntries.size(); @@ -753,10 +749,10 @@ // Reserves TLS entries for a TLS module ID and a TLS block offset. // In total it takes two GOT slots. -template bool MipsGotSection::addTlsIndex() { +bool MipsGotSection::addTlsIndex() { if (TlsIndexOff != uint32_t(-1)) return false; - TlsIndexOff = TlsEntries.size() * sizeof(uintX_t); + TlsIndexOff = TlsEntries.size() * Config->Wordsize; TlsEntries.push_back(nullptr); TlsEntries.push_back(nullptr); return true; @@ -770,25 +766,21 @@ return (Size + 0xfffe) / 0xffff + 1; } -template -typename MipsGotSection::uintX_t -MipsGotSection::getPageEntryOffset(const SymbolBody &B, - int64_t Addend) const { +uint64_t MipsGotSection::getPageEntryOffset(const SymbolBody &B, + int64_t Addend) const { const OutputSection *OutSec = cast(&B)->Section->getOutputSection(); - uintX_t SecAddr = getMipsPageAddr(OutSec->Addr); - uintX_t SymAddr = getMipsPageAddr(B.getVA(Addend)); - uintX_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff; + uint64_t SecAddr = getMipsPageAddr(OutSec->Addr); + uint64_t SymAddr = getMipsPageAddr(B.getVA(Addend)); + uint64_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff; assert(Index < PageEntriesNum); - return (HeaderEntriesNum + Index) * sizeof(uintX_t); + return (HeaderEntriesNum + Index) * Config->Wordsize; } -template -typename MipsGotSection::uintX_t -MipsGotSection::getBodyEntryOffset(const SymbolBody &B, - int64_t Addend) const { +uint64_t MipsGotSection::getBodyEntryOffset(const SymbolBody &B, + int64_t Addend) const { // Calculate offset of the GOT entries block: TLS, global, local. - uintX_t Index = HeaderEntriesNum + PageEntriesNum; + uint64_t Index = HeaderEntriesNum + PageEntriesNum; if (B.isTls()) Index += LocalEntries.size() + LocalEntries32.size() + GlobalEntries.size(); else if (B.IsInGlobalMipsGot) @@ -803,37 +795,31 @@ assert(It != EntryIndexMap.end()); Index += It->second; } - return Index * sizeof(uintX_t); + return Index * Config->Wordsize; } -template -typename MipsGotSection::uintX_t -MipsGotSection::getTlsOffset() const { - return (getLocalEntriesNum() + GlobalEntries.size()) * sizeof(uintX_t); +uint64_t MipsGotSection::getTlsOffset() const { + return (getLocalEntriesNum() + GlobalEntries.size()) * Config->Wordsize; } -template -typename MipsGotSection::uintX_t -MipsGotSection::getGlobalDynOffset(const SymbolBody &B) const { - return B.GlobalDynIndex * sizeof(uintX_t); +uint64_t MipsGotSection::getGlobalDynOffset(const SymbolBody &B) const { + return B.GlobalDynIndex * Config->Wordsize; } -template -const SymbolBody *MipsGotSection::getFirstGlobalEntry() const { +const SymbolBody *MipsGotSection::getFirstGlobalEntry() const { return GlobalEntries.empty() ? nullptr : GlobalEntries.front().first; } -template -unsigned MipsGotSection::getLocalEntriesNum() const { +unsigned MipsGotSection::getLocalEntriesNum() const { return HeaderEntriesNum + PageEntriesNum + LocalEntries.size() + LocalEntries32.size(); } -template void MipsGotSection::finalizeContents() { +void MipsGotSection::finalizeContents() { updateAllocSize(); } -template void MipsGotSection::updateAllocSize() { +void MipsGotSection::updateAllocSize() { PageEntriesNum = 0; for (std::pair &P : PageIndexMap) { // For each output section referenced by GOT page relocations calculate @@ -846,27 +832,29 @@ PageEntriesNum += getMipsPageCount(P.first->Size); } Size = (getLocalEntriesNum() + GlobalEntries.size() + TlsEntries.size()) * - sizeof(uintX_t); + Config->Wordsize; } -template bool MipsGotSection::empty() const { +bool MipsGotSection::empty() const { // We add the .got section to the result for dynamic MIPS target because // its address and properties are mentioned in the .dynamic section. return Config->Relocatable; } -template -typename MipsGotSection::uintX_t MipsGotSection::getGp() const { +uint64_t MipsGotSection::getGp() const { return ElfSym::MipsGp->getVA(0); } -template -static void writeUint(uint8_t *Buf, typename ELFT::uint Val) { - typedef typename ELFT::uint uintX_t; - write(Buf, Val); +static void writeUint(uint8_t *Buf, uint64_t Val) { + support::endianness E = + Config->IsLE ? support::endianness::little : support::endianness::big; + if (Config->Wordsize == 0) + write64(Buf, Val, E); + else + write32(Buf, Val, E); } -template void MipsGotSection::writeTo(uint8_t *Buf) { +void MipsGotSection::writeTo(uint8_t *Buf) { // Set the MSB of the second GOT slot. This is not required by any // MIPS ABI documentation, though. // @@ -881,25 +869,24 @@ // we've been doing this for years, it is probably a safe bet to // keep doing this for now. We really need to revisit this to see // if we had to do this. - auto *P = reinterpret_cast(Buf); - P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31); - Buf += HeaderEntriesNum * sizeof(uintX_t); + writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1)); + Buf += HeaderEntriesNum * Config->Wordsize; // Write 'page address' entries to the local part of the GOT. for (std::pair &L : PageIndexMap) { size_t PageCount = getMipsPageCount(L.first->Size); - uintX_t FirstPageAddr = getMipsPageAddr(L.first->Addr); + uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr); for (size_t PI = 0; PI < PageCount; ++PI) { - uint8_t *Entry = Buf + (L.second + PI) * sizeof(uintX_t); - writeUint(Entry, FirstPageAddr + PI * 0x10000); + uint8_t *Entry = Buf + (L.second + PI) * Config->Wordsize; + writeUint(Entry, FirstPageAddr + PI * 0x10000); } } - Buf += PageEntriesNum * sizeof(uintX_t); + Buf += PageEntriesNum * Config->Wordsize; auto AddEntry = [&](const GotEntry &SA) { uint8_t *Entry = Buf; - Buf += sizeof(uintX_t); + Buf += Config->Wordsize; const SymbolBody *Body = SA.first; - uintX_t VA = Body->getVA(SA.second); - writeUint(Entry, VA); + uint64_t VA = Body->getVA(SA.second); + writeUint(Entry, VA); }; std::for_each(std::begin(LocalEntries), std::end(LocalEntries), AddEntry); std::for_each(std::begin(LocalEntries32), std::end(LocalEntries32), AddEntry); @@ -910,20 +897,20 @@ // for thread-local storage. // https://www.linux-mips.org/wiki/NPTL if (TlsIndexOff != -1U && !Config->Pic) - writeUint(Buf + TlsIndexOff, 1); + writeUint(Buf + TlsIndexOff, 1); for (const SymbolBody *B : TlsEntries) { if (!B || B->isPreemptible()) continue; - uintX_t VA = B->getVA(); + uint64_t VA = B->getVA(); if (B->GotIndex != -1U) { - uint8_t *Entry = Buf + B->GotIndex * sizeof(uintX_t); - writeUint(Entry, VA - 0x7000); + uint8_t *Entry = Buf + B->GotIndex * Config->Wordsize; + writeUint(Entry, VA - 0x7000); } if (B->GlobalDynIndex != -1U) { - uint8_t *Entry = Buf + B->GlobalDynIndex * sizeof(uintX_t); - writeUint(Entry, 1); - Entry += sizeof(uintX_t); - writeUint(Entry, VA - 0x8000); + uint8_t *Entry = Buf + B->GlobalDynIndex * Config->Wordsize; + writeUint(Entry, 1); + Entry += Config->Wordsize; + writeUint(Entry, VA - 0x8000); } } } @@ -2254,6 +2241,7 @@ InputSection *InX::Interp; GotPltSection *InX::GotPlt; IgotPltSection *InX::IgotPlt; +MipsGotSection *InX::MipsGot; MipsRldMapSection *InX::MipsRldMap; PltSection *InX::Plt; PltSection *InX::Iplt; @@ -2308,11 +2296,6 @@ template class elf::GotSection; template class elf::GotSection; -template class elf::MipsGotSection; -template class elf::MipsGotSection; -template class elf::MipsGotSection; -template class elf::MipsGotSection; - template class elf::DynamicSection; template class elf::DynamicSection; template class elf::DynamicSection; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -415,7 +415,7 @@ // Add .got. MIPS' .got is so different from the other archs, // it has its own class. if (Config->EMachine == EM_MIPS) { - In::MipsGot = make>(); + In::MipsGot = make(); Add(In::MipsGot); } else { In::Got = make>();