Remove another case of almost duplicated code.

Were had very similar code for deciding to keep a local symbol and for
actually writing it.

llvm-svn: 258958
This commit is contained in:
Rafael Espindola 2016-01-27 18:04:26 +00:00
parent c8be5be968
commit 10d71ffc65
4 changed files with 39 additions and 59 deletions

View File

@ -129,6 +129,8 @@ public:
// R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
uint32_t getMipsGp0() const;
std::vector<const Elf_Sym *> KeptLocalSyms;
private:
void initializeSections(llvm::DenseSet<StringRef> &ComdatGroups);
void initializeSymbols();

View File

@ -1382,34 +1382,6 @@ template <class ELFT> void StringTableSection<ELFT>::writeTo(uint8_t *Buf) {
}
}
template <class ELFT>
bool elf2::shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
const typename ELFFile<ELFT>::Elf_Sym &Sym) {
if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
return false;
InputSectionBase<ELFT> *Sec = File.getSection(Sym);
// If sym references a section in a discarded group, don't keep it.
if (Sec == &InputSection<ELFT>::Discarded)
return false;
if (Config->DiscardNone)
return true;
// In ELF assembly .L symbols are normally discarded by the assembler.
// If the assembler fails to do so, the linker discards them if
// * --discard-locals is used.
// * The symbol is in a SHF_MERGE section, which is normally the reason for
// the assembler keeping the .L symbol.
if (!SymName.startswith(".L") && !SymName.empty())
return true;
if (Config->DiscardLocals)
return false;
return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);
}
template <class ELFT>
SymbolTableSection<ELFT>::SymbolTableSection(
SymbolTable<ELFT> &Table, StringTableSection<ELFT> &StrTabSec)
@ -1486,34 +1458,29 @@ void SymbolTableSection<ELFT>::writeLocalSymbols(uint8_t *&Buf) {
// Iterate over all input object files to copy their local symbols
// to the output symbol table pointed by Buf.
for (const std::unique_ptr<ObjectFile<ELFT>> &File : Table.getObjectFiles()) {
Elf_Sym_Range Syms = File->getLocalSymbols();
for (const Elf_Sym &Sym : Syms) {
ErrorOr<StringRef> SymNameOrErr = Sym.getName(File->getStringTable());
for (const Elf_Sym *Sym : File->KeptLocalSyms) {
ErrorOr<StringRef> SymNameOrErr = Sym->getName(File->getStringTable());
error(SymNameOrErr);
StringRef SymName = *SymNameOrErr;
if (!shouldKeepInSymtab<ELFT>(*File, SymName, Sym))
continue;
auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
uintX_t VA = 0;
if (Sym.st_shndx == SHN_ABS) {
if (Sym->st_shndx == SHN_ABS) {
ESym->st_shndx = SHN_ABS;
VA = Sym.st_value;
VA = Sym->st_value;
} else {
InputSectionBase<ELFT> *Section = File->getSection(Sym);
if (!Section->isLive())
continue;
InputSectionBase<ELFT> *Section = File->getSection(*Sym);
const OutputSectionBase<ELFT> *OutSec = Section->OutSec;
ESym->st_shndx = OutSec->SectionIndex;
VA = Section->getOffset(Sym);
VA = Section->getOffset(*Sym);
// Symbol offsets for AMDGPU need to be the offset in bytes of the
// symbol from the beginning of the section.
if (Config->EMachine != EM_AMDGPU)
VA += OutSec->getVA();
}
ESym->st_name = StrTabSec.addString(SymName);
ESym->st_size = Sym.st_size;
ESym->setBindingAndType(Sym.getBinding(), Sym.getType());
ESym->st_size = Sym->st_size;
ESym->setBindingAndType(Sym->getBinding(), Sym->getType());
ESym->st_value = VA;
Buf += sizeof(*ESym);
}
@ -1737,18 +1704,5 @@ template uint64_t getLocalRelTarget(const ObjectFile<ELF64LE> &,
template uint64_t getLocalRelTarget(const ObjectFile<ELF64BE> &,
const ELFFile<ELF64BE>::Elf_Rela &,
uint64_t);
template bool shouldKeepInSymtab<ELF32LE>(const ObjectFile<ELF32LE> &,
StringRef,
const ELFFile<ELF32LE>::Elf_Sym &);
template bool shouldKeepInSymtab<ELF32BE>(const ObjectFile<ELF32BE> &,
StringRef,
const ELFFile<ELF32BE>::Elf_Sym &);
template bool shouldKeepInSymtab<ELF64LE>(const ObjectFile<ELF64LE> &,
StringRef,
const ELFFile<ELF64LE>::Elf_Sym &);
template bool shouldKeepInSymtab<ELF64BE>(const ObjectFile<ELF64BE> &,
StringRef,
const ELFFile<ELF64BE>::Elf_Sym &);
}
}

View File

@ -59,11 +59,6 @@ getLocalRelTarget(const ObjectFile<ELFT> &File,
bool canBePreempted(const SymbolBody *Body, bool NeedsGot);
template <class ELFT>
bool shouldKeepInSymtab(
const ObjectFile<ELFT> &File, StringRef Name,
const typename llvm::object::ELFFile<ELFT>::Elf_Sym &Sym);
// This represents a section in an output file.
// Different sub classes represent different types of sections. Some contain
// input sections, others are created by the linker.

View File

@ -385,6 +385,34 @@ static void reportUndefined(SymbolTable<ELFT> &Symtab, SymbolBody *Sym) {
error(Msg);
}
template <class ELFT>
static bool shouldKeepInSymtab(const ObjectFile<ELFT> &File, StringRef SymName,
const typename ELFFile<ELFT>::Elf_Sym &Sym) {
if (Sym.getType() == STT_SECTION || Sym.getType() == STT_FILE)
return false;
InputSectionBase<ELFT> *Sec = File.getSection(Sym);
// If sym references a section in a discarded group, don't keep it.
if (Sec == &InputSection<ELFT>::Discarded)
return false;
if (Config->DiscardNone)
return true;
// In ELF assembly .L symbols are normally discarded by the assembler.
// If the assembler fails to do so, the linker discards them if
// * --discard-locals is used.
// * The symbol is in a SHF_MERGE section, which is normally the reason for
// the assembler keeping the .L symbol.
if (!SymName.startswith(".L") && !SymName.empty())
return true;
if (Config->DiscardLocals)
return false;
return !(Sec->getSectionHdr()->sh_flags & SHF_MERGE);
}
// Local symbols are not in the linker's symbol table. This function scans
// each object file's symbol table to copy local symbols to the output.
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
@ -403,6 +431,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
continue;
}
Out<ELFT>::SymTab->addLocalSymbol(SymName);
F->KeptLocalSyms.push_back(&Sym);
}
}
}