diff --git a/llvm/test/tools/llvm-readobj/ELF/ARM/unwind-non-relocatable.test b/llvm/test/tools/llvm-readobj/ELF/ARM/unwind-non-relocatable.test --- a/llvm/test/tools/llvm-readobj/ELF/ARM/unwind-non-relocatable.test +++ b/llvm/test/tools/llvm-readobj/ELF/ARM/unwind-non-relocatable.test @@ -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 @@ 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 @@ Type: STT_FUNC Section: .text Value: 0x4000026b + - Name: func5 + Type: STT_FUNC + Section: .text + Value: 0x25c + - Name: personality1 + Type: STT_FUNC + Value: 0x33cccf44 diff --git a/llvm/tools/llvm-readobj/ARMEHABIPrinter.h b/llvm/tools/llvm-readobj/ARMEHABIPrinter.h --- a/llvm/tools/llvm-readobj/ARMEHABIPrinter.h +++ b/llvm/tools/llvm-readobj/ARMEHABIPrinter.h @@ -347,7 +347,7 @@ 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 @@ } template -void PrinterContext::PrintExceptionTable(const Elf_Shdr *IT, - const Elf_Shdr *EHT, +static const typename ET::Shdr * +findSectionContainingAddress(const object::ELFFile &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 +void PrinterContext::PrintExceptionTable(const Elf_Shdr &EHT, uint64_t TableEntryOffset) const { // TODO: handle failure. - Expected> Contents = ELF.getSectionContents(*EHT); + Expected> Contents = ELF.getSectionContents(EHT); if (!Contents) return; @@ -487,11 +496,14 @@ } } 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 Name = - FunctionAtAddress(Address, (unsigned)EHT->sh_link)) + Optional SecIndex = + IsRelocatable ? Optional(EHT.sh_link) : None; + if (ErrorOr Name = FunctionAtAddress(Address, SecIndex)) SW.printString("PersonalityRoutineName", *Name); } } @@ -580,19 +592,30 @@ 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 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); + } } } }