<div dir="ltr">Nice change. Thank you for doing this.<div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 4, 2016 at 7:04 AM, Rafael Espindola via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Mon Apr 4 09:04:16 2016<br>
New Revision: 265293<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=265293&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=265293&view=rev</a><br>
Log:<br>
Don't store an Elf_Sym for most symbols.<br>
<br>
Our symbol representation was redundant, and some times would get out of<br>
sync. It had an Elf_Sym, but some fields were copied to SymbolBody.<br>
<br>
Different parts of the code were checking the bits in SymbolBody and<br>
others were checking Elf_Sym.<br>
<br>
There are two general approaches to fix this:<br>
* Copy the required information and don't store and Elf_Sym.<br>
* Don't copy the information and always use the Elf_Smy.<br>
<br>
The second way sounds tempting, but has a big problem: we would have to<br>
template SymbolBody. I started doing it, but it requires templeting<br>
*everything* and creates a bit chicken and egg problem at the driver<br>
where we have to find ELFT before we can create an ArchiveFile for<br>
example.<br>
<br>
As much as possible I compared the test differences with what gold and<br>
bfd produce to make sure they are still valid. In most cases we are just<br>
adding hidden visibility to a local symbol, which is harmless.<br>
<br>
In most tests this is a small speedup. The only slowdown was scylla<br>
(1.006X). The largest speedup was clang with no --build-id, -O3 or<br>
--gc-sections (i.e.: focus on the relocations): 1.019X.<br>
<br>
Modified:<br>
lld/trunk/ELF/Driver.cpp<br>
lld/trunk/ELF/ICF.cpp<br>
lld/trunk/ELF/InputFiles.cpp<br>
lld/trunk/ELF/InputFiles.h<br>
lld/trunk/ELF/InputSection.cpp<br>
lld/trunk/ELF/InputSection.h<br>
lld/trunk/ELF/MarkLive.cpp<br>
lld/trunk/ELF/OutputSections.cpp<br>
lld/trunk/ELF/SymbolTable.cpp<br>
lld/trunk/ELF/SymbolTable.h<br>
lld/trunk/ELF/Symbols.cpp<br>
lld/trunk/ELF/Symbols.h<br>
lld/trunk/ELF/Target.cpp<br>
lld/trunk/ELF/Writer.cpp<br>
lld/trunk/test/ELF/aarch64-gnu-ifunc.s<br>
lld/trunk/test/ELF/basic-mips.s<br>
lld/trunk/test/ELF/global_offset_table_shared.s<br>
lld/trunk/test/ELF/gnu-ifunc-i386.s<br>
lld/trunk/test/ELF/gnu-ifunc.s<br>
lld/trunk/test/ELF/mips-gp-disp.s<br>
lld/trunk/test/ELF/mips-hilo-gp-disp.s<br>
<br>
Modified: lld/trunk/ELF/Driver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Driver.cpp (original)<br>
+++ lld/trunk/ELF/Driver.cpp Mon Apr 4 09:04:16 2016<br>
@@ -366,17 +366,7 @@ void LinkerDriver::createFiles(opt::Inpu<br>
error("no input files.");<br>
}<br>
<br>
-template <class ELFT> static void initSymbols() {<br>
- ElfSym<ELFT>::Etext.setBinding(STB_GLOBAL);<br>
- ElfSym<ELFT>::Edata.setBinding(STB_GLOBAL);<br>
- ElfSym<ELFT>::End.setBinding(STB_GLOBAL);<br>
- ElfSym<ELFT>::Ignored.setBinding(STB_WEAK);<br>
- ElfSym<ELFT>::Ignored.setVisibility(STV_HIDDEN);<br>
-}<br>
-<br>
template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {<br>
- initSymbols<ELFT>();<br>
-<br>
SymbolTable<ELFT> Symtab;<br>
std::unique_ptr<TargetInfo> TI(createTarget());<br>
Target = TI.get();<br>
@@ -390,21 +380,6 @@ template <class ELFT> void LinkerDriver:<br>
Config->EMachine != EM_AMDGPU)<br>
Config->Entry = Config->EMachine == EM_MIPS ? "__start" : "_start";<br>
<br>
- // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol<br>
- // is magical and is used to produce a R_386_GOTPC relocation.<br>
- // The R_386_GOTPC relocation value doesn't actually depend on the<br>
- // symbol value, so it could use an index of STN_UNDEF which, according<br>
- // to the spec, means the symbol value is 0.<br>
- // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in<br>
- // the object file.<br>
- // The situation is even stranger on x86_64 where the assembly doesn't<br>
- // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as<br>
- // an undefined symbol in the .o files.<br>
- // Given that the symbol is effectively unused, we just create a dummy<br>
- // hidden one to avoid the undefined symbol error.<br>
- if (!Config->Relocatable)<br>
- Symtab.addIgnored("_GLOBAL_OFFSET_TABLE_");<br>
-<br>
if (!Config->Entry.empty()) {<br>
// Set either EntryAddr (if S is a number) or EntrySym (otherwise).<br>
StringRef S = Config->Entry;<br>
@@ -413,20 +388,11 @@ template <class ELFT> void LinkerDriver:<br>
}<br>
<br>
if (Config->EMachine == EM_MIPS) {<br>
- // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between<br>
- // start of function and 'gp' pointer into GOT.<br>
- Config->MipsGpDisp = Symtab.addIgnored("_gp_disp");<br>
- // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'<br>
- // pointer. This symbol is used in the code generated by .cpload pseudo-op<br>
- // in case of using -mno-shared option.<br>
- // <a href="https://sourceware.org/ml/binutils/2004-12/msg00094.html" rel="noreferrer" target="_blank">https://sourceware.org/ml/binutils/2004-12/msg00094.html</a><br>
- Config->MipsLocalGp = Symtab.addIgnored("__gnu_local_gp");<br>
-<br>
// Define _gp for MIPS. st_value of _gp symbol will be updated by Writer<br>
// so that it points to an absolute address which is relative to GOT.<br>
// See "Global Data Symbols" in Chapter 6 in the following document:<br>
// <a href="ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf" rel="noreferrer" target="_blank">ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf</a><br>
- Symtab.addAbsolute("_gp", ElfSym<ELFT>::MipsGp);<br>
+ ElfSym<ELFT>::MipsGp = Symtab.addAbsolute("_gp", STV_DEFAULT);<br>
}<br>
<br>
for (std::unique_ptr<InputFile> &F : Files)<br>
<br>
Modified: lld/trunk/ELF/ICF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ICF.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/ICF.cpp (original)<br>
+++ lld/trunk/ELF/ICF.cpp Mon Apr 4 09:04:16 2016<br>
@@ -132,7 +132,7 @@ template <class ELFT> uint64_t ICF<ELFT><br>
<br>
// Returns true if Sec is subject of ICF.<br>
template <class ELFT> bool ICF<ELFT>::isEligible(InputSectionBase<ELFT> *Sec) {<br>
- if (!Sec || Sec == InputSection<ELFT>::Discarded || !Sec->Live)<br>
+ if (!Sec || Sec == &InputSection<ELFT>::Discarded || !Sec->Live)<br>
return false;<br>
auto *S = dyn_cast<InputSection<ELFT>>(Sec);<br>
if (!S)<br>
@@ -270,7 +270,7 @@ bool ICF<ELFT>::variableEq(const InputSe<br>
auto *DB = dyn_cast<DefinedRegular<ELFT>>(&SB);<br>
if (!DA || !DB)<br>
return false;<br>
- if (DA->Sym.st_value != DB->Sym.st_value)<br>
+ if (DA->Value != DB->Value)<br>
return false;<br>
InputSection<ELFT> *X = dyn_cast<InputSection<ELFT>>(DA->Section);<br>
InputSection<ELFT> *Y = dyn_cast<InputSection<ELFT>>(DB->Section);<br>
<br>
Modified: lld/trunk/ELF/InputFiles.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputFiles.cpp (original)<br>
+++ lld/trunk/ELF/InputFiles.cpp Mon Apr 4 09:04:16 2016<br>
@@ -175,18 +175,18 @@ void elf::ObjectFile<ELFT>::initializeSe<br>
const ELFFile<ELFT> &Obj = this->ELFObj;<br>
for (const Elf_Shdr &Sec : Obj.sections()) {<br>
++I;<br>
- if (Sections[I] == InputSection<ELFT>::Discarded)<br>
+ if (Sections[I] == &InputSection<ELFT>::Discarded)<br>
continue;<br>
<br>
switch (Sec.sh_type) {<br>
case SHT_GROUP:<br>
- Sections[I] = InputSection<ELFT>::Discarded;<br>
+ Sections[I] = &InputSection<ELFT>::Discarded;<br>
if (ComdatGroups.insert(getShtGroupSignature(Sec)).second)<br>
continue;<br>
for (uint32_t SecIndex : getShtGroupEntries(Sec)) {<br>
if (SecIndex >= Size)<br>
fatal("invalid section index in group");<br>
- Sections[SecIndex] = InputSection<ELFT>::Discarded;<br>
+ Sections[SecIndex] = &InputSection<ELFT>::Discarded;<br>
}<br>
break;<br>
case SHT_SYMTAB:<br>
@@ -242,7 +242,7 @@ elf::ObjectFile<ELFT>::getRelocTarget(co<br>
// Strictly speaking, a relocation section must be included in the<br>
// group of the section it relocates. However, LLVM 3.3 and earlier<br>
// would fail to do so, so we gracefully handle that case.<br>
- if (Target == InputSection<ELFT>::Discarded)<br>
+ if (Target == &InputSection<ELFT>::Discarded)<br>
return nullptr;<br>
<br>
if (!Target)<br>
@@ -260,7 +260,7 @@ elf::ObjectFile<ELFT>::createInputSectio<br>
// is controlled only by the command line option (-z execstack) in LLD,<br>
// .note.GNU-stack is ignored.<br>
if (Name == ".note.GNU-stack")<br>
- return InputSection<ELFT>::Discarded;<br>
+ return &InputSection<ELFT>::Discarded;<br>
<br>
if (Name == ".note.GNU-split-stack")<br>
error("objects using splitstacks are not supported");<br>
@@ -299,19 +299,20 @@ elf::ObjectFile<ELFT>::getSection(const<br>
if (Index >= Sections.size() || !Sections[Index])<br>
fatal("invalid section index");<br>
InputSectionBase<ELFT> *S = Sections[Index];<br>
- if (S == InputSectionBase<ELFT>::Discarded)<br>
+ if (S == &InputSectionBase<ELFT>::Discarded)<br>
return S;<br>
return S->Repl;<br>
}<br>
<br>
template <class ELFT><br>
SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {<br>
+ uint32_t NameOffset = Sym->st_name;<br>
unsigned char Binding = Sym->getBinding();<br>
InputSectionBase<ELFT> *Sec = getSection(*Sym);<br>
if (Binding == STB_LOCAL) {<br>
- if (Sec == InputSection<ELFT>::Discarded)<br>
- Sec = nullptr;<br>
- return new (Alloc) DefinedRegular<ELFT>("", *Sym, Sec);<br>
+ if (Sym->st_shndx == SHN_UNDEF)<br>
+ return new (Alloc) UndefinedElf<ELFT>(NameOffset, *Sym);<br>
+ return new (Alloc) DefinedRegular<ELFT>(NameOffset, *Sym, Sec);<br>
}<br>
<br>
StringRef Name = check(Sym->getName(this->StringTable));<br>
@@ -320,9 +321,8 @@ SymbolBody *elf::ObjectFile<ELFT>::creat<br>
case SHN_UNDEF:<br>
return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);<br>
case SHN_COMMON:<br>
- return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value,<br>
- Sym->getBinding() == llvm::ELF::STB_WEAK,<br>
- Sym->getVisibility());<br>
+ return new (Alloc) DefinedCommon(Name, Sym->st_size, Sym->st_value, Binding,<br>
+ Sym->st_other, Sym->getType());<br>
}<br>
<br>
switch (Binding) {<br>
@@ -331,7 +331,7 @@ SymbolBody *elf::ObjectFile<ELFT>::creat<br>
case STB_GLOBAL:<br>
case STB_WEAK:<br>
case STB_GNU_UNIQUE:<br>
- if (Sec == InputSection<ELFT>::Discarded)<br>
+ if (Sec == &InputSection<ELFT>::Discarded)<br>
return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);<br>
return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);<br>
}<br>
@@ -426,6 +426,9 @@ template <class ELFT> void SharedFile<EL<br>
uint32_t NumSymbols = std::distance(Syms.begin(), Syms.end());<br>
SymbolBodies.reserve(NumSymbols);<br>
for (const Elf_Sym &Sym : Syms) {<br>
+ // FIXME: We should probably just err if we get a local symbol in here.<br>
+ if (Sym.getBinding() == STB_LOCAL)<br>
+ continue;<br>
StringRef Name = check(Sym.getName(this->StringTable));<br>
if (Sym.isUndefined())<br>
Undefs.push_back(Name);<br>
@@ -479,11 +482,13 @@ BitcodeFile::createSymbolBody(const Dens<br>
const DataLayout &DL = M.getDataLayout();<br>
uint64_t Size = DL.getTypeAllocSize(GV->getValueType());<br>
Body = new (Alloc)<br>
- DefinedCommon(NameRef, Size, GV->getAlignment(), IsWeak, Visibility);<br>
+ DefinedCommon(NameRef, Size, GV->getAlignment(),<br>
+ IsWeak ? STB_WEAK : STB_GLOBAL, Visibility, /*Type*/ 0);<br>
} else {<br>
Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);<br>
}<br>
- Body->IsTls = GV->isThreadLocal();<br>
+ if (GV->isThreadLocal())<br>
+ Body->Type = STT_TLS;<br>
return Body;<br>
}<br>
<br>
<br>
Modified: lld/trunk/ELF/InputFiles.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputFiles.h (original)<br>
+++ lld/trunk/ELF/InputFiles.h Mon Apr 4 09:04:16 2016<br>
@@ -129,7 +129,7 @@ public:<br>
<br>
// The number is the offset in the string table. It will be used as the<br>
// st_name of the symbol.<br>
- std::vector<std::pair<const Elf_Sym *, unsigned>> KeptLocalSyms;<br>
+ std::vector<std::pair<const DefinedRegular<ELFT> *, unsigned>> KeptLocalSyms;<br>
<br>
private:<br>
void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups);<br>
<br>
Modified: lld/trunk/ELF/InputSection.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputSection.cpp (original)<br>
+++ lld/trunk/ELF/InputSection.cpp Mon Apr 4 09:04:16 2016<br>
@@ -72,8 +72,9 @@ typename ELFT::uint InputSectionBase<ELF<br>
}<br>
<br>
template <class ELFT><br>
-typename ELFT::uint InputSectionBase<ELFT>::getOffset(const Elf_Sym &Sym) {<br>
- return getOffset(Sym.st_value);<br>
+typename ELFT::uint<br>
+InputSectionBase<ELFT>::getOffset(const DefinedRegular<ELFT> &Sym) {<br>
+ return getOffset(Sym.Value);<br>
}<br>
<br>
// Returns a section that Rel relocation is pointing to.<br>
@@ -305,7 +306,7 @@ void InputSectionBase<ELFT>::relocate(ui<br>
SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc);<br>
else<br>
SymVA = Body.getGotVA<ELFT>() + A;<br>
- if (Body.IsTls)<br>
+ if (Body.isTls())<br>
Type = Target->getTlsGotRel(Type);<br>
} else if (Target->isSizeRel(Type) && Body.isPreemptible()) {<br>
// A SIZE relocation is supposed to set a symbol size, but if a symbol<br>
<br>
Modified: lld/trunk/ELF/InputSection.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/InputSection.h (original)<br>
+++ lld/trunk/ELF/InputSection.h Mon Apr 4 09:04:16 2016<br>
@@ -19,6 +19,7 @@ namespace lld {<br>
namespace elf {<br>
<br>
template <class ELFT> class ICF;<br>
+template <class ELFT> class DefinedRegular;<br>
template <class ELFT> class ObjectFile;<br>
template <class ELFT> class OutputSection;<br>
template <class ELFT> class OutputSectionBase;<br>
@@ -40,6 +41,8 @@ public:<br>
enum Kind { Regular, EHFrame, Merge, MipsReginfo };<br>
Kind SectionKind;<br>
<br>
+ InputSectionBase() : Repl(this) {}<br>
+<br>
InputSectionBase(ObjectFile<ELFT> *File, const Elf_Shdr *Header,<br>
Kind SectionKind);<br>
OutputSectionBase<ELFT> *OutSec = nullptr;<br>
@@ -58,12 +61,12 @@ public:<br>
// Returns the size of this section (even if this is a common or BSS.)<br>
size_t getSize() const;<br>
<br>
- static InputSectionBase<ELFT> *Discarded;<br>
+ static InputSectionBase<ELFT> Discarded;<br>
<br>
StringRef getSectionName() const;<br>
const Elf_Shdr *getSectionHdr() const { return Header; }<br>
ObjectFile<ELFT> *getFile() const { return File; }<br>
- uintX_t getOffset(const Elf_Sym &Sym);<br>
+ uintX_t getOffset(const DefinedRegular<ELFT> &Sym);<br>
<br>
// Translate an offset in the input section to an offset in the output<br>
// section.<br>
@@ -85,9 +88,7 @@ private:<br>
const RelTy *Rel, const RelTy *End);<br>
};<br>
<br>
-template <class ELFT><br>
-InputSectionBase<ELFT> *<br>
- InputSectionBase<ELFT>::Discarded = (InputSectionBase<ELFT> *)-1ULL;<br>
+template <class ELFT> InputSectionBase<ELFT> InputSectionBase<ELFT>::Discarded;<br>
<br>
// Usually sections are copied to the output as atomic chunks of data,<br>
// but some special types of sections are split into small pieces of data<br>
<br>
Modified: lld/trunk/ELF/MarkLive.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/MarkLive.cpp (original)<br>
+++ lld/trunk/ELF/MarkLive.cpp Mon Apr 4 09:04:16 2016<br>
@@ -124,7 +124,7 @@ template <class ELFT> void elf::markLive<br>
// script KEEP command.<br>
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles())<br>
for (InputSectionBase<ELFT> *Sec : F->getSections())<br>
- if (Sec && Sec != InputSection<ELFT>::Discarded)<br>
+ if (Sec && Sec != &InputSection<ELFT>::Discarded)<br>
if (isReserved(Sec) || Script->shouldKeep<ELFT>(Sec))<br>
Enqueue(Sec);<br>
<br>
<br>
Modified: lld/trunk/ELF/OutputSections.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/OutputSections.cpp (original)<br>
+++ lld/trunk/ELF/OutputSections.cpp Mon Apr 4 09:04:16 2016<br>
@@ -1426,22 +1426,23 @@ void SymbolTableSection<ELFT>::writeLoca<br>
// Iterate over all input object files to copy their local symbols<br>
// to the output symbol table pointed by Buf.<br>
for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) {<br>
- for (const std::pair<const Elf_Sym *, size_t> &P : File->KeptLocalSyms) {<br>
- const Elf_Sym *Sym = P.first;<br>
-<br>
+ for (const std::pair<const DefinedRegular<ELFT> *, size_t> &P :<br>
+ File->KeptLocalSyms) {<br>
+ const DefinedRegular<ELFT> &Body = *P.first;<br>
+ InputSectionBase<ELFT> *Section = Body.Section;<br>
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);<br>
- if (Sym->st_shndx == SHN_ABS) {<br>
+<br>
+ if (!Section) {<br>
ESym->st_shndx = SHN_ABS;<br>
- ESym->st_value = Sym->st_value;<br>
+ ESym->st_value = Body.Value;<br>
} else {<br>
- InputSectionBase<ELFT> *Section = File->getSection(*Sym);<br>
const OutputSectionBase<ELFT> *OutSec = Section->OutSec;<br>
ESym->st_shndx = OutSec->SectionIndex;<br>
- ESym->st_value = OutSec->getVA() + Section->getOffset(*Sym);<br>
+ ESym->st_value = OutSec->getVA() + Section->getOffset(Body);<br>
}<br>
ESym->st_name = P.second;<br>
- ESym->st_size = Sym->st_size;<br>
- ESym->setBindingAndType(Sym->getBinding(), Sym->getType());<br>
+ ESym->st_size = Body.template getSize<ELFT>();<br>
+ ESym->setBindingAndType(Body.Binding, Body.Type);<br>
Buf += sizeof(*ESym);<br>
}<br>
}<br>
@@ -1456,15 +1457,8 @@ void SymbolTableSection<ELFT>::writeGlob<br>
SymbolBody *Body = P.first;<br>
size_t StrOff = P.second;<br>
<br>
- uint8_t Type = STT_NOTYPE;<br>
- uintX_t Size = 0;<br>
- if (const Elf_Sym *InputSym = Body->getElfSym<ELFT>()) {<br>
- Type = InputSym->getType();<br>
- Size = InputSym->st_size;<br>
- } else if (auto *C = dyn_cast<DefinedCommon>(Body)) {<br>
- Type = STT_OBJECT;<br>
- Size = C->Size;<br>
- }<br>
+ uint8_t Type = Body->Type;<br>
+ uintX_t Size = Body->getSize<ELFT>();<br>
<br>
ESym->setBindingAndType(getSymbolBinding(Body), Type);<br>
ESym->st_size = Size;<br>
@@ -1521,11 +1515,9 @@ uint8_t SymbolTableSection<ELFT>::getSym<br>
uint8_t Visibility = Body->getVisibility();<br>
if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)<br>
return STB_LOCAL;<br>
- if (const Elf_Sym *ESym = Body->getElfSym<ELFT>())<br>
- return ESym->getBinding();<br>
if (isa<DefinedSynthetic<ELFT>>(Body))<br>
return STB_LOCAL;<br>
- return Body->isWeak() ? STB_WEAK : STB_GLOBAL;<br>
+ return Body->Binding;<br>
}<br>
<br>
template <class ELFT><br>
<br>
Modified: lld/trunk/ELF/SymbolTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/SymbolTable.cpp (original)<br>
+++ lld/trunk/ELF/SymbolTable.cpp Mon Apr 4 09:04:16 2016<br>
@@ -135,9 +135,10 @@ SymbolBody *SymbolTable<ELFT>::addUndefi<br>
}<br>
<br>
template <class ELFT><br>
-SymbolBody *SymbolTable<ELFT>::addAbsolute(StringRef Name, Elf_Sym &ESym) {<br>
+DefinedRegular<ELFT> *SymbolTable<ELFT>::addAbsolute(StringRef Name,<br>
+ uint8_t Visibility) {<br>
// Pass nullptr because absolute symbols have no corresponding input sections.<br>
- auto *Sym = new (Alloc) DefinedRegular<ELFT>(Name, ESym, nullptr);<br>
+ auto *Sym = new (Alloc) DefinedRegular<ELFT>(Name, STB_GLOBAL, Visibility);<br>
resolve(Sym);<br>
return Sym;<br>
}<br>
@@ -152,11 +153,13 @@ SymbolBody *SymbolTable<ELFT>::addSynthe<br>
}<br>
<br>
// Add Name as an "ignored" symbol. An ignored symbol is a regular<br>
-// linker-synthesized defined symbol, but it is not recorded to the output<br>
-// file's symbol table. Such symbols are useful for some linker-defined symbols.<br>
+// linker-synthesized defined symbol, but is only defined if needed.<br>
template <class ELFT><br>
-SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) {<br>
- return addAbsolute(Name, ElfSym<ELFT>::Ignored);<br>
+DefinedRegular<ELFT> *SymbolTable<ELFT>::addIgnored(StringRef Name,<br>
+ uint8_t Visibility) {<br>
+ if (!find(Name))<br>
+ return nullptr;<br>
+ return addAbsolute(Name, Visibility);<br>
}<br>
<br>
// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.<br>
@@ -228,7 +231,7 @@ template <class ELFT> void SymbolTable<E<br>
return;<br>
}<br>
<br>
- if (New->IsTls != Existing->IsTls) {<br>
+ if (New->isTls() != Existing->isTls()) {<br>
error("TLS attribute mismatch for symbol: " + conflictMsg(Existing, New));<br>
return;<br>
}<br>
@@ -286,10 +289,10 @@ void SymbolTable<ELFT>::addMemberFile(Un<br>
// symbols and copy information to reduce how many special cases are needed.<br>
if (Undef->isWeak()) {<br>
L->setUsedInRegularObj();<br>
- L->setWeak();<br>
+ L->Binding = Undef->Binding;<br>
+ L->Type = Undef->Type;<br>
<br>
// FIXME: Do we need to copy more?<br>
- L->IsTls |= Undef->IsTls;<br>
return;<br>
}<br>
<br>
<br>
Modified: lld/trunk/ELF/SymbolTable.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/SymbolTable.h (original)<br>
+++ lld/trunk/ELF/SymbolTable.h Mon Apr 4 09:04:16 2016<br>
@@ -53,21 +53,23 @@ public:<br>
<br>
SymbolBody *addUndefined(StringRef Name);<br>
SymbolBody *addUndefinedOpt(StringRef Name);<br>
- SymbolBody *addAbsolute(StringRef Name, Elf_Sym &ESym);<br>
+ DefinedRegular<ELFT> *addAbsolute(StringRef Name,<br>
+ uint8_t Visibility = llvm::ELF::STV_HIDDEN);<br>
SymbolBody *addSynthetic(StringRef Name, OutputSectionBase<ELFT> &Section,<br>
uintX_t Value, uint8_t Visibility);<br>
- SymbolBody *addIgnored(StringRef Name);<br>
+ DefinedRegular<ELFT> *addIgnored(StringRef Name,<br>
+ uint8_t Visibility = llvm::ELF::STV_HIDDEN);<br>
<br>
void scanShlibUndefined();<br>
SymbolBody *find(StringRef Name);<br>
void wrap(StringRef Name);<br>
InputFile *findFile(SymbolBody *B);<br>
+ void resolve(SymbolBody *Body);<br>
<br>
private:<br>
Symbol *insert(SymbolBody *New);<br>
void addLazy(Lazy *New);<br>
void addMemberFile(Undefined *Undef, Lazy *L);<br>
- void resolve(SymbolBody *Body);<br></blockquote><div><br></div><div>Why did you change the visibility of resolve() function?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
std::string conflictMsg(SymbolBody *Old, SymbolBody *New);<br>
<br>
// The order the global symbols are in is not defined. We can use an arbitrary<br>
<br>
Modified: lld/trunk/ELF/Symbols.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Symbols.cpp (original)<br>
+++ lld/trunk/ELF/Symbols.cpp Mon Apr 4 09:04:16 2016<br>
@@ -31,7 +31,6 @@ using namespace lld::elf;<br>
template <class ELFT><br>
static typename ELFT::uint getSymVA(const SymbolBody &Body,<br>
typename ELFT::uint &Addend) {<br>
- typedef typename ELFT::Sym Elf_Sym;<br>
typedef typename ELFT::uint uintX_t;<br>
<br>
switch (Body.kind()) {<br>
@@ -45,18 +44,24 @@ static typename ELFT::uint getSymVA(cons<br>
auto &D = cast<DefinedRegular<ELFT>>(Body);<br>
InputSectionBase<ELFT> *SC = D.Section;<br>
<br>
+ // According to the ELF spec reference to a local symbol from outside<br>
+ // the group are not allowed. Unfortunately .eh_frame breaks that rule<br>
+ // and must be treated specially. For now we just replace the symbol with<br>
+ // 0.<br>
+ if (SC == &InputSection<ELFT>::Discarded)<br>
+ return 0;<br>
+<br>
// This is an absolute symbol.<br>
if (!SC)<br>
- return D.Sym.st_value;<br>
+ return D.Value;<br>
<br>
- const Elf_Sym &Sym = D.Sym;<br>
- uintX_t Offset = Sym.st_value;<br>
- if (Sym.getType() == STT_SECTION) {<br>
+ uintX_t Offset = D.Value;<br>
+ if (D.isSection()) {<br>
Offset += Addend;<br>
Addend = 0;<br>
}<br>
uintX_t VA = SC->OutSec->getVA() + SC->getOffset(Offset);<br>
- if (Sym.getType() == STT_TLS)<br>
+ if (D.isTls())<br>
return VA - Out<ELFT>::TlsPhdr->p_vaddr;<br>
return VA;<br>
}<br>
@@ -66,7 +71,7 @@ static typename ELFT::uint getSymVA(cons<br>
auto &SS = cast<SharedSymbol<ELFT>>(Body);<br>
if (!SS.NeedsCopyOrPltAddr)<br>
return 0;<br>
- if (SS.IsFunc)<br>
+ if (SS.isFunc())<br>
return Body.getPltVA<ELFT>();<br>
return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;<br>
}<br>
@@ -82,6 +87,13 @@ static typename ELFT::uint getSymVA(cons<br>
llvm_unreachable("invalid symbol kind");<br>
}<br>
<br>
+SymbolBody::SymbolBody(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type)<br>
+ : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),<br>
+ Type(Type), Binding(STB_LOCAL), Other(Other), NameOffset(NameOffset) {<br>
+ IsUsedInRegularObj =<br>
+ K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;<br>
+}<br>
+<br>
// Returns true if a symbol can be replaced at load-time by a symbol<br>
// with the same name defined in other ELF executable or DSO.<br>
bool SymbolBody::isPreemptible() const {<br>
@@ -109,7 +121,7 @@ bool SymbolBody::isPreemptible() const {<br>
return false;<br>
if (getVisibility() != STV_DEFAULT)<br>
return false;<br>
- if (Config->Bsymbolic || (Config->BsymbolicFunctions && IsFunc))<br>
+ if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))<br>
return false;<br>
return true;<br>
}<br>
@@ -143,21 +155,17 @@ template <class ELFT> typename ELFT::uin<br>
}<br>
<br>
template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {<br>
- if (const typename ELFT::Sym *Sym = getElfSym<ELFT>())<br>
- return Sym->st_size;<br>
+ if (const auto *C = dyn_cast<DefinedCommon>(this))<br>
+ return C->Size;<br>
+ if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))<br>
+ return DR->Size;<br>
+ if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))<br>
+ return S->Sym.st_size;<br>
+ if (const auto *U = dyn_cast<UndefinedElf<ELFT>>(this))<br>
+ return U->Size;<br>
return 0;<br>
}<br>
<br>
-template <class ELFT> const typename ELFT::Sym *SymbolBody::getElfSym() const {<br>
- if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))<br>
- return &S->Sym;<br>
- if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))<br>
- return &S->Sym;<br>
- if (auto *S = dyn_cast<UndefinedElf<ELFT>>(this))<br>
- return &S->Sym;<br>
- return nullptr;<br>
-}<br>
-<br>
static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {<br>
if (VA == STV_DEFAULT)<br>
return VB;<br>
@@ -185,8 +193,9 @@ template <class ELFT> int SymbolBody::co<br>
if (L > R)<br>
return -Other->compare<ELFT>(this);<br>
<br>
- Visibility = Other->Visibility =<br>
- getMinVisibility(Visibility, Other->Visibility);<br>
+ uint8_t V = getMinVisibility(getVisibility(), Other->getVisibility());<br>
+ setVisibility(V);<br>
+ Other->setVisibility(V);<br>
<br>
if (IsUsedInRegularObj || Other->IsUsedInRegularObj)<br>
IsUsedInRegularObj = Other->IsUsedInRegularObj = true;<br>
@@ -212,48 +221,61 @@ template <class ELFT> int SymbolBody::co<br>
return isCommon() ? -1 : 1;<br>
}<br>
<br>
-Defined::Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal,<br>
- uint8_t Visibility, uint8_t Type)<br>
- : SymbolBody(K, Name, IsWeak, IsLocal, Visibility, Type) {}<br>
+Defined::Defined(Kind K, StringRef Name, uint8_t Binding, uint8_t Visibility,<br>
+ uint8_t Type)<br>
+ : SymbolBody(K, Name, Binding, Visibility, Type) {}<br>
+<br>
+Defined::Defined(Kind K, uint32_t NameOffset, uint8_t Visibility, uint8_t Type)<br>
+ : SymbolBody(K, NameOffset, Visibility, Type) {}<br>
<br>
DefinedBitcode::DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Visibility)<br>
- : Defined(DefinedBitcodeKind, Name, IsWeak, false, Visibility,<br>
- 0 /* Type */) {}<br>
+ : Defined(DefinedBitcodeKind, Name, IsWeak ? STB_WEAK : STB_GLOBAL,<br>
+ Visibility, 0 /* Type */) {}<br>
<br>
bool DefinedBitcode::classof(const SymbolBody *S) {<br>
return S->kind() == DefinedBitcodeKind;<br>
}<br>
<br>
-Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,<br>
+Undefined::Undefined(SymbolBody::Kind K, StringRef N, uint8_t Binding,<br>
+ uint8_t Other, uint8_t Type)<br>
+ : SymbolBody(K, N, Binding, Other, Type), CanKeepUndefined(false) {}<br>
+<br>
+Undefined::Undefined(SymbolBody::Kind K, uint32_t NameOffset,<br>
uint8_t Visibility, uint8_t Type)<br>
- : SymbolBody(K, N, IsWeak, false, Visibility, Type),<br>
- CanKeepUndefined(false) {}<br>
+ : SymbolBody(K, NameOffset, Visibility, Type), CanKeepUndefined(false) {}<br>
<br>
Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility,<br>
bool CanKeepUndefined)<br>
- : Undefined(SymbolBody::UndefinedKind, N, IsWeak, Visibility, 0 /* Type */) {<br>
+ : Undefined(SymbolBody::UndefinedKind, N, IsWeak ? STB_WEAK : STB_GLOBAL,<br>
+ Visibility, 0 /* Type */) {<br>
this->CanKeepUndefined = CanKeepUndefined;<br>
}<br>
<br>
template <typename ELFT><br>
UndefinedElf<ELFT>::UndefinedElf(StringRef N, const Elf_Sym &Sym)<br>
- : Undefined(SymbolBody::UndefinedElfKind, N,<br>
- Sym.getBinding() == llvm::ELF::STB_WEAK, Sym.getVisibility(),<br>
+ : Undefined(SymbolBody::UndefinedElfKind, N, Sym.getBinding(), Sym.st_other,<br>
Sym.getType()),<br>
- Sym(Sym) {}<br>
+ Size(Sym.st_size) {}<br>
+<br>
+template <typename ELFT><br>
+UndefinedElf<ELFT>::UndefinedElf(uint32_t NameOffset, const Elf_Sym &Sym)<br>
+ : Undefined(SymbolBody::UndefinedElfKind, NameOffset, Sym.st_other,<br>
+ Sym.getType()),<br>
+ Size(Sym.st_size) {<br>
+ assert(Sym.getBinding() == STB_LOCAL);<br>
+}<br>
<br>
template <typename ELFT><br>
DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,<br>
OutputSectionBase<ELFT> &Section,<br>
uint8_t Visibility)<br>
- : Defined(SymbolBody::DefinedSyntheticKind, N, false, false, Visibility,<br>
+ : Defined(SymbolBody::DefinedSyntheticKind, N, STB_GLOBAL, Visibility,<br>
0 /* Type */),<br>
Value(Value), Section(Section) {}<br>
<br>
DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,<br>
- bool IsWeak, uint8_t Visibility)<br>
- : Defined(SymbolBody::DefinedCommonKind, N, IsWeak, false, Visibility,<br>
- 0 /* Type */),<br>
+ uint8_t Binding, uint8_t Visibility, uint8_t Type)<br>
+ : Defined(SymbolBody::DefinedCommonKind, N, Binding, Visibility, Type),<br>
Alignment(Alignment), Size(Size) {}<br>
<br>
std::unique_ptr<InputFile> Lazy::getMember() {<br>
@@ -317,11 +339,6 @@ template uint32_t SymbolBody::template g<br>
template uint64_t SymbolBody::template getSize<ELF64LE>() const;<br>
template uint64_t SymbolBody::template getSize<ELF64BE>() const;<br>
<br>
-template const ELF32LE::Sym *SymbolBody::template getElfSym<ELF32LE>() const;<br>
-template const ELF32BE::Sym *SymbolBody::template getElfSym<ELF32BE>() const;<br>
-template const ELF64LE::Sym *SymbolBody::template getElfSym<ELF64LE>() const;<br>
-template const ELF64BE::Sym *SymbolBody::template getElfSym<ELF64BE>() const;<br>
-<br>
template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const;<br>
template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const;<br>
template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const;<br>
<br>
Modified: lld/trunk/ELF/Symbols.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Symbols.h (original)<br>
+++ lld/trunk/ELF/Symbols.h Mon Apr 4 09:04:16 2016<br>
@@ -62,7 +62,7 @@ public:<br>
<br>
Kind kind() const { return static_cast<Kind>(SymbolKind); }<br>
<br>
- bool isWeak() const { return IsWeak; }<br>
+ bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }<br>
bool isUndefined() const {<br>
return SymbolKind == UndefinedKind || SymbolKind == UndefinedElfKind;<br>
}<br>
@@ -70,14 +70,21 @@ public:<br>
bool isCommon() const { return SymbolKind == DefinedCommonKind; }<br>
bool isLazy() const { return SymbolKind == LazyKind; }<br>
bool isShared() const { return SymbolKind == SharedKind; }<br>
- bool isLocal() const { return IsLocal; }<br>
+ bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; }<br>
bool isUsedInRegularObj() const { return IsUsedInRegularObj; }<br>
bool isPreemptible() const;<br>
<br>
// Returns the symbol name.<br>
- StringRef getName() const { return Name; }<br>
+ StringRef getName() const {<br>
+ assert(!isLocal());<br>
+ return Name;<br>
+ }<br>
+ uint32_t getNameOffset() const {<br>
+ assert(isLocal());<br>
+ return NameOffset;<br>
+ }<br>
<br>
- uint8_t getVisibility() const { return Visibility; }<br>
+ uint8_t getVisibility() const { return Other & 0x3; }<br>
<br>
unsigned DynsymIndex = 0;<br>
uint32_t GlobalDynIndex = -1;<br>
@@ -100,7 +107,6 @@ public:<br>
template <class ELFT> typename ELFT::uint getPltVA() const;<br>
template <class ELFT> typename ELFT::uint getThunkVA() const;<br>
template <class ELFT> typename ELFT::uint getSize() const;<br>
- template <class ELFT> const typename ELFT::Sym *getElfSym() const;<br>
<br>
// A SymbolBody has a backreference to a Symbol. Originally they are<br>
// doubly-linked. A backreference will never change. But the pointer<br>
@@ -118,21 +124,18 @@ public:<br>
template <class ELFT> int compare(SymbolBody *Other);<br>
<br>
protected:<br>
- SymbolBody(Kind K, StringRef Name, bool IsWeak, bool IsLocal,<br>
- uint8_t Visibility, uint8_t Type)<br>
- : SymbolKind(K), IsWeak(IsWeak), IsLocal(IsLocal), Visibility(Visibility),<br>
- MustBeInDynSym(false), NeedsCopyOrPltAddr(false), Name(Name) {<br>
- IsFunc = Type == llvm::ELF::STT_FUNC;<br>
- IsTls = Type == llvm::ELF::STT_TLS;<br>
- IsGnuIFunc = Type == llvm::ELF::STT_GNU_IFUNC;<br>
+ SymbolBody(Kind K, StringRef Name, uint8_t Binding, uint8_t Other,<br>
+ uint8_t Type)<br>
+ : SymbolKind(K), MustBeInDynSym(false), NeedsCopyOrPltAddr(false),<br>
+ Type(Type), Binding(Binding), Other(Other), Name(Name) {<br>
+ assert(!isLocal());<br>
IsUsedInRegularObj =<br>
K != SharedKind && K != LazyKind && K != DefinedBitcodeKind;<br>
}<br>
<br>
+ SymbolBody(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type);<br>
+<br>
const unsigned SymbolKind : 8;<br>
- unsigned IsWeak : 1;<br>
- unsigned IsLocal : 1;<br>
- unsigned Visibility : 2;<br>
<br>
// True if the symbol was used for linking and thus need to be<br>
// added to the output file's symbol table. It is usually true,<br>
@@ -148,34 +151,44 @@ public:<br>
// symbol or if the symbol should point to its plt entry.<br>
unsigned NeedsCopyOrPltAddr : 1;<br>
<br>
- unsigned IsTls : 1;<br>
- unsigned IsFunc : 1;<br>
- unsigned IsGnuIFunc : 1;<br>
+ uint8_t Type;<br>
+ uint8_t Binding;<br>
+ uint8_t Other;<br>
+ bool isSection() const { return Type == llvm::ELF::STT_SECTION; }<br>
+ bool isTls() const { return Type == llvm::ELF::STT_TLS; }<br>
+ bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }<br>
+ bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }<br>
+ bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }<br>
+ bool isFile() const { return Type == llvm::ELF::STT_FILE; }<br>
+ void setVisibility(uint8_t V) { Other = (Other & ~0x3) | V; }<br>
<br>
protected:<br>
- StringRef Name;<br>
+ union {<br>
+ StringRef Name;<br>
+ uint32_t NameOffset;<br>
+ };<br>
Symbol *Backref = nullptr;<br>
};<br>
<br>
// The base class for any defined symbols.<br>
class Defined : public SymbolBody {<br>
public:<br>
- Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal, uint8_t Visibility,<br>
- uint8_t Type);<br>
+ Defined(Kind K, StringRef Name, uint8_t Binding, uint8_t Other, uint8_t Type);<br>
+ Defined(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type);<br>
static bool classof(const SymbolBody *S) { return S->isDefined(); }<br>
};<br>
<br>
// The defined symbol in LLVM bitcode files.<br>
class DefinedBitcode : public Defined {<br>
public:<br>
- DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Visibility);<br>
+ DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Other);<br>
static bool classof(const SymbolBody *S);<br>
};<br>
<br>
class DefinedCommon : public Defined {<br>
public:<br>
- DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, bool IsWeak,<br>
- uint8_t Visibility);<br>
+ DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, uint8_t Binding,<br>
+ uint8_t Other, uint8_t Type);<br>
<br>
static bool classof(const SymbolBody *S) {<br>
return S->kind() == SymbolBody::DefinedCommonKind;<br>
@@ -194,21 +207,36 @@ public:<br>
// Regular defined symbols read from object file symbol tables.<br>
template <class ELFT> class DefinedRegular : public Defined {<br>
typedef typename ELFT::Sym Elf_Sym;<br>
+ typedef typename ELFT::uint uintX_t;<br>
<br>
public:<br>
DefinedRegular(StringRef Name, const Elf_Sym &Sym,<br>
InputSectionBase<ELFT> *Section)<br>
- : Defined(SymbolBody::DefinedRegularKind, Name,<br>
- Sym.getBinding() == llvm::ELF::STB_WEAK,<br>
- Sym.getBinding() == llvm::ELF::STB_LOCAL,<br>
- Sym.getVisibility(), Sym.getType()),<br>
- Sym(Sym), Section(Section ? Section->Repl : NullInputSection) {}<br>
+ : Defined(SymbolBody::DefinedRegularKind, Name, Sym.getBinding(),<br>
+ Sym.st_other, Sym.getType()),<br>
+ Value(Sym.st_value), Size(Sym.st_size),<br>
+ Section(Section ? Section->Repl : NullInputSection) {}<br>
+<br>
+ DefinedRegular(uint32_t NameOffset, const Elf_Sym &Sym,<br>
+ InputSectionBase<ELFT> *Section)<br>
+ : Defined(SymbolBody::DefinedRegularKind, NameOffset, Sym.st_other,<br>
+ Sym.getType()),<br>
+ Value(Sym.st_value), Size(Sym.st_size),<br>
+ Section(Section ? Section->Repl : NullInputSection) {<br>
+ assert(isLocal());<br>
+ }<br>
+<br>
+ DefinedRegular(StringRef Name, uint8_t Binding, uint8_t Other)<br>
+ : Defined(SymbolBody::DefinedRegularKind, Name, Binding, Other,<br>
+ llvm::ELF::STT_NOTYPE),<br>
+ Value(0), Size(0), Section(NullInputSection) {}<br>
<br>
static bool classof(const SymbolBody *S) {<br>
return S->kind() == SymbolBody::DefinedRegularKind;<br>
}<br>
<br>
- const Elf_Sym &Sym;<br>
+ uintX_t Value;<br>
+ uintX_t Size;<br>
<br>
// The input section this symbol belongs to. Notice that this is<br>
// a reference to a pointer. We are using two levels of indirections<br>
@@ -231,10 +259,9 @@ InputSectionBase<ELFT> *DefinedRegular<E<br>
// takes an output section to calculate output VA, etc.<br>
template <class ELFT> class DefinedSynthetic : public Defined {<br>
public:<br>
- typedef typename ELFT::Sym Elf_Sym;<br>
typedef typename ELFT::uint uintX_t;<br>
DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase<ELFT> &Section,<br>
- uint8_t Visibility);<br>
+ uint8_t Other);<br>
<br>
static bool classof(const SymbolBody *S) {<br>
return S->kind() == SymbolBody::DefinedSyntheticKind;<br>
@@ -254,11 +281,11 @@ class Undefined : public SymbolBody {<br>
bool CanKeepUndefined;<br>
<br>
protected:<br>
- Undefined(Kind K, StringRef N, bool IsWeak, uint8_t Visibility, uint8_t Type);<br>
+ Undefined(Kind K, StringRef N, uint8_t Binding, uint8_t Other, uint8_t Type);<br>
+ Undefined(Kind K, uint32_t NameOffset, uint8_t Other, uint8_t Type);<br>
<br>
public:<br>
- Undefined(StringRef N, bool IsWeak, uint8_t Visibility,<br>
- bool CanKeepUndefined);<br>
+ Undefined(StringRef N, bool IsWeak, uint8_t Other, bool CanKeepUndefined);<br>
<br>
static bool classof(const SymbolBody *S) { return S->isUndefined(); }<br>
<br>
@@ -266,11 +293,14 @@ public:<br>
};<br>
<br>
template <class ELFT> class UndefinedElf : public Undefined {<br>
+ typedef typename ELFT::uint uintX_t;<br>
typedef typename ELFT::Sym Elf_Sym;<br>
<br>
public:<br>
UndefinedElf(StringRef N, const Elf_Sym &Sym);<br>
- const Elf_Sym &Sym;<br>
+ UndefinedElf(uint32_t NameOffset, const Elf_Sym &Sym);<br>
+<br>
+ uintX_t Size;<br>
<br>
static bool classof(const SymbolBody *S) {<br>
return S->kind() == SymbolBody::UndefinedElfKind;<br>
@@ -287,10 +317,8 @@ public:<br>
}<br>
<br>
SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)<br>
- : Defined(SymbolBody::SharedKind, Name,<br>
- Sym.getBinding() == llvm::ELF::STB_WEAK,<br>
- Sym.getBinding() == llvm::ELF::STB_LOCAL,<br>
- Sym.getVisibility(), Sym.getType()),<br>
+ : Defined(SymbolBody::SharedKind, Name, Sym.getBinding(), Sym.st_other,<br>
+ Sym.getType()),<br>
File(F), Sym(Sym) {}<br>
<br>
SharedFile<ELFT> *File;<br>
@@ -299,7 +327,7 @@ public:<br>
// OffsetInBss is significant only when needsCopy() is true.<br>
uintX_t OffsetInBss = 0;<br>
<br>
- bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->IsFunc; }<br>
+ bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->isFunc(); }<br>
};<br>
<br>
// This class represents a symbol defined in an archive file. It is<br>
@@ -310,8 +338,8 @@ public:<br>
class Lazy : public SymbolBody {<br>
public:<br>
Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S)<br>
- : SymbolBody(LazyKind, S.getName(), false, false, llvm::ELF::STV_DEFAULT,<br>
- /* Type */ 0),<br>
+ : SymbolBody(LazyKind, S.getName(), llvm::ELF::STB_GLOBAL,<br>
+ llvm::ELF::STV_DEFAULT, /* Type */ 0),<br>
File(F), Sym(S) {}<br>
<br>
static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; }<br>
@@ -320,48 +348,44 @@ public:<br>
// was already returned.<br>
std::unique_ptr<InputFile> getMember();<br>
<br>
- void setWeak() { IsWeak = true; }<br>
-<br>
private:<br>
ArchiveFile *File;<br>
const llvm::object::Archive::Symbol Sym;<br>
};<br>
<br>
// Some linker-generated symbols need to be created as<br>
-// DefinedRegular symbols, so they need Elf_Sym symbols.<br>
-// Here we allocate such Elf_Sym symbols statically.<br>
+// DefinedRegular symbols.<br>
template <class ELFT> struct ElfSym {<br>
- typedef typename ELFT::Sym Elf_Sym;<br>
-<br>
- // Used to represent an undefined symbol which we don't want to add to the<br>
- // output file's symbol table. It has weak binding and can be substituted.<br>
- static Elf_Sym Ignored;<br>
-<br>
// The content for _etext and etext symbols.<br>
- static Elf_Sym Etext;<br>
+ static DefinedRegular<ELFT> *Etext;<br>
+ static DefinedRegular<ELFT> *Etext2;<br>
<br>
// The content for _edata and edata symbols.<br>
- static Elf_Sym Edata;<br>
+ static DefinedRegular<ELFT> *Edata;<br>
+ static DefinedRegular<ELFT> *Edata2;<br>
<br>
// The content for _end and end symbols.<br>
- static Elf_Sym End;<br>
+ static DefinedRegular<ELFT> *End;<br>
+ static DefinedRegular<ELFT> *End2;<br>
<br>
// The content for _gp symbol for MIPS target.<br>
- static Elf_Sym MipsGp;<br>
+ static DefinedRegular<ELFT> *MipsGp;<br>
<br>
// __rel_iplt_start/__rel_iplt_end for signaling<br>
// where R_[*]_IRELATIVE relocations do live.<br>
- static Elf_Sym RelaIpltStart;<br>
- static Elf_Sym RelaIpltEnd;<br>
+ static DefinedRegular<ELFT> *RelaIpltStart;<br>
+ static DefinedRegular<ELFT> *RelaIpltEnd;<br>
};<br>
<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::Ignored;<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::Etext;<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::Edata;<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::End;<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::MipsGp;<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::RelaIpltStart;<br>
-template <class ELFT> typename ELFT::Sym ElfSym<ELFT>::RelaIpltEnd;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Etext;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Etext2;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::Edata2;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::End2;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::MipsGp;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::RelaIpltStart;<br>
+template <class ELFT> DefinedRegular<ELFT> *ElfSym<ELFT>::RelaIpltEnd;<br>
<br>
} // namespace elf<br>
} // namespace lld<br>
<br>
Modified: lld/trunk/ELF/Target.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Target.cpp (original)<br>
+++ lld/trunk/ELF/Target.cpp Mon Apr 4 09:04:16 2016<br>
@@ -248,7 +248,7 @@ uint64_t TargetInfo::getImplicitAddend(c<br>
}<br>
<br>
bool TargetInfo::canRelaxTls(uint32_t Type, const SymbolBody *S) const {<br>
- if (Config->Shared || (S && !S->IsTls))<br>
+ if (Config->Shared || (S && !S->isTls()))<br>
return false;<br>
<br>
// We know we are producing an executable.<br>
@@ -280,7 +280,7 @@ template <typename ELFT> static bool may<br>
auto *SS = dyn_cast<SharedSymbol<ELFT>>(&S);<br>
if (!SS)<br>
return false;<br>
- return SS->Sym.getType() == STT_OBJECT;<br>
+ return SS->isObject();<br>
}<br>
<br>
template <class ELFT><br>
@@ -303,7 +303,7 @@ bool TargetInfo::refersToGotEntry(uint32<br>
<br>
TargetInfo::PltNeed TargetInfo::needsPlt(uint32_t Type,<br>
const SymbolBody &S) const {<br>
- if (S.IsGnuIFunc)<br>
+ if (S.isGnuIFunc())<br>
return Plt_Explicit;<br>
if (S.isPreemptible() && needsPltImpl(Type))<br>
return Plt_Explicit;<br>
@@ -330,7 +330,7 @@ TargetInfo::PltNeed TargetInfo::needsPlt<br>
// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,<br>
// R_386_JMP_SLOT, etc).<br>
if (S.isShared())<br>
- if (!Config->Pic && S.IsFunc && !refersToGotEntry(Type))<br>
+ if (!Config->Pic && S.isFunc() && !refersToGotEntry(Type))<br>
return Plt_Implicit;<br>
<br>
return Plt_No;<br>
@@ -500,7 +500,7 @@ bool X86TargetInfo::needsCopyRelImpl(uin<br>
}<br>
<br>
bool X86TargetInfo::needsGot(uint32_t Type, const SymbolBody &S) const {<br>
- if (S.IsTls && Type == R_386_TLS_GD)<br>
+ if (S.isTls() && Type == R_386_TLS_GD)<br>
return Target->canRelaxTls(Type, &S) && S.isPreemptible();<br>
if (Type == R_386_TLS_GOTIE || Type == R_386_TLS_IE)<br>
return !canRelaxTls(Type, &S);<br>
@@ -1762,7 +1762,7 @@ bool MipsTargetInfo<ELFT>::needsThunk(ui<br>
// LA25 is required if target file has PIC code<br>
// or target symbol is a PIC symbol.<br>
return (D->Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC) ||<br>
- (D->Sym.st_other & STO_MIPS_MIPS16) == STO_MIPS_PIC;<br>
+ (D->Other & STO_MIPS_MIPS16) == STO_MIPS_PIC;<br>
}<br>
<br>
template <class ELFT><br>
<br>
Modified: lld/trunk/ELF/Writer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Writer.cpp (original)<br>
+++ lld/trunk/ELF/Writer.cpp Mon Apr 4 09:04:16 2016<br>
@@ -287,7 +287,7 @@ static unsigned handleTlsRelocation(uint<br>
return 1;<br>
}<br>
<br>
- if (!Body.IsTls)<br>
+ if (!Body.isTls())<br>
return 0;<br>
<br>
if (Target->isTlsGlobalDynamicRel(Type)) {<br>
@@ -403,7 +403,7 @@ void Writer<ELFT>::scanRelocs(InputSecti<br>
Out<ELFT>::Plt->addEntry(Body);<br>
<br>
uint32_t Rel;<br>
- if (Body.IsGnuIFunc)<br>
+ if (Body.isGnuIFunc())<br>
Rel = Preemptible ? Target->PltRel : Target->IRelativeRel;<br>
else<br>
Rel = Target->UseLazyBinding ? Target->PltRel : Target->GotRel;<br>
@@ -440,7 +440,7 @@ void Writer<ELFT>::scanRelocs(InputSecti<br>
!Target->isSizeRel(Type);<br>
if (Preemptible || Dynrel) {<br>
uint32_t DynType;<br>
- if (Body.IsTls)<br>
+ if (Body.isTls())<br>
DynType = Target->TlsGotRel;<br>
else if (Preemptible)<br>
DynType = Target->GotRel;<br>
@@ -525,23 +525,17 @@ static void reportUndefined(SymbolTable<<br>
}<br>
<br>
template <class ELFT><br>
-static bool shouldKeepInSymtab(const elf::ObjectFile<ELFT> &File,<br>
- StringRef SymName,<br>
- const typename ELFT::Sym &Sym) {<br>
- if (Sym.getType() == STT_FILE)<br>
+static bool shouldKeepInSymtab(InputSectionBase<ELFT> *Sec, StringRef SymName,<br>
+ const SymbolBody &B) {<br>
+ if (B.isFile())<br>
return false;<br>
<br>
// We keep sections in symtab for relocatable output.<br>
- if (Sym.getType() == STT_SECTION)<br>
+ if (B.isSection())<br>
return Config->Relocatable;<br>
<br>
- // No reason to keep local undefined symbol in symtab.<br>
- if (Sym.st_shndx == SHN_UNDEF)<br>
- return false;<br>
-<br>
- InputSectionBase<ELFT> *Sec = File.getSection(Sym);<br>
// If sym references a section in a discarded group, don't keep it.<br>
- if (Sec == InputSection<ELFT>::Discarded)<br>
+ if (Sec == &InputSection<ELFT>::Discarded)<br>
return false;<br>
<br>
if (Config->DiscardNone)<br>
@@ -568,18 +562,23 @@ template <class ELFT> void Writer<ELFT>:<br>
return;<br>
for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :<br>
Symtab.getObjectFiles()) {<br>
+ const char *StrTab = F->getStringTable().data();<br>
for (SymbolBody *B : F->getLocalSymbols()) {<br>
- const Elf_Sym &Sym = cast<DefinedRegular<ELFT>>(B)->Sym;<br>
- StringRef SymName = check(Sym.getName(F->getStringTable()));<br>
- if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))<br>
+ auto *DR = dyn_cast<DefinedRegular<ELFT>>(B);<br>
+ // No reason to keep local undefined symbol in symtab.<br>
+ if (!DR)<br>
continue;<br>
- if (Sym.st_shndx != SHN_ABS && !F->getSection(Sym)->Live)<br>
+ StringRef SymName(StrTab + B->getNameOffset());<br>
+ InputSectionBase<ELFT> *Sec = DR->Section;<br>
+ if (!shouldKeepInSymtab<ELFT>(Sec, SymName, *B))<br>
+ continue;<br>
+ if (Sec && !Sec->Live)<br>
continue;<br>
++Out<ELFT>::SymTab->NumLocals;<br>
if (Config->Relocatable)<br>
B->DynsymIndex = Out<ELFT>::SymTab->NumLocals;<br>
- F->KeptLocalSyms.push_back(std::make_pair(<br>
- &Sym, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));<br>
+ F->KeptLocalSyms.push_back(<br>
+ std::make_pair(DR, Out<ELFT>::SymTab->StrTabSec.addString(SymName)));<br>
}<br>
}<br>
}<br>
@@ -754,7 +753,7 @@ void Writer<ELFT>::addCopyRelSymbols(std<br>
uintX_t Align = getAlignment(SS);<br>
Off = alignTo(Off, Align);<br>
SS->OffsetInBss = Off;<br>
- Off += SS->Sym.st_size;<br>
+ Off += SS->template getSize<ELFT>();<br>
MaxAlign = std::max(MaxAlign, Align);<br>
}<br>
Out<ELFT>::Bss->setSize(Off);<br>
@@ -787,7 +786,7 @@ void reportDiscarded(InputSectionBase<EL<br>
<br>
template <class ELFT><br>
bool Writer<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) const {<br>
- return !S || S == InputSection<ELFT>::Discarded || !S->Live ||<br>
+ return !S || S == &InputSection<ELFT>::Discarded || !S->Live ||<br>
Script->isDiscarded(S);<br>
}<br>
<br>
@@ -802,12 +801,10 @@ void Writer<ELFT>::addRelIpltSymbols() {<br>
if (isOutputDynamic() || !Out<ELFT>::RelaPlt)<br>
return;<br>
StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";<br>
- if (Symtab.find(S))<br>
- Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltStart);<br>
+ ElfSym<ELFT>::RelaIpltStart = Symtab.addIgnored(S);<br>
<br>
S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";<br>
- if (Symtab.find(S))<br>
- Symtab.addAbsolute(S, ElfSym<ELFT>::RelaIpltEnd);<br>
+ ElfSym<ELFT>::RelaIpltEnd = Symtab.addIgnored(S);<br>
}<br>
<br>
template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {<br>
@@ -815,9 +812,6 @@ template <class ELFT> static bool includ<br>
return false;<br>
<br>
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B)) {<br>
- // Don't include synthetic symbols like __init_array_start in every output.<br>
- if (&D->Sym == &ElfSym<ELFT>::Ignored)<br>
- return false;<br>
// Exclude symbols pointing to garbage-collected sections.<br>
if (D->Section && !D->Section->Live)<br>
return false;<br>
@@ -922,6 +916,32 @@ OutputSectionFactory<ELFT>::createKey(In<br>
// The linker is expected to define some symbols depending on<br>
// the linking result. This function defines such symbols.<br>
template <class ELFT> void Writer<ELFT>::addReservedSymbols() {<br>
+ if (Config->EMachine == EM_MIPS) {<br>
+ // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between<br>
+ // start of function and 'gp' pointer into GOT.<br>
+ Config->MipsGpDisp = Symtab.addIgnored("_gp_disp");<br>
+ // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'<br>
+ // pointer. This symbol is used in the code generated by .cpload pseudo-op<br>
+ // in case of using -mno-shared option.<br>
+ // <a href="https://sourceware.org/ml/binutils/2004-12/msg00094.html" rel="noreferrer" target="_blank">https://sourceware.org/ml/binutils/2004-12/msg00094.html</a><br>
+ Config->MipsLocalGp = Symtab.addIgnored("__gnu_local_gp");<br>
+ }<br>
+<br>
+ // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol<br>
+ // is magical and is used to produce a R_386_GOTPC relocation.<br>
+ // The R_386_GOTPC relocation value doesn't actually depend on the<br>
+ // symbol value, so it could use an index of STN_UNDEF which, according<br>
+ // to the spec, means the symbol value is 0.<br>
+ // Unfortunately both gas and MC keep the _GLOBAL_OFFSET_TABLE_ symbol in<br>
+ // the object file.<br>
+ // The situation is even stranger on x86_64 where the assembly doesn't<br>
+ // need the magical symbol, but gas still puts _GLOBAL_OFFSET_TABLE_ as<br>
+ // an undefined symbol in the .o files.<br>
+ // Given that the symbol is effectively unused, we just create a dummy<br>
+ // hidden one to avoid the undefined symbol error.<br>
+ if (!Config->Relocatable)<br>
+ Symtab.addIgnored("_GLOBAL_OFFSET_TABLE_");<br>
+<br>
// __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For<br>
// static linking the linker is required to optimize away any references to<br>
// __tls_get_addr, so it's not defined anywhere. Create a hidden definition<br>
@@ -929,9 +949,9 @@ template <class ELFT> void Writer<ELFT>:<br>
if (!isOutputDynamic())<br>
Symtab.addIgnored("__tls_get_addr");<br>
<br>
- auto Define = [this](StringRef S, Elf_Sym &Sym) {<br>
- if (Symtab.find(S))<br>
- Symtab.addAbsolute(S, Sym);<br>
+ auto Define = [this](StringRef S, DefinedRegular<ELFT> *&Sym,<br>
+ DefinedRegular<ELFT> *&Sym2) {<br>
+ Sym = Symtab.addIgnored(S, STV_DEFAULT);<br>
<br>
// The name without the underscore is not a reserved name,<br>
// so it is defined only when there is a reference against it.<br>
@@ -939,12 +959,12 @@ template <class ELFT> void Writer<ELFT>:<br>
S = S.substr(1);<br>
if (SymbolBody *B = Symtab.find(S))<br>
if (B->isUndefined())<br>
- Symtab.addAbsolute(S, Sym);<br>
+ Sym2 = Symtab.addAbsolute(S, STV_DEFAULT);<br>
};<br>
<br>
- Define("_end", ElfSym<ELFT>::End);<br>
- Define("_etext", ElfSym<ELFT>::Etext);<br>
- Define("_edata", ElfSym<ELFT>::Edata);<br>
+ Define("_end", ElfSym<ELFT>::End, ElfSym<ELFT>::End2);<br>
+ Define("_etext", ElfSym<ELFT>::Etext, ElfSym<ELFT>::Etext2);<br>
+ Define("_edata", ElfSym<ELFT>::Edata, ElfSym<ELFT>::Edata2);<br>
}<br>
<br>
// Sort input sections by section name suffixes for<br>
@@ -1467,13 +1487,15 @@ template <class ELFT> void Writer<ELFT>:<br>
// to beginning or ending of .rela.plt section, respectively.<br>
if (Out<ELFT>::RelaPlt) {<br>
uintX_t Start = Out<ELFT>::RelaPlt->getVA();<br>
- ElfSym<ELFT>::RelaIpltStart.st_value = Start;<br>
- ElfSym<ELFT>::RelaIpltEnd.st_value = Start + Out<ELFT>::RelaPlt->getSize();<br>
+ if (ElfSym<ELFT>::RelaIpltStart)<br>
+ ElfSym<ELFT>::RelaIpltStart->Value = Start;<br>
+ if (ElfSym<ELFT>::RelaIpltEnd)<br>
+ ElfSym<ELFT>::RelaIpltEnd->Value = Start + Out<ELFT>::RelaPlt->getSize();<br>
}<br>
<br>
// Update MIPS _gp absolute symbol so that it points to the static data.<br>
if (Config->EMachine == EM_MIPS)<br>
- ElfSym<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();<br>
+ ElfSym<ELFT>::MipsGp->Value = getMipsGpAddr<ELFT>();<br>
<br>
// _etext is the first location after the last read-only loadable segment.<br>
// _edata is the first location after the last read-write loadable segment.<br>
@@ -1482,12 +1504,24 @@ template <class ELFT> void Writer<ELFT>:<br>
Elf_Phdr &H = P.H;<br>
if (H.p_type != PT_LOAD)<br>
continue;<br>
- ElfSym<ELFT>::End.st_value = H.p_vaddr + H.p_memsz;<br>
- uintX_t Val = H.p_vaddr + H.p_filesz;<br>
- if (H.p_flags & PF_W)<br>
- ElfSym<ELFT>::Edata.st_value = Val;<br>
- else<br>
- ElfSym<ELFT>::Etext.st_value = Val;<br>
+ uintX_t Val = H.p_vaddr + H.p_memsz;<br>
+ if (ElfSym<ELFT>::End)<br>
+ ElfSym<ELFT>::End->Value = Val;<br>
+ if (ElfSym<ELFT>::End2)<br>
+ ElfSym<ELFT>::End2->Value = Val;<br>
+<br>
+ Val = H.p_vaddr + H.p_filesz;<br>
+ if (H.p_flags & PF_W) {<br>
+ if (ElfSym<ELFT>::Edata)<br>
+ ElfSym<ELFT>::Edata->Value = Val;<br>
+ if (ElfSym<ELFT>::Edata2)<br>
+ ElfSym<ELFT>::Edata2->Value = Val;<br>
+ } else {<br>
+ if (ElfSym<ELFT>::Etext)<br>
+ ElfSym<ELFT>::Etext->Value = Val;<br>
+ if (ElfSym<ELFT>::Etext2)<br>
+ ElfSym<ELFT>::Etext2->Value = Val;<br>
+ }<br>
}<br>
}<br>
<br>
<br>
Modified: lld/trunk/test/ELF/aarch64-gnu-ifunc.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-gnu-ifunc.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/aarch64-gnu-ifunc.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/aarch64-gnu-ifunc.s (original)<br>
+++ lld/trunk/test/ELF/aarch64-gnu-ifunc.s Mon Apr 4 09:04:16 2016<br>
@@ -51,7 +51,9 @@<br>
// CHECK-NEXT: Size: 0<br>
// CHECK-NEXT: Binding: Local<br>
// CHECK-NEXT: Type: None<br>
-// CHECK-NEXT: Other: 0<br>
+// CHECK-NEXT: Other [<br>
+// CHECK-NEXT: STV_HIDDEN<br>
+// CHECK-NEXT: ]<br>
// CHECK-NEXT: Section: Absolute<br>
// CHECK-NEXT: }<br>
// CHECK-NEXT: Symbol {<br>
@@ -60,7 +62,9 @@<br>
// CHECK-NEXT: Size: 0<br>
// CHECK-NEXT: Binding: Local<br>
// CHECK-NEXT: Type: None<br>
-// CHECK-NEXT: Other: 0<br>
+// CHECK-NEXT: Other [<br>
+// CHECK-NEXT: STV_HIDDEN<br>
+// CHECK-NEXT: ]<br>
// CHECK-NEXT: Section: Absolute<br>
// CHECK-NEXT: }<br>
// CHECK-NEXT: Symbol {<br>
<br>
Modified: lld/trunk/test/ELF/basic-mips.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/basic-mips.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/basic-mips.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/basic-mips.s (original)<br>
+++ lld/trunk/test/ELF/basic-mips.s Mon Apr 4 09:04:16 2016<br>
@@ -187,22 +187,22 @@ __start:<br>
# CHECK-NEXT: Section: Undefined (0x0)<br>
# CHECK-NEXT: }<br>
# CHECK-NEXT: Symbol {<br>
-# CHECK-NEXT: Name: _gp<br>
-# CHECK-NEXT: Value: 0x0<br>
+# CHECK-NEXT: Name: __start<br>
+# CHECK-NEXT: Value: 0x20000<br>
# CHECK-NEXT: Size: 0<br>
-# CHECK-NEXT: Binding: Local (0x0)<br>
+# CHECK-NEXT: Binding: Global (0x1)<br>
# CHECK-NEXT: Type: None (0x0)<br>
# CHECK-NEXT: Other: 0<br>
-# CHECK-NEXT: Section: Absolute (0xFFF1)<br>
+# CHECK-NEXT: Section: .text<br>
# CHECK-NEXT: }<br>
# CHECK-NEXT: Symbol {<br>
-# CHECK-NEXT: Name: __start<br>
-# CHECK-NEXT: Value: 0x20000<br>
+# CHECK-NEXT: Name: _gp<br>
+# CHECK-NEXT: Value: 0x0<br>
# CHECK-NEXT: Size: 0<br>
-# CHECK-NEXT: Binding: Global (0x1)<br>
+# CHECK-NEXT: Binding: Global<br>
# CHECK-NEXT: Type: None (0x0)<br>
# CHECK-NEXT: Other: 0<br>
-# CHECK-NEXT: Section: .text<br>
+# CHECK-NEXT: Section: Absolute (0xFFF1)<br>
# CHECK-NEXT: }<br>
# CHECK-NEXT: ]<br>
# CHECK-NEXT: ProgramHeaders [<br>
<br>
Modified: lld/trunk/test/ELF/global_offset_table_shared.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global_offset_table_shared.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/global_offset_table_shared.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/global_offset_table_shared.s (original)<br>
+++ lld/trunk/test/ELF/global_offset_table_shared.s Mon Apr 4 09:04:16 2016<br>
@@ -3,4 +3,7 @@<br>
// RUN: llvm-readobj -t %t2 | FileCheck %s<br>
.long _GLOBAL_OFFSET_TABLE_<br>
<br>
-// CHECK-NOT: Name: _GLOBAL_OFFSET_TABLE_<br>
+// CHECK: Name: _GLOBAL_OFFSET_TABLE_<br>
+// CHECK-NEXT: Value:<br>
+// CHECK-NEXT: Size: 0<br>
+// CHECK-NEXT: Binding: Local<br>
<br>
Modified: lld/trunk/test/ELF/gnu-ifunc-i386.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-i386.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc-i386.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/gnu-ifunc-i386.s (original)<br>
+++ lld/trunk/test/ELF/gnu-ifunc-i386.s Mon Apr 4 09:04:16 2016<br>
@@ -43,7 +43,9 @@<br>
// CHECK-NEXT: Size: 0<br>
// CHECK-NEXT: Binding: Local<br>
// CHECK-NEXT: Type: None<br>
-// CHECK-NEXT: Other: 0<br>
+// CHECK-NEXT: Other [<br>
+// CHECK-NEXT: STV_HIDDEN<br>
+// CHECK-NEXT: ]<br>
// CHECK-NEXT: Section: Absolute<br>
// CHECK-NEXT: }<br>
// CHECK-NEXT: Symbol {<br>
@@ -52,7 +54,9 @@<br>
// CHECK-NEXT: Size: 0<br>
// CHECK-NEXT: Binding: Local<br>
// CHECK-NEXT: Type: None<br>
-// CHECK-NEXT: Other: 0<br>
+// CHECK-NEXT: Other [<br>
+// CHECK-NEXT: STV_HIDDEN<br>
+// CHECK-NEXT: ]<br>
// CHECK-NEXT: Section: Absolute<br>
// CHECK-NEXT: }<br>
// CHECK-NEXT: Symbol {<br>
<br>
Modified: lld/trunk/test/ELF/gnu-ifunc.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/gnu-ifunc.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/gnu-ifunc.s (original)<br>
+++ lld/trunk/test/ELF/gnu-ifunc.s Mon Apr 4 09:04:16 2016<br>
@@ -42,7 +42,9 @@<br>
// CHECK-NEXT: Size: 0<br>
// CHECK-NEXT: Binding: Local<br>
// CHECK-NEXT: Type: None<br>
-// CHECK-NEXT: Other: 0<br>
+// CHECK-NEXT: Other [<br>
+// CHECK-NEXT: STV_HIDDEN<br>
+// CHECK-NEXT: ]<br>
// CHECK-NEXT: Section: Absolute<br>
// CHECK-NEXT: }<br>
// CHECK-NEXT: Symbol {<br>
@@ -51,7 +53,9 @@<br>
// CHECK-NEXT: Size: 0<br>
// CHECK-NEXT: Binding: Local<br>
// CHECK-NEXT: Type: None<br>
-// CHECK-NEXT: Other: 0<br>
+// CHECK-NEXT: Other [<br>
+// CHECK-NEXT: STV_HIDDEN<br>
+// CHECK-NEXT: ]<br>
// CHECK-NEXT: Section: Absolute<br>
// CHECK-NEXT: }<br>
// CHECK-NEXT: Symbol {<br>
<br>
Modified: lld/trunk/test/ELF/mips-gp-disp.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-gp-disp.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-gp-disp.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/mips-gp-disp.s (original)<br>
+++ lld/trunk/test/ELF/mips-gp-disp.s Mon Apr 4 09:04:16 2016<br>
@@ -11,7 +11,10 @@<br>
<br>
# REQUIRES: mips<br>
<br>
-# INT-SO-NOT: Name: _gp_disp<br>
+# INT-SO: Name: _gp_disp<br>
+# INT-SO-NEXT: Value:<br>
+# INT-SO-NEXT: Size:<br>
+# INT-SO-NEXT: Binding: Local<br>
<br>
# EXT-SO: Name: _gp_disp<br>
# EXT-SO-NEXT: Value: 0x20010<br>
<br>
Modified: lld/trunk/test/ELF/mips-hilo-gp-disp.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-hilo-gp-disp.s?rev=265293&r1=265292&r2=265293&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/mips-hilo-gp-disp.s?rev=265293&r1=265292&r2=265293&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/mips-hilo-gp-disp.s (original)<br>
+++ lld/trunk/test/ELF/mips-hilo-gp-disp.s Mon Apr 4 09:04:16 2016<br>
@@ -25,8 +25,8 @@ __start:<br>
# ^-- %lo(0x37ff0-0x20004+4)<br>
<br>
# EXE: SYMBOL TABLE:<br>
-# EXE: 00037ff0 *ABS* 00000000 _gp<br>
# EXE: 00020000 .text 00000000 __start<br>
+# EXE: 00037ff0 *ABS* 00000000 _gp<br>
# EXE: 00020010 .text 00000000 _foo<br>
<br>
# SO: Disassembly of section .text:<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>