[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