diff options
author | Sean Silva <silvas@purdue.edu> | 2013-06-18 23:14:03 +0000 |
---|---|---|
committer | Sean Silva <silvas@purdue.edu> | 2013-06-18 23:14:03 +0000 |
commit | afcf60fe15999ea07193118f447a34f41171e433 (patch) | |
tree | 50990c3d24b6d6181abb247883b52fcfb8bcd273 /tools | |
parent | bd4bd3686d5e623514cc7564227a6fa45254c610 (diff) | |
download | llvm-afcf60fe15999ea07193118f447a34f41171e433.tar.gz llvm-afcf60fe15999ea07193118f447a34f41171e433.tar.bz2 llvm-afcf60fe15999ea07193118f447a34f41171e433.tar.xz |
[yaml2obj][ELF] Rudimentary symbol table support.
Currently, we only output the name.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184255 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
-rw-r--r-- | tools/yaml2obj/yaml2elf.cpp | 45 |
1 files changed, 43 insertions, 2 deletions
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")); |