[llvm] cea5d28 - [llvm-lib] [llvm-readobj] [llvm-cvtres] Add Support for ARM64X object files.

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 21 05:46:31 PDT 2023


Author: Jacek Caban
Date: 2023-04-21T15:46:20+03:00
New Revision: cea5d2870f379e7f93ba9da01747a279e4225998

URL: https://github.com/llvm/llvm-project/commit/cea5d2870f379e7f93ba9da01747a279e4225998
DIFF: https://github.com/llvm/llvm-project/commit/cea5d2870f379e7f93ba9da01747a279e4225998.diff

LOG: [llvm-lib] [llvm-readobj] [llvm-cvtres] Add Support for ARM64X object files.

Similar to D125411, but for ARM64X.

ARM64X PE binaries are hybrids containing both ARM64EC and pure ARM64
variants in one file. They are usually linked by passing separate
ARM64EC and ARM64 object files to linker. Linked binaries use ARM64
machine and contain additional CHPE metadata in their load config.
CHPE metadata support is not part of this patch, I plan to send that later.

Using ARM64X as a machine type of object files themselves is somewhat
ambiguous, but such files are allowed by MSVC. It treats them as ARM64
or ARM64EC object, depending on the context. Such objects can be
produced with cvtres.exe -machine:arm64x.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D148517

Added: 
    llvm/test/tools/llvm-lib/Inputs/arm64x.yaml
    llvm/test/tools/llvm-readobj/COFF/arm64x.yaml

Modified: 
    llvm/include/llvm/BinaryFormat/COFF.h
    llvm/lib/BinaryFormat/Magic.cpp
    llvm/lib/Object/COFFImportFile.cpp
    llvm/lib/Object/COFFObjectFile.cpp
    llvm/lib/Object/WindowsMachineFlag.cpp
    llvm/lib/Object/WindowsResource.cpp
    llvm/lib/ObjectYAML/COFFEmitter.cpp
    llvm/lib/ObjectYAML/COFFYAML.cpp
    llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
    llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
    llvm/test/tools/llvm-cvtres/machine.test
    llvm/test/tools/llvm-lib/machine-mismatch.test
    llvm/tools/llvm-readobj/COFFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/COFF.h b/llvm/include/llvm/BinaryFormat/COFF.h
index c9b1174c9eaa2..d2ec2a2f67e54 100644
--- a/llvm/include/llvm/BinaryFormat/COFF.h
+++ b/llvm/include/llvm/BinaryFormat/COFF.h
@@ -99,6 +99,7 @@ enum MachineTypes : unsigned {
   IMAGE_FILE_MACHINE_ARMNT = 0x1C4,
   IMAGE_FILE_MACHINE_ARM64 = 0xAA64,
   IMAGE_FILE_MACHINE_ARM64EC = 0xA641,
+  IMAGE_FILE_MACHINE_ARM64X = 0xA64E,
   IMAGE_FILE_MACHINE_EBC = 0xEBC,
   IMAGE_FILE_MACHINE_I386 = 0x14C,
   IMAGE_FILE_MACHINE_IA64 = 0x200,
@@ -120,6 +121,15 @@ enum MachineTypes : unsigned {
   IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169
 };
 
+template <typename T> bool isArm64EC(T Machine) {
+  return Machine == IMAGE_FILE_MACHINE_ARM64EC ||
+         Machine == IMAGE_FILE_MACHINE_ARM64X;
+}
+
+template <typename T> bool isAnyArm64(T Machine) {
+  return Machine == IMAGE_FILE_MACHINE_ARM64 || isArm64EC(Machine);
+}
+
 enum Characteristics : unsigned {
   C_Invalid = 0,
 

diff  --git a/llvm/lib/BinaryFormat/Magic.cpp b/llvm/lib/BinaryFormat/Magic.cpp
index aa84bc36bfde9..025334f9f3f42 100644
--- a/llvm/lib/BinaryFormat/Magic.cpp
+++ b/llvm/lib/BinaryFormat/Magic.cpp
@@ -246,6 +246,11 @@ file_magic llvm::identify_magic(StringRef Magic) {
       return file_magic::coff_object;
     break;
 
+  case 0x4e: // ARM64X 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
index ce6d84d5c2347..765c12cc076c9 100644
--- a/llvm/lib/Object/COFFImportFile.cpp
+++ b/llvm/lib/Object/COFFImportFile.cpp
@@ -39,6 +39,7 @@ static bool is32bit(MachineTypes Machine) {
     llvm_unreachable("unsupported machine");
   case IMAGE_FILE_MACHINE_ARM64:
   case IMAGE_FILE_MACHINE_ARM64EC:
+  case IMAGE_FILE_MACHINE_ARM64X:
   case IMAGE_FILE_MACHINE_AMD64:
     return false;
   case IMAGE_FILE_MACHINE_ARMNT:
@@ -57,6 +58,7 @@ static uint16_t getImgRelRelocation(MachineTypes Machine) {
     return IMAGE_REL_ARM_ADDR32NB;
   case IMAGE_FILE_MACHINE_ARM64:
   case IMAGE_FILE_MACHINE_ARM64EC:
+  case IMAGE_FILE_MACHINE_ARM64X:
     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
index 726e25517bb51..1b7ab45ea8aac 100644
--- a/llvm/lib/Object/COFFObjectFile.cpp
+++ b/llvm/lib/Object/COFFObjectFile.cpp
@@ -1016,6 +1016,8 @@ StringRef COFFObjectFile::getFileFormatName() const {
     return "COFF-ARM64";
   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
     return "COFF-ARM64EC";
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
+    return "COFF-ARM64X";
   default:
     return "COFF-<unknown arch>";
   }
@@ -1031,6 +1033,7 @@ Triple::ArchType COFFObjectFile::getArch() const {
     return Triple::thumb;
   case COFF::IMAGE_FILE_MACHINE_ARM64:
   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
     return Triple::aarch64;
   default:
     return Triple::UnknownArch;
@@ -1318,6 +1321,7 @@ StringRef COFFObjectFile::getRelocationTypeName(uint16_t Type) const {
     break;
   case COFF::IMAGE_FILE_MACHINE_ARM64:
   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
     switch (Type) {
     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ABSOLUTE);
     LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM64_ADDR32);
@@ -1901,6 +1905,7 @@ ResourceSectionRef::getContents(const coff_resource_data_entry &Entry) {
       break;
     case COFF::IMAGE_FILE_MACHINE_ARM64:
     case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+    case COFF::IMAGE_FILE_MACHINE_ARM64X:
       RVAReloc = COFF::IMAGE_REL_ARM64_ADDR32NB;
       break;
     default:

diff  --git a/llvm/lib/Object/WindowsMachineFlag.cpp b/llvm/lib/Object/WindowsMachineFlag.cpp
index 8335ea745548a..b9f818775768a 100644
--- a/llvm/lib/Object/WindowsMachineFlag.cpp
+++ b/llvm/lib/Object/WindowsMachineFlag.cpp
@@ -27,6 +27,7 @@ COFF::MachineTypes llvm::getMachineType(StringRef S) {
       .Case("arm", COFF::IMAGE_FILE_MACHINE_ARMNT)
       .Case("arm64", COFF::IMAGE_FILE_MACHINE_ARM64)
       .Case("arm64ec", COFF::IMAGE_FILE_MACHINE_ARM64EC)
+      .Case("arm64x", COFF::IMAGE_FILE_MACHINE_ARM64X)
       .Default(COFF::IMAGE_FILE_MACHINE_UNKNOWN);
 }
 
@@ -38,6 +39,8 @@ StringRef llvm::machineToStr(COFF::MachineTypes MT) {
     return "arm64";
   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
     return "arm64ec";
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
+    return "arm64x";
   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
index 089a3fa0f91f5..0764dc8f75233 100644
--- a/llvm/lib/Object/WindowsResource.cpp
+++ b/llvm/lib/Object/WindowsResource.cpp
@@ -990,6 +990,7 @@ void WindowsResourceCOFFWriter::writeFirstSectionRelocations() {
       break;
     case COFF::IMAGE_FILE_MACHINE_ARM64:
     case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+    case COFF::IMAGE_FILE_MACHINE_ARM64X:
       Reloc->Type = COFF::IMAGE_REL_ARM64_ADDR32NB;
       break;
     default:

diff  --git a/llvm/lib/ObjectYAML/COFFEmitter.cpp b/llvm/lib/ObjectYAML/COFFEmitter.cpp
index a57da9b3287d4..f8a285d36f9c0 100644
--- a/llvm/lib/ObjectYAML/COFFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/COFFEmitter.cpp
@@ -50,8 +50,7 @@ struct COFFParser {
   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_ARM64EC;
+           COFF::isAnyArm64(Obj.Header.Machine);
   }
 
   uint32_t getFileAlignment() const {

diff  --git a/llvm/lib/ObjectYAML/COFFYAML.cpp b/llvm/lib/ObjectYAML/COFFYAML.cpp
index 2fa0433a24f86..fe9a9f8931381 100644
--- a/llvm/lib/ObjectYAML/COFFYAML.cpp
+++ b/llvm/lib/ObjectYAML/COFFYAML.cpp
@@ -66,6 +66,7 @@ void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
   ECase(IMAGE_FILE_MACHINE_ARMNT);
   ECase(IMAGE_FILE_MACHINE_ARM64);
   ECase(IMAGE_FILE_MACHINE_ARM64EC);
+  ECase(IMAGE_FILE_MACHINE_ARM64X);
   ECase(IMAGE_FILE_MACHINE_EBC);
   ECase(IMAGE_FILE_MACHINE_I386);
   ECase(IMAGE_FILE_MACHINE_IA64);
@@ -430,8 +431,7 @@ void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO,
     MappingNormalization<NType<COFF::RelocationTypesARM>, uint16_t> NT(
         IO, Rel.Type);
     IO.mapRequired("Type", NT->Type);
-  } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_ARM64 ||
-             H.Machine == COFF::IMAGE_FILE_MACHINE_ARM64EC) {
+  } else if (COFF::isAnyArm64(H.Machine)) {
     MappingNormalization<NType<COFF::RelocationTypesARM64>, 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
index 3f758fdc6879e..8d2028abfe9b4 100644
--- a/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
+++ b/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
@@ -167,6 +167,7 @@ void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
     break;
   case COFF::IMAGE_FILE_MACHINE_ARM64:
   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
     CpuType = CPUType::ARM64;
     break;
   }

diff  --git a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
index 9bde40d78fbd3..17bdb1236efd4 100644
--- a/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
+++ b/llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp
@@ -167,9 +167,7 @@ static Expected<COFF::MachineTypes> getCOFFFileMachine(MemoryBufferRef MB) {
   uint16_t Machine = (*Obj)->getMachine();
   if (Machine != COFF::IMAGE_FILE_MACHINE_I386 &&
       Machine != COFF::IMAGE_FILE_MACHINE_AMD64 &&
-      Machine != COFF::IMAGE_FILE_MACHINE_ARMNT &&
-      Machine != COFF::IMAGE_FILE_MACHINE_ARM64 &&
-      Machine != COFF::IMAGE_FILE_MACHINE_ARM64EC) {
+      Machine != COFF::IMAGE_FILE_MACHINE_ARMNT && !COFF::isAnyArm64(Machine)) {
     return createStringError(inconvertibleErrorCode(),
                              "unknown machine: " + std::to_string(Machine));
   }
@@ -205,9 +203,16 @@ static bool machineMatches(COFF::MachineTypes LibMachine,
     return true;
   // ARM64EC mode allows both pure ARM64, ARM64EC and X64 objects to be mixed in
   // the archive.
-  return LibMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC &&
-         (FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64 ||
-          FileMachine == COFF::IMAGE_FILE_MACHINE_AMD64);
+  switch (LibMachine) {
+  case COFF::IMAGE_FILE_MACHINE_ARM64:
+    return FileMachine == COFF::IMAGE_FILE_MACHINE_ARM64X;
+  case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
+    return COFF::isAnyArm64(FileMachine) ||
+           FileMachine == COFF::IMAGE_FILE_MACHINE_AMD64;
+  default:
+    return false;
+  }
 }
 
 static void appendFile(std::vector<NewArchiveMember> &Members,
@@ -482,7 +487,7 @@ int llvm::libDriverMain(ArrayRef<const char *> ArgsArr) {
                        /*WriteSymtab=*/true,
                        Thin ? object::Archive::K_GNU : object::Archive::K_COFF,
                        /*Deterministic*/ true, Thin, nullptr,
-                       LibMachine == COFF::IMAGE_FILE_MACHINE_ARM64EC)) {
+                       COFF::isArm64EC(LibMachine))) {
     handleAllErrors(std::move(E), [&](const ErrorInfoBase &EI) {
       llvm::errs() << OutputPath << ": " << EI.message() << "\n";
     });

diff  --git a/llvm/test/tools/llvm-cvtres/machine.test b/llvm/test/tools/llvm-cvtres/machine.test
index aacc8c554c19d..2a84d352dbe26 100644
--- a/llvm/test/tools/llvm-cvtres/machine.test
+++ b/llvm/test/tools/llvm-cvtres/machine.test
@@ -25,6 +25,12 @@ RUN: llvm-readobj -h -r %t | FileCheck %s -check-prefix=ARM
 RUN: llvm-cvtres /machine:ARM64 /out:%t %p/Inputs/test_resource.res
 RUN: llvm-readobj -h -r %t | FileCheck %s -check-prefix=ARM64
 
+RUN: llvm-cvtres /machine:ARM64EC /out:%t %p/Inputs/test_resource.res
+RUN: llvm-readobj -h -r %t | FileCheck %s -check-prefix=ARM64EC
+
+RUN: llvm-cvtres /machine:ARM64X /out:%t %p/Inputs/test_resource.res
+RUN: llvm-readobj -h -r %t | FileCheck %s -check-prefix=ARM64X
+
 X86:         Machine: IMAGE_FILE_MACHINE_I386 (0x14C)
 X86-DAG:   Relocations [
 X86-DAG:                 .rsrc$01 {
@@ -72,3 +78,27 @@ ARM64-NEXT:    0x1D8 IMAGE_REL_ARM64_ADDR32NB $R000004
 ARM64-NEXT:    0x1F8 IMAGE_REL_ARM64_ADDR32NB $R000005
 ARM64-NEXT:    0x1B8 IMAGE_REL_ARM64_ADDR32NB $R000006
 ARM64-NEXT:    0x188 IMAGE_REL_ARM64_ADDR32NB $R000007
+
+ARM64EC:       Machine: IMAGE_FILE_MACHINE_ARM64EC (0xA641)
+ARM64EC-DAG: Relocations [
+ARM64EC-DAG:               .rsrc$01 {
+ARM64EC-NEXT:    0x1E8 IMAGE_REL_ARM64_ADDR32NB $R000000
+ARM64EC-NEXT:    0x198 IMAGE_REL_ARM64_ADDR32NB $R000001
+ARM64EC-NEXT:    0x1A8 IMAGE_REL_ARM64_ADDR32NB $R000002
+ARM64EC-NEXT:    0x1C8 IMAGE_REL_ARM64_ADDR32NB $R000003
+ARM64EC-NEXT:    0x1D8 IMAGE_REL_ARM64_ADDR32NB $R000004
+ARM64EC-NEXT:    0x1F8 IMAGE_REL_ARM64_ADDR32NB $R000005
+ARM64EC-NEXT:    0x1B8 IMAGE_REL_ARM64_ADDR32NB $R000006
+ARM64EC-NEXT:    0x188 IMAGE_REL_ARM64_ADDR32NB $R000007
+
+ARM64X:       Machine: IMAGE_FILE_MACHINE_ARM64X (0xA64E)
+ARM64X-DAG: Relocations [
+ARM64X-DAG:               .rsrc$01 {
+ARM64X-NEXT:    0x1E8 IMAGE_REL_ARM64_ADDR32NB $R000000
+ARM64X-NEXT:    0x198 IMAGE_REL_ARM64_ADDR32NB $R000001
+ARM64X-NEXT:    0x1A8 IMAGE_REL_ARM64_ADDR32NB $R000002
+ARM64X-NEXT:    0x1C8 IMAGE_REL_ARM64_ADDR32NB $R000003
+ARM64X-NEXT:    0x1D8 IMAGE_REL_ARM64_ADDR32NB $R000004
+ARM64X-NEXT:    0x1F8 IMAGE_REL_ARM64_ADDR32NB $R000005
+ARM64X-NEXT:    0x1B8 IMAGE_REL_ARM64_ADDR32NB $R000006
+ARM64X-NEXT:    0x188 IMAGE_REL_ARM64_ADDR32NB $R000007

diff  --git a/llvm/test/tools/llvm-lib/Inputs/arm64x.yaml b/llvm/test/tools/llvm-lib/Inputs/arm64x.yaml
new file mode 100644
index 0000000000000..424a16a644a2c
--- /dev/null
+++ b/llvm/test/tools/llvm-lib/Inputs/arm64x.yaml
@@ -0,0 +1,23 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARM64X
+  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/test/tools/llvm-lib/machine-mismatch.test b/llvm/test/tools/llvm-lib/machine-mismatch.test
index 0a6aac624bc28..678edd65df2a4 100644
--- a/llvm/test/tools/llvm-lib/machine-mismatch.test
+++ b/llvm/test/tools/llvm-lib/machine-mismatch.test
@@ -8,6 +8,7 @@ RUN: llvm-mc -triple=arm64ec-pc-windows-msvc -filetype=obj -o %t/arm64ec.obj %S/
 RUN: llvm-as -o %t/i386.bc %S/Inputs/i386.ll
 RUN: llvm-as -o %t/x86_64.bc %S/Inputs/x86_64.ll
 RUN: llvm-as -o %t/arm64.bc %S/Inputs/arm64.ll
+RUN: yaml2obj -o %t/arm64x.obj %S/Inputs/arm64x.yaml
 
 
 Mixing bitcode and normal object files with the same machine type is ok:
@@ -49,15 +50,26 @@ OBJ64: x86_64.obj: file machine type x64 conflicts with library machine type x86
 
 Mixing arm64 and x86_64 is possible using arm64ec:
 
-RUN: llvm-lib -machine:arm64ec %t/arm64.bc %t/x86_64.bc %t/arm64.obj %t/x86_64.obj %t/arm64ec.obj
+RUN: llvm-lib -machine:arm64ec %t/arm64.bc %t/x86_64.bc %t/arm64.obj %t/x86_64.obj %t/arm64ec.obj %t/arm64x.obj
+RUN: llvm-lib -machine:arm64x %t/arm64.bc %t/x86_64.bc %t/arm64.obj %t/x86_64.obj %t/arm64ec.obj %t/arm64x.obj
+RUN: llvm-lib -machine:arm64 %t/arm64.bc %t/arm64.obj %t/arm64x.obj
 
 RUN: not llvm-lib %t/arm64ec.obj 2>&1 | FileCheck --check-prefix=NOEC %s
 NOEC: arm64ec.obj: file machine type arm64ec conflicts with inferred library machine type, use /machine:arm64ec or /machine:arm64x
 
 RUN: not llvm-lib -machine:arm64ec %t/arm64ec.obj %t/i386.obj 2>&1 | \
 RUN:     FileCheck --check-prefix=OBJEC %s
+RUN: not llvm-lib -machine:arm64x %t/arm64ec.obj %t/i386.obj 2>&1 | \
+RUN:     FileCheck --check-prefix=OBJX %s
+RUN: not llvm-lib -machine:x64 %t/x86_64.obj %t/arm64x.obj 2>&1 | \
+RUN:     FileCheck --check-prefix=OBJX2 %s
 OBJEC: i386.obj: file machine type x86 conflicts with library machine type arm64ec (from '/machine:arm64ec' flag)
+OBJX:  i386.obj: file machine type x86 conflicts with library machine type arm64x (from '/machine:arm64x' flag)
+OBJX2: arm64x.obj: file machine type arm64x conflicts with library machine type x64 (from '/machine:x64' flag)
 
 RUN: not llvm-lib -machine:arm64ec %t/arm64.bc %t/x86_64.bc %t/i386.bc 2>&1 | \
 RUN:     FileCheck --check-prefix=BCEC %s
+RUN: not llvm-lib -machine:arm64x %t/arm64.bc %t/x86_64.bc %t/i386.bc 2>&1 | \
+RUN:     FileCheck --check-prefix=BCX %s
 BCEC: i386.bc: file machine type x86 conflicts with library machine type arm64ec (from '/machine:arm64ec' flag)
+BCX:  i386.bc: file machine type x86 conflicts with library machine type arm64x (from '/machine:arm64x' flag)

diff  --git a/llvm/test/tools/llvm-readobj/COFF/arm64x.yaml b/llvm/test/tools/llvm-readobj/COFF/arm64x.yaml
new file mode 100644
index 0000000000000..f956b282b1a36
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/arm64x.yaml
@@ -0,0 +1,27 @@
+# RUN: yaml2obj < %s | llvm-readobj - --file-headers | FileCheck %s
+# Check we can process a simple arm64x file.
+# CHECK: Format: COFF-ARM64X
+# CHECK: Machine: IMAGE_FILE_MACHINE_ARM64X (0xA64E)
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_ARM64X
+  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
index 22b4c58acde9d..c6d1f2cf9c63d 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -344,6 +344,7 @@ const EnumEntry<COFF::MachineTypes> ImageFileMachineType[] = {
   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_ARM64X   ),
   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     ),
@@ -1671,6 +1672,7 @@ void COFFDumper::printUnwindInfo() {
   }
   case COFF::IMAGE_FILE_MACHINE_ARM64:
   case COFF::IMAGE_FILE_MACHINE_ARM64EC:
+  case COFF::IMAGE_FILE_MACHINE_ARM64X:
   case COFF::IMAGE_FILE_MACHINE_ARMNT: {
     ARM::WinEH::Decoder Decoder(W, Obj->getMachine() !=
                                        COFF::IMAGE_FILE_MACHINE_ARMNT);


        


More information about the llvm-commits mailing list