summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Object/ELFYAML.h11
-rw-r--r--lib/Object/ELFYAML.cpp10
-rw-r--r--test/Object/yaml2obj-elf-symbol-basic.yaml22
-rw-r--r--tools/yaml2obj/yaml2elf.cpp45
4 files changed, 86 insertions, 2 deletions
diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h
index 04ba0a6622..d6ce525248 100644
--- a/include/llvm/Object/ELFYAML.h
+++ b/include/llvm/Object/ELFYAML.h
@@ -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);
};
diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp
index e0e95bee93..32a759dc0b 100644
--- a/lib/Object/ELFYAML.cpp
+++ b/lib/Object/ELFYAML.cpp
@@ -260,6 +260,10 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
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>::mapping(IO &IO,
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) {
diff --git a/test/Object/yaml2obj-elf-symbol-basic.yaml b/test/Object/yaml2obj-elf-symbol-basic.yaml
new file mode 100644
index 0000000000..c33d385304
--- /dev/null
+++ b/test/Object/yaml2obj-elf-symbol-basic.yaml
@@ -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
diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp
index b83dd1d1a3..bebcbde256 100644
--- a/tools/yaml2obj/yaml2elf.cpp
+++ b/tools/yaml2obj/yaml2elf.cpp
@@ -133,6 +133,42 @@ static void createStringTableSectionHeader(Elf_Shdr &SHeader,
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, const ELFYAML::Object &Doc) {
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, const ELFYAML::Object &Doc) {
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, const ELFYAML::Object &Doc) {
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"));