diff options
Diffstat (limited to 'lld/ELF')
-rw-r--r-- | lld/ELF/Symbols.h | 12 | ||||
-rw-r--r-- | lld/ELF/Target.cpp | 3 | ||||
-rw-r--r-- | lld/ELF/Target.h | 1 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 40 |
4 files changed, 29 insertions, 27 deletions
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index b5ade14715c..1b3cb2dc226 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -403,10 +403,10 @@ template <class ELFT> struct ElfSym { static DefinedRegular<ELFT> *End2; // The content for _gp symbol for MIPS target. - static DefinedRegular<ELFT> *MipsGp; + static SymbolBody *MipsGp; - static DefinedRegular<ELFT> *MipsLocalGp; - static DefinedRegular<ELFT> *MipsGpDisp; + static SymbolBody *MipsLocalGp; + static SymbolBody *MipsGpDisp; // __rel_iplt_start/__rel_iplt_end for signaling // where R_[*]_IRELATIVE relocations do live. @@ -420,9 +420,9 @@ template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata; template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata2; template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End; template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End2; -template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsGp; -template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsLocalGp; -template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsGpDisp; +template <class ELFT> SymbolBody *ElfSym<ELFT>::MipsGp; +template <class ELFT> SymbolBody *ElfSym<ELFT>::MipsLocalGp; +template <class ELFT> SymbolBody *ElfSym<ELFT>::MipsGpDisp; template <class ELFT> SymbolBody *ElfSym<ELFT>::RelaIpltStart; template <class ELFT> SymbolBody *ElfSym<ELFT>::RelaIpltEnd; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index bb1297c2177..ce272739f8d 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1920,8 +1920,7 @@ bool MipsTargetInfo<ELFT>::isRelRelative(uint32_t Type) const { // a location that is relative to GOT. This function returns // the value for the symbol. template <class ELFT> typename ELFT::uint getMipsGpAddr() { - unsigned GPOffset = 0x7ff0; - return Out<ELFT>::Got->getVA() + GPOffset; + return Out<ELFT>::Got->getVA() + MipsGPOffset; } template uint32_t getMipsGpAddr<ELF32LE>(); diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index b81db7d37b8..7d23772f8f7 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -119,6 +119,7 @@ private: uint64_t getPPC64TocBase(); +const unsigned MipsGPOffset = 0x7ff0; template <class ELFT> typename ELFT::uint getMipsGpAddr(); extern TargetInfo *Target; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index d990990a266..4bbd812dec7 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -795,6 +795,16 @@ bool Writer<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) const { Script->isDiscarded(S); } +template <class ELFT> +static SymbolBody * +addOptionalSynthetic(SymbolTable<ELFT> &Table, StringRef Name, + OutputSectionBase<ELFT> &Sec, typename ELFT::uint Val, + uint8_t Visibility) { + if (!Table.find(Name)) + return nullptr; + return Table.addSynthetic(Name, Sec, Val, Visibility); +} + // The beginning and the ending of .rel[a].plt section are marked // with __rel[a]_iplt_{start,end} symbols if it is a statically linked // executable. The runtime needs these symbols in order to resolve @@ -806,14 +816,13 @@ void Writer<ELFT>::addRelIpltSymbols() { if (isOutputDynamic() || !Out<ELFT>::RelaPlt) return; StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start"; - if (Symtab.find(S)) - ElfSym<ELFT>::RelaIpltStart = - Symtab.addSynthetic(S, *Out<ELFT>::RelaPlt, 0, STV_HIDDEN); + ElfSym<ELFT>::RelaIpltStart = + addOptionalSynthetic(Symtab, S, *Out<ELFT>::RelaPlt, 0, STV_HIDDEN); S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end"; - if (Symtab.find(S)) - ElfSym<ELFT>::RelaIpltEnd = Symtab.addSynthetic( - S, *Out<ELFT>::RelaPlt, DefinedSynthetic<ELFT>::SectionEnd, STV_HIDDEN); + ElfSym<ELFT>::RelaIpltEnd = + addOptionalSynthetic(Symtab, S, *Out<ELFT>::RelaPlt, + DefinedSynthetic<ELFT>::SectionEnd, STV_HIDDEN); } template <class ELFT> static bool includeInSymtab(const SymbolBody &B) { @@ -932,16 +941,19 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // 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 - ElfSym<ELFT>::MipsGp = Symtab.addAbsolute("_gp", STV_DEFAULT); + ElfSym<ELFT>::MipsGp = + Symtab.addSynthetic("_gp", *Out<ELFT>::Got, MipsGPOffset, STV_DEFAULT); // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between // start of function and 'gp' pointer into GOT. - ElfSym<ELFT>::MipsGpDisp = Symtab.addIgnored("_gp_disp"); + ElfSym<ELFT>::MipsGpDisp = addOptionalSynthetic( + Symtab, "_gp_disp", *Out<ELFT>::Got, MipsGPOffset, STV_HIDDEN); // The __gnu_local_gp is a magic symbol equal to the current value of 'gp' // 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 - ElfSym<ELFT>::MipsLocalGp = Symtab.addIgnored("__gnu_local_gp"); + ElfSym<ELFT>::MipsLocalGp = addOptionalSynthetic( + Symtab, "__gnu_local_gp", *Out<ELFT>::Got, MipsGPOffset, STV_HIDDEN); } // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol @@ -1515,16 +1527,6 @@ static uint16_t getELFType() { // to each section. This function fixes some predefined absolute // symbol values that depend on section address and size. template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() { - // Update MIPS _gp absolute symbol so that it points to the static data. - - if (Config->EMachine == EM_MIPS) { - ElfSym<ELFT>::MipsGp->Value = getMipsGpAddr<ELFT>(); - if (ElfSym<ELFT>::MipsLocalGp) - ElfSym<ELFT>::MipsLocalGp->Value = getMipsGpAddr<ELFT>(); - if (ElfSym<ELFT>::MipsGpDisp) - ElfSym<ELFT>::MipsGpDisp->Value = getMipsGpAddr<ELFT>(); - } - // _etext is the first location after the last read-only loadable segment. // _edata is the first location after the last read-write loadable segment. // _end is the first location after the uninitialized data region. |