aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/DWARFLinker
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/DWARFLinker')
-rw-r--r--llvm/lib/DWARFLinker/DWARFLinker.cpp64
-rw-r--r--llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp6
-rw-r--r--llvm/lib/DWARFLinker/DWARFStreamer.cpp20
3 files changed, 40 insertions, 50 deletions
diff --git a/llvm/lib/DWARFLinker/DWARFLinker.cpp b/llvm/lib/DWARFLinker/DWARFLinker.cpp
index 298359dea9af..62b7f629f403 100644
--- a/llvm/lib/DWARFLinker/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinker.cpp
@@ -504,9 +504,14 @@ unsigned DWARFLinker::shouldKeepSubprogramDIE(
&DIE);
return Flags;
}
+ if (*LowPc > *HighPc) {
+ reportWarning("low_pc greater than high_pc. Range will be discarded.\n",
+ File, &DIE);
+ return Flags;
+ }
// Replace the debug map range with a more accurate one.
- Ranges[*LowPc] = ObjFileAddressRange(*HighPc, MyInfo.AddrAdjust);
+ Ranges.insert({*LowPc, *HighPc}, MyInfo.AddrAdjust);
Unit.addFunctionRange(*LowPc, *HighPc, MyInfo.AddrAdjust);
return Flags;
}
@@ -1575,7 +1580,7 @@ void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit,
DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),
OrigDwarf.getDWARFObj().getRangesSection(),
OrigDwarf.isLittleEndian(), AddressSize);
- auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
+ Optional<std::pair<AddressRange, int64_t>> CurrRange;
DWARFUnit &OrigUnit = Unit.getOrigUnit();
auto OrigUnitDie = OrigUnit.getUnitDIE(false);
uint64_t OrigLowPc =
@@ -1598,12 +1603,11 @@ void DWARFLinker::patchRangesForUnit(const CompileUnit &Unit,
if (!Entries.empty()) {
const DWARFDebugRangeList::RangeListEntry &First = Entries.front();
- if (CurrRange == InvalidRange ||
- First.StartAddress + OrigLowPc < CurrRange.start() ||
- First.StartAddress + OrigLowPc >= CurrRange.stop()) {
- CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc);
- if (CurrRange == InvalidRange ||
- CurrRange.start() > First.StartAddress + OrigLowPc) {
+ if (!CurrRange ||
+ !CurrRange->first.contains(First.StartAddress + OrigLowPc)) {
+ CurrRange = FunctionRanges.getRangeValueThatContains(
+ First.StartAddress + OrigLowPc);
+ if (!CurrRange) {
reportWarning("no mapping for range.", File);
continue;
}
@@ -1710,7 +1714,7 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
// in NewRows.
std::vector<DWARFDebugLine::Row> Seq;
const auto &FunctionRanges = Unit.getFunctionRanges();
- auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange;
+ Optional<std::pair<AddressRange, int64_t>> CurrRange;
// FIXME: This logic is meant to generate exactly the same output as
// Darwin's classic dsymutil. There is a nicer way to implement this
@@ -1729,19 +1733,14 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
// it is marked as end_sequence in the input (because in that
// case, the relocation offset is accurate and that entry won't
// serve as the start of another function).
- if (CurrRange == InvalidRange || Row.Address.Address < CurrRange.start() ||
- Row.Address.Address > CurrRange.stop() ||
- (Row.Address.Address == CurrRange.stop() && !Row.EndSequence)) {
+ if (!CurrRange || !CurrRange->first.contains(Row.Address.Address) ||
+ (Row.Address.Address == CurrRange->first.end() && !Row.EndSequence)) {
// We just stepped out of a known range. Insert a end_sequence
// corresponding to the end of the range.
- uint64_t StopAddress = CurrRange != InvalidRange
- ? CurrRange.stop() + CurrRange.value()
- : -1ULL;
- CurrRange = FunctionRanges.find(Row.Address.Address);
- bool CurrRangeValid =
- CurrRange != InvalidRange && CurrRange.start() <= Row.Address.Address;
- if (!CurrRangeValid) {
- CurrRange = InvalidRange;
+ uint64_t StopAddress =
+ CurrRange ? CurrRange->first.end() + CurrRange->second : -1ULL;
+ CurrRange = FunctionRanges.getRangeValueThatContains(Row.Address.Address);
+ if (!CurrRange) {
if (StopAddress != -1ULL) {
// Try harder by looking in the Address ranges map.
// There are corner cases where this finds a
@@ -1749,14 +1748,9 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
// for now do as dsymutil.
// FIXME: Understand exactly what cases this addresses and
// potentially remove it along with the Ranges map.
- auto Range = Ranges.lower_bound(Row.Address.Address);
- if (Range != Ranges.begin() && Range != Ranges.end())
- --Range;
-
- if (Range != Ranges.end() && Range->first <= Row.Address.Address &&
- Range->second.HighPC >= Row.Address.Address) {
- StopAddress = Row.Address.Address + Range->second.Offset;
- }
+ if (Optional<std::pair<AddressRange, int64_t>> Range =
+ Ranges.getRangeValueThatContains(Row.Address.Address))
+ StopAddress = Row.Address.Address + (*Range).second;
}
}
if (StopAddress != -1ULL && !Seq.empty()) {
@@ -1772,7 +1766,7 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
insertLineSequence(Seq, NewRows);
}
- if (!CurrRangeValid)
+ if (!CurrRange)
continue;
}
@@ -1781,7 +1775,7 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
continue;
// Relocate row address and add it to the current sequence.
- Row.Address.Address += CurrRange.value();
+ Row.Address.Address += CurrRange->second;
Seq.emplace_back(Row);
if (Row.EndSequence)
@@ -1921,11 +1915,9 @@ void DWARFLinker::patchFrameInfoForObject(const DWARFFile &File,
// the function entry point, thus we can't just lookup the address
// in the debug map. Use the AddressInfo's range map to see if the FDE
// describes something that we can relocate.
- auto Range = Ranges.upper_bound(Loc);
- if (Range != Ranges.begin())
- --Range;
- if (Range == Ranges.end() || Range->first > Loc ||
- Range->second.HighPC <= Loc) {
+ Optional<std::pair<AddressRange, int64_t>> Range =
+ Ranges.getRangeValueThatContains(Loc);
+ if (!Range) {
// The +4 is to account for the size of the InitialLength field itself.
InputOffset = EntryOffset + InitialLength + 4;
continue;
@@ -1953,7 +1945,7 @@ void DWARFLinker::patchFrameInfoForObject(const DWARFFile &File,
// fields that will get reconstructed by emitFDE().
unsigned FDERemainingBytes = InitialLength - (4 + AddrSize);
TheDwarfEmitter->emitFDE(IteratorInserted.first->getValue(), AddrSize,
- Loc + Range->second.Offset,
+ Loc + Range->second,
FrameData.substr(InputOffset, FDERemainingBytes));
InputOffset += FDERemainingBytes;
}
diff --git a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
index e9e8be7fd008..1cb20c0bb948 100644
--- a/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
+++ b/llvm/lib/DWARFLinker/DWARFLinkerCompileUnit.cpp
@@ -105,11 +105,7 @@ void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
int64_t PcOffset) {
- // Don't add empty ranges to the interval map. They are a problem because
- // the interval map expects half open intervals. This is safe because they
- // are empty anyway.
- if (FuncHighPc != FuncLowPc)
- Ranges.insert(FuncLowPc, FuncHighPc, PcOffset);
+ Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
this->LowPc = std::min(LowPc, FuncLowPc + PcOffset);
this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
}
diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
index 55ff6b14f945..a00e51fcf135 100644
--- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
@@ -321,13 +321,14 @@ void DwarfStreamer::emitSwiftReflectionSection(
/// sized addresses describing the ranges.
void DwarfStreamer::emitRangesEntries(
int64_t UnitPcOffset, uint64_t OrigLowPc,
- const FunctionIntervals::const_iterator &FuncRange,
+ Optional<std::pair<AddressRange, int64_t>> FuncRange,
const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
unsigned AddressSize) {
MS->switchSection(MC->getObjectFileInfo()->getDwarfRangesSection());
// Offset each range by the right amount.
- int64_t PcOffset = Entries.empty() ? 0 : FuncRange.value() + UnitPcOffset;
+ int64_t PcOffset =
+ (Entries.empty() || !FuncRange) ? 0 : FuncRange->second + UnitPcOffset;
for (const auto &Range : Entries) {
if (Range.isBaseAddressSelectionEntry(AddressSize)) {
warn("unsupported base address selection operation",
@@ -339,8 +340,7 @@ void DwarfStreamer::emitRangesEntries(
continue;
// All range entries should lie in the function range.
- if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() &&
- Range.EndAddress + OrigLowPc <= FuncRange.stop()))
+ if (!FuncRange->first.contains(Range.StartAddress + OrigLowPc))
warn("inconsistent range data.", "emitting debug_ranges");
MS->emitIntValue(Range.StartAddress + PcOffset, AddressSize);
MS->emitIntValue(Range.EndAddress + PcOffset, AddressSize);
@@ -365,11 +365,13 @@ void DwarfStreamer::emitUnitRangesEntries(CompileUnit &Unit,
// IntervalMap will have coalesced the non-linked ranges, but here
// we want to coalesce the linked addresses.
std::vector<std::pair<uint64_t, uint64_t>> Ranges;
- const auto &FunctionRanges = Unit.getFunctionRanges();
- for (auto Range = FunctionRanges.begin(), End = FunctionRanges.end();
- Range != End; ++Range)
- Ranges.push_back(std::make_pair(Range.start() + Range.value(),
- Range.stop() + Range.value()));
+ const RangesTy &FunctionRanges = Unit.getFunctionRanges();
+ for (size_t Idx = 0; Idx < FunctionRanges.size(); Idx++) {
+ std::pair<AddressRange, int64_t> CurRange = FunctionRanges[Idx];
+
+ Ranges.push_back(std::make_pair(CurRange.first.start() + CurRange.second,
+ CurRange.first.end() + CurRange.second));
+ }
// The object addresses where sorted, but again, the linked
// addresses might end up in a different order.