1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[yaml2obj][ELF] Don't explicitly set Binding with STB_*

Instead, just have 3 sub-lists, one for each of
{STB_LOCAL,STB_GLOBAL,STB_WEAK}.

This allows us to be a lot more explicit w.r.t. the symbol ordering in
the object file, because if we allowed explicitly setting the STB_*
`Binding` key for the symbol, then we might have ended up having to
shuffle STB_LOCAL symbols to the front of the list, which is likely to
cause confusion and potential for error.

Also, this new approach is simpler ;)

llvm-svn: 184506
This commit is contained in:
Sean Silva 2013-06-21 00:27:50 +00:00
parent bdb6bfd975
commit 891dc92008
5 changed files with 99 additions and 51 deletions

View File

@ -40,7 +40,6 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
// Just use 64, since it can hold 32-bit values too.
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
@ -55,12 +54,16 @@ struct FileHeader {
};
struct Symbol {
StringRef Name;
ELF_STB Binding;
ELF_STT Type;
StringRef Section;
llvm::yaml::Hex64 Value;
llvm::yaml::Hex64 Size;
};
struct LocalGlobalWeakSymbols {
std::vector<Symbol> Local;
std::vector<Symbol> Global;
std::vector<Symbol> Weak;
};
struct Section {
StringRef Name;
ELF_SHT Type;
@ -70,7 +73,7 @@ struct Section {
StringRef Link;
llvm::yaml::Hex64 AddressAlign;
// For SHT_SYMTAB; should be empty otherwise.
std::vector<Symbol> Symbols;
LocalGlobalWeakSymbols Symbols;
};
struct Object {
FileHeader Header;
@ -121,11 +124,6 @@ struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
};
template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
};
template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
@ -141,6 +139,11 @@ struct MappingTraits<ELFYAML::Symbol> {
static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
};
template <>
struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
};
template <>
struct MappingTraits<ELFYAML::Section> {
static void mapping(IO &IO, ELFYAML::Section &Section);

View File

@ -278,15 +278,6 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
#undef BCase
}
void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
IO &IO, ELFYAML::ELF_STB &Value) {
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
ECase(STB_LOCAL)
ECase(STB_GLOBAL)
ECase(STB_WEAK)
#undef ECase
}
void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
IO &IO, ELFYAML::ELF_STT &Value) {
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
@ -313,13 +304,19 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
IO.mapOptional("Name", Symbol.Name, StringRef());
IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
IO.mapOptional("Section", Symbol.Section, StringRef());
IO.mapOptional("Value", Symbol.Value, Hex64(0));
IO.mapOptional("Size", Symbol.Size, Hex64(0));
}
void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
IO.mapOptional("Local", Symbols.Local);
IO.mapOptional("Global", Symbols.Global);
IO.mapOptional("Weak", Symbols.Weak);
}
void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
ELFYAML::Section &Section) {
IO.mapOptional("Name", Section.Name, StringRef());

View File

@ -0,0 +1,39 @@
# RUN: yaml2obj -format=elf %s | llvm-readobj -symbols - | FileCheck %s
!ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: .data
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_WRITE ]
Content: "DEADBEEF"
- Name: .symtab
Type: SHT_SYMTAB
Symbols:
Local:
- Name: local_symbol
Type: STT_OBJECT
Section: .data
Global:
- Name: global_symbol
Type: STT_OBJECT
Section: .data
Weak:
- Name: weak_symbol
Type: STT_OBJECT
Section: .data
# CHECK: Symbol {
# CHECK: Name: (0)
# CHECK: Symbol {
# CHECK: Name: local_symbol
# CHECK: Binding: Local
# CHECK: Symbol {
# CHECK: Name: global_symbol
# CHECK: Binding: Global
# CHECK: Symbol {
# CHECK: Name: weak_symbol
# CHECK: Binding: Weak

View File

@ -20,12 +20,12 @@ Sections:
- Name: .symtab
Type: SHT_SYMTAB
Symbols:
- Name: main
Binding: STB_GLOBAL
Type: STT_FUNC
Section: .text
Value: 0x1
Size: 2
Global:
- Name: main
Type: STT_FUNC
Section: .text
Value: 0x1
Size: 2
# CHECK: Symbols [
# CHECK-NEXT: Symbol {

View File

@ -168,37 +168,21 @@ public:
};
} // end anonymous namespace
// FIXME: This function is hideous. The hideous ELF type names are hideous.
// Factor the ELF output into a class (templated on ELFT) and share some
// typedefs.
template <class ELFT>
static void handleSymtabSectionHeader(
const ELFYAML::Section &Sec, ELFState<ELFT> &State,
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
typedef typename object::ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
// TODO: Ensure that a manually specified `Link` field is diagnosed as an
// error for SHT_SYMTAB.
SHeader.sh_link = State.getDotStrTabSecNo();
// TODO: Once we handle symbol binding, this should be one greater than
// symbol table index of the last local symbol.
SHeader.sh_info = 0;
SHeader.sh_entsize = sizeof(Elf_Sym);
std::vector<Elf_Sym> Syms;
{
// Ensure STN_UNDEF is present
Elf_Sym Sym;
zero(Sym);
Syms.push_back(Sym);
}
for (unsigned i = 0, e = Sec.Symbols.size(); i != e; ++i) {
const ELFYAML::Symbol &Sym = Sec.Symbols[i];
// FIXME: At this point it is fairly clear that we need to refactor these
// static functions into methods of a class sharing some typedefs. These
// ELF type names are insane.
template <class ELFT,
class Elf_Sym = typename object::ELFObjectFile<ELFT>::Elf_Sym>
static void addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
ELFState<ELFT> &State, std::vector<Elf_Sym> &Syms,
unsigned SymbolBinding) {
for (unsigned i = 0, e = Symbols.size(); i != e; ++i) {
const ELFYAML::Symbol &Sym = Symbols[i];
Elf_Sym Symbol;
zero(Symbol);
if (!Sym.Name.empty())
Symbol.st_name = State.getStringTable().addString(Sym.Name);
Symbol.setBindingAndType(Sym.Binding, Sym.Type);
Symbol.setBindingAndType(SymbolBinding, Sym.Type);
unsigned Index;
if (State.getSN2I().lookupSection(Sym.Section, Index)) {
errs() << "error: Unknown section referenced: '" << Sym.Section
@ -210,6 +194,31 @@ static void handleSymtabSectionHeader(
Symbol.st_size = Sym.Size;
Syms.push_back(Symbol);
}
}
template <class ELFT>
static void handleSymtabSectionHeader(
const ELFYAML::Section &Sec, ELFState<ELFT> &State,
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
typedef typename object::ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
// TODO: Ensure that a manually specified `Link` field is diagnosed as an
// error for SHT_SYMTAB.
SHeader.sh_link = State.getDotStrTabSecNo();
// One greater than symbol table index of the last local symbol.
SHeader.sh_info = Sec.Symbols.Local.size() + 1;
SHeader.sh_entsize = sizeof(Elf_Sym);
std::vector<Elf_Sym> Syms;
{
// Ensure STN_UNDEF is present
Elf_Sym Sym;
zero(Sym);
Syms.push_back(Sym);
}
addSymbols(Sec.Symbols.Local, State, Syms, ELF::STB_LOCAL);
addSymbols(Sec.Symbols.Global, State, Syms, ELF::STB_GLOBAL);
addSymbols(Sec.Symbols.Weak, State, Syms, ELF::STB_WEAK);
ContiguousBlobAccumulator &CBA = State.getSectionContentAccum();
SHeader.sh_offset = CBA.currentOffset();