Path: blob/main/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp
39587 views
//===-- UtilityFunction.cpp -----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <cstdio>9#include <sys/types.h>1011#include "lldb/Core/Module.h"12#include "lldb/Expression/DiagnosticManager.h"13#include "lldb/Expression/FunctionCaller.h"14#include "lldb/Expression/IRExecutionUnit.h"15#include "lldb/Expression/UtilityFunction.h"16#include "lldb/Host/Host.h"17#include "lldb/Target/ExecutionContext.h"18#include "lldb/Target/Process.h"19#include "lldb/Target/Target.h"20#include "lldb/Utility/ConstString.h"21#include "lldb/Utility/Log.h"22#include "lldb/Utility/State.h"23#include "lldb/Utility/Stream.h"2425using namespace lldb_private;26using namespace lldb;2728char UtilityFunction::ID;2930/// Constructor31///32/// \param[in] text33/// The text of the function. Must be a full translation unit.34///35/// \param[in] name36/// The name of the function, as used in the text.37UtilityFunction::UtilityFunction(ExecutionContextScope &exe_scope,38std::string text, std::string name,39bool enable_debugging)40: Expression(exe_scope), m_execution_unit_sp(), m_jit_module_wp(),41m_function_text(std::move(text)), m_function_name(std::move(name)) {}4243UtilityFunction::~UtilityFunction() {44lldb::ProcessSP process_sp(m_jit_process_wp.lock());45if (process_sp) {46lldb::ModuleSP jit_module_sp(m_jit_module_wp.lock());47if (jit_module_sp)48process_sp->GetTarget().GetImages().Remove(jit_module_sp);49}50}5152// FIXME: We should check that every time this is called it is called with the53// same return type & arguments...5455FunctionCaller *UtilityFunction::MakeFunctionCaller(56const CompilerType &return_type, const ValueList &arg_value_list,57lldb::ThreadSP thread_to_use_sp, Status &error) {58if (m_caller_up)59return m_caller_up.get();6061ProcessSP process_sp = m_jit_process_wp.lock();62if (!process_sp) {63error.SetErrorString("Can't make a function caller without a process.");64return nullptr;65}66// Since we might need to allocate memory and maybe call code to make67// the caller, we need to be stopped.68if (process_sp->GetState() != lldb::eStateStopped) {69error.SetErrorStringWithFormatv(70"Can't make a function caller while the process is {0}: the process "71"must be stopped to allocate memory.",72StateAsCString(process_sp->GetState()));73return nullptr;74}7576Address impl_code_address;77impl_code_address.SetOffset(StartAddress());78std::string name(m_function_name);79name.append("-caller");8081m_caller_up.reset(process_sp->GetTarget().GetFunctionCallerForLanguage(82Language().AsLanguageType(), return_type, impl_code_address,83arg_value_list, name.c_str(), error));84if (error.Fail()) {8586return nullptr;87}88if (m_caller_up) {89DiagnosticManager diagnostics;9091unsigned num_errors =92m_caller_up->CompileFunction(thread_to_use_sp, diagnostics);93if (num_errors) {94error.SetErrorStringWithFormat(95"Error compiling %s caller function: \"%s\".",96m_function_name.c_str(), diagnostics.GetString().c_str());97m_caller_up.reset();98return nullptr;99}100101diagnostics.Clear();102ExecutionContext exe_ctx(process_sp);103104if (!m_caller_up->WriteFunctionWrapper(exe_ctx, diagnostics)) {105error.SetErrorStringWithFormat(106"Error inserting caller function for %s: \"%s\".",107m_function_name.c_str(), diagnostics.GetString().c_str());108m_caller_up.reset();109return nullptr;110}111}112return m_caller_up.get();113}114115116