1358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===// 2358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer// 3358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer// The LLVM Compiler Infrastructure 4358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer// 5358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer// This file is distributed under the University of Illinois Open Source 6358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer// License. See LICENSE.TXT for details. 7358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer// 8358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer//===----------------------------------------------------------------------===// 9358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h" 11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 12ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFContext.h" 13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" 14358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer#include "llvm/Support/Format.h" 15358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer#include "llvm/Support/raw_ostream.h" 16358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer#include <algorithm> 17358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer#include <cassert> 18c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include <set> 19358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramerusing namespace llvm; 20358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 21d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonovvoid DWARFDebugAranges::extract(DataExtractor DebugArangesData) { 22d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonov if (!DebugArangesData.isValidOffset(0)) 23d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonov return; 24041f7c8d65a653701cb9ed464911cd44b19ab47eAlexey Samsonov uint32_t Offset = 0; 25041f7c8d65a653701cb9ed464911cd44b19ab47eAlexey Samsonov DWARFDebugArangeSet Set; 26041f7c8d65a653701cb9ed464911cd44b19ab47eAlexey Samsonov 27041f7c8d65a653701cb9ed464911cd44b19ab47eAlexey Samsonov while (Set.extract(DebugArangesData, &Offset)) { 28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t CUOffset = Set.getCompileUnitDIEOffset(); 29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &Desc : Set.descriptors()) { 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t LowPC = Desc.Address; 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t HighPC = Desc.getEndAddress(); 32041f7c8d65a653701cb9ed464911cd44b19ab47eAlexey Samsonov appendRange(CUOffset, LowPC, HighPC); 33041f7c8d65a653701cb9ed464911cd44b19ab47eAlexey Samsonov } 34c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ParsedCUOffsets.insert(CUOffset); 35358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } 36358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer} 37358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 38d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonovvoid DWARFDebugAranges::generate(DWARFContext *CTX) { 393db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov clear(); 403db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov if (!CTX) 413db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov return; 423db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov 433db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov // Extract aranges from .debug_aranges section. 443db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov DataExtractor ArangesData(CTX->getARangeSection(), CTX->isLittleEndian(), 0); 453db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov extract(ArangesData); 4610df80692cc1594fb06fc02cae6eba177123cfd9Benjamin Kramer 473db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov // Generate aranges from DIEs: even if .debug_aranges section is present, 483db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov // it may describe only a small subset of compilation units, so we need to 493db24f52c5c0404529b627688106e0fd11a64400Alexey Samsonov // manually build aranges for the rest of them. 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (const auto &CU : CTX->compile_units()) { 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t CUOffset = CU->getOffset(); 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (ParsedCUOffsets.insert(CUOffset).second) { 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DWARFAddressRangesVector CURanges; 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CU->collectAddressRanges(CURanges); 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &R : CURanges) { 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines appendRange(CUOffset, R.first, R.second); 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 58dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 59358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } 60358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 61c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines construct(); 62358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer} 63358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugAranges::clear() { 65c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Endpoints.clear(); 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Aranges.clear(); 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ParsedCUOffsets.clear(); 68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 70d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonovvoid DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC, 71d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonov uint64_t HighPC) { 72c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (LowPC >= HighPC) 73358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer return; 74c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Endpoints.emplace_back(LowPC, CUOffset, true); 75c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Endpoints.emplace_back(HighPC, CUOffset, false); 76c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines} 77358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 78c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesvoid DWARFDebugAranges::construct() { 79c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing 80c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // a current address range. 81c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::sort(Endpoints.begin(), Endpoints.end()); 82c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines uint64_t PrevAddress = -1ULL; 83c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines for (const auto &E : Endpoints) { 84c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (PrevAddress < E.Address && ValidCUs.size() > 0) { 85c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // If the address range between two endpoints is described by some 86c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // CU, first try to extend the last range in Aranges. If we can't 87c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // do it, start a new range. 88c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress && 89c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) { 90c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Aranges.back().setHighPC(E.Address); 91c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } else { 92c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin()); 93c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 94c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines } 95c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Update the set of valid CUs. 96c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines if (E.IsRangeStart) { 97c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ValidCUs.insert(E.CUOffset); 98358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } else { 99c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines auto CUPos = ValidCUs.find(E.CUOffset); 100c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(CUPos != ValidCUs.end()); 101c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines ValidCUs.erase(CUPos); 102358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } 103c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines PrevAddress = E.Address; 104358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } 105c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines assert(ValidCUs.empty()); 106358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 107c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines // Endpoints are not needed now. 108c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines std::vector<RangeEndpoint> EmptyEndpoints; 109c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines EmptyEndpoints.swap(Endpoints); 110358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer} 111358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 112d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonovuint32_t DWARFDebugAranges::findAddress(uint64_t Address) const { 113358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer if (!Aranges.empty()) { 114d1fc0f8d4ef32b4302338b8a3fd0d976e5bd8ae3Alexey Samsonov Range range(Address); 115358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer RangeCollIterator begin = Aranges.begin(); 116358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer RangeCollIterator end = Aranges.end(); 11717f7d099e4a381a3876ce1e9412f0b0d76d71e8aAlexey Samsonov RangeCollIterator pos = 11817f7d099e4a381a3876ce1e9412f0b0d76d71e8aAlexey Samsonov std::lower_bound(begin, end, range); 119358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer 12017f7d099e4a381a3876ce1e9412f0b0d76d71e8aAlexey Samsonov if (pos != end && pos->containsAddress(Address)) { 12117f7d099e4a381a3876ce1e9412f0b0d76d71e8aAlexey Samsonov return pos->CUOffset; 122358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } else if (pos != begin) { 123358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer --pos; 12417f7d099e4a381a3876ce1e9412f0b0d76d71e8aAlexey Samsonov if (pos->containsAddress(Address)) 12517f7d099e4a381a3876ce1e9412f0b0d76d71e8aAlexey Samsonov return pos->CUOffset; 126358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } 127358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer } 128358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer return -1U; 129358f4fd9ee078b3c79597fc688855fb48bc1f356Benjamin Kramer} 130