summaryrefslogtreecommitdiffstats
path: root/lld/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/Symbols.h12
-rw-r--r--lld/ELF/Target.cpp3
-rw-r--r--lld/ELF/Target.h1
-rw-r--r--lld/ELF/Writer.cpp40
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.
OpenPOWER on IntegriCloud