diff --git a/llvm/test/tools/llvm-readobj/COFF/x86_64-unwind-preferred-symbol-gcc.yaml b/llvm/test/tools/llvm-readobj/COFF/x86_64-unwind-preferred-symbol-gcc.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/x86_64-unwind-preferred-symbol-gcc.yaml @@ -0,0 +1,118 @@ +## Check that we print the external symbols "func1" and "func2", even though +## the pdata relocations point at the '.text' symbol. + +# RUN: yaml2obj %s -o %t.obj +# RUN: llvm-readobj --unwind %t.obj | FileCheck %s + +# CHECK: StartAddress: func1 +# CHECK: EndAddress: func2 +# CHECK: UnwindInfoAddress: .xdata + +# CHECK: StartAddress: func2 +# CHECK: EndAddress: func2 +0x20 +# CHECK: UnwindInfoAddress: .xdata +0xC + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ IMAGE_FILE_LINE_NUMS_STRIPPED ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 554889E54883EC3048894D10488D45FC4889C2488B4D10E800000000904883C4305DC3554889E54883EC30488D45FC4889C2B900000000E800000000904883C4305DC390909090909090909090909090 + Relocations: + - VirtualAddress: 24 + SymbolName: other + Type: IMAGE_REL_AMD64_REL32 + - VirtualAddress: 56 + SymbolName: other + Type: IMAGE_REL_AMD64_REL32 + - Name: .xdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '010803050852040301500000010803050852040301500000' + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 00000000230000000000000023000000430000000C000000 + Relocations: + - VirtualAddress: 0 + SymbolName: .text + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 4 + SymbolName: .text + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 8 + SymbolName: .xdata + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 12 + SymbolName: .text + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 16 + SymbolName: .text + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 20 + SymbolName: .xdata + Type: IMAGE_REL_AMD64_ADDR32NB +symbols: + - Name: func1 + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + FunctionDefinition: + TagIndex: 0 + TotalSize: 0 + PointerToLinenumber: 0 + PointerToNextFunction: 0 + - Name: func2 + Value: 35 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 67 + NumberOfRelocations: 2 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: .xdata + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 24 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: .pdata + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 24 + NumberOfRelocations: 6 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: other + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/llvm/test/tools/llvm-readobj/COFF/x86_64-unwind-preferred-symbol-msvc.yaml b/llvm/test/tools/llvm-readobj/COFF/x86_64-unwind-preferred-symbol-msvc.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/COFF/x86_64-unwind-preferred-symbol-msvc.yaml @@ -0,0 +1,149 @@ +## Check that we print the external symbols "func1" and "func2", even though +## the pdata relocations point at the '$LN3' symbols. + +# RUN: yaml2obj %s -o %t.obj +# RUN: llvm-readobj --unwind %t.obj | FileCheck %s + +# CHECK: StartAddress: func1 +# CHECK: EndAddress: func1 +0x1D +# CHECK: UnwindInfoAddress: $unwind$func1 + +# CHECK: StartAddress: func2 +# CHECK: EndAddress: func2 +0x15 +# CHECK: UnwindInfoAddress: $unwind$func2 + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 48894C24084883EC38488D542420488B4C2440E8000000004883C438C3CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC4883EC38488D54242033C9E8000000004883C438C3 + Relocations: + - VirtualAddress: 20 + SymbolName: other + Type: IMAGE_REL_AMD64_REL32 + - VirtualAddress: 60 + SymbolName: other + Type: IMAGE_REL_AMD64_REL32 + - Name: .xdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '01090100096200000104010004620000' + - Name: .pdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 000000001D00000000000000000000001500000000000000 + Relocations: + - VirtualAddress: 0 + SymbolTableIndex: 5 + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 4 + SymbolTableIndex: 5 + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 8 + SymbolName: '$unwind$func1' + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 12 + SymbolTableIndex: 6 + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 16 + SymbolTableIndex: 6 + Type: IMAGE_REL_AMD64_ADDR32NB + - VirtualAddress: 20 + SymbolName: '$unwind$func2' + Type: IMAGE_REL_AMD64_ADDR32NB +symbols: + - Name: '.text$mn' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 69 + NumberOfRelocations: 2 + NumberOfLinenumbers: 0 + CheckSum: 1184383679 + Number: 0 + - Name: other + Value: 0 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: func1 + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: func2 + Value: 48 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: '$LN3' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_LABEL + - Name: '$LN3' + Value: 48 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_LABEL + - Name: .xdata + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 16 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 3884715473 + Number: 0 + - Name: '$unwind$func1' + 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 + SectionDefinition: + Length: 24 + NumberOfRelocations: 6 + NumberOfLinenumbers: 0 + CheckSum: 1657574087 + Number: 0 + - Name: '$pdata$func1' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '$unwind$func2' + Value: 8 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: '$pdata$func2' + Value: 12 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... diff --git a/llvm/tools/llvm-readobj/Win64EHDumper.cpp b/llvm/tools/llvm-readobj/Win64EHDumper.cpp --- a/llvm/tools/llvm-readobj/Win64EHDumper.cpp +++ b/llvm/tools/llvm-readobj/Win64EHDumper.cpp @@ -125,6 +125,34 @@ return inconvertibleErrorCode(); } +static object::SymbolRef getPreferredSymbol(const COFFObjectFile &COFF, + object::SymbolRef Sym, + uint32_t &SymbolOffset) { + // The symbol resolved by ResolveSymbol can be any internal + // nondescriptive symbol; try to resolve a more descriptive one. + COFFSymbolRef CoffSym = COFF.getCOFFSymbol(Sym); + if (CoffSym.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL && + CoffSym.getSectionDefinition() == nullptr) + return Sym; + for (const auto &S : COFF.symbols()) { + COFFSymbolRef CS = COFF.getCOFFSymbol(S); + if (CS.getSectionNumber() == CoffSym.getSectionNumber() && + CS.getValue() <= CoffSym.getValue() + SymbolOffset && + CS.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL && + CS.getSectionDefinition() == nullptr) { + uint32_t Offset = CoffSym.getValue() + SymbolOffset - CS.getValue(); + if (Offset <= SymbolOffset) { + SymbolOffset = Offset; + Sym = S; + CoffSym = CS; + if (CS.isExternal() && SymbolOffset == 0) + return Sym; + } + } + } + return Sym; +} + static std::string formatSymbol(const Dumper::Context &Ctx, const coff_section *Section, uint64_t Offset, uint32_t Displacement) { @@ -133,6 +161,12 @@ SymbolRef Symbol; if (!Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData)) { + // We found a relocation at the given offset in the section, pointing + // at a symbol. + + // Try to resolve label/section symbols into function names. + Symbol = getPreferredSymbol(Ctx.COFF, Symbol, Displacement); + Expected Name = Symbol.getName(); if (Name) { OS << *Name;