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

Commit 2b4cee4

Browse files
committed
DebugInfo: reduce DIE range verification on object files
Relocatable content may have overlapping ranges until the sections are finalized. This reduces the amount of verification that is done on an object file so that invalid errors are not raised. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@345441 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent a646cd0 commit 2b4cee4

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