Index: include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- include/llvm/ObjectYAML/ELFYAML.h +++ include/llvm/ObjectYAML/ELFYAML.h @@ -50,6 +50,7 @@ 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(uint32_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 @@ StringRef Name; ELF_STT Type; StringRef Section; + Optional Index; llvm::yaml::Hex64 Value; llvm::yaml::Hex64 Size; uint8_t Other; @@ -267,6 +269,10 @@ static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, ELFYAML::ELF_SHN &Value); +}; + template <> struct ScalarEnumerationTraits { static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); @@ -334,6 +340,7 @@ template <> struct MappingTraits { static void mapping(IO &IO, ELFYAML::Symbol &Symbol); + static StringRef validate(IO &IO, ELFYAML::Symbol &Symbol); }; template <> Index: lib/ObjectYAML/ELFYAML.cpp =================================================================== --- lib/ObjectYAML/ELFYAML.cpp +++ lib/ObjectYAML/ELFYAML.cpp @@ -477,6 +477,28 @@ #undef BCase } +void ScalarEnumerationTraits::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(Value); +} + void ScalarEnumerationTraits::enumeration( IO &IO, ELFYAML::ELF_STT &Value) { #define ECase(X) IO.enumCase(Value, #X, ELF::X) @@ -701,6 +723,7 @@ 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 @@ IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0)); } +StringRef MappingTraits::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 < ELFYAML::ELF_SHN(ELF::SHN_LORESERVE)) { + return "Use a section name to define which section a symbol is defined in"; + } + return StringRef(); +} + void MappingTraits::mapping( IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) { IO.mapOptional("Local", Symbols.Local); Index: test/tools/yaml2obj/symbol-index-invalid.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/symbol-index-invalid.yaml @@ -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 Index: test/tools/yaml2obj/symbol-index.yaml =================================================================== --- /dev/null +++ test/tools/yaml2obj/symbol-index.yaml @@ -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:] Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -409,7 +409,10 @@ 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;