mirror of
https://gitee.com/openharmony/arkcompiler_runtime_core
synced 2025-04-17 01:50:20 +00:00

Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/I687G9?from=project-issue Test: tdd Signed-off-by: shawn_hu_ls <huxiaowei3@huawei.com>
185 lines
5.2 KiB
C++
185 lines
5.2 KiB
C++
/**
|
|
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef LIBPANDABASE_OS_DEBUG_INFO_H
|
|
#define LIBPANDABASE_OS_DEBUG_INFO_H
|
|
|
|
#include <set>
|
|
#include <list>
|
|
#include <string>
|
|
#include <libdwarf/libdwarf.h>
|
|
#include "macros.h"
|
|
#include "utils/span.h"
|
|
|
|
namespace panda {
|
|
|
|
class DebugInfo {
|
|
public:
|
|
enum ErrorCode { SUCCESS, NO_DEBUG_INFO, ERROR };
|
|
|
|
explicit DebugInfo() = default;
|
|
|
|
~DebugInfo()
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
ErrorCode ReadFromFile(const char *filename);
|
|
|
|
/*
|
|
* Find location (name, source file, line) of the specified pc in source code
|
|
*/
|
|
bool GetSrcLocation(uintptr_t pc, std::string *function, std::string *src_file, uint32_t *line);
|
|
|
|
void Destroy();
|
|
|
|
DEFAULT_MOVE_SEMANTIC(DebugInfo);
|
|
NO_COPY_SEMANTIC(DebugInfo);
|
|
|
|
private:
|
|
/**
|
|
* Cache entry for a compilation unit (object file).
|
|
* It contains the pointer to the corresponding DIE (Debug Information Entity),
|
|
* offset of the DIE in .debug_info, decoded line numbers for the compilation unit
|
|
* and function cache.
|
|
*/
|
|
class CompUnit {
|
|
public:
|
|
CompUnit(Dwarf_Die cu_die, Dwarf_Debug dbg) : dbg_(dbg), cu_die_(cu_die) {}
|
|
|
|
CompUnit(CompUnit &&e) : dbg_(e.dbg_), cu_die_(e.cu_die_), line_ctx_(e.line_ctx_)
|
|
{
|
|
e.cu_die_ = nullptr;
|
|
e.line_ctx_ = nullptr;
|
|
}
|
|
|
|
~CompUnit();
|
|
|
|
CompUnit &operator=(CompUnit &&e)
|
|
{
|
|
dbg_ = e.dbg_;
|
|
cu_die_ = e.cu_die_;
|
|
e.cu_die_ = nullptr;
|
|
line_ctx_ = e.line_ctx_;
|
|
e.line_ctx_ = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
Dwarf_Die GetDie() const
|
|
{
|
|
return cu_die_;
|
|
}
|
|
|
|
Dwarf_Line_Context GetLineContext();
|
|
|
|
NO_COPY_SEMANTIC(CompUnit);
|
|
|
|
private:
|
|
Dwarf_Debug dbg_;
|
|
Dwarf_Die cu_die_;
|
|
Dwarf_Line_Context line_ctx_ {nullptr};
|
|
};
|
|
|
|
class Range {
|
|
public:
|
|
Range(Dwarf_Addr low_pc, Dwarf_Addr high_pc, CompUnit *cu = nullptr,
|
|
const std::string &function = std::string()) // NOLINT(modernize-pass-by-value)
|
|
: low_pc_(low_pc), high_pc_(high_pc), cu_(cu), function_(function)
|
|
{
|
|
}
|
|
|
|
Dwarf_Addr GetLowPc() const
|
|
{
|
|
return low_pc_;
|
|
}
|
|
|
|
Dwarf_Addr GetHighPc() const
|
|
{
|
|
return high_pc_;
|
|
}
|
|
|
|
bool Contain(Dwarf_Addr addr) const
|
|
{
|
|
return low_pc_ <= addr && addr < high_pc_;
|
|
}
|
|
|
|
bool Contain(const Range &r) const
|
|
{
|
|
return low_pc_ <= r.low_pc_ && r.high_pc_ <= high_pc_;
|
|
}
|
|
|
|
CompUnit *GetCu() const
|
|
{
|
|
return cu_;
|
|
}
|
|
|
|
std::string GetFunction() const
|
|
{
|
|
return function_;
|
|
}
|
|
|
|
void SetFunction(const std::string &function)
|
|
{
|
|
this->function_ = function;
|
|
}
|
|
|
|
bool operator<(const Range &r) const
|
|
{
|
|
return high_pc_ < r.high_pc_;
|
|
}
|
|
|
|
bool operator==(const Range &r) const
|
|
{
|
|
return low_pc_ == r.low_pc_ && high_pc_ == r.high_pc_;
|
|
}
|
|
|
|
private:
|
|
Dwarf_Addr low_pc_;
|
|
Dwarf_Addr high_pc_;
|
|
CompUnit *cu_ = nullptr;
|
|
std::string function_;
|
|
};
|
|
|
|
private:
|
|
bool FindCompUnitByPc(uintptr_t pc, Dwarf_Die *cu_die);
|
|
void TraverseChildren(CompUnit *cu, Dwarf_Die die);
|
|
void TraverseSiblings(CompUnit *cu, Dwarf_Die die);
|
|
void GetFunctionName(Dwarf_Die die, std::string *function);
|
|
void AddFunction(CompUnit *cu, Dwarf_Addr low_pc, Dwarf_Addr high_pc, const std::string &function);
|
|
bool GetSrcFileAndLine(uintptr_t pc, Dwarf_Line_Context line_ctx, std::string *src_file, uint32_t *line);
|
|
Dwarf_Line GetLastLineWithPc(Dwarf_Addr pc, Span<Dwarf_Line>::ConstIterator it,
|
|
Span<Dwarf_Line>::ConstIterator end);
|
|
void GetSrcFileAndLine(Dwarf_Line line, std::string *out_src_file, uint32_t *out_line);
|
|
bool PcMatches(uintptr_t pc, Dwarf_Die die);
|
|
bool GetDieRange(Dwarf_Die die, Dwarf_Addr *out_low_pc, Dwarf_Addr *out_high_pc);
|
|
bool GetDieRangeForPc(uintptr_t pc, Dwarf_Die die, Dwarf_Addr *out_low_pc, Dwarf_Addr *out_high_pc);
|
|
bool FindRangeForPc(uintptr_t pc, const Span<Dwarf_Ranges> &ranges, Dwarf_Addr base_addr, Dwarf_Addr *out_low_pc,
|
|
Dwarf_Addr *out_high_pc);
|
|
|
|
private:
|
|
static constexpr int INVALID_FD = -1;
|
|
|
|
int fd_ {INVALID_FD};
|
|
Dwarf_Debug dbg_ {nullptr};
|
|
Dwarf_Arange *aranges_ {nullptr};
|
|
Dwarf_Signed arange_count_ {0};
|
|
std::list<CompUnit> cu_list_;
|
|
std::set<Range> ranges_;
|
|
};
|
|
|
|
} // namespace panda
|
|
|
|
#endif // LIBPANDABASE_OS_DEBUG_INFO_H
|