[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:
Georgii Rymar 2020-09-29 13:53:38 +03:00
parent cdda7822d6
commit fdceec7aea
2 changed files with 85 additions and 20 deletions

View File

@ -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

View File

@ -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);
}
}
}
}