mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
[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
This commit is contained in:
parent
bd4bd3686d
commit
afcf60fe15
@ -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 {
|
||||
@ -106,6 +112,11 @@ struct MappingTraits<ELFYAML::FileHeader> {
|
||||
static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -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) {
|
||||
|
22
test/Object/yaml2obj-elf-symbol-basic.yaml
Normal file
22
test/Object/yaml2obj-elf-symbol-basic.yaml
Normal file
@ -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
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user