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 ;)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184506
91177308-0d34-0410-b5e6-
96231b3b80d8
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
};
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;
StringRef Link;
llvm::yaml::Hex64 AddressAlign;
// For SHT_SYMTAB; should be empty otherwise.
- std::vector<Symbol> Symbols;
+ LocalGlobalWeakSymbols Symbols;
};
struct Object {
FileHeader Header;
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);
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);
#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);
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());
--- /dev/null
+# 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
- 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 {
};
} // 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.
+// 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(SymbolBinding, Sym.Type);
+ unsigned Index;
+ if (State.getSN2I().lookupSection(Sym.Section, Index)) {
+ errs() << "error: Unknown section referenced: '" << Sym.Section
+ << "' by YAML symbol " << Sym.Name << ".\n";
+ exit(1);
+ }
+ Symbol.st_shndx = Index;
+ Symbol.st_value = Sym.Value;
+ Symbol.st_size = Sym.Size;
+ Syms.push_back(Symbol);
+ }
+}
+
template <class ELFT>
static void handleSymtabSectionHeader(
const ELFYAML::Section &Sec, ELFState<ELFT> &State,
// 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;
+ // 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;
zero(Sym);
Syms.push_back(Sym);
}
- for (unsigned i = 0, e = Sec.Symbols.size(); i != e; ++i) {
- const ELFYAML::Symbol &Sym = Sec.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);
- unsigned Index;
- if (State.getSN2I().lookupSection(Sym.Section, Index)) {
- errs() << "error: Unknown section referenced: '" << Sym.Section
- << "' by YAML symbol " << Sym.Name << ".\n";
- exit(1);
- }
- Symbol.st_shndx = Index;
- Symbol.st_value = Sym.Value;
- Symbol.st_size = Sym.Size;
- Syms.push_back(Symbol);
- }
+ 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();