mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
[yaml2obj][ELF] Don't explicitly set Binding
with STB_*
Instead, just have 3 sub-lists, one for each of {STB_LOCAL,STB_GLOBAL,STB_WEAK}. This allows us to be a lot more explicit w.r.t. the symbol ordering in the object file, because if we allowed explicitly setting the STB_* `Binding` key for the symbol, then we might have ended up having to shuffle STB_LOCAL symbols to the front of the list, which is likely to cause confusion and potential for error. Also, this new approach is simpler ;) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@184506 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2b7cdf09a1
commit
4235ba32f2
@ -40,7 +40,6 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
|
||||
// Just use 64, since it can hold 32-bit values too.
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
|
||||
|
||||
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
|
||||
@ -55,12 +54,16 @@ struct FileHeader {
|
||||
};
|
||||
struct Symbol {
|
||||
StringRef Name;
|
||||
ELF_STB Binding;
|
||||
ELF_STT Type;
|
||||
StringRef Section;
|
||||
llvm::yaml::Hex64 Value;
|
||||
llvm::yaml::Hex64 Size;
|
||||
};
|
||||
struct LocalGlobalWeakSymbols {
|
||||
std::vector<Symbol> Local;
|
||||
std::vector<Symbol> Global;
|
||||
std::vector<Symbol> Weak;
|
||||
};
|
||||
struct Section {
|
||||
StringRef Name;
|
||||
ELF_SHT Type;
|
||||
@ -70,7 +73,7 @@ struct Section {
|
||||
StringRef Link;
|
||||
llvm::yaml::Hex64 AddressAlign;
|
||||
// For SHT_SYMTAB; should be empty otherwise.
|
||||
std::vector<Symbol> Symbols;
|
||||
LocalGlobalWeakSymbols Symbols;
|
||||
};
|
||||
struct Object {
|
||||
FileHeader Header;
|
||||
@ -121,11 +124,6 @@ struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
|
||||
static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<ELFYAML::ELF_STB> {
|
||||
static void enumeration(IO &IO, ELFYAML::ELF_STB &Value);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
|
||||
static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
|
||||
@ -141,6 +139,11 @@ struct MappingTraits<ELFYAML::Symbol> {
|
||||
static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
|
||||
static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MappingTraits<ELFYAML::Section> {
|
||||
static void mapping(IO &IO, ELFYAML::Section &Section);
|
||||
|
@ -278,15 +278,6 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
|
||||
#undef BCase
|
||||
}
|
||||
|
||||
void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
|
||||
IO &IO, ELFYAML::ELF_STB &Value) {
|
||||
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
|
||||
ECase(STB_LOCAL)
|
||||
ECase(STB_GLOBAL)
|
||||
ECase(STB_WEAK)
|
||||
#undef ECase
|
||||
}
|
||||
|
||||
void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
|
||||
IO &IO, ELFYAML::ELF_STT &Value) {
|
||||
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
|
||||
@ -313,13 +304,19 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
|
||||
|
||||
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
|
||||
IO.mapOptional("Name", Symbol.Name, StringRef());
|
||||
IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
|
||||
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
|
||||
IO.mapOptional("Section", Symbol.Section, StringRef());
|
||||
IO.mapOptional("Value", Symbol.Value, Hex64(0));
|
||||
IO.mapOptional("Size", Symbol.Size, Hex64(0));
|
||||
}
|
||||
|
||||
void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
|
||||
IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
|
||||
IO.mapOptional("Local", Symbols.Local);
|
||||
IO.mapOptional("Global", Symbols.Global);
|
||||
IO.mapOptional("Weak", Symbols.Weak);
|
||||
}
|
||||
|
||||
void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
|
||||
ELFYAML::Section &Section) {
|
||||
IO.mapOptional("Name", Section.Name, StringRef());
|
||||
|
39
test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml
Normal file
39
test/Object/yaml2obj-elf-symbol-LocalGlobalWeak.yaml
Normal file
@ -0,0 +1,39 @@
|
||||
# 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: .data
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_WRITE ]
|
||||
Content: "DEADBEEF"
|
||||
- Name: .symtab
|
||||
Type: SHT_SYMTAB
|
||||
Symbols:
|
||||
Local:
|
||||
- Name: local_symbol
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
Global:
|
||||
- Name: global_symbol
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
Weak:
|
||||
- Name: weak_symbol
|
||||
Type: STT_OBJECT
|
||||
Section: .data
|
||||
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: (0)
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: local_symbol
|
||||
# CHECK: Binding: Local
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: global_symbol
|
||||
# CHECK: Binding: Global
|
||||
# CHECK: Symbol {
|
||||
# CHECK: Name: weak_symbol
|
||||
# CHECK: Binding: Weak
|
@ -20,12 +20,12 @@ Sections:
|
||||
- Name: .symtab
|
||||
Type: SHT_SYMTAB
|
||||
Symbols:
|
||||
- Name: main
|
||||
Binding: STB_GLOBAL
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x1
|
||||
Size: 2
|
||||
Global:
|
||||
- Name: main
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x1
|
||||
Size: 2
|
||||
|
||||
# CHECK: Symbols [
|
||||
# CHECK-NEXT: Symbol {
|
||||
|
@ -168,37 +168,21 @@ public:
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
// FIXME: This function is hideous. The hideous ELF type names are hideous.
|
||||
// Factor the ELF output into a class (templated on ELFT) and share some
|
||||
// typedefs.
|
||||
template <class ELFT>
|
||||
static void handleSymtabSectionHeader(
|
||||
const ELFYAML::Section &Sec, ELFState<ELFT> &State,
|
||||
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
|
||||
|
||||
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 = State.getDotStrTabSecNo();
|
||||
// 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;
|
||||
{
|
||||
// Ensure STN_UNDEF is present
|
||||
Elf_Sym Sym;
|
||||
zero(Sym);
|
||||
Syms.push_back(Sym);
|
||||
}
|
||||
for (unsigned i = 0, e = Sec.Symbols.size(); i != e; ++i) {
|
||||
const ELFYAML::Symbol &Sym = Sec.Symbols[i];
|
||||
// FIXME: At this point it is fairly clear that we need to refactor these
|
||||
// static functions into methods of a class sharing some typedefs. These
|
||||
// ELF type names are insane.
|
||||
template <class ELFT,
|
||||
class Elf_Sym = typename object::ELFObjectFile<ELFT>::Elf_Sym>
|
||||
static void addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
|
||||
ELFState<ELFT> &State, std::vector<Elf_Sym> &Syms,
|
||||
unsigned SymbolBinding) {
|
||||
for (unsigned i = 0, e = Symbols.size(); i != e; ++i) {
|
||||
const ELFYAML::Symbol &Sym = Symbols[i];
|
||||
Elf_Sym Symbol;
|
||||
zero(Symbol);
|
||||
if (!Sym.Name.empty())
|
||||
Symbol.st_name = State.getStringTable().addString(Sym.Name);
|
||||
Symbol.setBindingAndType(Sym.Binding, Sym.Type);
|
||||
Symbol.setBindingAndType(SymbolBinding, Sym.Type);
|
||||
unsigned Index;
|
||||
if (State.getSN2I().lookupSection(Sym.Section, Index)) {
|
||||
errs() << "error: Unknown section referenced: '" << Sym.Section
|
||||
@ -210,6 +194,31 @@ static void handleSymtabSectionHeader(
|
||||
Symbol.st_size = Sym.Size;
|
||||
Syms.push_back(Symbol);
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
static void handleSymtabSectionHeader(
|
||||
const ELFYAML::Section &Sec, ELFState<ELFT> &State,
|
||||
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
|
||||
|
||||
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 = State.getDotStrTabSecNo();
|
||||
// One greater than symbol table index of the last local symbol.
|
||||
SHeader.sh_info = Sec.Symbols.Local.size() + 1;
|
||||
SHeader.sh_entsize = sizeof(Elf_Sym);
|
||||
|
||||
std::vector<Elf_Sym> Syms;
|
||||
{
|
||||
// Ensure STN_UNDEF is present
|
||||
Elf_Sym Sym;
|
||||
zero(Sym);
|
||||
Syms.push_back(Sym);
|
||||
}
|
||||
addSymbols(Sec.Symbols.Local, State, Syms, ELF::STB_LOCAL);
|
||||
addSymbols(Sec.Symbols.Global, State, Syms, ELF::STB_GLOBAL);
|
||||
addSymbols(Sec.Symbols.Weak, State, Syms, ELF::STB_WEAK);
|
||||
|
||||
ContiguousBlobAccumulator &CBA = State.getSectionContentAccum();
|
||||
SHeader.sh_offset = CBA.currentOffset();
|
||||
|
Loading…
Reference in New Issue
Block a user