forked from OSchip/llvm-project
Make addReservedSymbols a static helper. NFC.
llvm-svn: 320175
This commit is contained in:
parent
ad840d2206
commit
1dd30ddd45
|
@ -49,7 +49,6 @@ private:
|
|||
void createSyntheticSections();
|
||||
void copyLocalSymbols();
|
||||
void addSectionSymbols();
|
||||
void addReservedSymbols();
|
||||
void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
|
||||
void sortSections();
|
||||
void sortInputSections();
|
||||
|
@ -158,6 +157,83 @@ template <class ELFT> static void combineEhFrameSections() {
|
|||
V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
|
||||
uint64_t Val, uint8_t StOther = STV_HIDDEN,
|
||||
uint8_t Binding = STB_GLOBAL) {
|
||||
Symbol *S = Symtab->find(Name);
|
||||
if (!S || S->isDefined())
|
||||
return nullptr;
|
||||
Symbol *Sym = Symtab->addRegular<ELFT>(Name, StOther, STT_NOTYPE, Val,
|
||||
/*Size=*/0, Binding, Sec,
|
||||
/*File=*/nullptr);
|
||||
return cast<Defined>(Sym);
|
||||
}
|
||||
|
||||
// The linker is expected to define some symbols depending on
|
||||
// the linking result. This function defines such symbols.
|
||||
template <class ELFT> static void addReservedSymbols() {
|
||||
if (Config->EMachine == EM_MIPS) {
|
||||
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
|
||||
// so that it points to an absolute address which by default is relative
|
||||
// to GOT. Default offset is 0x7ff0.
|
||||
// See "Global Data Symbols" in Chapter 6 in the following document:
|
||||
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
||||
ElfSym::MipsGp = Symtab->addAbsolute<ELFT>("_gp", STV_HIDDEN, STB_GLOBAL);
|
||||
|
||||
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
|
||||
// start of function and 'gp' pointer into GOT.
|
||||
if (Symtab->find("_gp_disp"))
|
||||
ElfSym::MipsGpDisp =
|
||||
Symtab->addAbsolute<ELFT>("_gp_disp", STV_HIDDEN, STB_GLOBAL);
|
||||
|
||||
// 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
|
||||
if (Symtab->find("__gnu_local_gp"))
|
||||
ElfSym::MipsLocalGp =
|
||||
Symtab->addAbsolute<ELFT>("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
|
||||
}
|
||||
|
||||
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
|
||||
// be at some offset from the base of the .got section, usually 0 or the end
|
||||
// of the .got
|
||||
InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
|
||||
: cast<InputSection>(InX::Got);
|
||||
ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
|
||||
"_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
|
||||
|
||||
// __ehdr_start is the location of ELF file headers. Note that we define
|
||||
// this symbol unconditionally even when using a linker script, which
|
||||
// differs from the behavior implemented by GNU linker which only define
|
||||
// this symbol if ELF headers are in the memory mapped segment.
|
||||
// __executable_start is not documented, but the expectation of at
|
||||
// least the android libc is that it points to the elf header too.
|
||||
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
|
||||
// each DSO. The address of the symbol doesn't matter as long as they are
|
||||
// different in different DSOs, so we chose the start address of the DSO.
|
||||
for (const char *Name :
|
||||
{"__ehdr_start", "__executable_start", "__dso_handle"})
|
||||
addOptionalRegular<ELFT>(Name, Out::ElfHeader, 0, STV_HIDDEN);
|
||||
|
||||
// If linker script do layout we do not need to create any standart symbols.
|
||||
if (Script->HasSectionsCommand)
|
||||
return;
|
||||
|
||||
auto Add = [](StringRef S, int64_t Pos) {
|
||||
return addOptionalRegular<ELFT>(S, Out::ElfHeader, Pos, STV_DEFAULT);
|
||||
};
|
||||
|
||||
ElfSym::Bss = Add("__bss_start", 0);
|
||||
ElfSym::End1 = Add("end", -1);
|
||||
ElfSym::End2 = Add("_end", -1);
|
||||
ElfSym::Etext1 = Add("etext", -1);
|
||||
ElfSym::Etext2 = Add("_etext", -1);
|
||||
ElfSym::Edata1 = Add("edata", -1);
|
||||
ElfSym::Edata2 = Add("_edata", -1);
|
||||
}
|
||||
|
||||
// The main function of the writer.
|
||||
template <class ELFT> void Writer<ELFT>::run() {
|
||||
// Create linker-synthesized sections such as .got or .plt.
|
||||
|
@ -169,7 +245,7 @@ template <class ELFT> void Writer<ELFT>::run() {
|
|||
|
||||
// We need to create some reserved symbols such as _end. Create them.
|
||||
if (!Config->Relocatable)
|
||||
addReservedSymbols();
|
||||
addReservedSymbols<ELFT>();
|
||||
|
||||
// We want to process linker script commands. When SECTIONS command
|
||||
// is given we let it create sections.
|
||||
|
@ -750,19 +826,6 @@ void PhdrEntry::add(OutputSection *Sec) {
|
|||
Sec->PtLoad = this;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static Defined *addOptionalRegular(StringRef Name, SectionBase *Sec,
|
||||
uint64_t Val, uint8_t StOther = STV_HIDDEN,
|
||||
uint8_t Binding = STB_GLOBAL) {
|
||||
Symbol *S = Symtab->find(Name);
|
||||
if (!S || S->isDefined())
|
||||
return nullptr;
|
||||
Symbol *Sym = Symtab->addRegular<ELFT>(Name, StOther, STT_NOTYPE, Val,
|
||||
/*Size=*/0, Binding, Sec,
|
||||
/*File=*/nullptr);
|
||||
return cast<Defined>(Sym);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -779,70 +842,6 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
|
|||
addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1, STV_HIDDEN, STB_WEAK);
|
||||
}
|
||||
|
||||
// The linker is expected to define some symbols depending on
|
||||
// the linking result. This function defines such symbols.
|
||||
template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
|
||||
if (Config->EMachine == EM_MIPS) {
|
||||
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
|
||||
// so that it points to an absolute address which by default is relative
|
||||
// to GOT. Default offset is 0x7ff0.
|
||||
// See "Global Data Symbols" in Chapter 6 in the following document:
|
||||
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
||||
ElfSym::MipsGp = Symtab->addAbsolute<ELFT>("_gp", STV_HIDDEN, STB_GLOBAL);
|
||||
|
||||
// On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
|
||||
// start of function and 'gp' pointer into GOT.
|
||||
if (Symtab->find("_gp_disp"))
|
||||
ElfSym::MipsGpDisp =
|
||||
Symtab->addAbsolute<ELFT>("_gp_disp", STV_HIDDEN, STB_GLOBAL);
|
||||
|
||||
// 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
|
||||
if (Symtab->find("__gnu_local_gp"))
|
||||
ElfSym::MipsLocalGp =
|
||||
Symtab->addAbsolute<ELFT>("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL);
|
||||
}
|
||||
|
||||
// The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
|
||||
// be at some offset from the base of the .got section, usually 0 or the end
|
||||
// of the .got
|
||||
InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
|
||||
: cast<InputSection>(InX::Got);
|
||||
ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
|
||||
"_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
|
||||
|
||||
// __ehdr_start is the location of ELF file headers. Note that we define
|
||||
// this symbol unconditionally even when using a linker script, which
|
||||
// differs from the behavior implemented by GNU linker which only define
|
||||
// this symbol if ELF headers are in the memory mapped segment.
|
||||
// __executable_start is not documented, but the expectation of at
|
||||
// least the android libc is that it points to the elf header too.
|
||||
// __dso_handle symbol is passed to cxa_finalize as a marker to identify
|
||||
// each DSO. The address of the symbol doesn't matter as long as they are
|
||||
// different in different DSOs, so we chose the start address of the DSO.
|
||||
for (const char *Name :
|
||||
{"__ehdr_start", "__executable_start", "__dso_handle"})
|
||||
addOptionalRegular<ELFT>(Name, Out::ElfHeader, 0, STV_HIDDEN);
|
||||
|
||||
// If linker script do layout we do not need to create any standart symbols.
|
||||
if (Script->HasSectionsCommand)
|
||||
return;
|
||||
|
||||
auto Add = [](StringRef S, int64_t Pos) {
|
||||
return addOptionalRegular<ELFT>(S, Out::ElfHeader, Pos, STV_DEFAULT);
|
||||
};
|
||||
|
||||
ElfSym::Bss = Add("__bss_start", 0);
|
||||
ElfSym::End1 = Add("end", -1);
|
||||
ElfSym::End2 = Add("_end", -1);
|
||||
ElfSym::Etext1 = Add("etext", -1);
|
||||
ElfSym::Etext2 = Add("_etext", -1);
|
||||
ElfSym::Edata1 = Add("edata", -1);
|
||||
ElfSym::Edata2 = Add("_edata", -1);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) {
|
||||
// Scan all relocations. Each relocation goes through a series
|
||||
|
|
Loading…
Reference in New Issue