[lldb][NFC] Fix all formatting errors in .cpp file headers
Summary:
A *.cpp file header in LLDB (and in LLDB) should like this:
```
//===-- TestUtilities.cpp -------------------------------------------------===//
```
However in LLDB most of our source files have arbitrary changes to this format and
these changes are spreading through LLDB as folks usually just use the existing
source files as templates for their new files (most notably the unnecessary
editor language indicator `-*- C++ -*-` is spreading and in every review
someone is pointing out that this is wrong, resulting in people pointing out that this
is done in the same way in other files).
This patch removes most of these inconsistencies including the editor language indicators,
all the different missing/additional '-' characters, files that center the file name, missing
trailing `===//` (mostly caused by clang-format breaking the line).
Reviewers: aprantl, espindola, jfb, shafik, JDevlieghere
Reviewed By: JDevlieghere
Subscribers: dexonsmith, wuzish, emaste, sdardis, nemanjai, kbarton, MaskRay, atanasyan, arphaman, jfb, abidh, jsji, JDevlieghere, usaxena95, lldb-commits
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D73258
2020-01-24 15:23:27 +08:00
|
|
|
//===-- Function.cpp ------------------------------------------------------===//
|
2010-06-09 00:52:24 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2010-06-09 00:52:24 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "lldb/Symbol/Function.h"
|
2014-01-28 07:43:24 +08:00
|
|
|
#include "lldb/Core/Disassembler.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/Module.h"
|
2018-10-06 07:23:15 +08:00
|
|
|
#include "lldb/Core/ModuleList.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Core/Section.h"
|
2012-01-05 11:57:59 +08:00
|
|
|
#include "lldb/Host/Host.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Symbol/CompileUnit.h"
|
2015-08-12 06:53:00 +08:00
|
|
|
#include "lldb/Symbol/CompilerType.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
#include "lldb/Symbol/LineTable.h"
|
2011-08-06 07:43:37 +08:00
|
|
|
#include "lldb/Symbol/SymbolFile.h"
|
2015-10-01 07:12:22 +08:00
|
|
|
#include "lldb/Target/Language.h"
|
2019-09-15 10:43:16 +08:00
|
|
|
#include "lldb/Target/Target.h"
|
2018-10-06 07:23:15 +08:00
|
|
|
#include "lldb/Utility/Log.h"
|
2011-07-30 10:42:06 +08:00
|
|
|
#include "llvm/Support/Casting.h"
|
2010-06-09 00:52:24 +08:00
|
|
|
|
2010-09-10 09:30:46 +08:00
|
|
|
using namespace lldb;
|
2010-06-09 00:52:24 +08:00
|
|
|
using namespace lldb_private;
|
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Basic function information is contained in the FunctionInfo class. It is
|
|
|
|
// designed to contain the name, linkage name, and declaration location.
|
2010-06-09 00:52:24 +08:00
|
|
|
FunctionInfo::FunctionInfo(const char *name, const Declaration *decl_ptr)
|
|
|
|
: m_name(name), m_declaration(decl_ptr) {}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
FunctionInfo::FunctionInfo(ConstString name, const Declaration *decl_ptr)
|
2010-06-09 00:52:24 +08:00
|
|
|
: m_name(name), m_declaration(decl_ptr) {}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
FunctionInfo::~FunctionInfo() {}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void FunctionInfo::Dump(Stream *s, bool show_fullpaths) const {
|
|
|
|
if (m_name)
|
|
|
|
*s << ", name = \"" << m_name << "\"";
|
2010-09-15 13:51:24 +08:00
|
|
|
m_declaration.Dump(s, show_fullpaths);
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int FunctionInfo::Compare(const FunctionInfo &a, const FunctionInfo &b) {
|
|
|
|
int result = ConstString::Compare(a.GetName(), b.GetName());
|
|
|
|
if (result)
|
|
|
|
return result;
|
|
|
|
|
|
|
|
return Declaration::Compare(a.m_declaration, b.m_declaration);
|
|
|
|
}
|
|
|
|
|
|
|
|
Declaration &FunctionInfo::GetDeclaration() { return m_declaration; }
|
|
|
|
|
|
|
|
const Declaration &FunctionInfo::GetDeclaration() const {
|
|
|
|
return m_declaration;
|
|
|
|
}
|
|
|
|
|
2010-09-15 13:51:24 +08:00
|
|
|
ConstString FunctionInfo::GetName() const { return m_name; }
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
size_t FunctionInfo::MemorySize() const {
|
2010-09-15 13:51:24 +08:00
|
|
|
return m_name.MemorySize() + m_declaration.MemorySize();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-10-10 00:22:14 +08:00
|
|
|
InlineFunctionInfo::InlineFunctionInfo(const char *name,
|
|
|
|
llvm::StringRef mangled,
|
2010-06-09 00:52:24 +08:00
|
|
|
const Declaration *decl_ptr,
|
|
|
|
const Declaration *call_decl_ptr)
|
2019-10-10 00:22:14 +08:00
|
|
|
: FunctionInfo(name, decl_ptr), m_mangled(mangled),
|
2010-06-09 00:52:24 +08:00
|
|
|
m_call_decl(call_decl_ptr) {}
|
|
|
|
|
2019-03-07 05:22:25 +08:00
|
|
|
InlineFunctionInfo::InlineFunctionInfo(ConstString name,
|
2010-06-09 00:52:24 +08:00
|
|
|
const Mangled &mangled,
|
|
|
|
const Declaration *decl_ptr,
|
|
|
|
const Declaration *call_decl_ptr)
|
|
|
|
: FunctionInfo(name, decl_ptr), m_mangled(mangled),
|
|
|
|
m_call_decl(call_decl_ptr) {}
|
|
|
|
|
|
|
|
InlineFunctionInfo::~InlineFunctionInfo() {}
|
|
|
|
|
|
|
|
void InlineFunctionInfo::Dump(Stream *s, bool show_fullpaths) const {
|
|
|
|
FunctionInfo::Dump(s, show_fullpaths);
|
|
|
|
if (m_mangled)
|
|
|
|
m_mangled.Dump(s);
|
|
|
|
}
|
|
|
|
|
2020-01-31 13:55:18 +08:00
|
|
|
void InlineFunctionInfo::DumpStopContext(Stream *s) const {
|
2010-06-09 00:52:24 +08:00
|
|
|
// s->Indent("[inlined] ");
|
|
|
|
s->Indent();
|
|
|
|
if (m_mangled)
|
2020-01-31 13:55:18 +08:00
|
|
|
s->PutCString(m_mangled.GetName().AsCString());
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2010-06-09 00:52:24 +08:00
|
|
|
s->PutCString(m_name.AsCString());
|
|
|
|
}
|
|
|
|
|
2020-01-31 13:55:18 +08:00
|
|
|
ConstString InlineFunctionInfo::GetName() const {
|
2010-06-09 00:52:24 +08:00
|
|
|
if (m_mangled)
|
2020-01-31 13:55:18 +08:00
|
|
|
return m_mangled.GetName();
|
2010-06-09 00:52:24 +08:00
|
|
|
return m_name;
|
|
|
|
}
|
|
|
|
|
2020-01-31 13:55:18 +08:00
|
|
|
ConstString InlineFunctionInfo::GetDisplayName() const {
|
2010-06-09 00:52:24 +08:00
|
|
|
if (m_mangled)
|
2020-01-31 13:55:18 +08:00
|
|
|
return m_mangled.GetDisplayDemangledName();
|
2010-06-09 00:52:24 +08:00
|
|
|
return m_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
Declaration &InlineFunctionInfo::GetCallSite() { return m_call_decl; }
|
|
|
|
|
|
|
|
const Declaration &InlineFunctionInfo::GetCallSite() const {
|
|
|
|
return m_call_decl;
|
|
|
|
}
|
|
|
|
|
|
|
|
Mangled &InlineFunctionInfo::GetMangled() { return m_mangled; }
|
|
|
|
|
|
|
|
const Mangled &InlineFunctionInfo::GetMangled() const { return m_mangled; }
|
|
|
|
|
2010-09-15 13:51:24 +08:00
|
|
|
size_t InlineFunctionInfo::MemorySize() const {
|
|
|
|
return FunctionInfo::MemorySize() + m_mangled.MemorySize();
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
/// @name Call site related structures
|
|
|
|
/// @{
|
2018-10-06 07:23:15 +08:00
|
|
|
|
2020-03-18 08:59:08 +08:00
|
|
|
lldb::addr_t CallEdge::GetLoadAddress(lldb::addr_t unresolved_pc,
|
|
|
|
Function &caller, Target &target) {
|
2020-01-10 10:00:33 +08:00
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
|
|
|
|
|
|
|
const Address &caller_start_addr = caller.GetAddressRange().GetBaseAddress();
|
|
|
|
|
|
|
|
ModuleSP caller_module_sp = caller_start_addr.GetModule();
|
|
|
|
if (!caller_module_sp) {
|
2020-03-18 08:59:08 +08:00
|
|
|
LLDB_LOG(log, "GetLoadAddress: cannot get Module for caller");
|
2020-01-10 10:00:33 +08:00
|
|
|
return LLDB_INVALID_ADDRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
SectionList *section_list = caller_module_sp->GetSectionList();
|
|
|
|
if (!section_list) {
|
2020-03-18 08:59:08 +08:00
|
|
|
LLDB_LOG(log, "GetLoadAddress: cannot get SectionList for Module");
|
2020-01-10 10:00:33 +08:00
|
|
|
return LLDB_INVALID_ADDRESS;
|
|
|
|
}
|
|
|
|
|
2020-03-18 08:59:08 +08:00
|
|
|
Address the_addr = Address(unresolved_pc, section_list);
|
|
|
|
lldb::addr_t load_addr = the_addr.GetLoadAddress(&target);
|
|
|
|
return load_addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller,
|
|
|
|
Target &target) const {
|
2020-06-02 22:01:11 +08:00
|
|
|
return GetLoadAddress(GetUnresolvedReturnPCAddress(), caller, target);
|
2019-09-12 05:23:45 +08:00
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
void DirectCallEdge::ParseSymbolFileAndResolve(ModuleList &images) {
|
2018-10-06 07:23:15 +08:00
|
|
|
if (resolved)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
2019-09-15 10:43:16 +08:00
|
|
|
LLDB_LOG(log, "DirectCallEdge: Lazily parsing the call graph for {0}",
|
2018-10-06 07:23:15 +08:00
|
|
|
lazy_callee.symbol_name);
|
|
|
|
|
|
|
|
auto resolve_lazy_callee = [&]() -> Function * {
|
|
|
|
ConstString callee_name{lazy_callee.symbol_name};
|
|
|
|
SymbolContextList sc_list;
|
2019-10-18 03:56:40 +08:00
|
|
|
images.FindFunctionSymbols(callee_name, eFunctionNameTypeAuto, sc_list);
|
|
|
|
size_t num_matches = sc_list.GetSize();
|
2018-10-06 07:23:15 +08:00
|
|
|
if (num_matches == 0 || !sc_list[0].symbol) {
|
2019-09-15 10:43:16 +08:00
|
|
|
LLDB_LOG(log,
|
|
|
|
"DirectCallEdge: Found no symbols for {0}, cannot resolve it",
|
2018-10-06 07:23:15 +08:00
|
|
|
callee_name);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
Address callee_addr = sc_list[0].symbol->GetAddress();
|
|
|
|
if (!callee_addr.IsValid()) {
|
2019-09-15 10:43:16 +08:00
|
|
|
LLDB_LOG(log, "DirectCallEdge: Invalid symbol address");
|
2018-10-06 07:23:15 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
Function *f = callee_addr.CalculateSymbolContextFunction();
|
|
|
|
if (!f) {
|
2019-09-15 10:43:16 +08:00
|
|
|
LLDB_LOG(log, "DirectCallEdge: Could not find complete function");
|
2018-10-06 07:23:15 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return f;
|
|
|
|
};
|
|
|
|
lazy_callee.def = resolve_lazy_callee();
|
|
|
|
resolved = true;
|
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
Function *DirectCallEdge::GetCallee(ModuleList &images, ExecutionContext &) {
|
2018-10-06 07:23:15 +08:00
|
|
|
ParseSymbolFileAndResolve(images);
|
2019-10-01 05:20:14 +08:00
|
|
|
assert(resolved && "Did not resolve lazy callee");
|
2018-10-06 07:23:15 +08:00
|
|
|
return lazy_callee.def;
|
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
Function *IndirectCallEdge::GetCallee(ModuleList &images,
|
|
|
|
ExecutionContext &exe_ctx) {
|
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
|
|
|
Status error;
|
|
|
|
Value callee_addr_val;
|
|
|
|
if (!call_target.Evaluate(&exe_ctx, exe_ctx.GetRegisterContext(),
|
|
|
|
/*loclist_base_addr=*/LLDB_INVALID_ADDRESS,
|
|
|
|
/*initial_value_ptr=*/nullptr,
|
|
|
|
/*object_address_ptr=*/nullptr, callee_addr_val,
|
|
|
|
&error)) {
|
|
|
|
LLDB_LOGF(log, "IndirectCallEdge: Could not evaluate expression: %s",
|
|
|
|
error.AsCString());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
addr_t raw_addr = callee_addr_val.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
|
|
|
|
if (raw_addr == LLDB_INVALID_ADDRESS) {
|
|
|
|
LLDB_LOG(log, "IndirectCallEdge: Could not extract address from scalar");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Address callee_addr;
|
|
|
|
if (!exe_ctx.GetTargetPtr()->ResolveLoadAddress(raw_addr, callee_addr)) {
|
|
|
|
LLDB_LOG(log, "IndirectCallEdge: Could not resolve callee's load address");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
Function *f = callee_addr.CalculateSymbolContextFunction();
|
|
|
|
if (!f) {
|
|
|
|
LLDB_LOG(log, "IndirectCallEdge: Could not find complete function");
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return f;
|
2018-10-06 07:23:15 +08:00
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
/// @}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
//
|
2015-07-09 06:32:23 +08:00
|
|
|
Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
|
|
|
|
lldb::user_id_t type_uid, const Mangled &mangled, Type *type,
|
2010-06-09 00:52:24 +08:00
|
|
|
const AddressRange &range)
|
2010-08-21 10:22:51 +08:00
|
|
|
: UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid),
|
2015-07-09 06:32:23 +08:00
|
|
|
m_type(type), m_mangled(mangled), m_block(func_uid), m_range(range),
|
2019-05-29 01:34:05 +08:00
|
|
|
m_frame_base(), m_flags(), m_prologue_byte_size(0) {
|
2015-07-09 06:32:23 +08:00
|
|
|
m_block.SetParentScope(this);
|
2014-04-20 21:17:36 +08:00
|
|
|
assert(comp_unit != nullptr);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
Function::~Function() {}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-08-20 09:15:01 +08:00
|
|
|
void Function::GetStartLineSourceInfo(FileSpec &source_file,
|
|
|
|
uint32_t &line_no) {
|
|
|
|
line_no = 0;
|
2015-07-09 06:32:23 +08:00
|
|
|
source_file.Clear();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2014-04-20 21:17:36 +08:00
|
|
|
if (m_comp_unit == nullptr)
|
2016-09-07 04:57:50 +08:00
|
|
|
return;
|
|
|
|
|
2016-09-08 10:26:58 +08:00
|
|
|
// Initialize m_type if it hasn't been initialized already
|
|
|
|
GetType();
|
|
|
|
|
2015-07-09 06:32:23 +08:00
|
|
|
if (m_type != nullptr && m_type->GetDeclaration().GetLine() != 0) {
|
2010-08-20 09:15:01 +08:00
|
|
|
source_file = m_type->GetDeclaration().GetFile();
|
|
|
|
line_no = m_type->GetDeclaration().GetLine();
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2010-08-20 09:15:01 +08:00
|
|
|
LineTable *line_table = m_comp_unit->GetLineTable();
|
2014-04-20 21:17:36 +08:00
|
|
|
if (line_table == nullptr)
|
2016-09-07 04:57:50 +08:00
|
|
|
return;
|
|
|
|
|
2010-08-20 09:15:01 +08:00
|
|
|
LineEntry line_entry;
|
2012-04-26 09:01:34 +08:00
|
|
|
if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(),
|
2014-04-20 21:17:36 +08:00
|
|
|
line_entry, nullptr)) {
|
2010-08-20 09:15:01 +08:00
|
|
|
line_no = line_entry.line;
|
|
|
|
source_file = line_entry.file;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-09 06:32:23 +08:00
|
|
|
void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) {
|
2010-06-09 00:52:24 +08:00
|
|
|
line_no = 0;
|
|
|
|
source_file.Clear();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// The -1 is kind of cheesy, but I want to get the last line entry for the
|
2018-05-01 00:49:04 +08:00
|
|
|
// given function, not the first entry of the next.
|
2010-08-20 09:15:01 +08:00
|
|
|
Address scratch_addr(GetAddressRange().GetBaseAddress());
|
2010-06-09 00:52:24 +08:00
|
|
|
scratch_addr.SetOffset(scratch_addr.GetOffset() +
|
2010-08-20 09:15:01 +08:00
|
|
|
GetAddressRange().GetByteSize() - 1);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
LineTable *line_table = m_comp_unit->GetLineTable();
|
|
|
|
if (line_table == nullptr)
|
2016-09-07 04:57:50 +08:00
|
|
|
return;
|
|
|
|
|
2010-08-20 09:15:01 +08:00
|
|
|
LineEntry line_entry;
|
2014-04-20 21:17:36 +08:00
|
|
|
if (line_table->FindLineEntryByAddress(scratch_addr, line_entry, nullptr)) {
|
2010-08-20 09:15:01 +08:00
|
|
|
line_no = line_entry.line;
|
|
|
|
source_file = line_entry.file;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetCallEdges() {
|
2020-07-08 07:54:09 +08:00
|
|
|
std::lock_guard<std::mutex> guard(m_call_edges_lock);
|
|
|
|
|
2018-10-06 07:23:15 +08:00
|
|
|
if (m_call_edges_resolved)
|
|
|
|
return m_call_edges;
|
|
|
|
|
|
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
|
|
|
|
LLDB_LOG(log, "GetCallEdges: Attempting to parse call site info for {0}",
|
|
|
|
GetDisplayName());
|
|
|
|
|
|
|
|
m_call_edges_resolved = true;
|
|
|
|
|
|
|
|
// Find the SymbolFile which provided this function's definition.
|
|
|
|
Block &block = GetBlock(/*can_create*/true);
|
|
|
|
SymbolFile *sym_file = block.GetSymbolFile();
|
|
|
|
if (!sym_file)
|
|
|
|
return llvm::None;
|
|
|
|
|
|
|
|
// Lazily read call site information from the SymbolFile.
|
|
|
|
m_call_edges = sym_file->ParseCallEdgesInFunction(GetID());
|
|
|
|
|
|
|
|
// Sort the call edges to speed up return_pc lookups.
|
2020-06-02 22:01:11 +08:00
|
|
|
llvm::sort(m_call_edges, [](const std::unique_ptr<CallEdge> &LHS,
|
|
|
|
const std::unique_ptr<CallEdge> &RHS) {
|
|
|
|
return LHS->GetSortKey() < RHS->GetSortKey();
|
|
|
|
});
|
2018-10-06 07:23:15 +08:00
|
|
|
|
|
|
|
return m_call_edges;
|
|
|
|
}
|
|
|
|
|
2019-09-15 10:43:16 +08:00
|
|
|
llvm::ArrayRef<std::unique_ptr<CallEdge>> Function::GetTailCallingEdges() {
|
2020-06-02 22:01:11 +08:00
|
|
|
// Tail calling edges are sorted at the end of the list. Find them by dropping
|
|
|
|
// all non-tail-calls.
|
|
|
|
return GetCallEdges().drop_until(
|
|
|
|
[](const std::unique_ptr<CallEdge> &edge) { return edge->IsTailCall(); });
|
2018-10-06 07:23:15 +08:00
|
|
|
}
|
|
|
|
|
2019-09-11 02:36:50 +08:00
|
|
|
CallEdge *Function::GetCallEdgeForReturnAddress(addr_t return_pc,
|
|
|
|
Target &target) {
|
|
|
|
auto edges = GetCallEdges();
|
|
|
|
auto edge_it =
|
2020-06-02 22:01:11 +08:00
|
|
|
llvm::partition_point(edges, [&](const std::unique_ptr<CallEdge> &edge) {
|
|
|
|
return std::make_pair(edge->IsTailCall(),
|
|
|
|
edge->GetReturnPCAddress(*this, target)) <
|
|
|
|
std::make_pair(false, return_pc);
|
|
|
|
});
|
2019-09-11 02:36:50 +08:00
|
|
|
if (edge_it == edges.end() ||
|
2019-09-15 10:43:16 +08:00
|
|
|
edge_it->get()->GetReturnPCAddress(*this, target) != return_pc)
|
2019-09-11 02:36:50 +08:00
|
|
|
return nullptr;
|
2020-06-02 22:01:11 +08:00
|
|
|
return edge_it->get();
|
2019-09-11 02:36:50 +08:00
|
|
|
}
|
|
|
|
|
2010-08-21 10:22:51 +08:00
|
|
|
Block &Function::GetBlock(bool can_create) {
|
2010-06-09 00:52:24 +08:00
|
|
|
if (!m_block.BlockInfoHasBeenParsed() && can_create) {
|
2019-01-15 06:40:41 +08:00
|
|
|
ModuleSP module_sp = CalculateSymbolContextModule();
|
|
|
|
if (module_sp) {
|
2019-08-06 17:12:42 +08:00
|
|
|
module_sp->GetSymbolFile()->ParseBlocksRecursive(*this);
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2019-01-15 06:40:41 +08:00
|
|
|
Host::SystemLog(Host::eSystemLogError,
|
|
|
|
"error: unable to find module "
|
|
|
|
"shared pointer for function '%s' "
|
|
|
|
"in %s\n",
|
2019-11-28 23:22:44 +08:00
|
|
|
GetName().GetCString(),
|
|
|
|
m_comp_unit->GetPrimaryFile().GetPath().c_str());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
m_block.SetBlockInfoHasBeenParsed(true, true);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-08-21 10:22:51 +08:00
|
|
|
return m_block;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
CompileUnit *Function::GetCompileUnit() { return m_comp_unit; }
|
Added support for inlined stack frames being represented as real stack frames
which is now on by default. Frames are gotten from the unwinder as concrete
frames, then if inline frames are to be shown, extra information to track
and reconstruct these frames is cached with each Thread and exanded as needed.
I added an inline height as part of the lldb_private::StackID class, the class
that helps us uniquely identify stack frames. This allows for two frames to
shared the same call frame address, yet differ only in inline height.
Fixed setting breakpoint by address to not require addresses to resolve.
A quick example:
% cat main.cpp
% ./build/Debug/lldb test/stl/a.out
Current executable set to 'test/stl/a.out' (x86_64).
(lldb) breakpoint set --address 0x0000000100000d31
Breakpoint created: 1: address = 0x0000000100000d31, locations = 1
(lldb) r
Launching 'a.out' (x86_64)
(lldb) Process 38031 Stopped
* thread #1: tid = 0x2e03, pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280, stop reason = breakpoint 1.1, queue = com.apple.main-thread
277
278 _CharT*
279 _M_data() const
280 -> { return _M_dataplus._M_p; }
281
282 _CharT*
283 _M_data(_CharT* __p)
(lldb) bt
thread #1: tid = 0x2e03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280
frame #1: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_rep() const at /usr/include/c++/4.2.1/bits/basic_string.h:288
frame #2: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::size() const at /usr/include/c++/4.2.1/bits/basic_string.h:606
frame #3: pc = 0x0000000100000d31, where = a.out`main [inlined] operator<< <char, std::char_traits<char>, std::allocator<char> > at /usr/include/c++/4.2.1/bits/basic_string.h:2414
frame #4: pc = 0x0000000100000d31, where = a.out`main + 33 at /Volumes/work/gclayton/Documents/src/lldb/test/stl/main.cpp:14
frame #5: pc = 0x0000000100000d08, where = a.out`start + 52
Each inline frame contains only the variables that they contain and each inlined
stack frame is treated as a single entity.
llvm-svn: 111877
2010-08-24 08:45:41 +08:00
|
|
|
|
2015-07-09 06:32:23 +08:00
|
|
|
const CompileUnit *Function::GetCompileUnit() const { return m_comp_unit; }
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-09 06:32:23 +08:00
|
|
|
void Function::GetDescription(Stream *s, lldb::DescriptionLevel level,
|
|
|
|
Target *target) {
|
2017-02-11 07:32:06 +08:00
|
|
|
ConstString name = GetName();
|
|
|
|
ConstString mangled = m_mangled.GetMangledName();
|
|
|
|
|
|
|
|
*s << "id = " << (const UserID &)*this;
|
|
|
|
if (name)
|
2020-05-22 15:36:37 +08:00
|
|
|
s->AsRawOstream() << ", name = \"" << name << '"';
|
2017-02-11 07:32:06 +08:00
|
|
|
if (mangled)
|
2020-05-22 15:36:37 +08:00
|
|
|
s->AsRawOstream() << ", mangled = \"" << mangled << '"';
|
2017-02-11 07:32:06 +08:00
|
|
|
*s << ", range = ";
|
2015-07-09 06:32:23 +08:00
|
|
|
Address::DumpStyle fallback_style;
|
|
|
|
if (level == eDescriptionLevelVerbose)
|
|
|
|
fallback_style = Address::DumpStyleModuleWithFileAddress;
|
2016-09-07 04:57:50 +08:00
|
|
|
else
|
2010-09-10 09:30:46 +08:00
|
|
|
fallback_style = Address::DumpStyleFileAddress;
|
2015-07-09 06:32:23 +08:00
|
|
|
GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress,
|
|
|
|
fallback_style);
|
2015-07-07 02:28:46 +08:00
|
|
|
}
|
Added support for inlined stack frames being represented as real stack frames
which is now on by default. Frames are gotten from the unwinder as concrete
frames, then if inline frames are to be shown, extra information to track
and reconstruct these frames is cached with each Thread and exanded as needed.
I added an inline height as part of the lldb_private::StackID class, the class
that helps us uniquely identify stack frames. This allows for two frames to
shared the same call frame address, yet differ only in inline height.
Fixed setting breakpoint by address to not require addresses to resolve.
A quick example:
% cat main.cpp
% ./build/Debug/lldb test/stl/a.out
Current executable set to 'test/stl/a.out' (x86_64).
(lldb) breakpoint set --address 0x0000000100000d31
Breakpoint created: 1: address = 0x0000000100000d31, locations = 1
(lldb) r
Launching 'a.out' (x86_64)
(lldb) Process 38031 Stopped
* thread #1: tid = 0x2e03, pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280, stop reason = breakpoint 1.1, queue = com.apple.main-thread
277
278 _CharT*
279 _M_data() const
280 -> { return _M_dataplus._M_p; }
281
282 _CharT*
283 _M_data(_CharT* __p)
(lldb) bt
thread #1: tid = 0x2e03, stop reason = breakpoint 1.1, queue = com.apple.main-thread
frame #0: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_data() const at /usr/include/c++/4.2.1/bits/basic_string.h:280
frame #1: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::_M_rep() const at /usr/include/c++/4.2.1/bits/basic_string.h:288
frame #2: pc = 0x0000000100000d31, where = a.out`main [inlined] std::string::size() const at /usr/include/c++/4.2.1/bits/basic_string.h:606
frame #3: pc = 0x0000000100000d31, where = a.out`main [inlined] operator<< <char, std::char_traits<char>, std::allocator<char> > at /usr/include/c++/4.2.1/bits/basic_string.h:2414
frame #4: pc = 0x0000000100000d31, where = a.out`main + 33 at /Volumes/work/gclayton/Documents/src/lldb/test/stl/main.cpp:14
frame #5: pc = 0x0000000100000d08, where = a.out`start + 52
Each inline frame contains only the variables that they contain and each inlined
stack frame is treated as a single entity.
llvm-svn: 111877
2010-08-24 08:45:41 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
void Function::Dump(Stream *s, bool show_context) const {
|
|
|
|
s->Printf("%p: ", static_cast<const void *>(this));
|
|
|
|
s->Indent();
|
2014-04-04 12:06:10 +08:00
|
|
|
*s << "Function" << static_cast<const UserID &>(*this);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
m_mangled.Dump(s);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (m_type)
|
2014-04-04 12:06:10 +08:00
|
|
|
s->Printf(", type = %p", static_cast<void *>(m_type));
|
2010-06-09 00:52:24 +08:00
|
|
|
else if (m_type_uid != LLDB_INVALID_UID)
|
|
|
|
s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
s->EOL();
|
|
|
|
// Dump the root object
|
2010-08-21 10:22:51 +08:00
|
|
|
if (m_block.BlockInfoHasBeenParsed())
|
2010-06-09 00:52:24 +08:00
|
|
|
m_block.Dump(s, m_range.GetBaseAddress().GetFileAddress(), INT_MAX,
|
|
|
|
show_context);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Function::CalculateSymbolContext(SymbolContext *sc) {
|
|
|
|
sc->function = this;
|
|
|
|
m_comp_unit->CalculateSymbolContext(sc);
|
|
|
|
}
|
|
|
|
|
2011-08-13 05:40:01 +08:00
|
|
|
ModuleSP Function::CalculateSymbolContextModule() {
|
2012-02-24 09:59:29 +08:00
|
|
|
SectionSP section_sp(m_range.GetBaseAddress().GetSection());
|
|
|
|
if (section_sp)
|
2013-03-05 05:46:16 +08:00
|
|
|
return section_sp->GetModule();
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
return this->GetCompileUnit()->GetModule();
|
|
|
|
}
|
|
|
|
|
|
|
|
CompileUnit *Function::CalculateSymbolContextCompileUnit() {
|
|
|
|
return this->GetCompileUnit();
|
|
|
|
}
|
|
|
|
|
|
|
|
Function *Function::CalculateSymbolContextFunction() { return this; }
|
|
|
|
|
|
|
|
lldb::DisassemblerSP Function::GetInstructions(const ExecutionContext &exe_ctx,
|
|
|
|
const char *flavor,
|
2010-08-21 10:22:51 +08:00
|
|
|
bool prefer_file_cache) {
|
2010-06-09 00:52:24 +08:00
|
|
|
ModuleSP module_sp(GetAddressRange().GetBaseAddress().GetModule());
|
2020-03-05 20:03:26 +08:00
|
|
|
if (module_sp && exe_ctx.HasTargetScope()) {
|
2010-06-09 00:52:24 +08:00
|
|
|
const bool prefer_file_cache = false;
|
2010-08-20 09:15:01 +08:00
|
|
|
return Disassembler::DisassembleRange(module_sp->GetArchitecture(), nullptr,
|
2020-03-05 20:03:26 +08:00
|
|
|
flavor, exe_ctx.GetTargetRef(),
|
|
|
|
GetAddressRange(), prefer_file_cache);
|
2010-08-20 09:15:01 +08:00
|
|
|
}
|
2014-04-20 21:17:36 +08:00
|
|
|
return lldb::DisassemblerSP();
|
2010-08-20 09:15:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Function::GetDisassembly(const ExecutionContext &exe_ctx,
|
|
|
|
const char *flavor, bool prefer_file_cache,
|
|
|
|
Stream &strm) {
|
|
|
|
lldb::DisassemblerSP disassembler_sp =
|
|
|
|
GetInstructions(exe_ctx, flavor, prefer_file_cache);
|
|
|
|
if (disassembler_sp) {
|
|
|
|
const bool show_address = true;
|
|
|
|
const bool show_bytes = false;
|
|
|
|
disassembler_sp->GetInstructionList().Dump(&strm, show_address, show_bytes,
|
|
|
|
&exe_ctx);
|
2014-04-20 21:17:36 +08:00
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-08-20 09:15:01 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
// Symbol *
|
|
|
|
// Function::CalculateSymbolContextSymbol ()
|
2011-06-24 11:47:23 +08:00
|
|
|
//{
|
2013-04-30 01:25:54 +08:00
|
|
|
// return // TODO: find the symbol for the function???
|
2016-09-07 04:57:50 +08:00
|
|
|
//}
|
|
|
|
|
2013-04-30 01:25:54 +08:00
|
|
|
void Function::DumpSymbolContext(Stream *s) {
|
|
|
|
m_comp_unit->DumpSymbolContext(s);
|
2010-08-21 10:22:51 +08:00
|
|
|
s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t Function::MemorySize() const {
|
|
|
|
size_t mem_size = sizeof(Function) + m_block.MemorySize();
|
|
|
|
return mem_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Function::GetIsOptimized() {
|
2015-07-29 08:42:47 +08:00
|
|
|
bool result = false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Currently optimization is only indicted by the vendor extension
|
|
|
|
// DW_AT_APPLE_optimized which is set on a compile unit level.
|
2010-06-09 00:52:24 +08:00
|
|
|
if (m_comp_unit) {
|
|
|
|
result = m_comp_unit->GetIsOptimized();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-10-01 07:12:22 +08:00
|
|
|
bool Function::IsTopLevelFunction() {
|
2015-07-29 08:42:47 +08:00
|
|
|
bool result = false;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-10-01 07:12:22 +08:00
|
|
|
if (Language *language = Language::FindPlugin(GetLanguage()))
|
|
|
|
result = language->IsTopLevelFunction(*this);
|
2010-06-29 05:30:43 +08:00
|
|
|
|
2010-09-10 09:30:46 +08:00
|
|
|
return result;
|
2010-06-29 05:30:43 +08:00
|
|
|
}
|
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
ConstString Function::GetDisplayName() const {
|
2020-01-31 13:55:18 +08:00
|
|
|
return m_mangled.GetDisplayDemangledName();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
|
|
|
|
CompilerDeclContext Function::GetDeclContext() {
|
|
|
|
ModuleSP module_sp = CalculateSymbolContextModule();
|
|
|
|
|
|
|
|
if (module_sp) {
|
2019-08-02 16:16:35 +08:00
|
|
|
if (SymbolFile *sym_file = module_sp->GetSymbolFile())
|
|
|
|
return sym_file->GetDeclContextForUID(GetID());
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2014-01-28 07:43:24 +08:00
|
|
|
return CompilerDeclContext();
|
|
|
|
}
|
|
|
|
|
2013-07-12 06:46:58 +08:00
|
|
|
Type *Function::GetType() {
|
2014-04-20 21:17:36 +08:00
|
|
|
if (m_type == nullptr) {
|
2011-09-30 11:20:47 +08:00
|
|
|
SymbolContext sc;
|
2014-01-28 07:43:24 +08:00
|
|
|
|
2011-08-13 05:40:01 +08:00
|
|
|
CalculateSymbolContext(&sc);
|
|
|
|
|
2011-09-30 11:20:47 +08:00
|
|
|
if (!sc.module_sp)
|
2014-04-20 21:17:36 +08:00
|
|
|
return nullptr;
|
2011-08-13 05:40:01 +08:00
|
|
|
|
2019-08-02 16:16:35 +08:00
|
|
|
SymbolFile *sym_file = sc.module_sp->GetSymbolFile();
|
2015-07-29 08:42:47 +08:00
|
|
|
|
|
|
|
if (sym_file == nullptr)
|
|
|
|
return nullptr;
|
|
|
|
|
2015-10-01 07:12:22 +08:00
|
|
|
m_type = sym_file->ResolveTypeUID(m_type_uid);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-10-01 07:12:22 +08:00
|
|
|
return m_type;
|
|
|
|
}
|
|
|
|
|
2015-07-07 02:28:46 +08:00
|
|
|
const Type *Function::GetType() const { return m_type; }
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-07-07 02:28:46 +08:00
|
|
|
CompilerType Function::GetCompilerType() {
|
|
|
|
Type *function_type = GetType();
|
|
|
|
if (function_type)
|
2015-07-09 06:32:23 +08:00
|
|
|
return function_type->GetFullCompilerType();
|
|
|
|
return CompilerType();
|
2015-07-07 02:28:46 +08:00
|
|
|
}
|
|
|
|
|
2015-08-25 07:46:31 +08:00
|
|
|
uint32_t Function::GetPrologueByteSize() {
|
|
|
|
if (m_prologue_byte_size == 0 &&
|
|
|
|
m_flags.IsClear(flagsCalculatedPrologueSize)) {
|
|
|
|
m_flags.Set(flagsCalculatedPrologueSize);
|
|
|
|
LineTable *line_table = m_comp_unit->GetLineTable();
|
2016-02-03 08:07:23 +08:00
|
|
|
uint32_t prologue_end_line_idx = 0;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2010-06-09 00:52:24 +08:00
|
|
|
if (line_table) {
|
2012-04-26 09:01:34 +08:00
|
|
|
LineEntry first_line_entry;
|
|
|
|
uint32_t first_line_entry_idx = UINT32_MAX;
|
|
|
|
if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(),
|
|
|
|
first_line_entry,
|
|
|
|
&first_line_entry_idx)) {
|
|
|
|
// Make sure the first line entry isn't already the end of the prologue
|
|
|
|
addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
|
2016-02-03 08:07:23 +08:00
|
|
|
addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2012-04-26 09:01:34 +08:00
|
|
|
if (first_line_entry.is_prologue_end) {
|
|
|
|
prologue_end_file_addr =
|
|
|
|
first_line_entry.range.GetBaseAddress().GetFileAddress();
|
2016-02-03 08:07:23 +08:00
|
|
|
prologue_end_line_idx = first_line_entry_idx;
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
2012-04-26 09:01:34 +08:00
|
|
|
// Check the first few instructions and look for one that has
|
|
|
|
// is_prologue_end set to true.
|
2015-08-25 07:46:31 +08:00
|
|
|
const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
|
2012-04-26 09:01:34 +08:00
|
|
|
for (uint32_t idx = first_line_entry_idx + 1;
|
|
|
|
idx < last_line_entry_idx; ++idx) {
|
2010-08-20 09:15:01 +08:00
|
|
|
LineEntry line_entry;
|
2015-08-25 07:46:31 +08:00
|
|
|
if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
|
2012-04-26 09:01:34 +08:00
|
|
|
if (line_entry.is_prologue_end) {
|
|
|
|
prologue_end_file_addr =
|
|
|
|
line_entry.range.GetBaseAddress().GetFileAddress();
|
2016-02-03 08:07:23 +08:00
|
|
|
prologue_end_line_idx = idx;
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-08-25 07:46:31 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// If we didn't find the end of the prologue in the line tables, then
|
|
|
|
// just use the end address of the first line table entry
|
2015-08-25 07:46:31 +08:00
|
|
|
if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
|
2018-05-01 00:49:04 +08:00
|
|
|
// Check the first few instructions and look for one that has a line
|
|
|
|
// number that's different than the first entry.
|
2012-04-26 09:01:34 +08:00
|
|
|
uint32_t last_line_entry_idx = first_line_entry_idx + 6;
|
2015-08-25 07:46:31 +08:00
|
|
|
for (uint32_t idx = first_line_entry_idx + 1;
|
2012-04-26 09:01:34 +08:00
|
|
|
idx < last_line_entry_idx; ++idx) {
|
2010-08-20 09:15:01 +08:00
|
|
|
LineEntry line_entry;
|
2015-08-25 07:46:31 +08:00
|
|
|
if (line_table->GetLineEntryAtIndex(idx, line_entry)) {
|
2013-07-02 03:45:50 +08:00
|
|
|
if (line_entry.line != first_line_entry.line) {
|
2015-08-25 07:46:31 +08:00
|
|
|
prologue_end_file_addr =
|
|
|
|
line_entry.range.GetBaseAddress().GetFileAddress();
|
2016-02-03 08:07:23 +08:00
|
|
|
prologue_end_line_idx = idx;
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-26 09:01:34 +08:00
|
|
|
if (prologue_end_file_addr == LLDB_INVALID_ADDRESS) {
|
|
|
|
prologue_end_file_addr =
|
2013-07-02 03:45:50 +08:00
|
|
|
first_line_entry.range.GetBaseAddress().GetFileAddress() +
|
|
|
|
first_line_entry.range.GetByteSize();
|
2015-08-25 07:46:31 +08:00
|
|
|
prologue_end_line_idx = first_line_entry_idx;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
|
|
|
}
|
2015-08-25 07:46:31 +08:00
|
|
|
|
2010-11-12 04:13:30 +08:00
|
|
|
const addr_t func_start_file_addr =
|
2015-08-25 07:46:31 +08:00
|
|
|
m_range.GetBaseAddress().GetFileAddress();
|
|
|
|
const addr_t func_end_file_addr =
|
|
|
|
func_start_file_addr + m_range.GetByteSize();
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2015-08-25 07:46:31 +08:00
|
|
|
// Now calculate the offset to pass the subsequent line 0 entries.
|
|
|
|
uint32_t first_non_zero_line = prologue_end_line_idx;
|
2019-05-24 08:44:33 +08:00
|
|
|
while (true) {
|
2013-07-02 03:45:50 +08:00
|
|
|
LineEntry line_entry;
|
2015-08-25 07:46:31 +08:00
|
|
|
if (line_table->GetLineEntryAtIndex(first_non_zero_line,
|
2012-04-26 09:01:34 +08:00
|
|
|
line_entry)) {
|
2016-02-03 08:07:23 +08:00
|
|
|
if (line_entry.line != 0)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
}
|
2016-02-03 08:07:23 +08:00
|
|
|
if (line_entry.range.GetBaseAddress().GetFileAddress() >=
|
|
|
|
func_end_file_addr)
|
2016-09-07 04:57:50 +08:00
|
|
|
break;
|
|
|
|
|
2016-02-03 08:07:23 +08:00
|
|
|
first_non_zero_line++;
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-08-25 07:46:31 +08:00
|
|
|
|
|
|
|
if (first_non_zero_line > prologue_end_line_idx) {
|
2016-02-03 08:07:23 +08:00
|
|
|
LineEntry first_non_zero_entry;
|
2015-08-25 07:46:31 +08:00
|
|
|
if (line_table->GetLineEntryAtIndex(first_non_zero_line,
|
|
|
|
first_non_zero_entry)) {
|
|
|
|
line_zero_end_file_addr =
|
|
|
|
first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2015-08-25 07:46:31 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2018-05-01 00:49:04 +08:00
|
|
|
// Verify that this prologue end file address in the function's address
|
|
|
|
// range just to be sure
|
2010-06-09 00:52:24 +08:00
|
|
|
if (func_start_file_addr < prologue_end_file_addr &&
|
2012-04-26 09:01:34 +08:00
|
|
|
prologue_end_file_addr < func_end_file_addr) {
|
|
|
|
m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
|
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
|
2013-07-02 03:45:50 +08:00
|
|
|
if (prologue_end_file_addr < line_zero_end_file_addr &&
|
2016-02-03 08:07:23 +08:00
|
|
|
line_zero_end_file_addr < func_end_file_addr) {
|
|
|
|
m_prologue_byte_size +=
|
|
|
|
line_zero_end_file_addr - prologue_end_file_addr;
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-09 00:52:24 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-09 06:32:23 +08:00
|
|
|
return m_prologue_byte_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
lldb::LanguageType Function::GetLanguage() const {
|
2019-07-02 04:36:33 +08:00
|
|
|
lldb::LanguageType lang = m_mangled.GuessLanguage();
|
|
|
|
if (lang != lldb::eLanguageTypeUnknown)
|
|
|
|
return lang;
|
|
|
|
|
2015-07-09 06:32:23 +08:00
|
|
|
if (m_comp_unit)
|
|
|
|
return m_comp_unit->GetLanguage();
|
2019-07-02 04:36:33 +08:00
|
|
|
|
|
|
|
return lldb::eLanguageTypeUnknown;
|
2015-07-09 06:32:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
ConstString Function::GetName() const {
|
2020-01-31 13:55:18 +08:00
|
|
|
return m_mangled.GetName();
|
2015-07-09 06:32:23 +08:00
|
|
|
}
|
|
|
|
|
2012-10-13 01:34:26 +08:00
|
|
|
ConstString Function::GetNameNoArguments() const {
|
2020-01-31 13:55:18 +08:00
|
|
|
return m_mangled.GetName(Mangled::ePreferDemangledWithoutArguments);
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|