[llvm-readobj][ARM] - Improve support of printing unwind (-u) information for non-relocatable objects.
This is the one more patch for https://bugs.llvm.org/show_bug.cgi?id=47581 It fixes how we print an information for the Generic model. With this patch we are able to read values from `.ARM.extab` and dump proper personality routines names/addresses. Differential revision: https://reviews.llvm.org/D88478
This commit is contained in:
parent
cdda7822d6
commit
fdceec7aea
@ -59,6 +59,23 @@
|
||||
# UNWIND-NEXT: 0xB0 ; finish
|
||||
# UNWIND-NEXT: ]
|
||||
# UNWIND-NEXT: }
|
||||
# UNWIND-NEXT: Entry {
|
||||
# UNWIND-NEXT: FunctionAddress: 0x25C
|
||||
# UNWIND-NEXT: FunctionName: func5
|
||||
# UNWIND-NEXT: ExceptionHandlingTable: .ARM.extab
|
||||
# UNWIND-NEXT: TableEntryAddress: 0xAABE44
|
||||
# UNWIND-NEXT: Model: Generic
|
||||
# UNWIND-NEXT: PersonalityRoutineAddress: 0x33CCCF44
|
||||
# UNWIND-NEXT: PersonalityRoutineName: personality1
|
||||
# UNWIND-NEXT: }
|
||||
# UNWIND-NEXT: Entry {
|
||||
# UNWIND-NEXT: FunctionAddress: 0x25C
|
||||
# UNWIND-NEXT: FunctionName: func5
|
||||
# UNWIND-NEXT: ExceptionHandlingTable: .ARM.extab
|
||||
# UNWIND-NEXT: TableEntryAddress: 0xAABE48
|
||||
# UNWIND-NEXT: Model: Generic
|
||||
# UNWIND-NEXT: PersonalityRoutineAddress: 0xFFFFFFFFF811138C
|
||||
# UNWIND-NEXT: }
|
||||
# UNWIND-NEXT: ]
|
||||
# UNWIND-NEXT: }
|
||||
# UNWIND-NEXT: }
|
||||
@ -77,21 +94,39 @@ Sections:
|
||||
Type: SHT_ARM_EXIDX
|
||||
Address: 0x24C
|
||||
Entries:
|
||||
## Address of .ARM.exidx (0x24C) + entry offset (0) + 0x7fffffe4 (31 bit) == 0x230 (func1).
|
||||
## A. Address of .ARM.exidx (0x24C) + entry offset (0) + 0x7fffffe4 (31 bit) == 0x230 (func1).
|
||||
- Offset: 0x7FFFFFE4
|
||||
Value: 0x80B0B0B0 ## arbitrary opcodes.
|
||||
## Address of .ARM.exidx (0x24C) + entry offset (8) + 0x7fffffe0 (31 bit) == 0x234 (func2).
|
||||
## B. Address of .ARM.exidx (0x24C) + entry offset (8) + 0x7fffffe0 (31 bit) == 0x234 (func2).
|
||||
- Offset: 0x7FFFFFE0
|
||||
Value: 0x809B8480 ## arbitrary opcodes.
|
||||
## Address of .ARM.exidx (0x24C) + entry offset (16) + 0x7fffffec (31 bit) == 0x248 (func2).
|
||||
## C. Address of .ARM.exidx (0x24C) + entry offset (16) + 0x7fffffec (31 bit) == 0x248 (func3).
|
||||
- Offset: 0x7FFFFFEC
|
||||
Value: 0x80B0B0B0 ## arbitrary opcodes.
|
||||
## Address of .ARM.exidx (0x24C) + entry offset (24) + 0x7fffffe8 (31 bit) == 0x24C.
|
||||
## D. Address of .ARM.exidx (0x24C) + entry offset (24) + 0x7fffffe8 (31 bit) == 0x24C.
|
||||
- Offset: 0x7FFFFFE8
|
||||
Value: EXIDX_CANTUNWIND
|
||||
## Address of .ARM.exidx (0x24C) + entry offset (32) + 0x3FFFFFFF (31 bit) == 0x4000026b.
|
||||
## E. Address of .ARM.exidx (0x24C) + entry offset (32) + 0x3FFFFFFF (31 bit) == 0x4000026b (func4).
|
||||
- Offset: 0x3FFFFFFF
|
||||
Value: 0x80B0B0B0 ## arbitrary opcodes.
|
||||
## F. Address of .ARM.exidx (0x24C) + entry offset (40) + 0x7FFFFFE8 (31 bit) == 0x25c (func5).
|
||||
- Offset: 0x7FFFFFE8
|
||||
## Generic model. .ARM.exidx (0x24C) + entry offset (40 + 4) + 0x00AABBCC ==
|
||||
## 0x00AABE44 == address of entry [0] in the .ARM.extab section.
|
||||
## 0x00AABE44 + 0x33221100 (31 bit, signed, .ARM.extab entry [0] value) ==
|
||||
## 0x33cccf44 == personality1 routine address.
|
||||
Value: 0x00AABBCC
|
||||
## G. Address of .ARM.exidx (0x24C) + entry offset (48) + 0x7FFFFFE0 (31 bit) == 0x25c (func5).
|
||||
- Offset: 0x7FFFFFE0
|
||||
## Generic model. .ARM.exidx (0x24C) + entry offset (48 + 4) + 0x00AABBC8 ==
|
||||
## 0x00AABE48 == address of entry [1] in the .ARM.extab section.
|
||||
## 0x00AABE48 + 0x77665544 (31 bit, signed, .ARM.extab entry [1] value) ==
|
||||
## 0xFFFFFFFFF811138C == the address of a personality routine function that does not exist.
|
||||
Value: 0x00AABBC8
|
||||
- Name: .ARM.extab
|
||||
Type: SHT_PROGBITS
|
||||
Address: 0x00AABE44
|
||||
Content: "0011223344556677"
|
||||
Symbols:
|
||||
- Name: func1
|
||||
Type: STT_FUNC
|
||||
@ -109,3 +144,10 @@ Symbols:
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x4000026b
|
||||
- Name: func5
|
||||
Type: STT_FUNC
|
||||
Section: .text
|
||||
Value: 0x25c
|
||||
- Name: personality1
|
||||
Type: STT_FUNC
|
||||
Value: 0x33cccf44
|
||||
|
||||
@ -347,7 +347,7 @@ class PrinterContext {
|
||||
off_t IndexTableOffset) const;
|
||||
|
||||
void PrintIndexTable(unsigned SectionIndex, const Elf_Shdr *IT) const;
|
||||
void PrintExceptionTable(const Elf_Shdr *IT, const Elf_Shdr *EHT,
|
||||
void PrintExceptionTable(const Elf_Shdr &EHT,
|
||||
uint64_t TableEntryOffset) const;
|
||||
void PrintOpcodes(const uint8_t *Entry, size_t Length, off_t Offset) const;
|
||||
|
||||
@ -434,11 +434,20 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
|
||||
}
|
||||
|
||||
template <typename ET>
|
||||
void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT,
|
||||
const Elf_Shdr *EHT,
|
||||
static const typename ET::Shdr *
|
||||
findSectionContainingAddress(const object::ELFFile<ET> &Obj, StringRef FileName,
|
||||
uint64_t Address) {
|
||||
for (const typename ET::Shdr &Sec : unwrapOrError(FileName, Obj.sections()))
|
||||
if (Address >= Sec.sh_addr && Address < Sec.sh_addr + Sec.sh_size)
|
||||
return &Sec;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <typename ET>
|
||||
void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr &EHT,
|
||||
uint64_t TableEntryOffset) const {
|
||||
// TODO: handle failure.
|
||||
Expected<ArrayRef<uint8_t>> Contents = ELF.getSectionContents(*EHT);
|
||||
Expected<ArrayRef<uint8_t>> Contents = ELF.getSectionContents(EHT);
|
||||
if (!Contents)
|
||||
return;
|
||||
|
||||
@ -487,11 +496,14 @@ void PrinterContext<ET>::PrintExceptionTable(const Elf_Shdr *IT,
|
||||
}
|
||||
} else {
|
||||
SW.printString("Model", StringRef("Generic"));
|
||||
|
||||
uint64_t Address = PREL31(Word, EHT->sh_addr);
|
||||
const bool IsRelocatable = ELF.getHeader().e_type == ELF::ET_REL;
|
||||
uint64_t Address = IsRelocatable
|
||||
? PREL31(Word, EHT.sh_addr)
|
||||
: PREL31(Word, EHT.sh_addr + TableEntryOffset);
|
||||
SW.printHex("PersonalityRoutineAddress", Address);
|
||||
if (ErrorOr<StringRef> Name =
|
||||
FunctionAtAddress(Address, (unsigned)EHT->sh_link))
|
||||
Optional<unsigned> SecIndex =
|
||||
IsRelocatable ? Optional<unsigned>(EHT.sh_link) : None;
|
||||
if (ErrorOr<StringRef> Name = FunctionAtAddress(Address, SecIndex))
|
||||
SW.printString("PersonalityRoutineName", *Name);
|
||||
}
|
||||
}
|
||||
@ -580,19 +592,30 @@ void PrinterContext<ET>::PrintIndexTable(unsigned SectionIndex,
|
||||
|
||||
PrintOpcodes(Contents->data() + Entry * IndexTableEntrySize + 4, 3, 1);
|
||||
} else {
|
||||
const Elf_Shdr *EHT =
|
||||
FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
|
||||
const Elf_Shdr *EHT;
|
||||
uint64_t TableEntryAddress;
|
||||
if (IsRelocatable) {
|
||||
TableEntryAddress = PREL31(Word1, IT->sh_addr);
|
||||
EHT = FindExceptionTable(SectionIndex, Entry * IndexTableEntrySize + 4);
|
||||
} else {
|
||||
TableEntryAddress =
|
||||
PREL31(Word1, IT->sh_addr + Entry * IndexTableEntrySize + 4);
|
||||
EHT = findSectionContainingAddress(ELF, FileName, TableEntryAddress);
|
||||
}
|
||||
|
||||
if (EHT)
|
||||
// TODO: handle failure.
|
||||
if (Expected<StringRef> Name = ELF.getSectionName(*EHT))
|
||||
SW.printString("ExceptionHandlingTable", *Name);
|
||||
|
||||
uint64_t TableEntryOffset = PREL31(Word1, IT->sh_addr);
|
||||
SW.printHex("TableEntryOffset", TableEntryOffset);
|
||||
|
||||
if (EHT)
|
||||
PrintExceptionTable(IT, EHT, TableEntryOffset);
|
||||
SW.printHex(IsRelocatable ? "TableEntryOffset" : "TableEntryAddress",
|
||||
TableEntryAddress);
|
||||
if (EHT) {
|
||||
if (IsRelocatable)
|
||||
PrintExceptionTable(*EHT, TableEntryAddress);
|
||||
else
|
||||
PrintExceptionTable(*EHT, TableEntryAddress - EHT->sh_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user