switch (Body.kind()) {
case SymbolBody::DefinedSyntheticKind: {
auto &D = cast<DefinedSynthetic<ELFT>>(Body);
+ const OutputSectionBase<ELFT> *Sec = D.Section;
+ if (!Sec)
+ return D.Value;
if (D.Value == DefinedSynthetic<ELFT>::SectionEnd)
- return D.Section.getVA() + D.Section.getSize();
- return D.Section.getVA() + D.Value;
+ return Sec->getVA() + Sec->getSize();
+ return Sec->getVA() + D.Value;
}
case SymbolBody::DefinedRegularKind: {
auto &D = cast<DefinedRegular<ELFT>>(Body);
template <typename ELFT>
DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
- OutputSectionBase<ELFT> &Section)
+ OutputSectionBase<ELFT> *Section)
: Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */),
Value(Value), Section(Section) {}
if (!AbsVal && RelE)
return true;
+ // Relative relocation to an absolute value. This is normally unrepresentable,
+ // but if the relocation refers to a weak undefined symbol, we allow it to
+ // resolve to the image base. This is a little strange, but it allows us to
+ // link function calls to such symbols. Normally such a call will be guarded
+ // with a comparison, which will load a zero from the GOT.
+ if (AbsVal && RelE) {
+ if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
+ return true;
+ StringRef S = getELFRelocationTypeName(Config->EMachine, Type);
+ error("relocation " + S + " cannot refer to absolute symbol " +
+ Body.getName());
+ return true;
+ }
+
return Target->usesOnlyLowPageBits(Type);
}
template <class ELFT>
static Symbol *addOptionalSynthetic(SymbolTable<ELFT> &Table, StringRef Name,
- OutputSectionBase<ELFT> &Sec,
+ OutputSectionBase<ELFT> *Sec,
typename ELFT::uint Val) {
if (!Table.find(Name))
return nullptr;
if (isOutputDynamic() || !Out<ELFT>::RelaPlt)
return;
StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
- addOptionalSynthetic(Symtab, S, *Out<ELFT>::RelaPlt, 0);
+ addOptionalSynthetic(Symtab, S, Out<ELFT>::RelaPlt, 0);
S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
- addOptionalSynthetic(Symtab, S, *Out<ELFT>::RelaPlt,
+ addOptionalSynthetic(Symtab, S, Out<ELFT>::RelaPlt,
DefinedSynthetic<ELFT>::SectionEnd);
}
// 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
- Symtab.addSynthetic("_gp", *Out<ELFT>::Got, MipsGPOffset);
+ Symtab.addSynthetic("_gp", Out<ELFT>::Got, MipsGPOffset);
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
// start of function and 'gp' pointer into GOT.
ElfSym<ELFT>::MipsGpDisp =
- addOptionalSynthetic(Symtab, "_gp_disp", *Out<ELFT>::Got, MipsGPOffset)
+ addOptionalSynthetic(Symtab, "_gp_disp", Out<ELFT>::Got, MipsGPOffset)
->body();
// 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
- addOptionalSynthetic(Symtab, "__gnu_local_gp", *Out<ELFT>::Got,
+ addOptionalSynthetic(Symtab, "__gnu_local_gp", Out<ELFT>::Got,
MipsGPOffset);
}
// Even the author of gold doesn't remember why gold behaves that way.
// https://sourceware.org/ml/binutils/2002-03/msg00360.html
if (isOutputDynamic())
- Symtab.addSynthetic("_DYNAMIC", *Out<ELFT>::Dynamic, 0);
+ Symtab.addSynthetic("_DYNAMIC", Out<ELFT>::Dynamic, 0);
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
auto Define = [&](StringRef Start, StringRef End,
OutputSectionBase<ELFT> *OS) {
if (OS) {
- this->Symtab.addSynthetic(Start, *OS, 0);
- this->Symtab.addSynthetic(End, *OS, DefinedSynthetic<ELFT>::SectionEnd);
+ this->Symtab.addSynthetic(Start, OS, 0);
+ this->Symtab.addSynthetic(End, OS, DefinedSynthetic<ELFT>::SectionEnd);
} else {
- this->Symtab.addIgnored(Start);
- this->Symtab.addIgnored(End);
+ addOptionalSynthetic(this->Symtab, Start,
+ (OutputSectionBase<ELFT> *)nullptr, 0);
+ addOptionalSynthetic(this->Symtab, End,
+ (OutputSectionBase<ELFT> *)nullptr, 0);
}
};
StringRef Stop = Saver.save("__stop_" + S);
if (SymbolBody *B = Symtab.find(Start))
if (B->isUndefined())
- Symtab.addSynthetic(Start, *Sec, 0);
+ Symtab.addSynthetic(Start, Sec, 0);
if (SymbolBody *B = Symtab.find(Stop))
if (B->isUndefined())
- Symtab.addSynthetic(Stop, *Sec, DefinedSynthetic<ELFT>::SectionEnd);
+ Symtab.addSynthetic(Stop, Sec, DefinedSynthetic<ELFT>::SectionEnd);
}
template <class ELFT> static bool needsPtLoad(OutputSectionBase<ELFT> *Sec) {