diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2019-09-27 09:24:42 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2019-09-30 07:43:38 +0000 |
commit | 5e4c4d0b29fbcc40210de7aea46cb9b1dccc9e42 (patch) | |
tree | 0d811f244425bdec03a41939b61929d838b17153 | |
parent | 4b98b893ebaded257d7693fb6500ca9955682d89 (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.cpp | 39 |
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}); + } } } |