Index: llvm/test/tools/llvm-objdump/arm64ec.yaml =================================================================== --- llvm/test/tools/llvm-objdump/arm64ec.yaml +++ llvm/test/tools/llvm-objdump/arm64ec.yaml @@ -5,7 +5,13 @@ # DISAS: 180001000: 52800040 mov w0, #0x2 # DISAS-NEXT: 180001004: d65f03c0 ret # DISAS-NEXT: ... -# DISAS: 180002020: 528000a0 mov w0, #0x5 +# DISAS-NEXT: 180001020: b8 03 00 00 00 movl $0x3, %eax +# DISAS-NEXT: 180001025: c3 retq +# DISAS: 180002000: b8 06 00 00 00 movl $0x6, %eax +# DISAS-NEXT: 180002005: c3 retq +# DISAS-NEXT: 180002006: cc int3 +# DISAS-NEXT: ... +# DISAS-NEXT: 180002020: 528000a0 mov w0, #0x5 # DISAS-NEXT: 180002024: d65f03c0 ret --- !COFF Index: llvm/tools/llvm-objdump/llvm-objdump.cpp =================================================================== --- llvm/tools/llvm-objdump/llvm-objdump.cpp +++ llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1393,8 +1393,24 @@ SourcePrinter &SP, bool InlineRelocs) { DisassemblerTarget *DT = &PrimaryTarget; bool PrimaryIsThumb = false; - if (isArmElf(Obj)) - PrimaryIsThumb = PrimaryTarget.SubtargetInfo->checkFeatures("+thumb-mode"); + const chpe_range_entry *CodeMap; + uint32_t CodeMapCount = 0; + + if (SecondaryTarget) { + if (isArmElf(Obj)) { + PrimaryIsThumb = + PrimaryTarget.SubtargetInfo->checkFeatures("+thumb-mode"); + } else if (const COFFObjectFile *COFFObj = dyn_cast(&Obj)) { + const chpe_metadata *CHPEMetadata = COFFObj->getCHPEMetadata(); + if (CHPEMetadata && CHPEMetadata->CodeMapCount) { + uintptr_t CodeMapInt; + if (Error E = COFFObj->getRvaPtr(CHPEMetadata->CodeMap, CodeMapInt)) + reportError(std::move(E), Obj.getFileName()); + CodeMap = reinterpret_cast(CodeMapInt); + CodeMapCount = CHPEMetadata->CodeMapCount; + } + } + } std::map> RelocMap; if (InlineRelocs) @@ -1569,6 +1585,24 @@ MappingSymbols.emplace_back(Address - SectionAddr, PrimaryIsThumb ? 'p' : 's'); } + } else if (CodeMapCount) { + DT = &PrimaryTarget; + for (uint32_t i = 0; i < CodeMapCount; i++) { + if ((CodeMap[i].StartOffset & 3) != CHPE_RANGE_AMD64) + continue; + + // Mark x86_64 CHPE code ranges. + uint64_t Start = (CodeMap[i].StartOffset & ~3) + + cast(&Obj)->getImageBase(); + uint64_t End = + std::min(Start + CodeMap[i].Length, SectionAddr + SectSize); + if (Start < SectionAddr) + Start = SectionAddr; + if (Start < End) { + MappingSymbols.emplace_back(Start - SectionAddr, 's'); + MappingSymbols.emplace_back(End - SectionAddr, 'p'); + } + } } llvm::sort(MappingSymbols); @@ -1845,6 +1879,14 @@ DumpARMELFData = Kind == 'd'; if (SecondaryTarget) { if (Kind == 'p') { + if (CodeMapCount && DT != &PrimaryTarget) { + // X64 disassebler range may have left Index unaligned, so + // make sure that it's aligned when we switch back to ARM64 + // code. + Index = llvm::alignTo(Index, 4); + if (Index >= End) + break; + } DT = &PrimaryTarget; } else if (Kind == 's') { DT = &*SecondaryTarget; @@ -2150,6 +2192,21 @@ Features.AddFeature("+thumb-mode"); SecondaryTarget.emplace(PrimaryTarget, Features); } + } else if (const COFFObjectFile *COFFObj = dyn_cast(Obj)) { + const chpe_metadata *CHPEMetadata = COFFObj->getCHPEMetadata(); + if (CHPEMetadata && CHPEMetadata->CodeMapCount) { + // Setup x86_64 disassembler for ARM64EC binaries. + Triple X64Triple("x86_64-windows-msvc"); + std::string Error; + const Target *X64Target = + TargetRegistry::lookupTarget("", X64Triple, Error); + if (!X64Target) + reportError(Obj->getFileName(), "can't find X86_64 target: " + Error); + + SubtargetFeatures X64Features; + SecondaryTarget.emplace(X64Target, *Obj, "x86_64-windows-msvc", "", + X64Features); + } } const ObjectFile *DbgObj = Obj;