1b1994897Sopenharmony_ci/** 2b1994897Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci * you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci * You may obtain a copy of the License at 6b1994897Sopenharmony_ci * 7b1994897Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci * 9b1994897Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci * See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci * limitations under the License. 14b1994897Sopenharmony_ci */ 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci#ifndef LIBPANDABASE_OS_DEBUG_INFO_H 17b1994897Sopenharmony_ci#define LIBPANDABASE_OS_DEBUG_INFO_H 18b1994897Sopenharmony_ci 19b1994897Sopenharmony_ci#include <set> 20b1994897Sopenharmony_ci#include <list> 21b1994897Sopenharmony_ci#include <string> 22b1994897Sopenharmony_ci#include <libdwarf/libdwarf.h> 23b1994897Sopenharmony_ci#include "macros.h" 24b1994897Sopenharmony_ci#include "utils/span.h" 25b1994897Sopenharmony_ci 26b1994897Sopenharmony_cinamespace panda { 27b1994897Sopenharmony_ci 28b1994897Sopenharmony_ciclass DebugInfo { 29b1994897Sopenharmony_cipublic: 30b1994897Sopenharmony_ci enum ErrorCode { SUCCESS, NO_DEBUG_INFO, ERROR }; 31b1994897Sopenharmony_ci 32b1994897Sopenharmony_ci explicit DebugInfo() = default; 33b1994897Sopenharmony_ci 34b1994897Sopenharmony_ci ~DebugInfo() 35b1994897Sopenharmony_ci { 36b1994897Sopenharmony_ci Destroy(); 37b1994897Sopenharmony_ci } 38b1994897Sopenharmony_ci 39b1994897Sopenharmony_ci ErrorCode ReadFromFile(const char *filename); 40b1994897Sopenharmony_ci 41b1994897Sopenharmony_ci /* 42b1994897Sopenharmony_ci * Find location (name, source file, line) of the specified pc in source code 43b1994897Sopenharmony_ci */ 44b1994897Sopenharmony_ci bool GetSrcLocation(uintptr_t pc, std::string *function, std::string *src_file, uint32_t *line); 45b1994897Sopenharmony_ci 46b1994897Sopenharmony_ci void Destroy(); 47b1994897Sopenharmony_ci 48b1994897Sopenharmony_ci DEFAULT_MOVE_SEMANTIC(DebugInfo); 49b1994897Sopenharmony_ci NO_COPY_SEMANTIC(DebugInfo); 50b1994897Sopenharmony_ci 51b1994897Sopenharmony_ciprivate: 52b1994897Sopenharmony_ci /** 53b1994897Sopenharmony_ci * Cache entry for a compilation unit (object file). 54b1994897Sopenharmony_ci * It contains the pointer to the corresponding DIE (Debug Information Entity), 55b1994897Sopenharmony_ci * offset of the DIE in .debug_info, decoded line numbers for the compilation unit 56b1994897Sopenharmony_ci * and function cache. 57b1994897Sopenharmony_ci */ 58b1994897Sopenharmony_ci class CompUnit { 59b1994897Sopenharmony_ci public: 60b1994897Sopenharmony_ci CompUnit(Dwarf_Die cu_die, Dwarf_Debug dbg) : dbg_(dbg), cu_die_(cu_die) {} 61b1994897Sopenharmony_ci 62b1994897Sopenharmony_ci CompUnit(CompUnit &&e) : dbg_(e.dbg_), cu_die_(e.cu_die_), line_ctx_(e.line_ctx_) 63b1994897Sopenharmony_ci { 64b1994897Sopenharmony_ci e.cu_die_ = nullptr; 65b1994897Sopenharmony_ci e.line_ctx_ = nullptr; 66b1994897Sopenharmony_ci } 67b1994897Sopenharmony_ci 68b1994897Sopenharmony_ci ~CompUnit(); 69b1994897Sopenharmony_ci 70b1994897Sopenharmony_ci CompUnit &operator=(CompUnit &&e) 71b1994897Sopenharmony_ci { 72b1994897Sopenharmony_ci dbg_ = e.dbg_; 73b1994897Sopenharmony_ci cu_die_ = e.cu_die_; 74b1994897Sopenharmony_ci e.cu_die_ = nullptr; 75b1994897Sopenharmony_ci line_ctx_ = e.line_ctx_; 76b1994897Sopenharmony_ci e.line_ctx_ = nullptr; 77b1994897Sopenharmony_ci return *this; 78b1994897Sopenharmony_ci } 79b1994897Sopenharmony_ci 80b1994897Sopenharmony_ci Dwarf_Die GetDie() const 81b1994897Sopenharmony_ci { 82b1994897Sopenharmony_ci return cu_die_; 83b1994897Sopenharmony_ci } 84b1994897Sopenharmony_ci 85b1994897Sopenharmony_ci Dwarf_Line_Context GetLineContext(); 86b1994897Sopenharmony_ci 87b1994897Sopenharmony_ci NO_COPY_SEMANTIC(CompUnit); 88b1994897Sopenharmony_ci 89b1994897Sopenharmony_ci private: 90b1994897Sopenharmony_ci Dwarf_Debug dbg_; 91b1994897Sopenharmony_ci Dwarf_Die cu_die_; 92b1994897Sopenharmony_ci Dwarf_Line_Context line_ctx_ {nullptr}; 93b1994897Sopenharmony_ci }; 94b1994897Sopenharmony_ci 95b1994897Sopenharmony_ci class Range { 96b1994897Sopenharmony_ci public: 97b1994897Sopenharmony_ci Range(Dwarf_Addr low_pc, Dwarf_Addr high_pc, CompUnit *cu = nullptr, 98b1994897Sopenharmony_ci const std::string &function = std::string()) // NOLINT(modernize-pass-by-value) 99b1994897Sopenharmony_ci : low_pc_(low_pc), high_pc_(high_pc), cu_(cu), function_(function) 100b1994897Sopenharmony_ci { 101b1994897Sopenharmony_ci } 102b1994897Sopenharmony_ci 103b1994897Sopenharmony_ci Dwarf_Addr GetLowPc() const 104b1994897Sopenharmony_ci { 105b1994897Sopenharmony_ci return low_pc_; 106b1994897Sopenharmony_ci } 107b1994897Sopenharmony_ci 108b1994897Sopenharmony_ci Dwarf_Addr GetHighPc() const 109b1994897Sopenharmony_ci { 110b1994897Sopenharmony_ci return high_pc_; 111b1994897Sopenharmony_ci } 112b1994897Sopenharmony_ci 113b1994897Sopenharmony_ci bool Contain(Dwarf_Addr addr) const 114b1994897Sopenharmony_ci { 115b1994897Sopenharmony_ci return low_pc_ <= addr && addr < high_pc_; 116b1994897Sopenharmony_ci } 117b1994897Sopenharmony_ci 118b1994897Sopenharmony_ci bool Contain(const Range &r) const 119b1994897Sopenharmony_ci { 120b1994897Sopenharmony_ci return low_pc_ <= r.low_pc_ && r.high_pc_ <= high_pc_; 121b1994897Sopenharmony_ci } 122b1994897Sopenharmony_ci 123b1994897Sopenharmony_ci CompUnit *GetCu() const 124b1994897Sopenharmony_ci { 125b1994897Sopenharmony_ci return cu_; 126b1994897Sopenharmony_ci } 127b1994897Sopenharmony_ci 128b1994897Sopenharmony_ci std::string GetFunction() const 129b1994897Sopenharmony_ci { 130b1994897Sopenharmony_ci return function_; 131b1994897Sopenharmony_ci } 132b1994897Sopenharmony_ci 133b1994897Sopenharmony_ci void SetFunction(const std::string &function) 134b1994897Sopenharmony_ci { 135b1994897Sopenharmony_ci this->function_ = function; 136b1994897Sopenharmony_ci } 137b1994897Sopenharmony_ci 138b1994897Sopenharmony_ci bool operator<(const Range &r) const 139b1994897Sopenharmony_ci { 140b1994897Sopenharmony_ci return high_pc_ < r.high_pc_; 141b1994897Sopenharmony_ci } 142b1994897Sopenharmony_ci 143b1994897Sopenharmony_ci bool operator==(const Range &r) const 144b1994897Sopenharmony_ci { 145b1994897Sopenharmony_ci return low_pc_ == r.low_pc_ && high_pc_ == r.high_pc_; 146b1994897Sopenharmony_ci } 147b1994897Sopenharmony_ci 148b1994897Sopenharmony_ci private: 149b1994897Sopenharmony_ci Dwarf_Addr low_pc_; 150b1994897Sopenharmony_ci Dwarf_Addr high_pc_; 151b1994897Sopenharmony_ci CompUnit *cu_ = nullptr; 152b1994897Sopenharmony_ci std::string function_; 153b1994897Sopenharmony_ci }; 154b1994897Sopenharmony_ci 155b1994897Sopenharmony_ciprivate: 156b1994897Sopenharmony_ci bool FindCompUnitByPc(uintptr_t pc, Dwarf_Die *cu_die); 157b1994897Sopenharmony_ci void TraverseChildren(CompUnit *cu, Dwarf_Die die); 158b1994897Sopenharmony_ci void TraverseSiblings(CompUnit *cu, Dwarf_Die die); 159b1994897Sopenharmony_ci void GetFunctionName(Dwarf_Die die, std::string *function); 160b1994897Sopenharmony_ci void AddFunction(CompUnit *cu, Dwarf_Addr low_pc, Dwarf_Addr high_pc, const std::string &function); 161b1994897Sopenharmony_ci bool GetSrcFileAndLine(uintptr_t pc, Dwarf_Line_Context line_ctx, std::string *src_file, uint32_t *line); 162b1994897Sopenharmony_ci Dwarf_Line GetLastLineWithPc(Dwarf_Addr pc, Span<Dwarf_Line>::ConstIterator it, 163b1994897Sopenharmony_ci Span<Dwarf_Line>::ConstIterator end); 164b1994897Sopenharmony_ci void GetSrcFileAndLine(Dwarf_Line line, std::string *out_src_file, uint32_t *out_line); 165b1994897Sopenharmony_ci bool PcMatches(uintptr_t pc, Dwarf_Die die); 166b1994897Sopenharmony_ci bool GetDieRange(Dwarf_Die die, Dwarf_Addr *out_low_pc, Dwarf_Addr *out_high_pc); 167b1994897Sopenharmony_ci bool GetDieRangeForPc(uintptr_t pc, Dwarf_Die die, Dwarf_Addr *out_low_pc, Dwarf_Addr *out_high_pc); 168b1994897Sopenharmony_ci bool FindRangeForPc(uintptr_t pc, const Span<Dwarf_Ranges> &ranges, Dwarf_Addr base_addr, Dwarf_Addr *out_low_pc, 169b1994897Sopenharmony_ci Dwarf_Addr *out_high_pc); 170b1994897Sopenharmony_ci 171b1994897Sopenharmony_ciprivate: 172b1994897Sopenharmony_ci static constexpr int INVALID_FD = -1; 173b1994897Sopenharmony_ci 174b1994897Sopenharmony_ci int fd_ {INVALID_FD}; 175b1994897Sopenharmony_ci Dwarf_Debug dbg_ {nullptr}; 176b1994897Sopenharmony_ci Dwarf_Arange *aranges_ {nullptr}; 177b1994897Sopenharmony_ci Dwarf_Signed arange_count_ {0}; 178b1994897Sopenharmony_ci std::list<CompUnit> cu_list_; 179b1994897Sopenharmony_ci std::set<Range> ranges_; 180b1994897Sopenharmony_ci}; 181b1994897Sopenharmony_ci 182b1994897Sopenharmony_ci} // namespace panda 183b1994897Sopenharmony_ci 184b1994897Sopenharmony_ci#endif // LIBPANDABASE_OS_DEBUG_INFO_H 185