summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2019-09-27 09:24:42 +0200
committerMilian Wolff <milian.wolff@kdab.com>2019-09-30 07:43:38 +0000
commit5e4c4d0b29fbcc40210de7aea46cb9b1dccc9e42 (patch)
tree0d811f244425bdec03a41939b61929d838b17153
parent4b98b893ebaded257d7693fb6500ca9955682d89 (diff)
Properly map discontiguous CU DIE ranges
Not all CU DIEs have a contiguous range, esp. when compiled with -ffunction-sections or when the linker deduplicates equal functions across compilation units. Change-Id: Ie22939e550b4b502a16c6e266740a885407f50f1 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--app/perfsymboltable.cpp39
1 files changed, 11 insertions, 28 deletions
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index 33248fb..2093bb8 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -603,29 +603,10 @@ class CuDieRanges
{
struct CuDieRange
{
- CuDieRange(Dwarf_Die *die, Dwarf_Addr bias)
- : cuDie(die)
- , bias(bias)
- {
- if (dwarf_lowpc(die, &low) != 0 || dwarf_highpc(die, &high) != 0) {
- Dwarf_Addr rangeLow = 0;
- Dwarf_Addr rangeHigh = 0;
- Dwarf_Addr base = 0;
- ptrdiff_t offset = 0;
- while ((offset = dwarf_ranges(die, offset, &base, &rangeLow, &rangeHigh)) > 0) {
- low = std::min(rangeLow, low);
- high = std::max(rangeHigh, high);
- }
- }
- low += bias;
- high += bias;
- }
-
- Dwarf_Die *cuDie = nullptr;
- Dwarf_Addr bias = 0;
-
- Dwarf_Addr low = std::numeric_limits<Dwarf_Addr>::max();
- Dwarf_Addr high = std::numeric_limits<Dwarf_Addr>::min();
+ Dwarf_Die *cuDie;
+ Dwarf_Addr bias;
+ Dwarf_Addr low;
+ Dwarf_Addr high;
bool contains(Dwarf_Addr addr) const
{
@@ -641,11 +622,13 @@ public:
Dwarf_Die *die = nullptr;
Dwarf_Addr bias = 0;
while ((die = dwfl_module_nextcu(mod, die, &bias))) {
- const auto range = CuDieRange(die, bias);
- if (range.low < range.high)
- ranges.push_back(range);
- else
- qWarning() << "failed to find range for CU DIE" << hex << bias;
+ Dwarf_Addr low = 0;
+ Dwarf_Addr high = 0;
+ Dwarf_Addr base = 0;
+ ptrdiff_t offset = 0;
+ while ((offset = dwarf_ranges(die, offset, &base, &low, &high)) > 0) {
+ ranges.push_back(CuDieRange{die, bias, low + bias, high + bias});
+ }
}
}