mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[yaml2obj][ELF] Add support for symbol indexes greater than SHN_LORESERVE
Right now Symbols must be either undefined or defined in a specific section. Some symbols have section indexes like SHN_ABS however. This change adds support for outputting symbols that have such section indexes. Patch by Jake Ehrlich Differential Revision: https://reviews.llvm.org/D37391 llvm-svn: 312745
This commit is contained in:
parent
8cd9088e66
commit
39b8dda8b4
@ -50,6 +50,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_REL)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_RSS)
|
||||
// Just use 64, since it can hold 32-bit values too.
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_SHN)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STV)
|
||||
LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STO)
|
||||
@ -89,6 +90,7 @@ struct Symbol {
|
||||
StringRef Name;
|
||||
ELF_STT Type;
|
||||
StringRef Section;
|
||||
Optional<ELF_SHN> Index;
|
||||
llvm::yaml::Hex64 Value;
|
||||
llvm::yaml::Hex64 Size;
|
||||
uint8_t Other;
|
||||
@ -267,6 +269,10 @@ struct ScalarBitSetTraits<ELFYAML::ELF_SHF> {
|
||||
static void bitset(IO &IO, ELFYAML::ELF_SHF &Value);
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<ELFYAML::ELF_SHN> {
|
||||
static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ScalarEnumerationTraits<ELFYAML::ELF_STT> {
|
||||
static void enumeration(IO &IO, ELFYAML::ELF_STT &Value);
|
||||
@ -334,6 +340,7 @@ template <> struct MappingTraits<ELFYAML::ProgramHeader> {
|
||||
template <>
|
||||
struct MappingTraits<ELFYAML::Symbol> {
|
||||
static void mapping(IO &IO, ELFYAML::Symbol &Symbol);
|
||||
static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol);
|
||||
};
|
||||
|
||||
template <>
|
||||
|
@ -477,6 +477,28 @@ void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
|
||||
#undef BCase
|
||||
}
|
||||
|
||||
void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
|
||||
IO &IO, ELFYAML::ELF_SHN &Value) {
|
||||
#define ECase(X) IO.enumCase(Value, #X, ELF::X)
|
||||
ECase(SHN_UNDEF);
|
||||
ECase(SHN_LORESERVE);
|
||||
ECase(SHN_LOPROC);
|
||||
ECase(SHN_HIPROC);
|
||||
ECase(SHN_LOOS);
|
||||
ECase(SHN_HIOS);
|
||||
ECase(SHN_ABS);
|
||||
ECase(SHN_COMMON);
|
||||
ECase(SHN_XINDEX);
|
||||
ECase(SHN_HIRESERVE);
|
||||
ECase(SHN_HEXAGON_SCOMMON);
|
||||
ECase(SHN_HEXAGON_SCOMMON_1);
|
||||
ECase(SHN_HEXAGON_SCOMMON_2);
|
||||
ECase(SHN_HEXAGON_SCOMMON_4);
|
||||
ECase(SHN_HEXAGON_SCOMMON_8);
|
||||
#undef ECase
|
||||
IO.enumFallback<Hex32>(Value);
|
||||
}
|
||||
|
||||
void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
|
||||
IO &IO, ELFYAML::ELF_STT &Value) {
|
||||
#define ECase(X) IO.enumCase(Value, #X, ELF::X)
|
||||
@ -701,6 +723,7 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
|
||||
IO.mapOptional("Name", Symbol.Name, StringRef());
|
||||
IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
|
||||
IO.mapOptional("Section", Symbol.Section, StringRef());
|
||||
IO.mapOptional("Index", Symbol.Index);
|
||||
IO.mapOptional("Value", Symbol.Value, Hex64(0));
|
||||
IO.mapOptional("Size", Symbol.Size, Hex64(0));
|
||||
|
||||
@ -709,6 +732,20 @@ void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
|
||||
IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
|
||||
}
|
||||
|
||||
StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
|
||||
ELFYAML::Symbol &Symbol) {
|
||||
if (Symbol.Index && Symbol.Section.data()) {
|
||||
return "Index and Section cannot both be specified for Symbol";
|
||||
}
|
||||
if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX)) {
|
||||
return "Large indexes are not supported";
|
||||
}
|
||||
if (Symbol.Index && *Symbol.Index < ELFYAML::ELF_SHN(ELF::SHN_LORESERVE)) {
|
||||
return "Use a section name to define which section a symbol is defined in";
|
||||
}
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
|
||||
IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
|
||||
IO.mapOptional("Local", Symbols.Local);
|
||||
|
21
test/tools/yaml2obj/symbol-index-invalid.yaml
Normal file
21
test/tools/yaml2obj/symbol-index-invalid.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
# This test insures that the user cannot have both an Index and a Section field.
|
||||
# RUN: not yaml2obj %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Sections:
|
||||
- Name: .text
|
||||
Type: SHT_PROGBITS
|
||||
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
|
||||
Address: 0x1000
|
||||
AddressAlign: 0x0000000000000010
|
||||
Content: "0000000000000000"
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: _start
|
||||
Section: .text
|
||||
Index: SHN_ABS
|
35
test/tools/yaml2obj/symbol-index.yaml
Normal file
35
test/tools/yaml2obj/symbol-index.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
# RUN: yaml2obj %s > %t
|
||||
# RUN: llvm-readobj -symbols %t | FileCheck %s
|
||||
|
||||
!ELF
|
||||
FileHeader:
|
||||
Class: ELFCLASS64
|
||||
Data: ELFDATA2LSB
|
||||
Type: ET_EXEC
|
||||
Machine: EM_X86_64
|
||||
Symbols:
|
||||
Global:
|
||||
- Name: test
|
||||
Index: SHN_ABS
|
||||
Value: 0x1234
|
||||
|
||||
#CHECK: Symbols [
|
||||
#CHECK-NEXT: Symbol {
|
||||
#CHECK-NEXT: Name: (0)
|
||||
#CHECK-NEXT: Value: 0x0
|
||||
#CHECK-NEXT: Size: 0
|
||||
#CHECK-NEXT: Binding: Local (0x0)
|
||||
#CHECK-NEXT: Type: None (0x0)
|
||||
#CHECK-NEXT: Other: 0
|
||||
#CHECK-NEXT: Section: Undefined (0x0)
|
||||
#CHECK-NEXT: }
|
||||
#CHECK-NEXT: Symbol {
|
||||
#CHECK-NEXT: Name: test (1)
|
||||
#CHECK-NEXT: Value: 0x1234
|
||||
#CHECK-NEXT: Size: 0
|
||||
#CHECK-NEXT: Binding: Global (0x1)
|
||||
#CHECK-NEXT: Type: None (0x0)
|
||||
#CHECK-NEXT: Other: 0
|
||||
#CHECK-NEXT: Section: Absolute (0xFFF1)
|
||||
#CHECK-NEXT: }
|
||||
#CHECK-NEXT:]
|
@ -409,7 +409,10 @@ void ELFState<ELFT>::addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
|
||||
exit(1);
|
||||
}
|
||||
Symbol.st_shndx = Index;
|
||||
} // else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
|
||||
} else if (Sym.Index) {
|
||||
Symbol.st_shndx = *Sym.Index;
|
||||
}
|
||||
// else Symbol.st_shndex == SHN_UNDEF (== 0), since it was zero'd earlier.
|
||||
Symbol.st_value = Sym.Value;
|
||||
Symbol.st_other = Sym.Other;
|
||||
Symbol.st_size = Sym.Size;
|
||||
|
Loading…
Reference in New Issue
Block a user