mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[yaml2obj][ELF] Make symbol table top-level key.
Although in reality the symbol table in ELF resides in a section, the standard requires that there be no more than one SHT_SYMTAB. To enforce this constraint, it is cleaner to group all the symbols under a top-level `Symbols` key on the object file. llvm-svn: 184627
This commit is contained in:
parent
ced30f0888
commit
726b33f897
@ -72,12 +72,15 @@ struct Section {
|
|||||||
object::yaml::BinaryRef Content;
|
object::yaml::BinaryRef Content;
|
||||||
StringRef Link;
|
StringRef Link;
|
||||||
llvm::yaml::Hex64 AddressAlign;
|
llvm::yaml::Hex64 AddressAlign;
|
||||||
// For SHT_SYMTAB; should be empty otherwise.
|
|
||||||
LocalGlobalWeakSymbols Symbols;
|
|
||||||
};
|
};
|
||||||
struct Object {
|
struct Object {
|
||||||
FileHeader Header;
|
FileHeader Header;
|
||||||
std::vector<Section> Sections;
|
std::vector<Section> Sections;
|
||||||
|
// Although in reality the symbols reside in a section, it is a lot
|
||||||
|
// cleaner and nicer if we read them from the YAML as a separate
|
||||||
|
// top-level key, which automatically ensures that invariants like there
|
||||||
|
// being a single SHT_SYMTAB section are upheld.
|
||||||
|
LocalGlobalWeakSymbols Symbols;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace ELFYAML
|
} // end namespace ELFYAML
|
||||||
|
@ -244,7 +244,8 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
|
|||||||
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
|
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
|
||||||
ECase(SHT_NULL)
|
ECase(SHT_NULL)
|
||||||
ECase(SHT_PROGBITS)
|
ECase(SHT_PROGBITS)
|
||||||
ECase(SHT_SYMTAB)
|
// No SHT_SYMTAB. Use the top-level `Symbols` key instead.
|
||||||
|
// FIXME: Issue a diagnostic with this information.
|
||||||
ECase(SHT_STRTAB)
|
ECase(SHT_STRTAB)
|
||||||
ECase(SHT_RELA)
|
ECase(SHT_RELA)
|
||||||
ECase(SHT_HASH)
|
ECase(SHT_HASH)
|
||||||
@ -326,17 +327,12 @@ void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
|
|||||||
IO.mapOptional("Content", Section.Content);
|
IO.mapOptional("Content", Section.Content);
|
||||||
IO.mapOptional("Link", Section.Link);
|
IO.mapOptional("Link", Section.Link);
|
||||||
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
|
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) {
|
void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
|
||||||
IO.mapRequired("FileHeader", Object.Header);
|
IO.mapRequired("FileHeader", Object.Header);
|
||||||
IO.mapOptional("Sections", Object.Sections);
|
IO.mapOptional("Sections", Object.Sections);
|
||||||
|
IO.mapOptional("Symbols", Object.Symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace yaml
|
} // end namespace yaml
|
||||||
|
@ -10,21 +10,19 @@ Sections:
|
|||||||
Type: SHT_PROGBITS
|
Type: SHT_PROGBITS
|
||||||
Flags: [ SHF_ALLOC, SHF_WRITE ]
|
Flags: [ SHF_ALLOC, SHF_WRITE ]
|
||||||
Content: "DEADBEEF"
|
Content: "DEADBEEF"
|
||||||
- Name: .symtab
|
Symbols:
|
||||||
Type: SHT_SYMTAB
|
Local:
|
||||||
Symbols:
|
- Name: local_symbol
|
||||||
Local:
|
Type: STT_OBJECT
|
||||||
- Name: local_symbol
|
Section: .data
|
||||||
Type: STT_OBJECT
|
Global:
|
||||||
Section: .data
|
- Name: global_symbol
|
||||||
Global:
|
Type: STT_OBJECT
|
||||||
- Name: global_symbol
|
Section: .data
|
||||||
Type: STT_OBJECT
|
Weak:
|
||||||
Section: .data
|
- Name: weak_symbol
|
||||||
Weak:
|
Type: STT_OBJECT
|
||||||
- Name: weak_symbol
|
Section: .data
|
||||||
Type: STT_OBJECT
|
|
||||||
Section: .data
|
|
||||||
|
|
||||||
# CHECK: Symbol {
|
# CHECK: Symbol {
|
||||||
# CHECK: Name: (0)
|
# CHECK: Name: (0)
|
||||||
|
@ -16,16 +16,14 @@ Sections:
|
|||||||
# This YAML file is a valid relocatable object that,
|
# This YAML file is a valid relocatable object that,
|
||||||
# when linked and run on x86_64, will go into an
|
# when linked and run on x86_64, will go into an
|
||||||
# infloop.
|
# infloop.
|
||||||
- Name: .symtab
|
Symbols:
|
||||||
Type: SHT_SYMTAB
|
Global:
|
||||||
Symbols:
|
- Name: main
|
||||||
Global:
|
Type: STT_FUNC
|
||||||
- Name: main
|
Section: .text
|
||||||
Type: STT_FUNC
|
Value: 0x1
|
||||||
Section: .text
|
Size: 2
|
||||||
Value: 0x1
|
- Name: undefined_symbol
|
||||||
Size: 2
|
|
||||||
- Name: undefined_symbol
|
|
||||||
|
|
||||||
# CHECK: Symbols [
|
# CHECK: Symbols [
|
||||||
# CHECK-NEXT: Symbol {
|
# CHECK-NEXT: Symbol {
|
||||||
|
@ -216,8 +216,7 @@ static void handleSymtabSectionHeader(
|
|||||||
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
|
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
|
||||||
|
|
||||||
typedef typename object::ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
|
typedef typename object::ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
|
||||||
// TODO: Ensure that a manually specified `Link` field is diagnosed as an
|
SHeader.sh_type = ELF::SHT_SYMTAB;
|
||||||
// error for SHT_SYMTAB.
|
|
||||||
SHeader.sh_link = State.getDotStrTabSecNo();
|
SHeader.sh_link = State.getDotStrTabSecNo();
|
||||||
// One greater than symbol table index of the last local symbol.
|
// One greater than symbol table index of the last local symbol.
|
||||||
SHeader.sh_info = Symbols.Local.size() + 1;
|
SHeader.sh_info = Symbols.Local.size() + 1;
|
||||||
@ -272,11 +271,12 @@ static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
|
|||||||
// Immediately following the ELF header.
|
// Immediately following the ELF header.
|
||||||
Header.e_shoff = sizeof(Header);
|
Header.e_shoff = sizeof(Header);
|
||||||
const std::vector<ELFYAML::Section> &Sections = Doc.Sections;
|
const std::vector<ELFYAML::Section> &Sections = Doc.Sections;
|
||||||
// "+ 3" for
|
// "+ 4" for
|
||||||
// - SHT_NULL entry (placed first, i.e. 0'th entry)
|
// - SHT_NULL entry (placed first, i.e. 0'th entry)
|
||||||
|
// - symbol table (.symtab) (placed third to last)
|
||||||
// - string table (.strtab) (placed second to last)
|
// - string table (.strtab) (placed second to last)
|
||||||
// - section header string table. (placed last)
|
// - section header string table. (placed last)
|
||||||
Header.e_shnum = Sections.size() + 3;
|
Header.e_shnum = Sections.size() + 4;
|
||||||
// Place section header string table last.
|
// Place section header string table last.
|
||||||
Header.e_shstrndx = Header.e_shnum - 1;
|
Header.e_shstrndx = Header.e_shnum - 1;
|
||||||
const unsigned DotStrtabSecNo = Header.e_shnum - 2;
|
const unsigned DotStrtabSecNo = Header.e_shnum - 2;
|
||||||
@ -334,14 +334,16 @@ static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
|
|||||||
SHeader.sh_info = 0;
|
SHeader.sh_info = 0;
|
||||||
SHeader.sh_addralign = Sec.AddressAlign;
|
SHeader.sh_addralign = Sec.AddressAlign;
|
||||||
SHeader.sh_entsize = 0;
|
SHeader.sh_entsize = 0;
|
||||||
// XXX: Really ugly right now. Should not be writing to `CBA` above
|
|
||||||
// (and setting sh_offset and sh_size) when going through this branch
|
|
||||||
// here.
|
|
||||||
if (Sec.Type == ELFYAML::ELF_SHT(SHT_SYMTAB))
|
|
||||||
handleSymtabSectionHeader<ELFT>(Sec.Symbols, State, SHeader);
|
|
||||||
SHeaders.push_back(SHeader);
|
SHeaders.push_back(SHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// .symtab section.
|
||||||
|
Elf_Shdr SymtabSHeader;
|
||||||
|
zero(SymtabSHeader);
|
||||||
|
SymtabSHeader.sh_name = SHStrTab.addString(StringRef(".symtab"));
|
||||||
|
handleSymtabSectionHeader<ELFT>(Doc.Symbols, State, SymtabSHeader);
|
||||||
|
SHeaders.push_back(SymtabSHeader);
|
||||||
|
|
||||||
// .strtab string table header.
|
// .strtab string table header.
|
||||||
Elf_Shdr DotStrTabSHeader;
|
Elf_Shdr DotStrTabSHeader;
|
||||||
zero(DotStrTabSHeader);
|
zero(DotStrTabSHeader);
|
||||||
|
Loading…
Reference in New Issue
Block a user