diff --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h --- a/llvm/include/llvm/BinaryFormat/COFF.h +++ b/llvm/include/llvm/BinaryFormat/COFF.h @@ -98,6 +98,7 @@ IMAGE_FILE_MACHINE_ARM = 0x1C0, IMAGE_FILE_MACHINE_ARMNT = 0x1C4, IMAGE_FILE_MACHINE_ARM64 = 0xAA64, + IMAGE_FILE_MACHINE_ARM64EC = 0xA641, IMAGE_FILE_MACHINE_EBC = 0xEBC, IMAGE_FILE_MACHINE_I386 = 0x14C, IMAGE_FILE_MACHINE_IA64 = 0x200, diff --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp --- a/llvm/lib/BinaryFormat/Magic.cpp +++ b/llvm/lib/BinaryFormat/Magic.cpp @@ -238,6 +238,11 @@ return file_magic::dxcontainer_object; break; + case 0x41: // ARM64EC windows + if (Magic[1] == char(0xA6)) + return file_magic::coff_object; + break; + default: break; } diff --git a/llvm/lib/Object/COFFImportFile.cpp b/llvm/lib/Object/COFFImportFile.cpp --- a/llvm/lib/Object/COFFImportFile.cpp +++ b/llvm/lib/Object/COFFImportFile.cpp @@ -38,6 +38,7 @@ default: llvm_unreachable("unsupported machine"); case IMAGE_FILE_MACHINE_ARM64: + case IMAGE_FILE_MACHINE_ARM64EC: case IMAGE_FILE_MACHINE_AMD64: return false; case IMAGE_FILE_MACHINE_ARMNT: @@ -55,6 +56,7 @@ case IMAGE_FILE_MACHINE_ARMNT: return IMAGE_REL_ARM_ADDR32NB; case IMAGE_FILE_MACHINE_ARM64: + case IMAGE_FILE_MACHINE_ARM64EC: return IMAGE_REL_ARM64_ADDR32NB; case IMAGE_FILE_MACHINE_I386: return IMAGE_REL_I386_DIR32NB; diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -1014,6 +1014,8 @@ return "COFF-ARM"; case COFF::IMAGE_FILE_MACHINE_ARM64: return "COFF-ARM64"; + case COFF::IMAGE_FILE_MACHINE_ARM64EC: + return "COFF-ARM64EC"; default: return "COFF-"; } @@ -1028,6 +1030,7 @@ case COFF::IMAGE_FILE_MACHINE_ARMNT: return Triple::thumb; case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: return Triple::aarch64; default: return Triple::UnknownArch; @@ -1314,6 +1317,7 @@ } break; case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: switch (Type) { LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ABSOLUTE); LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR32); @@ -1896,6 +1900,7 @@ RVAReloc = COFF::IMAGE_REL_ARM_ADDR32NB; break; case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: RVAReloc = COFF::IMAGE_REL_ARM64_ADDR32NB; break; default: diff --git a/llvm/lib/Object/WindowsMachineFlag.cpp b/llvm/lib/Object/WindowsMachineFlag.cpp --- a/llvm/lib/Object/WindowsMachineFlag.cpp +++ b/llvm/lib/Object/WindowsMachineFlag.cpp @@ -25,6 +25,7 @@ .Cases("x86", "i386", COFF::IMAGE_FILE_MACHINE_I386) .Case("arm", COFF::IMAGE_FILE_MACHINE_ARMNT) .Case("arm64", COFF::IMAGE_FILE_MACHINE_ARM64) + .Case("arm64ec", COFF::IMAGE_FILE_MACHINE_ARM64EC) .Default(COFF::IMAGE_FILE_MACHINE_UNKNOWN); } @@ -34,6 +35,8 @@ return "arm"; case COFF::IMAGE_FILE_MACHINE_ARM64: return "arm64"; + case COFF::IMAGE_FILE_MACHINE_ARM64EC: + return "arm64ec"; case COFF::IMAGE_FILE_MACHINE_AMD64: return "x64"; case COFF::IMAGE_FILE_MACHINE_I386: diff --git a/llvm/lib/Object/WindowsResource.cpp b/llvm/lib/Object/WindowsResource.cpp --- a/llvm/lib/Object/WindowsResource.cpp +++ b/llvm/lib/Object/WindowsResource.cpp @@ -989,6 +989,7 @@ Reloc->Type = COFF::IMAGE_REL_I386_DIR32NB; break; case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: Reloc->Type = COFF::IMAGE_REL_ARM64_ADDR32NB; break; default: diff --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/lib/ObjectYAML/COFFEmitter.cpp --- a/llvm/lib/ObjectYAML/COFFEmitter.cpp +++ b/llvm/lib/ObjectYAML/COFFEmitter.cpp @@ -49,7 +49,8 @@ bool isPE() const { return Obj.OptionalHeader.has_value(); } bool is64Bit() const { return Obj.Header.Machine == COFF::IMAGE_FILE_MACHINE_AMD64 || - Obj.Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64; + Obj.Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 || + Obj.Header.Machine == COFF::IMAGE_FILE_MACHINE_ARM64EC; } uint32_t getFileAlignment() const { diff --git a/llvm/lib/ObjectYAML/COFFYAML.cpp b/llvm/lib/ObjectYAML/COFFYAML.cpp --- a/llvm/lib/ObjectYAML/COFFYAML.cpp +++ b/llvm/lib/ObjectYAML/COFFYAML.cpp @@ -65,6 +65,7 @@ ECase(IMAGE_FILE_MACHINE_ARM); ECase(IMAGE_FILE_MACHINE_ARMNT); ECase(IMAGE_FILE_MACHINE_ARM64); + ECase(IMAGE_FILE_MACHINE_ARM64EC); ECase(IMAGE_FILE_MACHINE_EBC); ECase(IMAGE_FILE_MACHINE_I386); ECase(IMAGE_FILE_MACHINE_IA64); @@ -429,7 +430,8 @@ MappingNormalization, uint16_t> NT( IO, Rel.Type); IO.mapRequired("Type", NT->Type); - } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_ARM64) { + } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 || + H.Machine == COFF::IMAGE_FILE_MACHINE_ARM64EC) { MappingNormalization, uint16_t> NT( IO, Rel.Type); IO.mapRequired("Type", NT->Type); diff --git a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp --- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp +++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp @@ -165,6 +165,7 @@ CpuType = CPUType::ARMNT; break; case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: CpuType = CPUType::ARM64; break; } diff --git a/llvm/test/tools/llvm-readobj/COFF/arm64ec.yaml b/llvm/test/tools/llvm-readobj/COFF/arm64ec.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/arm64ec.yaml @@ -0,0 +1,27 @@ +# RUN: yaml2obj < %s | llvm-readobj - --file-headers | FileCheck %s +# Check we can process a simple arm64ec file. +# CHECK: Format: COFF-ARM64EC +# CHECK: Machine: IMAGE_FILE_MACHINE_ARM64EC (0xA641) +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_ARM64EC + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '' +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 0 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 1 +... diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -343,6 +343,7 @@ LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM64EC ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMNT ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ), LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ), @@ -1670,9 +1671,10 @@ break; } case COFF::IMAGE_FILE_MACHINE_ARM64: + case COFF::IMAGE_FILE_MACHINE_ARM64EC: case COFF::IMAGE_FILE_MACHINE_ARMNT: { - ARM::WinEH::Decoder Decoder(W, Obj->getMachine() == - COFF::IMAGE_FILE_MACHINE_ARM64); + ARM::WinEH::Decoder Decoder(W, Obj->getMachine() != + COFF::IMAGE_FILE_MACHINE_ARMNT); // TODO Propagate the error. consumeError(Decoder.dumpProcedureData(*Obj)); break;