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

Commit 35c4cd1

Browse files
committed
[dsymutil] Correctly handle DW_TAG_label
This patch contains logic for handling DW_TAG_label that's present in darwin's dsymutil implementation, but not yet upstream. Differential revision: https://reviews.llvm.org/D43438 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@325600 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent aedbf6f commit 35c4cd1

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

test/tools/dsymutil/Inputs/label.o

1.06 KB
Binary file not shown.

test/tools/dsymutil/X86/label.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# RUN: llvm-dsymutil -oso-prepend-path %p/../Inputs -y %s -f -o - | llvm-dwarfdump - --debug-info | FileCheck %s
2+
3+
# Compile with:
4+
# echo -e ".global _foo;\nfoo:\nnop" | clang -x assembler -g - -c -o /tmp/label.o
5+
6+
# CHECK: DW_TAG_label
7+
# CHECK-NEXT: DW_AT_name ("foo")
8+
9+
---
10+
triple: 'x86_64-apple-darwin'
11+
objects:
12+
- filename: label.o
13+
symbols:
14+
- { sym: _foo, objAddr: 0x0, binAddr: 0x1000, size: 0x1 }
15+
...
16+

tools/dsymutil/DwarfLinker.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ class CompileUnit {
327327

328328
uint64_t getLowPc() const { return LowPc; }
329329
uint64_t getHighPc() const { return HighPc; }
330+
bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }
330331

331332
Optional<PatchLocation> getUnitRangesAttribute() const {
332333
return UnitRangeAttribute;
@@ -366,6 +367,10 @@ class CompileUnit {
366367
/// Apply all fixups recored by noteForwardReference().
367368
void fixupForwardReferences();
368369

370+
/// Add the low_pc of a label that is relocatad by applying
371+
/// offset \p PCOffset.
372+
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);
373+
369374
/// Add a function range [\p LowPC, \p HighPC) that is relocatad by applying
370375
/// offset \p PCOffset.
371376
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
@@ -471,6 +476,9 @@ class CompileUnit {
471476
/// to the addresses to get the linked address.
472477
FunctionIntervals Ranges;
473478

479+
/// The DW_AT_low_pc of each DW_TAG_label.
480+
SmallDenseMap<uint64_t, uint64_t, 1> Labels;
481+
474482
/// DW_AT_ranges attributes to patch after we have gathered
475483
/// all the unit's function addresses.
476484
/// @{
@@ -585,6 +593,10 @@ void CompileUnit::fixupForwardReferences() {
585593
}
586594
}
587595

596+
void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
597+
Labels.insert({LabelLowPc, PcOffset});
598+
}
599+
588600
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
589601
int64_t PcOffset) {
590602
Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
@@ -2453,7 +2465,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
24532465
return Flags;
24542466

24552467
uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
2456-
const DWARFUnit &OrigUnit = Unit.getOrigUnit();
2468+
DWARFUnit &OrigUnit = Unit.getOrigUnit();
24572469
uint32_t LowPcOffset, LowPcEndOffset;
24582470
std::tie(LowPcOffset, LowPcEndOffset) =
24592471
getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit);
@@ -2471,6 +2483,20 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE(
24712483
DIE.dump(outs(), 8 /* Indent */, DumpOpts);
24722484
}
24732485

2486+
if (DIE.getTag() == dwarf::DW_TAG_label) {
2487+
if (Unit.hasLabelAt(*LowPc))
2488+
return Flags;
2489+
// FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider labels
2490+
// that don't fall into the CU's aranges. This is wrong IMO. Debug info
2491+
// generation bugs aside, this is really wrong in the case of labels, where
2492+
// a label marking the end of a function will have a PC == CU's high_pc.
2493+
if (dwarf::toAddress(OrigUnit.getUnitDIE().find(dwarf::DW_AT_high_pc))
2494+
.getValueOr(UINT64_MAX) <= LowPc)
2495+
return Flags;
2496+
Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust);
2497+
return Flags | TF_Keep;
2498+
}
2499+
24742500
Flags |= TF_Keep;
24752501

24762502
Optional<uint64_t> HighPc = DIE.getHighPC(*LowPc);
@@ -2498,6 +2524,7 @@ unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr,
24982524
case dwarf::DW_TAG_variable:
24992525
return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
25002526
case dwarf::DW_TAG_subprogram:
2527+
case dwarf::DW_TAG_label:
25012528
return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags);
25022529
case dwarf::DW_TAG_imported_module:
25032530
case dwarf::DW_TAG_imported_declaration:

0 commit comments

Comments
 (0)