From 0168722e3913f30fa0b61b57796db79886c3243a Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Sat, 26 Dec 2015 09:47:57 +0000 Subject: [PATCH] Simplify __rel[a]_iplt_{start,end} handling a bit. Also updated a comment. llvm-svn: 256444 --- lld/ELF/Writer.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index a167f760ead4..814a973423c2 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -79,6 +79,7 @@ private: std::vector>> OwningSections; unsigned getNumSections() const { return OutputSections.size() + 1; } + void addRelIpltSymbols(); void addStartStopSymbols(OutputSectionBase *Sec); void setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags, uintX_t FileOff, uintX_t VA, uintX_t Size, uintX_t Align); @@ -574,25 +575,25 @@ static bool compareSections(OutputSectionBase *A, return std::distance(ItA, ItB) > 0; } -// A statically linked executable will have rel[a].plt section -// to hold R_[*]_IRELATIVE relocations. -// The multi-arch libc will use these symbols to locate -// these relocations at program startup time. -// If RelaPlt is empty then there is no reason to create this symbols. +// 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 +// all IRELATIVE relocs on startup. For dynamic executables, we don't +// need these symbols, since IRELATIVE relocs are resolved through GOT +// and PLT. For details, see http://www.airs.com/blog/archives/403. template -static void addIRelocMarkers(SymbolTable &Symtab, bool IsDynamic) { - if (IsDynamic || !Out::RelaPlt || !Out::RelaPlt->hasRelocs()) +void Writer::addRelIpltSymbols() { + if (isOutputDynamic() || !Out::RelaPlt) return; bool IsRela = shouldUseRela(); - auto AddMarker = [&](StringRef Name, typename Writer::Elf_Sym &Sym) { - if (SymbolBody *B = Symtab.find(Name)) - if (B->isUndefined()) - Symtab.addAbsolute(Name, Sym); - }; - AddMarker(IsRela ? "__rela_iplt_start" : "__rel_iplt_start", - ElfSym::RelaIpltStart); - AddMarker(IsRela ? "__rela_iplt_end" : "__rel_iplt_end", - ElfSym::RelaIpltEnd); + + StringRef S = IsRela ? "__rela_iplt_start" : "__rel_iplt_start"; + if (Symtab.find(S)) + Symtab.addAbsolute(S, ElfSym::RelaIpltStart); + + S = IsRela ? "__rela_iplt_end" : "__rel_iplt_end"; + if (Symtab.find(S)) + Symtab.addAbsolute(S, ElfSym::RelaIpltEnd); } template static bool includeInSymtab(const SymbolBody &B) { @@ -806,7 +807,8 @@ template void Writer::createSections() { } } - addIRelocMarkers(Symtab, isOutputDynamic()); + // Define __rel[a]_iplt_{start,end} symbols if needed. + addRelIpltSymbols(); std::vector CommonSymbols; std::vector *> SharedCopySymbols;