Index: llvm/test/tools/llvm-readobj/COFF/unwind-arm64-image.yaml =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/COFF/unwind-arm64-image.yaml @@ -0,0 +1,180 @@ +# RUN: yaml2obj %s > %t.exe +# RUN: llvm-readobj --unwind %t.exe | FileCheck %s + +# CHECK: RuntimeFunction { +# CHECK: Function: entry (0x140001014) +# CHECK-NEXT: ExceptionRecord: 0x140002018 +# CHECK-NEXT: ExceptionData { +# CHECK-NEXT: FunctionLength: 92 +# CHECK-NEXT: Version: 0 +# CHECK-NEXT: ExceptionData: Yes +# CHECK-NEXT: EpiloguePacked: No +# CHECK-NEXT: EpilogueScopes: 1 +# CHECK-NEXT: ByteCodeLength: 8 +# CHECK-NEXT: Prologue [ +# CHECK-NEXT: 0xd2c4 ; str x30, [sp, #32] +# CHECK-NEXT: 0x03 ; sub sp, #48 +# CHECK-NEXT: 0xe4 ; end +# CHECK-NEXT: ] +# CHECK-NEXT: EpilogueScopes [ +# CHECK-NEXT: EpilogueScope { +# CHECK-NEXT: StartOffset: 11 +# CHECK-NEXT: EpilogueStartIndex: 4 +# CHECK-NEXT: Opcodes [ +# CHECK-NEXT: 0xd2c4 ; ldr x30, [sp, #32] +# CHECK-NEXT: 0x03 ; add sp, #48 +# CHECK-NEXT: 0xe4 ; end +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: ExceptionHandler [ +# CHECK-NEXT: Routine: __gxx_personality_seh0 (0x140001074) +# CHECK-NEXT: Parameter: 0x801FFFF +# CHECK-NEXT: ] +# CHECK-NEXT: } +# CHECK-NEXT: } + +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 4116 + ImageBase: 5368709120 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 6 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 6 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI + DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ] + SizeOfStackReserve: 1048576 + SizeOfStackCommit: 4096 + SizeOfHeapReserve: 1048576 + SizeOfHeapCommit: 4096 + ExportTable: + RelativeVirtualAddress: 0 + Size: 0 + ImportTable: + RelativeVirtualAddress: 0 + Size: 0 + ResourceTable: + RelativeVirtualAddress: 0 + Size: 0 + ExceptionTable: + RelativeVirtualAddress: 12288 + Size: 40 + CertificateTable: + RelativeVirtualAddress: 0 + Size: 0 + BaseRelocationTable: + RelativeVirtualAddress: 0 + Size: 0 + Debug: + RelativeVirtualAddress: 0 + Size: 0 + Architecture: + RelativeVirtualAddress: 0 + Size: 0 + GlobalPtr: + RelativeVirtualAddress: 0 + Size: 0 + TlsTable: + RelativeVirtualAddress: 0 + Size: 0 + LoadConfigTable: + RelativeVirtualAddress: 0 + Size: 0 + BoundImport: + RelativeVirtualAddress: 0 + Size: 0 + IAT: + RelativeVirtualAddress: 0 + Size: 0 + DelayImportDescriptor: + RelativeVirtualAddress: 0 + Size: 0 + ClrRuntimeHeader: + RelativeVirtualAddress: 0 + Size: 0 +header: + Machine: IMAGE_FILE_MACHINE_ARM64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 4096 + VirtualSize: 120 + SectionData: C0035FD6FF4300D1E00700F9FF430091C0035FD6FFC300D1FE1300F90800009008C10191E80300F9F6FFFF9701000014E07F0091080000900811009100013FD6FE1340F9FFC30091C0035FD6E00B00F9E10F00B9E07F0091080000900811009100013FD6E00B40F9E80340F900013FD6C0035FD6C0035FD6 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 8192 + VirtualSize: 80 + SectionData: 0100400800000000E4E3E3E3040040080200800001E401E4170050100B000001D2C403E4D2C403E474100000FFFF010810083800184400000100400800000000E4E3E3E30100400800000000E4E3E3E3 + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 12288 + VirtualSize: 40 + SectionData: 0010000000200000041000000C200000141000001820000070100000382000007410000044200000 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .xdata + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .pdata + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: other + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _ZN4RAIID2Ev + Value: 4 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: entry + Value: 20 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _Unwind_Resume + Value: 112 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _ZN4RAIID1Ev + Value: 4 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: __gxx_personality_seh0 + Value: 116 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: GCC_except_table2 + Value: 44 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... Index: llvm/test/tools/llvm-readobj/COFF/unwind-x86_64-image.yaml =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/COFF/unwind-x86_64-image.yaml @@ -0,0 +1,168 @@ +# RUN: yaml2obj %s > %t.exe +# RUN: llvm-readobj --unwind %t.exe | FileCheck %s + +# CHECK: RuntimeFunction { +# CHECK: StartAddress: entry (0x140001020) +# CHECK-NEXT: EndAddress: (0x14000105C) +# CHECK-NEXT: UnwindInfoAddress: (0x140002008) +# CHECK-NEXT: UnwindInfo { +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Flags [ (0x3) +# CHECK-NEXT: ExceptionHandler (0x1) +# CHECK-NEXT: TerminateHandler (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: PrologSize: 4 +# CHECK-NEXT: FrameRegister: - +# CHECK-NEXT: FrameOffset: - +# CHECK-NEXT: UnwindCodeCount: 1 +# CHECK-NEXT: UnwindCodes [ +# CHECK-NEXT: 0x04: ALLOC_SMALL size=56 +# CHECK-NEXT: ] +# CHECK-NEXT: Handler: __gxx_personality_seh0 (0x140001070) +# CHECK-NEXT: } +# CHECK-NEXT: } + +--- !COFF +OptionalHeader: + AddressOfEntryPoint: 4128 + ImageBase: 5368709120 + SectionAlignment: 4096 + FileAlignment: 512 + MajorOperatingSystemVersion: 6 + MinorOperatingSystemVersion: 0 + MajorImageVersion: 0 + MinorImageVersion: 0 + MajorSubsystemVersion: 6 + MinorSubsystemVersion: 0 + Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI + DLLCharacteristics: [ IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA, IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE, IMAGE_DLL_CHARACTERISTICS_NX_COMPAT, IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE ] + SizeOfStackReserve: 1048576 + SizeOfStackCommit: 4096 + SizeOfHeapReserve: 1048576 + SizeOfHeapCommit: 4096 + ExportTable: + RelativeVirtualAddress: 0 + Size: 0 + ImportTable: + RelativeVirtualAddress: 0 + Size: 0 + ResourceTable: + RelativeVirtualAddress: 0 + Size: 0 + ExceptionTable: + RelativeVirtualAddress: 12288 + Size: 24 + CertificateTable: + RelativeVirtualAddress: 0 + Size: 0 + BaseRelocationTable: + RelativeVirtualAddress: 0 + Size: 0 + Debug: + RelativeVirtualAddress: 0 + Size: 0 + Architecture: + RelativeVirtualAddress: 0 + Size: 0 + GlobalPtr: + RelativeVirtualAddress: 0 + Size: 0 + TlsTable: + RelativeVirtualAddress: 0 + Size: 0 + LoadConfigTable: + RelativeVirtualAddress: 0 + Size: 0 + BoundImport: + RelativeVirtualAddress: 0 + Size: 0 + IAT: + RelativeVirtualAddress: 0 + Size: 0 + DelayImportDescriptor: + RelativeVirtualAddress: 0 + Size: 0 + ClrRuntimeHeader: + RelativeVirtualAddress: 0 + Size: 0 +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_EXECUTABLE_IMAGE, IMAGE_FILE_LARGE_ADDRESS_AWARE ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + VirtualAddress: 4096 + VirtualSize: 113 + SectionData: C3662E0F1F8400000000000F1F4400005048890C2458C3660F1F8400000000004883EC38E8D7FFFFFFE900000000488D4C2430E8D8FFFFFF904883C438C3488944242889542424488D4C2430E8BFFFFFFF488B4C2428E805000000CC0F1F4000C3662E0F1F8400000000000F1F440000C3 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 8192 + VirtualSize: 32 + SectionData: 0101010001020000190401000462000070100000FFFF010804051E0009330000 + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + VirtualAddress: 12288 + VirtualSize: 24 + SectionData: 101000001710000000200000201000005C10000008200000 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .xdata + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .pdata + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: other + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _ZN4RAIID2Ev + Value: 16 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: entry + Value: 32 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _ZN4RAIID1Ev + Value: 16 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _Unwind_Resume + Value: 96 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: __gxx_personality_seh0 + Value: 112 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: GCC_except_table2 + Value: 20 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... Index: llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp =================================================================== --- llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp +++ llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp @@ -884,7 +884,7 @@ } if (XData.X()) { - const uint32_t Address = XData.ExceptionHandlerRVA(); + const uint64_t Address = COFF.getImageBase() + XData.ExceptionHandlerRVA(); const uint32_t Parameter = XData.ExceptionHandlerParameter(); const size_t HandlerOffset = HeaderWords(XData) + (XData.E() ? 0 : XData.EpilogueCount()) @@ -896,7 +896,8 @@ Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true); if (!Symbol) { ListScope EHS(SW, "ExceptionHandler"); - SW.printString("Routine", "(null)"); + SW.printHex("Routine", Address); + SW.printHex("Parameter", Parameter); return true; } @@ -925,7 +926,8 @@ ErrorOr Function = getRelocatedSymbol(COFF, Section, Offset); if (!Function) - Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true); + Function = getSymbol(COFF, COFF.getImageBase() + RF.BeginAddress, + /*FunctionOnly=*/true); ErrorOr XDataRecord = getRelocatedSymbol(COFF, Section, Offset + 4); if (!XDataRecord) Index: llvm/tools/llvm-readobj/Win64EHDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/Win64EHDumper.cpp +++ llvm/tools/llvm-readobj/Win64EHDumper.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Win64EHDumper.h" +#include "Error.h" #include "llvm-readobj.h" #include "llvm/Object/COFF.h" #include "llvm/Support/ErrorHandling.h" @@ -111,6 +112,20 @@ } } +static std::error_code getSymbol(const COFFObjectFile &COFF, uint64_t VA, + object::SymbolRef &Sym) { + for (const auto &Symbol : COFF.symbols()) { + Expected Address = Symbol.getAddress(); + if (!Address) + return errorToErrorCode(Address.takeError()); + if (*Address == VA) { + Sym = Symbol; + return readobj_error::success; + } + } + return readobj_error::unknown_symbol; +} + static std::string formatSymbol(const Dumper::Context &Ctx, const coff_section *Section, uint64_t Offset, uint32_t Displacement) { @@ -131,9 +146,22 @@ // TODO: Actually report errors helpfully. consumeError(Name.takeError()); } + } else if (!getSymbol(Ctx.COFF, Ctx.COFF.getImageBase() + Displacement, + Symbol)) { + Expected Name = Symbol.getName(); + if (Name) { + OS << *Name; + OS << format(" (0x%" PRIX64 ")", Ctx.COFF.getImageBase() + Displacement); + return OS.str(); + } else { + consumeError(Name.takeError()); + } } - OS << format(" (0x%" PRIX64 ")", Offset); + if (Displacement > 0) + OS << format("(0x%" PRIX64 ")", Ctx.COFF.getImageBase() + Displacement); + else + OS << format("(0x%" PRIX64 ")", Offset); return OS.str(); } @@ -159,6 +187,18 @@ return std::error_code(); } +static const object::coff_section * +getSectionContaining(const COFFObjectFile &COFF, uint64_t VA) { + for (const auto &Section : COFF.sections()) { + uint64_t Address = Section.getAddress(); + uint64_t Size = Section.getSize(); + + if (VA >= Address && (VA - Address) <= Size) + return COFF.getCOFFSection(Section); + } + return nullptr; +} + namespace llvm { namespace Win64EH { void Dumper::printRuntimeFunctionEntry(const Context &Ctx, @@ -284,9 +324,18 @@ DictScope RFS(SW, "RuntimeFunction"); printRuntimeFunctionEntry(Ctx, Section, SectionOffset, RF); - const coff_section *XData; + const coff_section *XData = nullptr; uint64_t Offset; resolveRelocation(Ctx, Section, SectionOffset + 8, XData, Offset); + Offset = Offset + RF.UnwindInfoOffset; + + if (!XData) { + uint64_t Address = Ctx.COFF.getImageBase() + RF.UnwindInfoOffset; + XData = getSectionContaining(Ctx.COFF, Address); + if (!XData) + return; + Offset = RF.UnwindInfoOffset - XData->VirtualAddress; + } ArrayRef Contents; if (Error E = Ctx.COFF.getSectionContents(XData, Contents)) @@ -295,7 +344,6 @@ if (Contents.empty()) return; - Offset = Offset + RF.UnwindInfoOffset; if (Offset > Contents.size()) return;