Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 0b03c95

Browse files
Merge pull request #120 from compnerd/die-must-die
Relax DIE verification
2 parents a646cd0 + 185f861 commit 0b03c95

File tree

3 files changed

+106
-15
lines changed

3 files changed

+106
-15
lines changed

include/llvm/DebugInfo/DWARF/DWARFVerifier.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class DWARFVerifier {
9797
/// lies between to valid DIEs.
9898
std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
9999
uint32_t NumDebugLineErrors = 0;
100+
// Used to relax some checks that do not currently work portably
101+
bool IsObjectFile;
102+
bool IsMachOObject;
100103

101104
raw_ostream &error() const;
102105
raw_ostream &warn() const;
@@ -286,8 +289,8 @@ class DWARFVerifier {
286289

287290
public:
288291
DWARFVerifier(raw_ostream &S, DWARFContext &D,
289-
DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE())
290-
: OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)) {}
292+
DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE());
293+
291294
/// Verify the information in any of the following sections, if available:
292295
/// .debug_abbrev, debug_abbrev.dwo
293296
///

lib/DebugInfo/DWARF/DWARFVerifier.cpp

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -379,20 +379,42 @@ unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
379379
// Build RI for this DIE and check that ranges within this DIE do not
380380
// overlap.
381381
DieRangeInfo RI(Die);
382-
for (auto Range : Ranges) {
383-
if (!Range.valid()) {
384-
++NumErrors;
385-
error() << "Invalid address range " << Range << "\n";
386-
continue;
387-
}
388382

389-
// Verify that ranges don't intersect.
390-
const auto IntersectingRange = RI.insert(Range);
391-
if (IntersectingRange != RI.Ranges.end()) {
392-
++NumErrors;
393-
error() << "DIE has overlapping address ranges: " << Range << " and "
394-
<< *IntersectingRange << "\n";
395-
break;
383+
// TODO support object files better
384+
//
385+
// Some object file formats (i.e. non-MachO) support COMDAT. ELF in
386+
// particular does so by placing each function into a section. The DWARF data
387+
// for the function at that point uses a section relative DW_FORM_addrp for
388+
// the DW_AT_low_pc and a DW_FORM_data4 for the offset as the DW_AT_high_pc.
389+
// In such a case, when the Die is the CU, the ranges will overlap, and we
390+
// will flag valid conflicting ranges as invalid.
391+
//
392+
// For such targets, we should read the ranges from the CU and partition them
393+
// by the section id. The ranges within a particular section should be
394+
// disjoint, although the ranges across sections may overlap. We would map
395+
// the child die to the entity that it references and the section with which
396+
// it is associated. The child would then be checked against the range
397+
// information for the associated section.
398+
//
399+
// For now, simply elide the range verification for the CU DIEs if we are
400+
// processing an object file.
401+
402+
if (!IsObjectFile || IsMachOObject || Die.getTag() == DW_TAG_subprogram) {
403+
for (auto Range : Ranges) {
404+
if (!Range.valid()) {
405+
++NumErrors;
406+
error() << "Invalid address range " << Range << "\n";
407+
continue;
408+
}
409+
410+
// Verify that ranges don't intersect.
411+
const auto IntersectingRange = RI.insert(Range);
412+
if (IntersectingRange != RI.Ranges.end()) {
413+
++NumErrors;
414+
error() << "DIE has overlapping address ranges: " << Range << " and "
415+
<< *IntersectingRange << "\n";
416+
break;
417+
}
396418
}
397419
}
398420

@@ -721,6 +743,15 @@ void DWARFVerifier::verifyDebugLineRows() {
721743
}
722744
}
723745

746+
DWARFVerifier::DWARFVerifier(raw_ostream &S, DWARFContext &D,
747+
DIDumpOptions DumpOpts)
748+
: OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)) {
749+
if (const auto *F = DCtx.getDWARFObj().getFile()) {
750+
IsObjectFile = F->isRelocatableObject();
751+
IsMachOObject = F->isMachO();
752+
}
753+
}
754+
724755
bool DWARFVerifier::handleDebugLine() {
725756
NumDebugLineErrors = 0;
726757
OS << "Verifying .debug_line...\n";
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# RUN: llvm-mc -triple x86_64-unknown-linux-gnu -filetype obj -o - %s | llvm-dwarfdump --verify -
2+
3+
.text
4+
5+
.section .text.f,"ax",@progbits
6+
.globl f
7+
.type f,@function
8+
f:
9+
.Lfunc_begin0:
10+
pushq $32
11+
popq %rax
12+
retq
13+
.Lfunc_end0:
14+
.size f, .Lfunc_end0-f
15+
16+
.section .text.g,"ax",@progbits
17+
.globl g
18+
.type g,@function
19+
g:
20+
.Lfunc_begin1:
21+
pushq $64
22+
popq %rax
23+
retq
24+
.Lfunc_end1:
25+
.size g, .Lfunc_end1-g
26+
27+
.section .debug_abbrev,"",@progbits
28+
.byte 1 # Abbreviation Code
29+
.byte 17 # DW_TAG_compile_unit
30+
.byte 0 # DW_CHILDREN_no
31+
.byte 17 # DW_AT_low_pc
32+
.byte 1 # DW_FORM_addr
33+
.byte 85 # DW_AT_ranges
34+
.byte 23 # DW_FORM_sec_offset
35+
.byte 0 # EOM(1)
36+
.byte 0 # EOM(2)
37+
.byte 0 # EOM(3)
38+
39+
.section .debug_info,"",@progbits
40+
.Lcu_begin0:
41+
.long 20 # Length of Unit
42+
.short 4 # DWARF version number
43+
.long .debug_abbrev # Offset Into Abbrev. Section
44+
.byte 8 # Address Size (in bytes)
45+
.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
46+
.quad 0 # DW_AT_low_pc
47+
.long .Ldebug_ranges0 # DW_AT_ranges
48+
49+
.section .debug_ranges,"",@progbits
50+
.Ldebug_ranges0:
51+
.quad .Lfunc_begin0
52+
.quad .Lfunc_end0
53+
.quad .Lfunc_begin1
54+
.quad .Lfunc_end1
55+
.quad 0
56+
.quad 0
57+

0 commit comments

Comments
 (0)