[llvm] r184255 - [yaml2obj][ELF] Rudimentary symbol table support.

Sean Silva silvas at purdue.edu
Tue Jun 18 16:14:03 PDT 2013


Author: silvas
Date: Tue Jun 18 18:14:03 2013
New Revision: 184255

URL: http://llvm.org/viewvc/llvm-project?rev=184255&view=rev
Log:
[yaml2obj][ELF] Rudimentary symbol table support.

Currently, we only output the name.

Added:
    llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml
Modified:
    llvm/trunk/include/llvm/Object/ELFYAML.h
    llvm/trunk/lib/Object/ELFYAML.cpp
    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=184255&r1=184254&r2=184255&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/Object/ELFYAML.h Tue Jun 18 18:14:03 2013
@@ -49,6 +49,9 @@ struct FileHeader {
   ELF_EM Machine;
   llvm::yaml::Hex64 Entry;
 };
+struct Symbol {
+  StringRef Name;
+};
 struct Section {
   StringRef Name;
   ELF_SHT Type;
@@ -57,6 +60,8 @@ struct Section {
   object::yaml::BinaryRef Content;
   StringRef Link;
   llvm::yaml::Hex64 AddressAlign;
+  // For SHT_SYMTAB; should be empty otherwise.
+  std::vector<Symbol> Symbols;
 };
 struct Object {
   FileHeader Header;
@@ -67,6 +72,7 @@ struct Object {
 } // end namespace llvm
 
 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
 
 namespace llvm {
 namespace yaml {
@@ -107,6 +113,11 @@ struct MappingTraits<ELFYAML::FileHeader
 };
 
 template <>
+struct MappingTraits<ELFYAML::Symbol> {
+  static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
+};
+
+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=184255&r1=184254&r2=184255&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELFYAML.cpp (original)
+++ llvm/trunk/lib/Object/ELFYAML.cpp Tue Jun 18 18:14:03 2013
@@ -260,6 +260,10 @@ void MappingTraits<ELFYAML::FileHeader>:
   IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
 }
 
+void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
+  IO.mapOptional("Name", Symbol.Name, StringRef());
+}
+
 void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
                                               ELFYAML::Section &Section) {
   IO.mapOptional("Name", Section.Name, StringRef());
@@ -269,6 +273,12 @@ void MappingTraits<ELFYAML::Section>::ma
   IO.mapOptional("Content", Section.Content);
   IO.mapOptional("Link", Section.Link);
   IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
+  // TODO: Error if `Type` is SHT_SYMTAB and this is not present, or if
+  // `Type` is *not* SHT_SYMTAB and this *is* present. (By SHT_SYMTAB I
+  // also mean SHT_DYNSYM, but for simplicity right now we just do
+  // SHT_SYMTAB). Want to be able to share the predicate with consumers of
+  // this structure.
+  IO.mapOptional("Symbols", Section.Symbols);
 }
 
 void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {

Added: 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=184255&view=auto
==============================================================================
--- llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml (added)
+++ llvm/trunk/test/Object/yaml2obj-elf-symbol-basic.yaml Tue Jun 18 18:14:03 2013
@@ -0,0 +1,22 @@
+# 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: .text
+    Type: SHT_PROGBITS
+    Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+  - Name: .symtab
+    Type: SHT_SYMTAB
+    Symbols:
+    - Name: "" # TODO: Add STN_UNDEF automatically.
+    - Name: main
+
+# CHECK:      Symbols [
+# CHECK-NEXT:   Symbol {
+# CHECK-NEXT:     Name:  (0)
+# CHECK:        Symbol {
+# CHECK-NEXT:     Name: main

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=184255&r1=184254&r2=184255&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Tue Jun 18 18:14:03 2013
@@ -133,6 +133,42 @@ static void createStringTableSectionHead
   SHeader.sh_addralign = 1;
 }
 
+// FIXME: This function is hideous. Between the sheer number of parameters
+// and the hideous ELF typenames, it's just a travesty. Factor the ELF
+// output into a class (templated on ELFT) and share some typedefs.
+template <class ELFT>
+static void handleSymtabSectionHeader(
+    const ELFYAML::Section &Sec,
+    const typename object::ELFObjectFile<ELFT>::Elf_Ehdr &Header,
+    typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader,
+    StringTableBuilder &StrTab, ContiguousBlobAccumulator &CBA,
+    unsigned DotStrtabSecNo) {
+
+  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 = DotStrtabSecNo;
+  // 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;
+  // FIXME: Ensure STN_UNDEF entry is present.
+  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 = StrTab.addString(Sym.Name);
+    Syms.push_back(Symbol);
+  }
+
+  SHeader.sh_offset = CBA.currentOffset();
+  SHeader.sh_size = vectorDataSize(Syms);
+  writeVectorData(CBA.getOS(), Syms);
+}
+
 template <class ELFT>
 static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
   using namespace llvm::ELF;
@@ -181,6 +217,7 @@ static int writeELF(raw_ostream &OS, con
   Header.e_shnum = Sections.size() + 2;
   // Place section header string table last.
   Header.e_shstrndx = Sections.size() + 1;
+  const unsigned DotStrtabSecNo = Sections.size();
 
   SectionNameToIdxMap SN2I;
   for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
@@ -202,6 +239,7 @@ static int writeELF(raw_ostream &OS, con
       Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
   ContiguousBlobAccumulator CBA(SectionContentBeginOffset, Buf);
   std::vector<Elf_Shdr> SHeaders;
+  StringTableBuilder DotStrTab;
   for (unsigned i = 0, e = Sections.size(); i != e; ++i) {
     const ELFYAML::Section &Sec = Sections[i];
     Elf_Shdr SHeader;
@@ -227,11 +265,14 @@ static int writeELF(raw_ostream &OS, con
     SHeader.sh_info = 0;
     SHeader.sh_addralign = Sec.AddressAlign;
     SHeader.sh_entsize = 0;
+    // XXX: Really ugly right now. Need to put common state into a class.
+    if (Sec.Type == ELFYAML::ELF_SHT(SHT_SYMTAB))
+      handleSymtabSectionHeader<ELFT>(Sec, Header, SHeader, DotStrTab, CBA,
+                                      DotStrtabSecNo);
     SHeaders.push_back(SHeader);
   }
 
-  // .strtab string table header. Currently emitted empty.
-  StringTableBuilder DotStrTab;
+  // .strtab string table header.
   Elf_Shdr DotStrTabSHeader;
   zero(DotStrTabSHeader);
   DotStrTabSHeader.sh_name = SHStrTab.addString(StringRef(".strtab"));





More information about the llvm-commits mailing list