[llvm] r184506 - [yaml2obj][ELF] Don't explicitly set `Binding` with STB_*

Sean Silva silvas at purdue.edu
Thu Jun 20 17:27:51 PDT 2013


Author: silvas
Date: Thu Jun 20 19:27:50 2013
New Revision: 184506

URL: http://llvm.org/viewvc/llvm-project?rev=184506&view=rev
Log:
[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 ;)

Added:
    llvm/trunk/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml
Modified:
    llvm/trunk/include/llvm/Object/ELFYAML.h
    llvm/trunk/lib/Object/ELFYAML.cpp
    llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/include/llvm/Object/ELFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFYAML.h?rev=184506&r1=184505&r2=184506&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/Object/ELFYAML.h Thu Jun 20 19:27:50 2013
@@ -40,7 +40,6 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_EL
 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_S
 };
 
 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);
 };

Modified: llvm/trunk/lib/Object/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELFYAML.cpp?rev=184506&r1=184505&r2=184506&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELFYAML.cpp (original)
+++ llvm/trunk/lib/Object/ELFYAML.cpp Thu Jun 20 19:27:50 2013
@@ -278,15 +278,6 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF
 #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>:
 
 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());

Added: llvm/trunk/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml?rev=184506&view=auto
==============================================================================
--- llvm/trunk/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml (added)
+++ llvm/trunk/test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml Thu Jun 20 19:27:50 2013
@@ -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

Modified: llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml?rev=184506&r1=184505&r2=184506&view=diff
==============================================================================
--- llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml (original)
+++ llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml Thu Jun 20 19:27:50 2013
@@ -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 {

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=184506&r1=184505&r2=184506&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Thu Jun 20 19:27:50 2013
@@ -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();





More information about the llvm-commits mailing list