mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +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)
|
LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT)
|
||||||
// Just use 64, since it can hold 32-bit values too.
|
// Just use 64, since it can hold 32-bit values too.
|
||||||
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
|
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
|
||||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STB)
|
|
||||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
|
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
|
||||||
|
|
||||||
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
|
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
|
||||||
@ -55,12 +54,16 @@ struct FileHeader {
|
|||||||
};
|
};
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
ELF_STB Binding;
|
|
||||||
ELF_STT Type;
|
ELF_STT Type;
|
||||||
StringRef Section;
|
StringRef Section;
|
||||||
llvm::yaml::Hex64 Value;
|
llvm::yaml::Hex64 Value;
|
||||||
llvm::yaml::Hex64 Size;
|
llvm::yaml::Hex64 Size;
|
||||||
};
|
};
|
||||||
|
struct LocalGlobalWeakSymbols {
|
||||||
|
std::vector<Symbol> Local;
|
||||||
|
std::vector<Symbol> Global;
|
||||||
|
std::vector<Symbol> Weak;
|
||||||
|
};
|
||||||
struct Section {
|
struct Section {
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
ELF_SHT Type;
|
ELF_SHT Type;
|
||||||
@ -70,7 +73,7 @@ struct Section {
|
|||||||
StringRef Link;
|
StringRef Link;
|
||||||
llvm::yaml::Hex64 AddressAlign;
|
llvm::yaml::Hex64 AddressAlign;
|
||||||
// For SHT_SYMTAB; should be empty otherwise.
|
// For SHT_SYMTAB; should be empty otherwise.
|
||||||
std::vector<Symbol> Symbols;
|
LocalGlobalWeakSymbols Symbols;
|
||||||
};
|
};
|
||||||
struct Object {
|
struct Object {
|
||||||
FileHeader Header;
|
FileHeader Header;
|
||||||
@ -121,11 +124,6 @@ struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
|
|||||||
static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
|
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 <>
|
template <>
|
||||||
struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
|
struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
|
||||||
static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
|
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);
|
static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> {
|
||||||
|
static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols);
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct MappingTraits<ELFYAML::Section> {
|
struct MappingTraits<ELFYAML::Section> {
|
||||||
static void mapping(IO &IO, ELFYAML::Section &Section);
|
static void mapping(IO &IO, ELFYAML::Section &Section);
|
||||||
|
@ -278,15 +278,6 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
|
|||||||
#undef BCase
|
#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(
|
void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
|
||||||
IO &IO, ELFYAML::ELF_STT &Value) {
|
IO &IO, ELFYAML::ELF_STT &Value) {
|
||||||
#define ECase(X) IO.enumCase(Value, #X, ELF::X);
|
#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) {
|
void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
|
||||||
IO.mapOptional("Name", Symbol.Name, StringRef());
|
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("Type", Symbol.Type, ELFYAML::ELF_STT(0));
|
||||||
IO.mapOptional("Section", Symbol.Section, StringRef());
|
IO.mapOptional("Section", Symbol.Section, StringRef());
|
||||||
IO.mapOptional("Value", Symbol.Value, Hex64(0));
|
IO.mapOptional("Value", Symbol.Value, Hex64(0));
|
||||||
IO.mapOptional("Size", Symbol.Size, 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,
|
void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
|
||||||
ELFYAML::Section &Section) {
|
ELFYAML::Section &Section) {
|
||||||
IO.mapOptional("Name", Section.Name, StringRef());
|
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,8 +20,8 @@ Sections:
|
|||||||
- Name: .symtab
|
- Name: .symtab
|
||||||
Type: SHT_SYMTAB
|
Type: SHT_SYMTAB
|
||||||
Symbols:
|
Symbols:
|
||||||
|
Global:
|
||||||
- Name: main
|
- Name: main
|
||||||
Binding: STB_GLOBAL
|
|
||||||
Type: STT_FUNC
|
Type: STT_FUNC
|
||||||
Section: .text
|
Section: .text
|
||||||
Value: 0x1
|
Value: 0x1
|
||||||
|
@ -168,37 +168,21 @@ public:
|
|||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
// FIXME: This function is hideous. The hideous ELF type names are hideous.
|
// FIXME: At this point it is fairly clear that we need to refactor these
|
||||||
// Factor the ELF output into a class (templated on ELFT) and share some
|
// static functions into methods of a class sharing some typedefs. These
|
||||||
// typedefs.
|
// ELF type names are insane.
|
||||||
template <class ELFT>
|
template <class ELFT,
|
||||||
static void handleSymtabSectionHeader(
|
class Elf_Sym = typename object::ELFObjectFile<ELFT>::Elf_Sym>
|
||||||
const ELFYAML::Section &Sec, ELFState<ELFT> &State,
|
static void addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
|
||||||
typename object::ELFObjectFile<ELFT>::Elf_Shdr &SHeader) {
|
ELFState<ELFT> &State, std::vector<Elf_Sym> &Syms,
|
||||||
|
unsigned SymbolBinding) {
|
||||||
typedef typename object::ELFObjectFile<ELFT>::Elf_Sym Elf_Sym;
|
for (unsigned i = 0, e = Symbols.size(); i != e; ++i) {
|
||||||
// TODO: Ensure that a manually specified `Link` field is diagnosed as an
|
const ELFYAML::Symbol &Sym = Symbols[i];
|
||||||
// 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];
|
|
||||||
Elf_Sym Symbol;
|
Elf_Sym Symbol;
|
||||||
zero(Symbol);
|
zero(Symbol);
|
||||||
if (!Sym.Name.empty())
|
if (!Sym.Name.empty())
|
||||||
Symbol.st_name = State.getStringTable().addString(Sym.Name);
|
Symbol.st_name = State.getStringTable().addString(Sym.Name);
|
||||||
Symbol.setBindingAndType(Sym.Binding, Sym.Type);
|
Symbol.setBindingAndType(SymbolBinding, Sym.Type);
|
||||||
unsigned Index;
|
unsigned Index;
|
||||||
if (State.getSN2I().lookupSection(Sym.Section, Index)) {
|
if (State.getSN2I().lookupSection(Sym.Section, Index)) {
|
||||||
errs() << "error: Unknown section referenced: '" << Sym.Section
|
errs() << "error: Unknown section referenced: '" << Sym.Section
|
||||||
@ -210,6 +194,31 @@ static void handleSymtabSectionHeader(
|
|||||||
Symbol.st_size = Sym.Size;
|
Symbol.st_size = Sym.Size;
|
||||||
Syms.push_back(Symbol);
|
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();
|
ContiguousBlobAccumulator &CBA = State.getSectionContentAccum();
|
||||||
SHeader.sh_offset = CBA.currentOffset();
|
SHeader.sh_offset = CBA.currentOffset();
|
||||||
|
Loading…
Reference in New Issue
Block a user