diff options
Diffstat (limited to 'lld/ELF/Writer.cpp')
-rw-r--r-- | lld/ELF/Writer.cpp | 40 |
1 files changed, 21 insertions, 19 deletions
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. |