diff options
| author | vitalyisaev <[email protected]> | 2023-06-29 10:00:50 +0300 |
|---|---|---|
| committer | vitalyisaev <[email protected]> | 2023-06-29 10:00:50 +0300 |
| commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
| tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm16/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp | |
| parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm16/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp')
| -rw-r--r-- | contrib/libs/llvm16/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/contrib/libs/llvm16/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/contrib/libs/llvm16/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp new file mode 100644 index 00000000000..49ee27db6d5 --- /dev/null +++ b/contrib/libs/llvm16/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp @@ -0,0 +1,130 @@ +//===- DWARFDebugAranges.cpp ----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h" +#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" +#include "llvm/DebugInfo/DWARF/DWARFObject.h" +#include "llvm/DebugInfo/DWARF/DWARFUnit.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <set> + +using namespace llvm; + +void DWARFDebugAranges::extract( + DWARFDataExtractor DebugArangesData, + function_ref<void(Error)> RecoverableErrorHandler, + function_ref<void(Error)> WarningHandler) { + if (!DebugArangesData.isValidOffset(0)) + return; + uint64_t Offset = 0; + DWARFDebugArangeSet Set; + + while (DebugArangesData.isValidOffset(Offset)) { + if (Error E = Set.extract(DebugArangesData, &Offset, WarningHandler)) { + RecoverableErrorHandler(std::move(E)); + return; + } + uint64_t CUOffset = Set.getCompileUnitDIEOffset(); + for (const auto &Desc : Set.descriptors()) { + uint64_t LowPC = Desc.Address; + uint64_t HighPC = Desc.getEndAddress(); + appendRange(CUOffset, LowPC, HighPC); + } + ParsedCUOffsets.insert(CUOffset); + } +} + +void DWARFDebugAranges::generate(DWARFContext *CTX) { + clear(); + if (!CTX) + return; + + // Extract aranges from .debug_aranges section. + DWARFDataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(), + CTX->isLittleEndian(), 0); + extract(ArangesData, CTX->getRecoverableErrorHandler(), + CTX->getWarningHandler()); + + // Generate aranges from DIEs: even if .debug_aranges section is present, + // it may describe only a small subset of compilation units, so we need to + // manually build aranges for the rest of them. + for (const auto &CU : CTX->compile_units()) { + uint64_t CUOffset = CU->getOffset(); + if (ParsedCUOffsets.insert(CUOffset).second) { + Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges(); + if (!CURanges) + CTX->getRecoverableErrorHandler()(CURanges.takeError()); + else + for (const auto &R : *CURanges) + appendRange(CUOffset, R.LowPC, R.HighPC); + } + } + + construct(); +} + +void DWARFDebugAranges::clear() { + Endpoints.clear(); + Aranges.clear(); + ParsedCUOffsets.clear(); +} + +void DWARFDebugAranges::appendRange(uint64_t CUOffset, uint64_t LowPC, + uint64_t HighPC) { + if (LowPC >= HighPC) + return; + Endpoints.emplace_back(LowPC, CUOffset, true); + Endpoints.emplace_back(HighPC, CUOffset, false); +} + +void DWARFDebugAranges::construct() { + std::multiset<uint64_t> ValidCUs; // Maintain the set of CUs describing + // a current address range. + llvm::sort(Endpoints); + uint64_t PrevAddress = -1ULL; + for (const auto &E : Endpoints) { + if (PrevAddress < E.Address && !ValidCUs.empty()) { + // If the address range between two endpoints is described by some + // CU, first try to extend the last range in Aranges. If we can't + // do it, start a new range. + if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress && + ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) { + Aranges.back().setHighPC(E.Address); + } else { + Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin()); + } + } + // Update the set of valid CUs. + if (E.IsRangeStart) { + ValidCUs.insert(E.CUOffset); + } else { + auto CUPos = ValidCUs.find(E.CUOffset); + assert(CUPos != ValidCUs.end()); + ValidCUs.erase(CUPos); + } + PrevAddress = E.Address; + } + assert(ValidCUs.empty()); + + // Endpoints are not needed now. + Endpoints.clear(); + Endpoints.shrink_to_fit(); +} + +uint64_t DWARFDebugAranges::findAddress(uint64_t Address) const { + RangeCollIterator It = + partition_point(Aranges, [=](Range R) { return R.HighPC() <= Address; }); + if (It != Aranges.end() && It->LowPC <= Address) + return It->CUOffset; + return -1ULL; +} |
