// If relocation against MIPS local symbol requires GOT entry, this entry
// should be initialized by 'page address'. This address is high 16-bits
// of sum the symbol's value and the addend.
- return In<ELFT>::Got->getMipsLocalPageOffset(Body.getVA<ELFT>(A));
+ return In<ELFT>::MipsGot->getMipsLocalPageOffset(Body.getVA<ELFT>(A));
case R_MIPS_GOT_OFF:
case R_MIPS_GOT_OFF32:
// In case of MIPS if a GOT relocation has non-zero addend this addend
// should be applied to the GOT entry content not to the GOT entry offset.
// That is why we use separate expression type.
- return In<ELFT>::Got->getMipsGotOffset(Body, A);
+ return In<ELFT>::MipsGot->getMipsGotOffset(Body, A);
+ case R_MIPS_GOTREL:
+ return Body.getVA<ELFT>(A) - In<ELFT>::MipsGot->getVA() - MipsGPOffset;
case R_MIPS_TLSGD:
- return In<ELFT>::Got->getGlobalDynOffset(Body) +
- In<ELFT>::Got->getMipsTlsOffset() - MipsGPOffset;
+ return In<ELFT>::MipsGot->getGlobalDynOffset(Body) +
+ In<ELFT>::MipsGot->getMipsTlsOffset() - MipsGPOffset;
case R_MIPS_TLSLD:
- return In<ELFT>::Got->getTlsIndexOff() + In<ELFT>::Got->getMipsTlsOffset() -
- MipsGPOffset;
+ return In<ELFT>::MipsGot->getTlsIndexOff() +
+ In<ELFT>::MipsGot->getMipsTlsOffset() - MipsGPOffset;
case R_PPC_OPD: {
uint64_t SymVA = Body.getVA<ELFT>(A);
// If we have an undefined weak symbol, we might get here with a symbol
// relocation even for non-preemptible symbols in applications. For static
// linking support we must either resolve the module index relocation at static
// link time, or hard code the module index (1) for the application in the GOT.
-template <class ELFT>
-static unsigned handleNoRelaxTlsRelocation(uint32_t Type, SymbolBody &Body,
- InputSectionBase<ELFT> &C,
- typename ELFT::uint Offset,
- typename ELFT::uint Addend,
- RelExpr Expr) {
+template <class ELFT, class GOT>
+static unsigned handleNoRelaxTlsRelocation(
+ GOT *Got, uint32_t Type, SymbolBody &Body, InputSectionBase<ELFT> &C,
+ typename ELFT::uint Offset, typename ELFT::uint Addend, RelExpr Expr) {
if (Expr == R_MIPS_TLSLD || Expr == R_TLSLD_PC) {
- if (In<ELFT>::Got->addTlsIndex() &&
- (Config->Pic || Config->EMachine == EM_ARM))
- In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
- In<ELFT>::Got->getTlsIndexOff(), false,
- nullptr, 0});
+ if (Got->addTlsIndex() && (Config->Pic || Config->EMachine == EM_ARM))
+ In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, Got,
+ Got->getTlsIndexOff(), false, nullptr, 0});
C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
return 1;
}
typedef typename ELFT::uint uintX_t;
if (Target->isTlsGlobalDynamicRel(Type)) {
- if (In<ELFT>::Got->addDynTlsEntry(Body) &&
+ if (Got->addDynTlsEntry(Body) &&
(Body.isPreemptible() || Config->EMachine == EM_ARM)) {
- uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
+ uintX_t Off = Got->getGlobalDynOffset(Body);
In<ELFT>::RelaDyn->addReloc(
- {Target->TlsModuleIndexRel, In<ELFT>::Got, Off, false, &Body, 0});
+ {Target->TlsModuleIndexRel, Got, Off, false, &Body, 0});
if (Body.isPreemptible())
- In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
+ In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Got,
Off + (uintX_t)sizeof(uintX_t), false,
&Body, 0});
}
typedef typename ELFT::uint uintX_t;
- if (Config->EMachine == EM_MIPS || Config->EMachine == EM_ARM)
- return handleNoRelaxTlsRelocation<ELFT>(Type, Body, C, Offset, Addend,
- Expr);
+ if (Config->EMachine == EM_ARM)
+ return handleNoRelaxTlsRelocation<ELFT>(In<ELFT>::Got, Type, Body, C,
+ Offset, Addend, Expr);
+ if (Config->EMachine == EM_MIPS)
+ return handleNoRelaxTlsRelocation<ELFT>(In<ELFT>::MipsGot, Type, Body, C,
+ Offset, Addend, Expr);
if ((Expr == R_TLSDESC || Expr == R_TLSDESC_PAGE || Expr == R_TLSDESC_CALL) &&
Config->Shared) {
// file (PC, or GOT for example).
static bool isRelExpr(RelExpr Expr) {
return Expr == R_PC || Expr == R_GOTREL || Expr == R_GOTREL_FROM_END ||
- Expr == R_PAGE_PC || Expr == R_RELAX_GOT_PC || Expr == R_THUNK_PC ||
- Expr == R_THUNK_PLT_PC;
+ Expr == R_MIPS_GOTREL || Expr == R_PAGE_PC || Expr == R_RELAX_GOT_PC ||
+ Expr == R_THUNK_PC || Expr == R_THUNK_PLT_PC;
}
template <class ELFT>
// For details see p. 4-19 at
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
Addend += 4;
- if (Expr == R_GOTREL) {
- Addend -= MipsGPOffset;
- if (Body.isLocal())
- Addend += File.MipsGp0;
- }
+ if (Expr == R_MIPS_GOTREL && Body.isLocal())
+ Addend += File.MipsGp0;
}
if (Config->Pic && Config->EMachine == EM_PPC64 && Type == R_PPC64_TOC)
Addend += getPPC64TocBase();
// a dynamic relocation.
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
if (Config->EMachine == EM_MIPS)
- In<ELFT>::Got->addMipsEntry(Body, Addend, Expr);
+ In<ELFT>::MipsGot->addEntry(Body, Addend, Expr);
continue;
}
// See "Global Offset Table" in Chapter 5 in the following document
// for detailed description:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- In<ELFT>::Got->addMipsEntry(Body, Addend, Expr);
+ In<ELFT>::MipsGot->addEntry(Body, Addend, Expr);
if (Body.isTls() && Body.isPreemptible())
- AddDyn({Target->TlsGotRel, In<ELFT>::Got, Body.getGotOffset<ELFT>(),
- false, &Body, 0});
+ AddDyn({Target->TlsGotRel, In<ELFT>::MipsGot,
+ Body.getGotOffset<ELFT>(), false, &Body, 0});
continue;
}
R_MIPS_GOT_LOCAL_PAGE,
R_MIPS_GOT_OFF,
R_MIPS_GOT_OFF32,
+ R_MIPS_GOTREL,
R_MIPS_TLSGD,
R_MIPS_TLSLD,
R_NEG_TLS,
template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
if (!Config->Relocatable)
getOptions()->getRegInfo().ri_gp_value =
- In<ELFT>::Got->getVA() + MipsGPOffset;
+ In<ELFT>::MipsGot->getVA() + MipsGPOffset;
}
// MIPS .reginfo section.
template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
if (!Config->Relocatable)
- Reginfo.ri_gp_value = In<ELFT>::Got->getVA() + MipsGPOffset;
+ Reginfo.ri_gp_value = In<ELFT>::MipsGot->getVA() + MipsGPOffset;
}
static ArrayRef<uint8_t> createInterp() {
template <class ELFT>
GotSection<ELFT>::GotSection()
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
- Target->GotEntrySize, ".got") {
- if (Config->EMachine == EM_MIPS)
- this->Flags |= SHF_MIPS_GPREL;
-}
+ Target->GotEntrySize, ".got") {}
template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) {
Sym.GotIndex = Entries.size();
Entries.push_back(&Sym);
}
+template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) {
+ if (Sym.GlobalDynIndex != -1U)
+ return false;
+ Sym.GlobalDynIndex = Entries.size();
+ // Global Dynamic TLS entries take two GOT slots.
+ Entries.push_back(nullptr);
+ Entries.push_back(&Sym);
+ return true;
+}
+
+// Reserves TLS entries for a TLS module ID and a TLS block offset.
+// In total it takes two GOT slots.
+template <class ELFT> bool GotSection<ELFT>::addTlsIndex() {
+ if (TlsIndexOff != uint32_t(-1))
+ return false;
+ TlsIndexOff = Entries.size() * sizeof(uintX_t);
+ Entries.push_back(nullptr);
+ Entries.push_back(nullptr);
+ return true;
+}
+
template <class ELFT>
-void GotSection<ELFT>::addMipsEntry(SymbolBody &Sym, uintX_t Addend,
+typename GotSection<ELFT>::uintX_t
+GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const {
+ return this->getVA() + B.GlobalDynIndex * sizeof(uintX_t);
+}
+
+template <class ELFT>
+typename GotSection<ELFT>::uintX_t
+GotSection<ELFT>::getGlobalDynOffset(const SymbolBody &B) const {
+ return B.GlobalDynIndex * sizeof(uintX_t);
+}
+
+template <class ELFT> void GotSection<ELFT>::finalize() {
+ Size = Entries.size() * sizeof(uintX_t);
+}
+
+template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
+ for (const SymbolBody *B : Entries) {
+ uint8_t *Entry = Buf;
+ Buf += sizeof(uintX_t);
+ if (!B)
+ continue;
+ if (B->isPreemptible())
+ continue; // The dynamic linker will take care of it.
+ uintX_t VA = B->getVA<ELFT>();
+ write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
+ }
+}
+
+template <class ELFT>
+MipsGotSection<ELFT>::MipsGotSection()
+ : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL,
+ SHT_PROGBITS, Target->GotEntrySize, ".got") {}
+
+template <class ELFT>
+void MipsGotSection<ELFT>::addEntry(SymbolBody &Sym, uintX_t Addend,
RelExpr Expr) {
// For "true" local symbols which can be referenced from the same module
// only compiler creates two instructions for address loading:
}
}
-template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) {
+template <class ELFT> bool MipsGotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) {
if (Sym.GlobalDynIndex != -1U)
return false;
Sym.GlobalDynIndex = Entries.size();
// Reserves TLS entries for a TLS module ID and a TLS block offset.
// In total it takes two GOT slots.
-template <class ELFT> bool GotSection<ELFT>::addTlsIndex() {
+template <class ELFT> bool MipsGotSection<ELFT>::addTlsIndex() {
if (TlsIndexOff != uint32_t(-1))
return false;
TlsIndexOff = Entries.size() * sizeof(uintX_t);
}
template <class ELFT>
-typename GotSection<ELFT>::uintX_t
-GotSection<ELFT>::getMipsLocalPageOffset(uintX_t EntryValue) {
+typename MipsGotSection<ELFT>::uintX_t
+MipsGotSection<ELFT>::getMipsLocalPageOffset(uintX_t EntryValue) {
// Initialize the entry by the %hi(EntryValue) expression
// but without right-shifting.
EntryValue = (EntryValue + 0x8000) & ~0xffff;
// Take into account MIPS GOT header.
- // See comment in the GotSection::writeTo.
+ // See comment in the MipsGotSection::writeTo.
size_t NewIndex = MipsLocalGotPos.size() + 2;
auto P = MipsLocalGotPos.insert(std::make_pair(EntryValue, NewIndex));
assert(!P.second || MipsLocalGotPos.size() <= MipsPageEntries);
}
template <class ELFT>
-typename GotSection<ELFT>::uintX_t
-GotSection<ELFT>::getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const {
+typename MipsGotSection<ELFT>::uintX_t
+MipsGotSection<ELFT>::getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const {
// Calculate offset of the GOT entries block: TLS, global, local.
uintX_t GotBlockOff;
if (B.isTls())
}
template <class ELFT>
-typename GotSection<ELFT>::uintX_t GotSection<ELFT>::getMipsTlsOffset() const {
+typename MipsGotSection<ELFT>::uintX_t MipsGotSection<ELFT>::getMipsTlsOffset() const {
return (getMipsLocalEntriesNum() + MipsGlobal.size()) * sizeof(uintX_t);
}
template <class ELFT>
-typename GotSection<ELFT>::uintX_t
-GotSection<ELFT>::getGlobalDynAddr(const SymbolBody &B) const {
- return this->getVA() + B.GlobalDynIndex * sizeof(uintX_t);
-}
-
-template <class ELFT>
-typename GotSection<ELFT>::uintX_t
-GotSection<ELFT>::getGlobalDynOffset(const SymbolBody &B) const {
+typename MipsGotSection<ELFT>::uintX_t
+MipsGotSection<ELFT>::getGlobalDynOffset(const SymbolBody &B) const {
return B.GlobalDynIndex * sizeof(uintX_t);
}
template <class ELFT>
-const SymbolBody *GotSection<ELFT>::getMipsFirstGlobalEntry() const {
+const SymbolBody *MipsGotSection<ELFT>::getMipsFirstGlobalEntry() const {
return MipsGlobal.empty() ? nullptr : MipsGlobal.front().first;
}
template <class ELFT>
-unsigned GotSection<ELFT>::getMipsLocalEntriesNum() const {
+unsigned MipsGotSection<ELFT>::getMipsLocalEntriesNum() const {
return MipsPageEntries + MipsLocal.size() + MipsLocal32.size();
}
-template <class ELFT> void GotSection<ELFT>::finalize() {
+template <class ELFT> void MipsGotSection<ELFT>::finalize() {
size_t EntriesNum = Entries.size();
- if (Config->EMachine == EM_MIPS) {
- // Take into account MIPS GOT header.
- // See comment in the GotSection::writeTo.
- MipsPageEntries += 2;
- for (const OutputSectionBase *OutSec : MipsOutSections) {
- // Calculate an upper bound of MIPS GOT entries required to store page
- // addresses of local symbols. We assume the worst case - each 64kb
- // page of the output section has at least one GOT relocation against it.
- // Add 0x8000 to the section's size because the page address stored
- // in the GOT entry is calculated as (value + 0x8000) & ~0xffff.
- MipsPageEntries += (OutSec->Size + 0x8000 + 0xfffe) / 0xffff;
- }
- EntriesNum += getMipsLocalEntriesNum() + MipsGlobal.size();
+ // Take into account MIPS GOT header.
+ // See comment in the MipsGotSection::writeTo.
+ MipsPageEntries += 2;
+ for (const OutputSectionBase *OutSec : MipsOutSections) {
+ // Calculate an upper bound of MIPS GOT entries required to store page
+ // addresses of local symbols. We assume the worst case - each 64kb
+ // page of the output section has at least one GOT relocation against it.
+ // Add 0x8000 to the section's size because the page address stored
+ // in the GOT entry is calculated as (value + 0x8000) & ~0xffff.
+ MipsPageEntries += (OutSec->Size + 0x8000 + 0xfffe) / 0xffff;
}
+ EntriesNum += getMipsLocalEntriesNum() + MipsGlobal.size();
Size = EntriesNum * sizeof(uintX_t);
}
write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Buf, Val);
}
-template <class ELFT> void GotSection<ELFT>::writeMipsGot(uint8_t *Buf) {
+template <class ELFT> void MipsGotSection<ELFT>::writeTo(uint8_t *Buf) {
// Set the MSB of the second GOT slot. This is not required by any
// MIPS ABI documentation, though.
//
}
}
-template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
- if (Config->EMachine == EM_MIPS) {
- writeMipsGot(Buf);
- return;
- }
- for (const SymbolBody *B : Entries) {
- uint8_t *Entry = Buf;
- Buf += sizeof(uintX_t);
- if (!B)
- continue;
- if (B->isPreemptible())
- continue; // The dynamic linker will take care of it.
- uintX_t VA = B->getVA<ELFT>();
- writeUint<ELFT>(Entry, VA);
- }
-}
-
template <class ELFT>
GotPltSection<ELFT>::GotPltSection()
: SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
Add({DT_MIPS_FLAGS, RHF_NOTPOT});
Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()});
- Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::Got->getMipsLocalEntriesNum()});
- if (const SymbolBody *B = In<ELFT>::Got->getMipsFirstGlobalEntry())
+ Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::MipsGot->getMipsLocalEntriesNum()});
+ if (const SymbolBody *B = In<ELFT>::MipsGot->getMipsFirstGlobalEntry())
Add({DT_MIPS_GOTSYM, B->DynsymIndex});
else
Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()});
- Add({DT_PLTGOT, In<ELFT>::Got});
+ Add({DT_PLTGOT, In<ELFT>::MipsGot});
if (Out<ELFT>::MipsRldMap)
Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap});
}
if (Config->Rela)
P->r_addend = Rel.getAddend();
P->r_offset = Rel.getOffset();
- if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::Got)
+ if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::MipsGot)
// Dynamic relocation against MIPS GOT section make deal TLS entries
// allocated in the end of the GOT. We need to adjust the offset to take
// in account 'local' and 'global' GOT entries.
- P->r_offset += In<ELFT>::Got->getMipsTlsOffset();
+ P->r_offset += In<ELFT>::MipsGot->getMipsTlsOffset();
P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL);
}
template class elf::GotSection<ELF64LE>;
template class elf::GotSection<ELF64BE>;
+template class elf::MipsGotSection<ELF32LE>;
+template class elf::MipsGotSection<ELF32BE>;
+template class elf::MipsGotSection<ELF64LE>;
+template class elf::MipsGotSection<ELF64BE>;
+
template class elf::GotPltSection<ELF32LE>;
template class elf::GotPltSection<ELF32BE>;
template class elf::GotPltSection<ELF64LE>;
size_t getSize() const override { return Size; }
void finalize() override;
void addEntry(SymbolBody &Sym);
- void addMipsEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr);
+ bool addDynTlsEntry(SymbolBody &Sym);
+ bool addTlsIndex();
+ bool empty() const { return Entries.empty(); }
+ uintX_t getGlobalDynAddr(const SymbolBody &B) const;
+ uintX_t getGlobalDynOffset(const SymbolBody &B) const;
+
+ uintX_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
+ uint32_t getTlsIndexOff() const { return TlsIndexOff; }
+
+ // Flag to force GOT to be in output if we have relocations
+ // that relies on its address.
+ bool HasGotOffRel = false;
+
+private:
+ std::vector<const SymbolBody *> Entries;
+ uint32_t TlsIndexOff = -1;
+ uintX_t Size = 0;
+};
+
+template <class ELFT> class MipsGotSection final : public SyntheticSection<ELFT> {
+ typedef typename ELFT::uint uintX_t;
+
+public:
+ MipsGotSection();
+ void writeTo(uint8_t *Buf) override;
+ size_t getSize() const override { return Size; }
+ void finalize() override;
+ void addEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr);
bool addDynTlsEntry(SymbolBody &Sym);
bool addTlsIndex();
bool empty() const { return MipsPageEntries == 0 && Entries.empty(); }
uintX_t getMipsLocalPageOffset(uintX_t Addr);
uintX_t getMipsGotOffset(const SymbolBody &B, uintX_t Addend) const;
- uintX_t getGlobalDynAddr(const SymbolBody &B) const;
uintX_t getGlobalDynOffset(const SymbolBody &B) const;
// Returns the symbol which corresponds to the first entry of the global part
// after 'local' and 'global' entries.
uintX_t getMipsTlsOffset() const;
- uintX_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
uint32_t getTlsIndexOff() const { return TlsIndexOff; }
- // Flag to force GOT to be in output if we have relocations
- // that relies on its address.
- bool HasGotOffRel = false;
-
private:
std::vector<const SymbolBody *> Entries;
uint32_t TlsIndexOff = -1;
MipsGotEntries MipsLocal;
MipsGotEntries MipsLocal32;
MipsGotEntries MipsGlobal;
-
- // Write MIPS-specific parts of the GOT.
- void writeMipsGot(uint8_t *Buf);
};
template <class ELFT>
static DynamicSection<ELFT> *Dynamic;
static StringTableSection<ELFT> *DynStrTab;
static GotSection<ELFT> *Got;
+ static MipsGotSection<ELFT> *MipsGot;
static GotPltSection<ELFT> *GotPlt;
static InputSection<ELFT> *Interp;
static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic;
template <class ELFT> StringTableSection<ELFT> *In<ELFT>::DynStrTab;
template <class ELFT> GotSection<ELFT> *In<ELFT>::Got;
+template <class ELFT> MipsGotSection<ELFT> *In<ELFT>::MipsGot;
template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
template <class ELFT> InputSection<ELFT> *In<ELFT>::Interp;
template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
return R_HINT;
case R_MIPS_GPREL16:
case R_MIPS_GPREL32:
- return R_GOTREL;
+ return R_MIPS_GOTREL;
case R_MIPS_26:
return R_PLT;
case R_MIPS_HI16:
}
}
- In<ELFT>::Got = make<GotSection<ELFT>>();
+ if (Config->EMachine == EM_MIPS)
+ In<ELFT>::MipsGot = make<MipsGotSection<ELFT>>();
+ else
+ In<ELFT>::Got = make<GotSection<ELFT>>();
+
In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
}
return true;
if (Sec == In<ELFT>::GotPlt->OutSec)
return Config->ZNow;
- if (Sec == In<ELFT>::Dynamic->OutSec || Sec == In<ELFT>::Got->OutSec)
+ if (Sec == In<ELFT>::Dynamic->OutSec)
+ return true;
+ if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
+ return true;
+ if (In<ELFT>::MipsGot && Sec == In<ELFT>::MipsGot->OutSec)
return true;
StringRef S = Sec->getName();
return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
// so that it points to an absolute address which is relative to GOT.
// See "Global Data Symbols" in Chapter 6 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
- addRegular("_gp", In<ELFT>::Got, MipsGPOffset);
+ addRegular("_gp", In<ELFT>::MipsGot, MipsGPOffset);
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
- Symbol *Sym = addOptionalRegular("_gp_disp", In<ELFT>::Got, MipsGPOffset);
+ Symbol *Sym =
+ addOptionalRegular("_gp_disp", In<ELFT>::MipsGot, MipsGPOffset);
if (Sym)
ElfSym<ELFT>::MipsGpDisp = Sym->body();
// pointer. This symbol is used in the code generated by .cpload pseudo-op
// in case of using -mno-shared option.
// https://sourceware.org/ml/binutils/2004-12/msg00094.html
- addOptionalRegular("__gnu_local_gp", In<ELFT>::Got, MipsGPOffset);
+ addOptionalRegular("__gnu_local_gp", In<ELFT>::MipsGot, MipsGPOffset);
}
// In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
Sec->finalize();
// Dynamic section must be the last one in this list.
- finalizeSynthetic<ELFT>({In<ELFT>::ShStrTab, In<ELFT>::StrTab,
- In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::GotPlt,
- In<ELFT>::RelaDyn, In<ELFT>::RelaPlt,
- In<ELFT>::Dynamic});
+ finalizeSynthetic<ELFT>(
+ {In<ELFT>::ShStrTab, In<ELFT>::StrTab, In<ELFT>::DynStrTab, In<ELFT>::Got,
+ In<ELFT>::MipsGot, In<ELFT>::GotPlt, In<ELFT>::RelaDyn,
+ In<ELFT>::RelaPlt, In<ELFT>::Dynamic});
// Now that all output offsets are fixed. Finalize mergeable sections
// to fix their maps from input offsets to output offsets.
}
template <class ELFT> bool Writer<ELFT>::needsGot() {
- if (!In<ELFT>::Got->empty())
- return true;
-
// We add the .got section to the result for dynamic MIPS target because
// its address and properties are mentioned in the .dynamic section.
- if (Config->EMachine == EM_MIPS && !Config->Relocatable)
+ if (Config->EMachine == EM_MIPS)
+ return !Config->Relocatable;
+
+ if (!In<ELFT>::Got->empty())
return true;
// If we have a relocation that is relative to GOT (such as GOTOFFREL),
// We fill .got and .got.plt sections in scanRelocs(). This is the
// reason we don't add it earlier in createSections().
- if (needsGot())
- addInputSec(In<ELFT>::Got);
+ if (needsGot()) {
+ if (Config->EMachine == EM_MIPS)
+ addInputSec(In<ELFT>::MipsGot);
+ else
+ addInputSec(In<ELFT>::Got);
+ }
if (!In<ELFT>::GotPlt->empty())
addInputSec(In<ELFT>::GotPlt);