diff --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h --- a/llvm/include/llvm/ObjectYAML/ELFYAML.h +++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -550,8 +550,9 @@ }; template <> -struct ScalarEnumerationTraits { - static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value); +struct ScalarEnumerationContextTraits { + static void enumeration(IO &IO, ELFYAML::ELF_ELFCLASS &Value, + ELFYAML::Object &Ctx); }; template <> diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -247,9 +247,24 @@ io.enumFallback(Value); } -void ScalarEnumerationTraits::enumeration( - IO &IO, ELFYAML::ELF_ELFCLASS &Value) { -#define ECase(X) IO.enumCase(Value, #X, ELF::X) +void ScalarEnumerationContextTraits:: + enumeration(IO &io, ELFYAML::ELF_ELFCLASS &Value, ELFYAML::Object &Ctx) { + Optional OverriddenStr; + auto It = Ctx.Overridden.find("EI_CLASS"); + if (It != Ctx.Overridden.end() && !io.outputting()) { + OverriddenStr = It->second; + Ctx.SeenOverridden.insert("EI_CLASS"); + } + +#define ECase(X) \ + if (!OverriddenStr) \ + io.enumCase(Value, #X, ELF::X); \ + else if (*OverriddenStr == #X) { \ + Value = ELF::X; \ + io.matchEnumFallback(); \ + return; \ + } + // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it // here. ECase(ELFCLASS32); @@ -850,7 +865,7 @@ void MappingTraits::mapping(IO &IO, ELFYAML::FileHeader &FileHdr) { auto &Ctx = *static_cast(IO.getContext()); - IO.mapRequired("Class", FileHdr.Class); + IO.mapRequired("Class", FileHdr.Class, Ctx); IO.mapRequired("Data", FileHdr.Data); IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0)); IO.mapOptional("ABIVersion", FileHdr.ABIVersion, Hex8(0)); diff --git a/llvm/test/tools/yaml2obj/ELF/class-endianness.yaml b/llvm/test/tools/yaml2obj/ELF/class-endianness.yaml --- a/llvm/test/tools/yaml2obj/ELF/class-endianness.yaml +++ b/llvm/test/tools/yaml2obj/ELF/class-endianness.yaml @@ -1,9 +1,9 @@ ## Check we can produce 32/64 bits outputs with a different endianness. # RUN: yaml2obj %s --docnum=1 | llvm-readobj --file-headers - | FileCheck %s --check-prefix LE64 -# RUN: yaml2obj %s --docnum=2 | llvm-readobj --file-headers - | FileCheck %s --check-prefix BE64 -# RUN: yaml2obj %s --docnum=3 | llvm-readobj --file-headers - | FileCheck %s --check-prefix LE32 -# RUN: yaml2obj %s --docnum=4 | llvm-readobj --file-headers - | FileCheck %s --check-prefix BE32 +# RUN: yaml2obj %s --docnum=2 -D EI_CLASS=ELFCLASS64 | llvm-readobj --file-headers - | FileCheck %s --check-prefix BE64 +# RUN: yaml2obj %s --docnum=1 -D EI_CLASS=ELFCLASS32 | llvm-readobj --file-headers - | FileCheck %s --check-prefix LE32 +# RUN: yaml2obj %s --docnum=2 | llvm-readobj --file-headers - | FileCheck %s --check-prefix BE32 # LE64: Class: 64-bit (0x2) # LE64-NEXT: DataEncoding: LittleEndian (0x1) @@ -17,6 +17,10 @@ # BE32: Class: 32-bit (0x1) # BE32-NEXT: DataEncoding: BigEndian (0x2) +# RUN: not yaml2obj --docnum=1 -D EI_CLASS=invalid %s 2>&1 | FileCheck --check-prefix=BAD %s + +# BAD: error: unknown enumerated scalar + --- !ELF FileHeader: !FileHeader Class: ELFCLASS64 @@ -24,20 +28,6 @@ Type: ET_EXEC Machine: EM_X86_64 ---- !ELF -FileHeader: !FileHeader - Class: ELFCLASS64 - Data: ELFDATA2MSB - Type: ET_EXEC - Machine: EM_PPC64 - ---- !ELF -FileHeader: !FileHeader - Class: ELFCLASS32 - Data: ELFDATA2LSB - Type: ET_EXEC - Machine: EM_386 - --- !ELF FileHeader: !FileHeader Class: ELFCLASS32 diff --git a/llvm/test/tools/yaml2obj/ELF/reloc-sec-entry-size.yaml b/llvm/test/tools/yaml2obj/ELF/reloc-sec-entry-size.yaml --- a/llvm/test/tools/yaml2obj/ELF/reloc-sec-entry-size.yaml +++ b/llvm/test/tools/yaml2obj/ELF/reloc-sec-entry-size.yaml @@ -1,9 +1,9 @@ ## Test how yaml2obj sets values for sh_entsize fields of relocation sections. -# RUN: yaml2obj --docnum=1 %s -o %t64 +# RUN: yaml2obj %s -o %t64 # RUN: llvm-readelf --sections %t64 | FileCheck %s --check-prefix=ELF64 -# RUN: yaml2obj --docnum=2 %s -o %t32 +# RUN: yaml2obj -D EI_CLASS=ELFCLASS32 %s -o %t32 # RUN: llvm-readelf --sections %t32 | FileCheck %s --check-prefix=ELF32 # ELF64: Name Type Address Off Size ES @@ -46,28 +46,3 @@ - Name: .relr.custom Type: SHT_RELR EntSize: 0xFF - ---- !ELF -FileHeader: - Class: ELFCLASS32 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_386 -Sections: -## Check default sh_entsizes field values. - - Name: .rela.default - Type: SHT_RELA - - Name: .rel.default - Type: SHT_REL - - Name: .relr.default - Type: SHT_RELR -## Check we can set sh_entsize fields to arbitrary values. - - Name: .rela.custom - Type: SHT_RELA - EntSize: 0xFF - - Name: .rel.custom - Type: SHT_REL - EntSize: 0xFF - - Name: .relr.custom - Type: SHT_RELR - EntSize: 0xFF