Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
ELF/Writer.cpp
Show First 20 Lines • Show All 580 Lines • ▼ Show 20 Lines | if (Config->EMachine == EM_MIPS && !Config->Relocatable) { | ||||
// The __gnu_local_gp is a magic symbol equal to the current value of 'gp' | // 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 | // pointer. This symbol is used in the code generated by .cpload pseudo-op | ||||
// in case of using -mno-shared option. | // in case of using -mno-shared option. | ||||
// https://sourceware.org/ml/binutils/2004-12/msg00094.html | // https://sourceware.org/ml/binutils/2004-12/msg00094.html | ||||
addOptionalSynthetic("__gnu_local_gp", Out<ELFT>::Got, MipsGPOffset); | addOptionalSynthetic("__gnu_local_gp", Out<ELFT>::Got, MipsGPOffset); | ||||
} | } | ||||
if (Config->EMachine == EM_PPC && !Config->Relocatable) { | |||||
// In the event a non-relocatable PPC32 target is being built, reserve | |||||
// Small Data base registers. These will be relocated midway through | |||||
// the .sdata and .sdata2 sections (if used). This symbol is meant to | |||||
// be applied in EABI systems, where r13 and r2 are initialized to these | |||||
// linker-generated symbols by the C runtime initialization. | |||||
Symbol *Sym; | |||||
constexpr OutputSectionBase<ELFT> *NullSec = nullptr; | |||||
Sym = addOptionalSynthetic("_SDA_BASE_", NullSec, 0); | |||||
if (Sym) | |||||
ElfSym<ELFT>::SdaBase = cast<DefinedSynthetic<ELFT>>(Sym->body()); | |||||
Sym = addOptionalSynthetic("_SDA2_BASE_", NullSec, 0); | |||||
if (Sym) | |||||
ElfSym<ELFT>::Sda2Base = cast<DefinedSynthetic<ELFT>>(Sym->body()); | |||||
} | |||||
// In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol | // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol | ||||
// is magical and is used to produce a R_386_GOTPC relocation. | // is magical and is used to produce a R_386_GOTPC relocation. | ||||
// The R_386_GOTPC relocation value doesn't actually depend on the | // The R_386_GOTPC relocation value doesn't actually depend on the | ||||
// symbol value, so it could use an index of STN_UNDEF which, according | // symbol value, so it could use an index of STN_UNDEF which, according | ||||
// to the spec, means the symbol value is 0. | // to the spec, means the symbol value is 0. | ||||
// Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in | // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in | ||||
// the object file. | // the object file. | ||||
// The situation is even stranger on x86_64 where the assembly doesn't | // The situation is even stranger on x86_64 where the assembly doesn't | ||||
▲ Show 20 Lines • Show All 666 Lines • ▼ Show 20 Lines | |||||
// This function is called after we have assigned address and size | // This function is called after we have assigned address and size | ||||
// to each section. This function fixes some predefined absolute | // to each section. This function fixes some predefined absolute | ||||
// symbol values that depend on section address and size. | // symbol values that depend on section address and size. | ||||
template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() { | template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() { | ||||
// __ehdr_start is the location of program headers. | // __ehdr_start is the location of program headers. | ||||
if (ElfSym<ELFT>::EhdrStart) | if (ElfSym<ELFT>::EhdrStart) | ||||
ElfSym<ELFT>::EhdrStart->Value = Out<ELFT>::ProgramHeaders->getVA(); | ElfSym<ELFT>::EhdrStart->Value = Out<ELFT>::ProgramHeaders->getVA(); | ||||
auto SectionMidpoint = [](OutputSectionBase<ELFT> *Sec) -> | |||||
typename ELFT::uint { | |||||
return ((Sec->getSize() / 2) & ~0x3) + Sec->getVA(); | |||||
}; | |||||
// PPC-EABI systems will need the _SDA_BASE_ and _SDA2_BASE_ symbols | |||||
// synthesized for use by C runtime init. The section midpoints are used | |||||
// to maximize addressing range. | |||||
if (ElfSym<ELFT>::SdaBase) { | |||||
OutputSectionBase<ELFT> *Sec = findSection(".sdata"); | |||||
if (!Sec) Sec = findSection(".sbss"); | |||||
if (Sec) | |||||
ElfSym<ELFT>::SdaBase->Value = SectionMidpoint(Sec); | |||||
} | |||||
if (ElfSym<ELFT>::Sda2Base) { | |||||
OutputSectionBase<ELFT> *Sec = findSection(".sdata2"); | |||||
if (Sec) | |||||
ElfSym<ELFT>::Sda2Base->Value = SectionMidpoint(Sec); | |||||
} | |||||
auto Set = [](DefinedRegular<ELFT> *S1, DefinedRegular<ELFT> *S2, uintX_t V) { | auto Set = [](DefinedRegular<ELFT> *S1, DefinedRegular<ELFT> *S2, uintX_t V) { | ||||
if (S1) | if (S1) | ||||
S1->Value = V; | S1->Value = V; | ||||
if (S2) | if (S2) | ||||
S2->Value = V; | S2->Value = V; | ||||
}; | }; | ||||
// _etext is the first location after the last read-only loadable segment. | // _etext is the first location after the last read-only loadable segment. | ||||
▲ Show 20 Lines • Show All 189 Lines • Show Last 20 Lines |