summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Silva <silvas@purdue.edu>2013-06-21 00:27:50 +0000
committerSean Silva <silvas@purdue.edu>2013-06-21 00:27:50 +0000
commit4235ba32f2610ee2ed1e0c4bfca5c67835e9f97d (patch)
treeaa2148433b9e8a6d81ca6e871f18f1122e1bfd45
parent2b7cdf09a142b7f3e9a0ec8c7044eaf89bc59caa (diff)
downloadllvm-4235ba32f2610ee2ed1e0c4bfca5c67835e9f97d.tar.gz
llvm-4235ba32f2610ee2ed1e0c4bfca5c67835e9f97d.tar.bz2
llvm-4235ba32f2610ee2ed1e0c4bfca5c67835e9f97d.tar.xz
[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 ;) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184506 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Object/ELFYAML.h19
-rw-r--r--lib/Object/ELFYAML.cpp17
-rw-r--r--test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml39
-rw-r--r--test/Object/yaml2obj-elf-symbol-basic.yaml12
-rw-r--r--tools/yaml2obj/yaml2elf.cpp57
5 files changed, 96 insertions, 48 deletions
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index abf3693e6f..b6c7556551 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -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;
@@ -122,11 +125,6 @@ struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
};
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);
};
@@ -142,6 +140,11 @@ struct MappingTraits<ELFYAML::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);
};
diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp
index 7fa775633a..107333c708 100644
--- a/lib/Object/ELFYAML.cpp
+++ b/lib/Object/ELFYAML.cpp
@@ -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());
diff --git a/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml b/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml
new file mode 100644
index 0000000000..44479dce7d
--- /dev/null
+++ b/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml
@@ -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
diff --git a/test/Object/yaml2obj-elf-symbol-basic.yaml b/test/Object/yaml2obj-elf-symbol-basic.yaml
index 12acb7e11e..238348b9b0 100644
--- a/test/Object/yaml2obj-elf-symbol-basic.yaml
+++ b/test/Object/yaml2obj-elf-symbol-basic.yaml
@@ -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 {
diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp
index a8eeeeacf1..cd6df144b7 100644
--- a/tools/yaml2obj/yaml2elf.cpp
+++ b/tools/yaml2obj/yaml2elf.cpp
@@ -168,9 +168,34 @@ 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.
+// 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,
@@ -180,9 +205,8 @@ static void handleSymtabSectionHeader(
// 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;
@@ -192,24 +216,9 @@ static void handleSymtabSectionHeader(
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();