mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[DWARF] Return Error from DWARFDebugArangeSet::extract().
This helps to detect and report parsing errors better. The patch follows the ideas of LLDB's patches D59370 and D59381. It adds tests for valid and some invalid cases. More checks and tests to come. Note that the patch fixes validation of the Length field because the value does not include the field itself. The existing users are updated to show the error messages. Differential Revision: https://reviews.llvm.org/D71875
This commit is contained in:
parent
6a79709adb
commit
25f6cfa0aa
@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Support/DataExtractor.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
@ -57,7 +58,7 @@ public:
|
||||
DWARFDebugArangeSet() { clear(); }
|
||||
|
||||
void clear();
|
||||
bool extract(DataExtractor data, uint64_t *offset_ptr);
|
||||
Error extract(DataExtractor data, uint64_t *offset_ptr);
|
||||
void dump(raw_ostream &OS) const;
|
||||
|
||||
uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }
|
||||
|
@ -453,9 +453,14 @@ void DWARFContext::dump(
|
||||
uint64_t offset = 0;
|
||||
DataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 0);
|
||||
DWARFDebugArangeSet set;
|
||||
while (set.extract(arangesData, &offset))
|
||||
while (arangesData.isValidOffset(offset)) {
|
||||
if (Error E = set.extract(arangesData, &offset)) {
|
||||
WithColor::error() << toString(std::move(E)) << '\n';
|
||||
break;
|
||||
}
|
||||
set.dump(OS);
|
||||
}
|
||||
}
|
||||
|
||||
auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
|
||||
DIDumpOptions DumpOpts,
|
||||
|
@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
@ -29,9 +30,8 @@ void DWARFDebugArangeSet::clear() {
|
||||
ArangeDescriptors.clear();
|
||||
}
|
||||
|
||||
bool
|
||||
DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
|
||||
if (data.isValidOffset(*offset_ptr)) {
|
||||
Error DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
|
||||
assert(data.isValidOffset(*offset_ptr));
|
||||
ArangeDescriptors.clear();
|
||||
Offset = *offset_ptr;
|
||||
|
||||
@ -56,11 +56,17 @@ DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
|
||||
HeaderData.SegSize = data.getU8(offset_ptr);
|
||||
|
||||
// Perform basic validation of the header fields.
|
||||
if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length) ||
|
||||
(HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
if (!data.isValidOffsetForDataOfSize(Offset, HeaderData.Length + 4))
|
||||
return createStringError(errc::invalid_argument,
|
||||
"the length of address range table at offset "
|
||||
"0x%" PRIx64 " exceeds section size",
|
||||
Offset);
|
||||
if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
|
||||
return createStringError(errc::invalid_argument,
|
||||
"address range table at offset 0x%" PRIx64
|
||||
" has unsupported address size: %d "
|
||||
"(4 and 8 supported)",
|
||||
Offset, HeaderData.AddrSize);
|
||||
|
||||
// The first tuple following the header in each set begins at an offset
|
||||
// that is a multiple of the size of a single tuple (that is, twice the
|
||||
@ -87,15 +93,15 @@ DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
|
||||
|
||||
// Each set of tuples is terminated by a 0 for the address and 0
|
||||
// for the length.
|
||||
if (arangeDescriptor.Address || arangeDescriptor.Length)
|
||||
if (arangeDescriptor.Address == 0 && arangeDescriptor.Length == 0)
|
||||
return ErrorSuccess();
|
||||
ArangeDescriptors.push_back(arangeDescriptor);
|
||||
else
|
||||
return true; // We are done if we get a zero address and length
|
||||
}
|
||||
|
||||
return false; // No termination tuple is found.
|
||||
}
|
||||
return false;
|
||||
return createStringError(errc::invalid_argument,
|
||||
"address range table at offset 0x%" PRIx64
|
||||
" is not terminated by null entry",
|
||||
Offset);
|
||||
}
|
||||
|
||||
void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
|
||||
|
@ -26,7 +26,11 @@ void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
|
||||
uint64_t Offset = 0;
|
||||
DWARFDebugArangeSet Set;
|
||||
|
||||
while (Set.extract(DebugArangesData, &Offset)) {
|
||||
while (DebugArangesData.isValidOffset(Offset)) {
|
||||
if (Error E = Set.extract(DebugArangesData, &Offset)) {
|
||||
WithColor::error() << toString(std::move(E)) << '\n';
|
||||
return;
|
||||
}
|
||||
uint64_t CUOffset = Set.getCompileUnitDIEOffset();
|
||||
for (const auto &Desc : Set.descriptors()) {
|
||||
uint64_t LowPC = Desc.Address;
|
||||
|
@ -5,7 +5,7 @@
|
||||
.section .debug_aranges,"",@progbits
|
||||
# CHECK: .debug_aranges contents:
|
||||
|
||||
## Check that an empty set of ranges is supported.
|
||||
## Case 1: Check that an empty set of ranges is supported.
|
||||
.long .L1end - .L1version # Length
|
||||
# CHECK: Address Range Header: length = 0x00000014,
|
||||
.L1version:
|
||||
@ -22,3 +22,44 @@
|
||||
.long 0, 0 # Termination tuple
|
||||
# CHECK-NOT: [0x
|
||||
.L1end:
|
||||
|
||||
## Case 2: Check that the address size of 4 is supported.
|
||||
.long .L2end - .L2version # Length
|
||||
# CHECK: Address Range Header: length = 0x0000001c,
|
||||
.L2version:
|
||||
.short 2 # Version
|
||||
.long 0x11223344 # Debug Info Offset
|
||||
.byte 4 # Address Size
|
||||
.byte 0 # Segment Selector Size
|
||||
# CHECK-SAME: version = 0x0002,
|
||||
# CHECK-SAME: cu_offset = 0x11223344,
|
||||
# CHECK-SAME: addr_size = 0x04,
|
||||
# CHECK-SAME: seg_size = 0x00
|
||||
.space 4 # Padding
|
||||
.L2tuples:
|
||||
.long 0x11223344, 0x01020304 # Address and length
|
||||
# CHECK-NEXT: [0x11223344, 0x12243648)
|
||||
.long 0, 0 # Termination tuple
|
||||
# CHECK-NOT: [0x
|
||||
.L2end:
|
||||
|
||||
## Case 3: Check that the address size of 8 is also supported.
|
||||
.long .L3end - .L3version # Length
|
||||
# CHECK: Address Range Header: length = 0x0000002c,
|
||||
.L3version:
|
||||
.short 2 # Version
|
||||
.long 0x22334455 # Debug Info Offset
|
||||
.byte 8 # Address Size
|
||||
.byte 0 # Segment Selector Size
|
||||
# CHECK-SAME: version = 0x0002,
|
||||
# CHECK-SAME: cu_offset = 0x22334455,
|
||||
# CHECK-SAME: addr_size = 0x08,
|
||||
# CHECK-SAME: seg_size = 0x00
|
||||
.space 4 # Padding
|
||||
.L3tuples:
|
||||
.quad 0x1122334455667788 # Address
|
||||
.quad 0x0102030405060708 # Length
|
||||
# CHECK-NEXT: [0x1122334455667788, 0x122436485a6c7e90)
|
||||
.quad 0, 0 # Termination tuple
|
||||
# CHECK-NOT: [0x
|
||||
.L3end:
|
||||
|
@ -189,18 +189,6 @@ LoadCommands:
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_aranges
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003083
|
||||
size: 48
|
||||
offset: 0x00002083
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_info
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000030B3
|
||||
|
@ -126,18 +126,6 @@ LoadCommands:
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_aranges
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100002084
|
||||
size: 48
|
||||
offset: 0x00002084
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_info
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000020B4
|
||||
|
@ -189,18 +189,6 @@ LoadCommands:
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_aranges
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003083
|
||||
size: 48
|
||||
offset: 0x00002083
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_info
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000030B3
|
||||
|
@ -189,18 +189,6 @@ LoadCommands:
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_aranges
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003083
|
||||
size: 48
|
||||
offset: 0x00002083
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_info
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000030B3
|
||||
|
@ -189,18 +189,6 @@ LoadCommands:
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_aranges
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003083
|
||||
size: 48
|
||||
offset: 0x00002083
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_info
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000030B3
|
||||
|
21
test/tools/llvm-dwarfdump/X86/debug_aranges-error.s
Normal file
21
test/tools/llvm-dwarfdump/X86/debug_aranges-error.s
Normal file
@ -0,0 +1,21 @@
|
||||
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
|
||||
# RUN: llvm-dwarfdump -debug-aranges %t.o 2>&1 | FileCheck %s
|
||||
# RUN: llvm-dwarfdump -lookup 10 %t.o 2>&1 | FileCheck %s
|
||||
|
||||
## This checks that llvm-dwarfdump shows parsing errors in .debug_aranges.
|
||||
## For more error cases see unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp.
|
||||
|
||||
# CHECK: the length of address range table at offset 0x0 exceeds section size
|
||||
|
||||
.section .debug_aranges,"",@progbits
|
||||
.long .Lend - .Lversion + 1 # The length exceeds the section boundaries
|
||||
.Lversion:
|
||||
.short 2 # Version
|
||||
.long 0 # Debug Info Offset
|
||||
.byte 4 # Address Size
|
||||
.byte 0 # Segment Selector Size
|
||||
.space 4 # Padding
|
||||
.Ltuples:
|
||||
.long 0, 1 # Address and length
|
||||
.long 0, 0 # Termination tuple
|
||||
.Lend:
|
301
test/tools/obj2yaml/macho-DWARF-debug_aranges-error.yaml
Normal file
301
test/tools/obj2yaml/macho-DWARF-debug_aranges-error.yaml
Normal file
@ -0,0 +1,301 @@
|
||||
# RUN: yaml2obj %s | not obj2yaml 2>&1 | FileCheck %s
|
||||
|
||||
--- !mach-o
|
||||
FileHeader:
|
||||
magic: 0xFEEDFACF
|
||||
cputype: 0x01000007
|
||||
cpusubtype: 0x00000003
|
||||
filetype: 0x0000000A
|
||||
ncmds: 5
|
||||
sizeofcmds: 1800
|
||||
flags: 0x00000000
|
||||
reserved: 0x00000000
|
||||
LoadCommands:
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 72
|
||||
segname: __PAGEZERO
|
||||
vmaddr: 0
|
||||
vmsize: 4294967296
|
||||
fileoff: 0
|
||||
filesize: 0
|
||||
maxprot: 0
|
||||
initprot: 0
|
||||
nsects: 0
|
||||
flags: 0
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 472
|
||||
segname: __TEXT
|
||||
vmaddr: 4294967296
|
||||
vmsize: 4096
|
||||
fileoff: 0
|
||||
filesize: 0
|
||||
maxprot: 7
|
||||
initprot: 5
|
||||
nsects: 5
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __text
|
||||
segname: __TEXT
|
||||
addr: 0x0000000100000F50
|
||||
size: 52
|
||||
offset: 0x00000000
|
||||
align: 4
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x80000400
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __stubs
|
||||
segname: __TEXT
|
||||
addr: 0x0000000100000F84
|
||||
size: 6
|
||||
offset: 0x00000000
|
||||
align: 1
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x80000408
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000006
|
||||
reserved3: 0x00000000
|
||||
- sectname: __stub_helper
|
||||
segname: __TEXT
|
||||
addr: 0x0000000100000F8C
|
||||
size: 26
|
||||
offset: 0x00000000
|
||||
align: 2
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x80000400
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __cstring
|
||||
segname: __TEXT
|
||||
addr: 0x0000000100000FA6
|
||||
size: 14
|
||||
offset: 0x00000000
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000002
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __unwind_info
|
||||
segname: __TEXT
|
||||
addr: 0x0000000100000FB4
|
||||
size: 72
|
||||
offset: 0x00000000
|
||||
align: 2
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 232
|
||||
segname: __DATA
|
||||
vmaddr: 4294971392
|
||||
vmsize: 4096
|
||||
fileoff: 0
|
||||
filesize: 0
|
||||
maxprot: 7
|
||||
initprot: 3
|
||||
nsects: 2
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __nl_symbol_ptr
|
||||
segname: __DATA
|
||||
addr: 0x0000000100001000
|
||||
size: 16
|
||||
offset: 0x00000000
|
||||
align: 3
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000006
|
||||
reserved1: 0x00000001
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __la_symbol_ptr
|
||||
segname: __DATA
|
||||
addr: 0x0000000100001010
|
||||
size: 8
|
||||
offset: 0x00000000
|
||||
align: 3
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000007
|
||||
reserved1: 0x00000003
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 72
|
||||
segname: __LINKEDIT
|
||||
vmaddr: 4294975488
|
||||
vmsize: 4096
|
||||
fileoff: 4096
|
||||
filesize: 60
|
||||
maxprot: 7
|
||||
initprot: 1
|
||||
nsects: 0
|
||||
flags: 0
|
||||
- cmd: LC_SEGMENT_64
|
||||
cmdsize: 952
|
||||
segname: __DWARF
|
||||
vmaddr: 4294979584
|
||||
vmsize: 4096
|
||||
fileoff: 8192
|
||||
filesize: 764
|
||||
maxprot: 7
|
||||
initprot: 3
|
||||
nsects: 11
|
||||
flags: 0
|
||||
Sections:
|
||||
- sectname: __debug_line
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003000
|
||||
size: 69
|
||||
offset: 0x00002000
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_pubnames
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003045
|
||||
size: 27
|
||||
offset: 0x00002045
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_pubtypes
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003060
|
||||
size: 35
|
||||
offset: 0x00002060
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_aranges
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003083
|
||||
size: 48
|
||||
offset: 0x00002083
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_info
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000030B3
|
||||
size: 121
|
||||
offset: 0x000020B3
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_abbrev
|
||||
segname: __DWARF
|
||||
addr: 0x000000010000312C
|
||||
size: 76
|
||||
offset: 0x0000212C
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __debug_str
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003178
|
||||
size: 142
|
||||
offset: 0x00002178
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __apple_names
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003206
|
||||
size: 60
|
||||
offset: 0x00002206
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __apple_namespac
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003242
|
||||
size: 36
|
||||
offset: 0x00002242
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __apple_types
|
||||
segname: __DWARF
|
||||
addr: 0x0000000100003266
|
||||
size: 114
|
||||
offset: 0x00002266
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
- sectname: __apple_objc
|
||||
segname: __DWARF
|
||||
addr: 0x00000001000032D8
|
||||
size: 36
|
||||
offset: 0x000022D8
|
||||
align: 0
|
||||
reloff: 0x00000000
|
||||
nreloc: 0
|
||||
flags: 0x00000000
|
||||
reserved1: 0x00000000
|
||||
reserved2: 0x00000000
|
||||
reserved3: 0x00000000
|
||||
DWARF:
|
||||
debug_aranges:
|
||||
- Length:
|
||||
TotalLength: 45
|
||||
Version: 2
|
||||
CuOffset: 0
|
||||
AddrSize: 8
|
||||
SegSize: 0
|
||||
Descriptors:
|
||||
- Address: 0x0000000100000F50
|
||||
Length: 52
|
||||
...
|
||||
|
||||
#CHECK: the length of address range table at offset 0x0 exceeds section size
|
@ -56,13 +56,15 @@ void dumpDebugStrings(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
}
|
||||
}
|
||||
|
||||
void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
Error dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
DataExtractor ArangesData(DCtx.getDWARFObj().getArangesSection(),
|
||||
DCtx.isLittleEndian(), 0);
|
||||
uint64_t Offset = 0;
|
||||
DWARFDebugArangeSet Set;
|
||||
|
||||
while (Set.extract(ArangesData, &Offset)) {
|
||||
while (ArangesData.isValidOffset(Offset)) {
|
||||
if (Error E = Set.extract(ArangesData, &Offset))
|
||||
return E;
|
||||
DWARFYAML::ARange Range;
|
||||
Range.Length.setLength(Set.getHeader().Length);
|
||||
Range.Version = Set.getHeader().Version;
|
||||
@ -77,6 +79,7 @@ void dumpDebugARanges(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
}
|
||||
Y.ARanges.push_back(Range);
|
||||
}
|
||||
return ErrorSuccess();
|
||||
}
|
||||
|
||||
void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y,
|
||||
@ -346,12 +349,13 @@ void dumpDebugLines(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
}
|
||||
}
|
||||
|
||||
std::error_code dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
llvm::Error dwarf2yaml(DWARFContext &DCtx, DWARFYAML::Data &Y) {
|
||||
dumpDebugAbbrev(DCtx, Y);
|
||||
dumpDebugStrings(DCtx, Y);
|
||||
dumpDebugARanges(DCtx, Y);
|
||||
if (Error E = dumpDebugARanges(DCtx, Y))
|
||||
return E;
|
||||
dumpDebugPubSections(DCtx, Y);
|
||||
dumpDebugInfo(DCtx, Y);
|
||||
dumpDebugLines(DCtx, Y);
|
||||
return obj2yaml_error::success;
|
||||
return ErrorSuccess();
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() {
|
||||
|
||||
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
|
||||
if (auto Err = dwarf2yaml(*DICtx, Y->DWARF))
|
||||
return errorCodeToError(Err);
|
||||
return std::move(Err);
|
||||
return std::move(Y);
|
||||
}
|
||||
|
||||
@ -543,20 +543,20 @@ Error macho2yaml(raw_ostream &Out, const object::MachOUniversalBinary &Obj) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
std::error_code macho2yaml(raw_ostream &Out, const object::Binary &Binary) {
|
||||
Error macho2yaml(raw_ostream &Out, const object::Binary &Binary) {
|
||||
if (const auto *MachOObj = dyn_cast<object::MachOUniversalBinary>(&Binary)) {
|
||||
if (auto Err = macho2yaml(Out, *MachOObj)) {
|
||||
return errorToErrorCode(std::move(Err));
|
||||
return Err;
|
||||
}
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
if (const auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Binary)) {
|
||||
if (auto Err = macho2yaml(Out, *MachOObj)) {
|
||||
return errorToErrorCode(std::move(Err));
|
||||
return Err;
|
||||
}
|
||||
return obj2yaml_error::success;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
return obj2yaml_error::unsupported_obj_file_format;
|
||||
return errorCodeToError(obj2yaml_error::unsupported_obj_file_format);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ static Error dumpInput(StringRef File) {
|
||||
// Universal MachO is not a subclass of ObjectFile, so it needs to be handled
|
||||
// here with the other binary types.
|
||||
if (Binary.isMachO() || Binary.isMachOUniversalBinary())
|
||||
return errorCodeToError(macho2yaml(outs(), Binary));
|
||||
return macho2yaml(outs(), Binary);
|
||||
// TODO: If this is an archive, then burst it and dump each entry
|
||||
if (ObjectFile *Obj = dyn_cast<ObjectFile>(&Binary))
|
||||
return dumpObject(*Obj);
|
||||
|
@ -23,7 +23,7 @@ std::error_code coff2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::COFFObjectFile &Obj);
|
||||
llvm::Error elf2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::ObjectFile &Obj);
|
||||
std::error_code macho2yaml(llvm::raw_ostream &Out,
|
||||
llvm::Error macho2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::Binary &Obj);
|
||||
llvm::Error minidump2yaml(llvm::raw_ostream &Out,
|
||||
const llvm::object::MinidumpFile &Obj);
|
||||
@ -40,6 +40,6 @@ struct Data;
|
||||
}
|
||||
}
|
||||
|
||||
std::error_code dwarf2yaml(llvm::DWARFContext &DCtx, llvm::DWARFYAML::Data &Y);
|
||||
llvm::Error dwarf2yaml(llvm::DWARFContext &DCtx, llvm::DWARFYAML::Data &Y);
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
|
||||
add_llvm_unittest(DebugInfoDWARFTests
|
||||
DwarfGenerator.cpp
|
||||
DwarfUtils.cpp
|
||||
DWARFDebugArangeSetTest.cpp
|
||||
DWARFDebugInfoTest.cpp
|
||||
DWARFDebugLineTest.cpp
|
||||
DWARFDieTest.cpp
|
||||
|
75
unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp
Normal file
75
unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
//===- llvm/unittest/DebugInfo/DWARFDebugArangeSetTest.cpp-----------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
template <size_t SecSize>
|
||||
void ExpectExtractError(const char (&SecDataRaw)[SecSize],
|
||||
const char *ErrorMessage) {
|
||||
DataExtractor Extractor(StringRef(SecDataRaw, SecSize - 1),
|
||||
/* IsLittleEndian = */ true,
|
||||
/* AddressSize = */ 4);
|
||||
DWARFDebugArangeSet Set;
|
||||
uint64_t Offset = 0;
|
||||
Error E = Set.extract(Extractor, &Offset);
|
||||
ASSERT_TRUE(E.operator bool());
|
||||
EXPECT_STREQ(ErrorMessage, toString(std::move(E)).c_str());
|
||||
}
|
||||
|
||||
TEST(DWARFDebugArangeSet, LengthExceedsSectionSize) {
|
||||
static const char DebugArangesSecRaw[] =
|
||||
"\x15\x00\x00\x00" // The length exceeds the section boundaries
|
||||
"\x02\x00" // Version
|
||||
"\x00\x00\x00\x00" // Debug Info Offset
|
||||
"\x04" // Address Size
|
||||
"\x00" // Segment Selector Size
|
||||
"\x00\x00\x00\x00" // Padding
|
||||
"\x00\x00\x00\x00" // Termination tuple
|
||||
"\x00\x00\x00\x00";
|
||||
ExpectExtractError(
|
||||
DebugArangesSecRaw,
|
||||
"the length of address range table at offset 0x0 exceeds section size");
|
||||
}
|
||||
|
||||
TEST(DWARFDebugArangeSet, UnsupportedAddressSize) {
|
||||
static const char DebugArangesSecRaw[] =
|
||||
"\x0c\x00\x00\x00" // Length
|
||||
"\x02\x00" // Version
|
||||
"\x00\x00\x00\x00" // Debug Info Offset
|
||||
"\x02" // Address Size (not supported)
|
||||
"\x00" // Segment Selector Size
|
||||
// No padding
|
||||
"\x00\x00\x00\x00"; // Termination tuple
|
||||
ExpectExtractError(
|
||||
DebugArangesSecRaw,
|
||||
"address range table at offset 0x0 has unsupported address size: 2 "
|
||||
"(4 and 8 supported)");
|
||||
}
|
||||
|
||||
TEST(DWARFDebugArangeSet, NoTerminationEntry) {
|
||||
static const char DebugArangesSecRaw[] =
|
||||
"\x14\x00\x00\x00" // Length
|
||||
"\x02\x00" // Version
|
||||
"\x00\x00\x00\x00" // Debug Info Offset
|
||||
"\x04" // Address Size
|
||||
"\x00" // Segment Selector Size
|
||||
"\x00\x00\x00\x00" // Padding
|
||||
"\x00\x00\x00\x00" // Entry: Address
|
||||
"\x01\x00\x00\x00" // Length
|
||||
; // No termination tuple
|
||||
ExpectExtractError(
|
||||
DebugArangesSecRaw,
|
||||
"address range table at offset 0x0 is not terminated by null entry");
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
Loading…
Reference in New Issue
Block a user