[llvm-readobj] [COFF] Resolve relocations pointing at section symbols for arm64 too

This syncs parts from the x86 implementation to the ARMWinEH
implementation.

Currently, neither of the compilers targeting COFF/arm64 (MSVC, LLVM)
produce such relocations, but LLVM might after a later patch.

Differential Revision: https://reviews.llvm.org/D109650
This commit is contained in:
Martin Storsjö 2021-09-06 15:30:37 +03:00
parent 197084fcee
commit 63784b9a75
3 changed files with 116 additions and 10 deletions

View File

@ -0,0 +1,99 @@
## Check that we print the external symbol "func1" and "func2", even though
## the pdata relocations point at .text with an immediate offset.
# RUN: yaml2obj %s -o %t.obj
# RUN: llvm-readobj --unwind %t.obj | FileCheck %s
# CHECK: Function: func1 (0x0)
# CHECK: Function: func2 (0x14)
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_ARM64
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: FE0F1FF8E133009100000094FE0741F8C0035FD6FF8300D1F60B00F9FE0F00F9E1330091E0031FAA00000094FE0F40F9F60B40F9FF830091C0035FD6
Relocations:
- VirtualAddress: 8
SymbolName: other
Type: IMAGE_REL_ARM64_BRANCH26
- VirtualAddress: 40
SymbolName: other
Type: IMAGE_REL_ARM64_BRANCH26
- Name: .xdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: 0A002010D2C3D0C202E4E3E3
- Name: .pdata
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: 000000001500A0001400000000000000
Relocations:
- VirtualAddress: 0
SymbolName: .text
Type: IMAGE_REL_ARM64_ADDR32NB
- VirtualAddress: 8
SymbolName: .text
Type: IMAGE_REL_ARM64_ADDR32NB
- VirtualAddress: 12
SymbolName: .xdata
Type: IMAGE_REL_ARM64_ADDR32NB
symbols:
- Name: .text
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 60
NumberOfRelocations: 2
NumberOfLinenumbers: 0
CheckSum: 2313530660
Number: 1
- Name: .xdata
Value: 0
SectionNumber: 2
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 12
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 2034129209
Number: 2
- Name: .pdata
Value: 0
SectionNumber: 3
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 16
NumberOfRelocations: 3
NumberOfLinenumbers: 0
CheckSum: 3306336236
Number: 3
- Name: func1
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: other
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: func2
Value: 20
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...

View File

@ -238,22 +238,27 @@ ErrorOr<SymbolRef> Decoder::getRelocatedSymbol(const COFFObjectFile &,
return inconvertibleErrorCode();
}
SymbolRef Decoder::getPreferredSymbol(const COFFObjectFile &COFF,
SymbolRef Sym) {
SymbolRef Decoder::getPreferredSymbol(const COFFObjectFile &COFF, SymbolRef Sym,
uint64_t &SymbolOffset) {
// The symbol resolved by getRelocatedSymbol 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)
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()) {
if (CS.isExternal())
return S;
if (CS.getStorageClass() != COFF::IMAGE_SYM_CLASS_LABEL) {
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;
}
}
}
@ -283,6 +288,9 @@ ErrorOr<SymbolRef> Decoder::getSymbolForLocation(
// We apply SymbolOffset here directly. We return it separately to allow
// the caller to print it as an offset on the symbol name.
SymbolAddress = *AddressOrErr + SymbolOffset;
if (FunctionOnly) // Resolve label/section symbols into function names.
SymOrErr = getPreferredSymbol(COFF, *SymOrErr, SymbolOffset);
} else {
// No matching relocation found; operating on a linked image. Try to
// find a descriptive symbol if possible. The immediate offset contains
@ -292,8 +300,6 @@ ErrorOr<SymbolRef> Decoder::getSymbolForLocation(
SymbolOffset = 0;
SymOrErr = getSymbol(COFF, SymbolAddress, FunctionOnly);
}
if (SymOrErr && FunctionOnly) // Resolve label symbols into function names
SymOrErr = getPreferredSymbol(COFF, *SymOrErr);
return SymOrErr;
}

View File

@ -154,7 +154,8 @@ class Decoder {
bool FunctionOnly = false);
object::SymbolRef getPreferredSymbol(const object::COFFObjectFile &COFF,
object::SymbolRef Sym);
object::SymbolRef Sym,
uint64_t &SymbolOffset);
bool dumpXDataRecord(const object::COFFObjectFile &COFF,
const object::SectionRef &Section,