forked from OSchip/llvm-project
[yaml2obj][obj2yaml] - Teach yaml2obj/obj2yaml tools about STB_GNU_UNIQUE symbols.
yaml2obj/obj2yaml does not support the symbols with STB_GNU_UNIQUE yet. Currently, obj2yaml fails with llvm_unreachable when met such a symbol. I faced it when investigated the https://bugs.llvm.org/show_bug.cgi?id=41196. Differential revision: https://reviews.llvm.org/D59875 llvm-svn: 357158
This commit is contained in:
parent
a833c2bd3e
commit
4111299584
|
@ -102,10 +102,11 @@ struct Symbol {
|
|||
uint8_t Other;
|
||||
};
|
||||
|
||||
struct LocalGlobalWeakSymbols {
|
||||
struct SymbolsDef {
|
||||
std::vector<Symbol> Local;
|
||||
std::vector<Symbol> Global;
|
||||
std::vector<Symbol> Weak;
|
||||
std::vector<Symbol> GNUUnique;
|
||||
};
|
||||
|
||||
struct SectionOrType {
|
||||
|
@ -288,8 +289,8 @@ struct Object {
|
|||
// cleaner and nicer if we read them from the YAML as a separate
|
||||
// top-level key, which automatically ensures that invariants like there
|
||||
// being a single SHT_SYMTAB section are upheld.
|
||||
LocalGlobalWeakSymbols Symbols;
|
||||
LocalGlobalWeakSymbols DynamicSymbols;
|
||||
SymbolsDef Symbols;
|
||||
SymbolsDef DynamicSymbols;
|
||||
};
|
||||
|
||||
} // end namespace ELFYAML
|
||||
|
@ -436,9 +437,8 @@ struct MappingTraits<ELFYAML::Symbol> {
|
|||
static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
|
||||
static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
|
||||
template <> struct MappingTraits<ELFYAML::SymbolsDef> {
|
||||
static void mapping(IO &IO, ELFYAML::SymbolsDef &Symbols);
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<ELFYAML::DynamicEntry> {
|
||||
|
|
|
@ -864,11 +864,12 @@ StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
|
|||
return StringRef();
|
||||
}
|
||||
|
||||
void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
|
||||
IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
|
||||
void MappingTraits<ELFYAML::SymbolsDef>::mapping(IO &IO,
|
||||
ELFYAML::SymbolsDef &Symbols) {
|
||||
IO.mapOptional("Local", Symbols.Local);
|
||||
IO.mapOptional("Global", Symbols.Global);
|
||||
IO.mapOptional("Weak", Symbols.Weak);
|
||||
IO.mapOptional("GNUUnique", Symbols.GNUUnique);
|
||||
}
|
||||
|
||||
static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: obj2yaml %t | FileCheck %s
|
||||
|
||||
## Check obj2yaml is able to dump the STB_GNU_UNIQUE symbol.
|
||||
|
||||
# CHECK: --- !ELF
|
||||
# CHECK-NEXT: FileHeader:
|
||||
# CHECK-NEXT: Class: ELFCLASS64
|
||||
# CHECK-NEXT: Data: ELFDATA2LSB
|
||||
# CHECK-NEXT: OSABI: ELFOSABI_GNU
|
||||
# CHECK-NEXT: Type: ET_REL
|
||||
# CHECK-NEXT: Machine: EM_X86_64
|
||||
# CHECK-NEXT: Symbols:
|
||||
# CHECK-NEXT: GNUUnique:
|
||||
# CHECK-NEXT: - Name: foo
|
||||
# CHECK-NEXT: Type: STT_OBJECT
|
||||
# CHECK-NEXT: DynamicSymbols: {}
|
||||
# CHECK-NEXT: ...
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
OSABI: ELFOSABI_GNU
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Symbols:
|
||||
GNUUnique:
|
||||
- Name: foo
|
||||
Type: STT_OBJECT
|
|
@ -0,0 +1,21 @@
|
|||
# RUN: yaml2obj %s -o %t
|
||||
# RUN: llvm-readobj -symbols %t | FileCheck %s
|
||||
|
||||
## Check yaml2obj is able to create the STB_GNU_UNIQUE symbol.
|
||||
|
||||
# CHECK: Name: foo
|
||||
# CHECK-NEXT: Value:
|
||||
# CHECK-NEXT: Size:
|
||||
# CHECK-NEXT: Binding: Unique
|
||||
|
||||
--- !ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
OSABI: ELFOSABI_GNU
|
||||
Type: ET_REL
|
||||
Machine: EM_X86_64
|
||||
Symbols:
|
||||
GNUUnique:
|
||||
- Name: foo
|
||||
Type: STT_OBJECT
|
|
@ -42,7 +42,7 @@ class ELFDumper {
|
|||
ArrayRef<Elf_Word> ShndxTable;
|
||||
|
||||
std::error_code dumpSymbols(const Elf_Shdr *Symtab,
|
||||
ELFYAML::LocalGlobalWeakSymbols &Symbols);
|
||||
ELFYAML::SymbolsDef &Symbols);
|
||||
std::error_code dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab,
|
||||
StringRef StrTable, ELFYAML::Symbol &S);
|
||||
std::error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
|
||||
|
@ -226,9 +226,8 @@ template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
std::error_code
|
||||
ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
|
||||
ELFYAML::LocalGlobalWeakSymbols &Symbols) {
|
||||
std::error_code ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
|
||||
ELFYAML::SymbolsDef &Symbols) {
|
||||
if (!Symtab)
|
||||
return std::error_code();
|
||||
|
||||
|
@ -262,6 +261,9 @@ ELFDumper<ELFT>::dumpSymbols(const Elf_Shdr *Symtab,
|
|||
case ELF::STB_WEAK:
|
||||
Symbols.Weak.push_back(S);
|
||||
break;
|
||||
case ELF::STB_GNU_UNIQUE:
|
||||
Symbols.GNUUnique.push_back(S);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unknown ELF symbol binding");
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ class ELFState {
|
|||
const ELFYAML::Object &Doc;
|
||||
|
||||
bool buildSectionIndex();
|
||||
bool buildSymbolIndex(const ELFYAML::LocalGlobalWeakSymbols &);
|
||||
bool buildSymbolIndex(const ELFYAML::SymbolsDef &);
|
||||
void initELFHeader(Elf_Ehdr &Header);
|
||||
void initProgramHeaders(std::vector<Elf_Phdr> &PHeaders);
|
||||
bool initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
|
||||
|
@ -362,6 +362,7 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
|
|||
addSymbols(Symbols.Local, Syms, ELF::STB_LOCAL, Strtab);
|
||||
addSymbols(Symbols.Global, Syms, ELF::STB_GLOBAL, Strtab);
|
||||
addSymbols(Symbols.Weak, Syms, ELF::STB_WEAK, Strtab);
|
||||
addSymbols(Symbols.GNUUnique, Syms, ELF::STB_GNU_UNIQUE, Strtab);
|
||||
|
||||
writeArrayData(
|
||||
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign),
|
||||
|
@ -795,11 +796,10 @@ template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
|
|||
}
|
||||
|
||||
template <class ELFT>
|
||||
bool ELFState<ELFT>::buildSymbolIndex(
|
||||
const ELFYAML::LocalGlobalWeakSymbols &Symbols) {
|
||||
bool ELFState<ELFT>::buildSymbolIndex(const ELFYAML::SymbolsDef &Symbols) {
|
||||
std::size_t I = 0;
|
||||
for (const std::vector<ELFYAML::Symbol> &V :
|
||||
{Symbols.Local, Symbols.Global, Symbols.Weak}) {
|
||||
{Symbols.Local, Symbols.Global, Symbols.Weak, Symbols.GNUUnique}) {
|
||||
for (const auto &Sym : V) {
|
||||
++I;
|
||||
if (Sym.Name.empty())
|
||||
|
@ -815,13 +815,15 @@ bool ELFState<ELFT>::buildSymbolIndex(
|
|||
|
||||
template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
|
||||
auto AddSymbols = [](StringTableBuilder &StrTab,
|
||||
const ELFYAML::LocalGlobalWeakSymbols &Symbols) {
|
||||
const ELFYAML::SymbolsDef &Symbols) {
|
||||
for (const auto &Sym : Symbols.Local)
|
||||
StrTab.add(Sym.Name);
|
||||
for (const auto &Sym : Symbols.Global)
|
||||
StrTab.add(Sym.Name);
|
||||
for (const auto &Sym : Symbols.Weak)
|
||||
StrTab.add(Sym.Name);
|
||||
for (const auto &Sym : Symbols.GNUUnique)
|
||||
StrTab.add(Sym.Name);
|
||||
};
|
||||
|
||||
// Add the regular symbol names to .strtab section.
|
||||
|
@ -919,9 +921,10 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
|
|||
}
|
||||
|
||||
template <class ELFT> bool ELFState<ELFT>::hasDynamicSymbols() const {
|
||||
return Doc.DynamicSymbols.Global.size() > 0 ||
|
||||
Doc.DynamicSymbols.Weak.size() > 0 ||
|
||||
Doc.DynamicSymbols.Local.size() > 0;
|
||||
return !Doc.DynamicSymbols.Global.empty() ||
|
||||
!Doc.DynamicSymbols.Weak.empty() ||
|
||||
!Doc.DynamicSymbols.Local.empty() ||
|
||||
!Doc.DynamicSymbols.GNUUnique.empty();
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
|
Loading…
Reference in New Issue