diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/test/tools/llvm-readobj/ELF/unwind-sdata8.test | 112 | ||||
| -rw-r--r-- | llvm/test/tools/llvm-readobj/ELF/unwind.test | 33 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h | 27 |
3 files changed, 165 insertions, 7 deletions
diff --git a/llvm/test/tools/llvm-readobj/ELF/unwind-sdata8.test b/llvm/test/tools/llvm-readobj/ELF/unwind-sdata8.test new file mode 100644 index 0000000..64f6f77 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/unwind-sdata8.test @@ -0,0 +1,112 @@ +## Check we can parse .eh_frame_hdr with sdata8 encoding (used for large binaries). +## Header uses eh_frame_ptr_enc=0x1c (pcrel|sdata8) and table_enc=0x3c (datarel|sdata8). +# RUN: yaml2obj --docnum=1 %s -o %t.sdata8 +# RUN: llvm-readelf --unwind %t.sdata8 | FileCheck %s --check-prefix=SDATA8 + +# SDATA8: EHFrameHeader { +# SDATA8-NEXT: Address: 0x1000 +# SDATA8-NEXT: Offset: 0x78 +# SDATA8-NEXT: Size: 0x30 +# SDATA8-NEXT: Corresponding Section: .eh_frame_hdr +# SDATA8-NEXT: Header { +# SDATA8-NEXT: version: 1 +# SDATA8-NEXT: eh_frame_ptr_enc: 0x1c +# SDATA8-NEXT: fde_count_enc: 0x3 +# SDATA8-NEXT: table_enc: 0x3c +# SDATA8-NEXT: eh_frame_ptr: 0x1030 +# SDATA8-NEXT: fde_count: 2 +# SDATA8-NEXT: entry 0 { +# SDATA8-NEXT: initial_location: 0x2000 +# SDATA8-NEXT: address: 0x1048 +# SDATA8-NEXT: } +# SDATA8-NEXT: entry 1 { +# SDATA8-NEXT: initial_location: 0x2001 +# SDATA8-NEXT: address: 0x1068 +# SDATA8-NEXT: } +# SDATA8-NEXT: } +# SDATA8-NEXT: } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x1000 + AddressAlign: 4 +## Header: version=1, eh_frame_ptr_enc=0x1c (pcrel|sdata8), +## fde_count_enc=0x03 (udata4), table_enc=0x3c (datarel|sdata8) +## eh_frame_ptr: 0x2c (8 bytes) -> points to 0x1004 + 0x2c = 0x1030 +## fde_count: 2 (4 bytes) +## entry 0: initial_location=0x1000 (0x2000-0x1000), address=0x48 (0x1048-0x1000) +## entry 1: initial_location=0x1001 (0x2001-0x1000), address=0x68 (0x1068-0x1000) + Content: 011c033c2c00000000000000020000000010000000000000480000000000000001100000000000006800000000000000 +ProgramHeaders: + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + VAddr: 0x1000 + PAddr: 0x1000 + MemSize: 0x30 + FileSize: 0x30 + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr + +## Check we can parse .eh_frame_hdr with mixed encoding: sdata8 for eh_frame_ptr, sdata4 for table. +# RUN: yaml2obj --docnum=2 %s -o %t.mixed +# RUN: llvm-readelf --unwind %t.mixed | FileCheck %s --check-prefix=MIXED + +# MIXED: EHFrameHeader { +# MIXED-NEXT: Address: 0x1000 +# MIXED-NEXT: Offset: 0x78 +# MIXED-NEXT: Size: 0x20 +# MIXED-NEXT: Corresponding Section: .eh_frame_hdr +# MIXED-NEXT: Header { +# MIXED-NEXT: version: 1 +# MIXED-NEXT: eh_frame_ptr_enc: 0x1c +# MIXED-NEXT: fde_count_enc: 0x3 +# MIXED-NEXT: table_enc: 0x3b +# MIXED-NEXT: eh_frame_ptr: 0x1020 +# MIXED-NEXT: fde_count: 2 +# MIXED-NEXT: entry 0 { +# MIXED-NEXT: initial_location: 0x2000 +# MIXED-NEXT: address: 0x1030 +# MIXED-NEXT: } +# MIXED-NEXT: entry 1 { +# MIXED-NEXT: initial_location: 0x2001 +# MIXED-NEXT: address: 0x1050 +# MIXED-NEXT: } +# MIXED-NEXT: } +# MIXED-NEXT: } + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x1000 + AddressAlign: 4 +## Header: version=1, eh_frame_ptr_enc=0x1c (pcrel|sdata8), +## fde_count_enc=0x03 (udata4), table_enc=0x3b (datarel|sdata4) +## eh_frame_ptr: 0x1c (8 bytes) -> points to 0x1004 + 0x1c = 0x1020 +## fde_count: 2 (4 bytes) +## entry 0: initial_location=0x1000 (4 bytes), address=0x30 (4 bytes) +## entry 1: initial_location=0x1001 (4 bytes), address=0x50 (4 bytes) + Content: 011c033b1c000000000000000200000000100000300000000110000050000000 +ProgramHeaders: + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + VAddr: 0x1000 + PAddr: 0x1000 + MemSize: 0x20 + FileSize: 0x20 + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr diff --git a/llvm/test/tools/llvm-readobj/ELF/unwind.test b/llvm/test/tools/llvm-readobj/ELF/unwind.test index 2e51ec2..16e3479 100644 --- a/llvm/test/tools/llvm-readobj/ELF/unwind.test +++ b/llvm/test/tools/llvm-readobj/ELF/unwind.test @@ -358,3 +358,36 @@ ProgramHeaders: # BROKEN-CONTENT2-NEXT: Size: [[SIZE]] # BROKEN-CONTENT2-NEXT: Corresponding Section: # BROKEN-CONTENT2-NEXT: error: '[[FILE]]': program header [index 0] has a p_offset ([[OFFSET]]) + p_filesz ([[SIZE]]) that cannot be represented + +## Check we report an error for an unsupported table_enc encoding. +# RUN: yaml2obj --docnum=5 %s -o %t.badtableenc +# RUN: not llvm-readelf --unwind %t.badtableenc 2>&1 | FileCheck %s -DFILE=%t.badtableenc --check-prefix=BAD-TABLE-ENC + +# BAD-TABLE-ENC: EHFrameHeader { +# BAD-TABLE-ENC-NEXT: Address: 0x1000 +# BAD-TABLE-ENC: table_enc: 0xfe +# BAD-TABLE-ENC-NEXT: error: '[[FILE]]': unexpected encoding table_enc 0xfe + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .eh_frame_hdr + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x1000 + AddressAlign: 4 +## Header with invalid table_enc (0xfe) + Content: 011b03fe00000000 +ProgramHeaders: + - Type: PT_GNU_EH_FRAME + Flags: [ PF_R ] + VAddr: 0x1000 + PAddr: 0x1000 + MemSize: 0x8 + FileSize: 0x8 + FirstSec: .eh_frame_hdr + LastSec: .eh_frame_hdr diff --git a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h index 85c4165d..3a45480 100644 --- a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h +++ b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h @@ -129,7 +129,12 @@ void PrinterContext<ELFT>::printEHFrameHdr(const Elf_Phdr *EHFramePHdr) const { uint64_t EHFramePtrEnc = DE.getU8(&Offset); W.startLine() << format("eh_frame_ptr_enc: 0x%" PRIx64 "\n", EHFramePtrEnc); - if (EHFramePtrEnc != (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4)) + unsigned EHFramePtrSize = 0; + if (EHFramePtrEnc == (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4)) + EHFramePtrSize = 4; + else if (EHFramePtrEnc == (dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8)) + EHFramePtrSize = 8; + else reportError(object::createError("unexpected encoding eh_frame_ptr_enc"), ObjF.getFileName()); @@ -141,11 +146,18 @@ void PrinterContext<ELFT>::printEHFrameHdr(const Elf_Phdr *EHFramePHdr) const { uint64_t TableEnc = DE.getU8(&Offset); W.startLine() << format("table_enc: 0x%" PRIx64 "\n", TableEnc); - if (TableEnc != (dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata4)) - reportError(object::createError("unexpected encoding table_enc"), + unsigned TableEntrySize = 0; + if (TableEnc == (dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata4)) + TableEntrySize = 4; + else if (TableEnc == (dwarf::DW_EH_PE_datarel | dwarf::DW_EH_PE_sdata8)) + TableEntrySize = 8; + else + reportError(object::createError("unexpected encoding table_enc 0x" + + Twine::utohexstr(TableEnc)), ObjF.getFileName()); - auto EHFramePtr = DE.getSigned(&Offset, 4) + EHFrameHdrAddress + 4; + auto EHFramePtr = + DE.getSigned(&Offset, EHFramePtrSize) + EHFrameHdrAddress + 4; W.startLine() << format("eh_frame_ptr: 0x%" PRIx64 "\n", EHFramePtr); auto FDECount = DE.getUnsigned(&Offset, 4); @@ -153,12 +165,13 @@ void PrinterContext<ELFT>::printEHFrameHdr(const Elf_Phdr *EHFramePHdr) const { unsigned NumEntries = 0; uint64_t PrevPC = 0; - while (Offset + 8 <= EHFramePHdr->p_memsz && NumEntries < FDECount) { + while (Offset + 2 * TableEntrySize <= EHFramePHdr->p_memsz && + NumEntries < FDECount) { DictScope D(W, std::string("entry ") + std::to_string(NumEntries)); - auto InitialPC = DE.getSigned(&Offset, 4) + EHFrameHdrAddress; + auto InitialPC = DE.getSigned(&Offset, TableEntrySize) + EHFrameHdrAddress; W.startLine() << format("initial_location: 0x%" PRIx64 "\n", InitialPC); - auto Address = DE.getSigned(&Offset, 4) + EHFrameHdrAddress; + auto Address = DE.getSigned(&Offset, TableEntrySize) + EHFrameHdrAddress; W.startLine() << format("address: 0x%" PRIx64 "\n", Address); if (InitialPC < PrevPC) |
