Re-implement --just-symbols as a regular object file.

I tried a few different designs to find a way to implement it without
too much hassle and settled down with this. Unlike before, object files
given as arguments for --just-symbols are handled as object files, with
an exception that their section tables are handled as if they were all
null.

Differential Revision: https://reviews.llvm.org/D42025

llvm-svn: 328852
This commit is contained in:
Rui Ueyama
2018-03-30 01:15:36 +00:00
parent 208fe67a78
commit 5a67a6ec4a
6 changed files with 69 additions and 68 deletions

View File

@@ -271,8 +271,13 @@ template <class ELFT> ArrayRef<Symbol *> ObjFile<ELFT>::getGlobalSymbols() {
template <class ELFT>
void ObjFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
// Read section and symbol tables.
initializeSections(ComdatGroups);
// Read a section table. JustSymbols is usually false.
if (this->JustSymbols)
initializeJustSymbols();
else
initializeSections(ComdatGroups);
// Read a symbol table.
initializeSymbols();
}
@@ -359,6 +364,27 @@ template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
return true;
}
// This is for --just-symbols.
//
// --just-symbols is a very minor feature that allows you to link your
// output against other existing program, so that if you load both your
// program and the other program into memory, your output can refer the
// other program's symbols.
//
// When the option is given, we link "just symbols". The section table is
// initialized with null pointers.
template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
ArrayRef<Elf_Shdr> ObjSections = CHECK(this->getObj().sections(), this);
this->Sections.resize(ObjSections.size());
for (const Elf_Shdr &Sec : ObjSections) {
if (Sec.sh_type != SHT_SYMTAB)
continue;
this->initSymtab(ObjSections, &Sec);
return;
}
}
template <class ELFT>
void ObjFile<ELFT>::initializeSections(
DenseSet<CachedHashStringRef> &ComdatGroups) {
@@ -1190,41 +1216,6 @@ template <class ELFT> void LazyObjFile::addElfSymbols() {
}
}
// This is for --just-symbols.
//
// This option allows you to link your output against other existing
// program, so that if you load both your program and the other program
// into memory, your output can use program's symbols.
//
// What we are doing here is to read defined symbols from a given ELF
// file and add them as absolute symbols.
template <class ELFT> void elf::readJustSymbolsFile(MemoryBufferRef MB) {
typedef typename ELFT::Shdr Elf_Shdr;
typedef typename ELFT::Sym Elf_Sym;
typedef typename ELFT::SymRange Elf_Sym_Range;
StringRef ObjName = MB.getBufferIdentifier();
ELFFile<ELFT> Obj = check(ELFFile<ELFT>::create(MB.getBuffer()));
ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), ObjName);
for (const Elf_Shdr &Sec : Sections) {
if (Sec.sh_type != SHT_SYMTAB)
continue;
Elf_Sym_Range Syms = CHECK(Obj.symbols(&Sec), ObjName);
uint32_t FirstGlobal = Sec.sh_info;
StringRef StringTable =
CHECK(Obj.getStringTableForSymtab(Sec, Sections), ObjName);
for (const Elf_Sym &Sym : Syms.slice(FirstGlobal))
if (Sym.st_shndx != SHN_UNDEF)
Symtab->addRegular(CHECK(Sym.getName(StringTable), ObjName),
Sym.st_other, Sym.getType(), Sym.st_value,
Sym.st_size, Sym.getBinding(), nullptr, nullptr);
return;
}
}
template void ArchiveFile::parse<ELF32LE>();
template void ArchiveFile::parse<ELF32BE>();
template void ArchiveFile::parse<ELF64LE>();
@@ -1254,8 +1245,3 @@ template class elf::SharedFile<ELF32LE>;
template class elf::SharedFile<ELF32BE>;
template class elf::SharedFile<ELF64LE>;
template class elf::SharedFile<ELF64BE>;
template void elf::readJustSymbolsFile<ELF32LE>(MemoryBufferRef);
template void elf::readJustSymbolsFile<ELF32BE>(MemoryBufferRef);
template void elf::readJustSymbolsFile<ELF64LE>(MemoryBufferRef);
template void elf::readJustSymbolsFile<ELF64BE>(MemoryBufferRef);