34#include "llvm/ADT/ScopeExit.h"
35#include "llvm/Support/ConvertUTF.h"
48 const bool is_host =
false;
51 if (!create && arch && arch->IsValid()) {
52 const llvm::Triple &triple = arch->GetTriple();
53 switch (triple.getVendor()) {
54 case llvm::Triple::PC:
58 case llvm::Triple::UnknownVendor:
59 create = !arch->TripleVendorWasSpecified();
67 switch (triple.getOS()) {
68 case llvm::Triple::Win32:
71 case llvm::Triple::UnknownOS:
72 create = arch->TripleOSWasSpecified();
87 return is_host ?
"Local Windows user platform plug-in."
88 :
"Remote Windows user platform plug-in.";
98 default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
120 const auto &AddArch = [&](
const ArchSpec &spec) {
122 return spec.IsExactMatch(rhs);
128 AddArch(HostInfo::GetArchitecture(HostInfo::eArchKindDefault));
129 AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind32));
130 AddArch(HostInfo::GetArchitecture(HostInfo::eArchKind64));
136 error.SetErrorStringWithFormatv(
137 "can't connect to the host platform '{0}', always connected",
146 if (
error.Success()) {
150 error.SetErrorString(
151 "\"platform connect\" takes a single argument: <connect-url>");
155 error.SetErrorString(
"failed to create a 'remote-gdb-server' platform");
166 const std::vector<std::string> *paths,
171 loaded_image->
Clear();
175 error.SetErrorString(
"LoadLibrary error: no thread available to invoke LoadLibrary");
180 thread->CalculateExecutionContext(context);
187 if (loader ==
nullptr)
192 error.SetErrorString(
"LoadLibrary error: could not get function caller");
197 llvm::SmallVector<llvm::UTF16, 261> name;
198 if (!llvm::convertUTF8ToUTF16String(remote_file.
GetPath(), name)) {
199 error.SetErrorString(
"LoadLibrary error: could not convert path to UCS2");
202 name.emplace_back(L
'\0');
207 ePermissionsReadable | ePermissionsWritable,
210 error.SetErrorStringWithFormat(
"LoadLibrary error: unable to allocate memory for name: %s",
215 auto name_cleanup = llvm::make_scope_exit([process, injected_name]() {
220 name.size() *
sizeof(llvm::UTF16), status);
222 error.SetErrorStringWithFormat(
"LoadLibrary error: unable to write name: %s",
229 std::optional<llvm::detail::scope_exit<std::function<void()>>> paths_cleanup;
231 llvm::SmallVector<llvm::UTF16, 261> search_paths;
233 for (
const auto &path : *paths) {
237 llvm::SmallVector<llvm::UTF16, 261> buffer;
238 if (!llvm::convertUTF8ToUTF16String(path, buffer))
241 search_paths.append(std::begin(buffer), std::end(buffer));
242 search_paths.emplace_back(L
'\0');
244 search_paths.emplace_back(L
'\0');
247 process->
AllocateMemory(search_paths.size() *
sizeof(llvm::UTF16),
248 ePermissionsReadable | ePermissionsWritable,
251 error.SetErrorStringWithFormat(
"LoadLibrary error: unable to allocate memory for paths: %s",
256 paths_cleanup.emplace([process, injected_paths]() {
260 process->
WriteMemory(injected_paths, search_paths.data(),
261 search_paths.size() *
sizeof(llvm::UTF16), status);
263 error.SetErrorStringWithFormat(
"LoadLibrary error: unable to write paths: %s",
273 unsigned injected_length = 261;
277 ePermissionsReadable | ePermissionsWritable,
280 error.SetErrorStringWithFormat(
"LoadLibrary error: unable to allocate memory for module location: %s",
285 auto injected_module_path_cleanup =
286 llvm::make_scope_exit([process, injected_module_path]() {
294 ePermissionsReadable | ePermissionsWritable,
297 error.SetErrorStringWithFormat(
"LoadLibrary error: could not allocate memory for result: %s",
302 auto result_cleanup = llvm::make_scope_exit([process, injected_result]() {
307 injected_module_path, status);
309 error.SetErrorStringWithFormat(
"LoadLibrary error: could not initialize result: %s",
316 Scalar{injected_length},
sizeof(unsigned),
319 error.SetErrorStringWithFormat(
"LoadLibrary error: could not initialize result: %s",
333 parameters, diagnostics)) {
334 error.SetErrorStringWithFormat(
"LoadLibrary error: unable to write function parameters: %s",
339 auto parameter_cleanup =
340 llvm::make_scope_exit([invocation, &context, injected_parameters]() {
346 if (!scratch_ts_sp) {
347 error.SetErrorString(
"LoadLibrary error: unable to get (clang) type system");
375 error.SetErrorStringWithFormat(
"LoadLibrary error: failed to execute LoadLibrary helper: %s",
383 error.SetErrorStringWithFormat(
"LoadLibrary error: could not read the result: %s",
390 uint64_t error_code =
394 error.SetErrorStringWithFormat(
"LoadLibrary error: could not read error status: %s",
399 error.SetErrorStringWithFormat(
"LoadLibrary Error: %" PRIu64, error_code);
403 std::string module_path;
406 error.SetErrorStringWithFormat(
"LoadLibrary error: could not read module path: %s",
412 loaded_image->
SetFile(module_path, llvm::sys::path::Style::native);
419 return Status(
"invalid image token");
422 expression.
Printf(
"FreeLibrary((HMODULE)0x%" PRIx64
")", address);
430 if (value->GetError().Fail())
434 if (value->ResolveValue(scalar)) {
436 return Status(
"expression failed: \"%s\"", expression.
GetData());
447 error.SetErrorStringWithFormatv(
448 "can't disconnect from the host platform '{0}', always connected",
454 error.SetErrorString(
"the platform is not currently connected");
486 error.SetErrorString(
"the platform is not currently connected");
492 return Attach(attach_info, debugger, &target,
error);
504 error = process_sp->Launch(launch_info);
519 error.SetErrorString(
"the platform is not currently connected");
523 if (target ==
nullptr) {
530 target = new_target_sp.get();
533 if (!target ||
error.Fail())
542 error = process_sp->Attach(attach_info);
551 llvm::VersionTuple version = HostInfo::GetOSVersion();
552 strm <<
" Host: Windows " << version.getAsString() <<
'\n';
572 const uint8_t *trap_opcode =
nullptr;
573 size_t trap_opcode_size = 0;
576 case llvm::Triple::aarch64: {
577 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e, 0xd4};
578 trap_opcode = g_aarch64_opcode;
579 trap_opcode_size =
sizeof(g_aarch64_opcode);
582 return trap_opcode_size;
586 case llvm::Triple::arm:
587 case llvm::Triple::thumb: {
588 static const uint8_t g_thumb_opcode[] = {0xfe, 0xde};
589 trap_opcode = g_thumb_opcode;
590 trap_opcode_size =
sizeof(g_thumb_opcode);
593 return trap_opcode_size;
602std::unique_ptr<UtilityFunction>
606 static constexpr const char kLoaderDecls[] = R
"(
610// `LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32 | LOAD_LIBRARY_SEARCH_USER_DIRS`
612// Directories in the standard search path are not searched. This value cannot
613// be combined with `LOAD_WITH_ALTERED_SEARCH_PATH`.
615// This value represents the recommended maximum number of directories an
616// application should include in its DLL search path.
617#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
619// WINBASEAPI DWORD WINAPI GetLastError(VOID);
620/* __declspec(dllimport) */ uint32_t __stdcall GetLastError();
624// WINBASEAPI DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory(LPCWSTR);
625/* __declspec(dllimport) */ void * __stdcall AddDllDirectory(const wchar_t *);
627// WINBASEAPI BOOL WINAPI FreeModule(HMODULE);
628/* __declspec(dllimport) */ int __stdcall FreeModule(void *hLibModule);
630// WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize);
631/* __declspec(dllimport) */ uint32_t GetModuleFileNameA(void *, char *, uint32_t);
633// WINBASEAPI HMODULE WINAPI LoadLibraryExW(LPCWSTR, HANDLE, DWORD);
634/* __declspec(dllimport) */ void * __stdcall LoadLibraryExW(const wchar_t *, void *, uint32_t);
638// _ACRTIMP size_t __cdecl wcslen(wchar_t const *_String);
639/* __declspec(dllimport) */ size_t __cdecl wcslen(const wchar_t *);
643struct __lldb_LoadLibraryResult {
650_Static_assert(sizeof(struct __lldb_LoadLibraryResult) <= 3 * sizeof(void *),
651 "__lldb_LoadLibraryResult size mismatch");
653void * __lldb_LoadLibraryHelper(const wchar_t *name, const wchar_t *paths,
654 __lldb_LoadLibraryResult *result) {
655 for (const wchar_t *path = paths; path && *path; ) {
656 (void)AddDllDirectory(path);
657 path += wcslen(path) + 1;
660 result->ImageBase = LoadLibraryExW(name, nullptr,
661 LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
662 if (result->ImageBase == nullptr)
663 result->ErrorCode = GetLastError();
665 result->Length = GetModuleFileNameA(result->ImageBase, result->ModulePath,
668 return result->ImageBase;
673 static constexpr const char kName[] =
"__lldb_LoadLibraryHelper";
676 Target &target = process->GetTarget();
682 std::string
error = llvm::toString(function.takeError());
711 std::unique_ptr<UtilityFunction> utility{std::move(*function)};
712 utility->MakeFunctionCaller(VoidPtrTy, parameters, context.
GetThreadSP(),
720 if (!utility->GetFunctionCaller()) {
721 status.
SetErrorString(
"LoadLibrary error: could not get function caller");
729 const char *expression,
732 static constexpr const char kLoaderDecls[] = R
"(
736// WINBASEAPI DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory(LPCWSTR);
737/* __declspec(dllimport) */ void * __stdcall AddDllDirectory(const wchar_t *);
739// WINBASEAPI BOOL WINAPI FreeModule(HMODULE);
740/* __declspec(dllimport) */ int __stdcall FreeModule(void *);
742// WINBASEAPI DWORD WINAPI GetModuleFileNameA(HMODULE, LPSTR, DWORD);
743/* __declspec(dllimport) */ uint32_t GetModuleFileNameA(void *, char *, uint32_t);
745// WINBASEAPI HMODULE WINAPI LoadLibraryExW(LPCWSTR, HANDLE, DWORD);
746/* __declspec(dllimport) */ void * __stdcall LoadLibraryExW(const wchar_t *, void *, uint32_t);
751 Status result = loader->CanLoadImage();
758 return Status(
"selected thread is invalid");
762 return Status(
"frame 0 is invalid");
765 frame->CalculateExecutionContext(context);
780 context, options, expression, kLoaderDecls, value,
error);
784 if (value->GetError().Fail())
785 return value->GetError();
static const size_t word_size
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_PLUGIN_DEFINE(PluginName)
An architecture specification class.
bool IsValid() const
Tests if this ArchSpec is valid.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
A command line argument class.
Class that manages the actual breakpoint that will be inserted into the running program.
bool SetTrapOpcode(const uint8_t *trap_opcode, uint32_t trap_opcode_size)
Sets the trap opcode.
Generic representation of a type in a programming language.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
A uniqued constant string class.
bool IsEmpty() const
Test for empty string.
const char * GetCString() const
Get the string value as a C string.
A class to manage flag bits.
TargetList & GetTargetList()
Get accessor for the target list.
std::string GetString(char separator='\n')
A plug-in interface definition class for dynamic loaders.
void SetUnwindOnError(bool unwind=false)
void SetExecutionPolicy(ExecutionPolicy policy=eExecutionPolicyAlways)
void SetLanguage(lldb::LanguageType language_type)
void SetTrapExceptions(bool b)
void SetTimeout(const Timeout< std::micro > &timeout)
void SetIsForUtilityExpr(bool b)
void SetIgnoreBreakpoints(bool ignore=false)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
const lldb::ThreadSP & GetThreadSP() const
Get accessor to get the thread shared pointer.
void SetFile(llvm::StringRef path, Style style)
Change the file specified with a new path.
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
void Clear()
Clears the object state.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
Encapsulates a function that can be called.
ValueList GetArgumentValues() const
void DeallocateFunctionResults(ExecutionContext &exe_ctx, lldb::addr_t args_addr)
Deallocate the arguments structure.
lldb::ExpressionResults ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager, Value &results)
Run the function this FunctionCaller was created with.
bool WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager)
Insert the default function argument struct.
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
lldb::ListenerSP GetListenerForProcess(Debugger &debugger)
llvm::StringRef GetProcessPluginName() const
lldb::ListenerSP GetHijackListener() const
lldb::pid_t GetProcessID() const
lldb::ListenerSP GetListener() const
llvm::StringRef GetProcessPluginName() const
std::chrono::seconds GetUtilityExpressionTimeout() const
A plug-in interface definition class for debugging a process.
UtilityFunction * GetLoadImageUtilityFunction(Platform *platform, llvm::function_ref< std::unique_ptr< UtilityFunction >()> factory)
Get the cached UtilityFunction that assists in loading binary images into the process.
void ResetImageToken(size_t token)
ThreadList & GetThreadList()
lldb::addr_t AllocateMemory(size_t size, uint32_t permissions, Status &error)
The public interface to allocating memory in the process.
size_t ReadCStringFromMemory(lldb::addr_t vm_addr, char *cstr, size_t cstr_max_len, Status &error)
Read a NULL terminated C string from memory.
bool WritePointerToMemory(lldb::addr_t vm_addr, lldb::addr_t ptr_value, Status &error)
size_t AddImageToken(lldb::addr_t image_ptr)
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Status DeallocateMemory(lldb::addr_t ptr)
The public interface to deallocating memory in the process.
lldb::addr_t GetImagePtrFromToken(size_t token) const
uint32_t GetAddressByteSize() const
size_t WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error)
Write memory to a process.
virtual DynamicLoader * GetDynamicLoader()
Get the dynamic loader plug-in for this process.
size_t WriteScalarToMemory(lldb::addr_t vm_addr, const Scalar &scalar, size_t size, Status &error)
Write all or part of a scalar value to memory.
Target & GetTarget()
Get the target object pointer for this module.
unsigned int UInt(unsigned int fail_value=0) const
static lldb::TypeSystemClangSP GetForTarget(Target &target, std::optional< IsolatedASTKind > ast_kind=DefaultAST, bool create_on_demand=true)
Returns the scratch TypeSystemClang for the given target.
ValueType GetError() const
Access the error value.
int SetErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Set the current error string to a formatted error string.
bool Fail() const
Test for error condition.
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp)
Create a new Target.
const lldb::ProcessSP & CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file, bool can_connect)
llvm::Expected< std::unique_ptr< UtilityFunction > > CreateUtilityFunction(std::string expression, std::string name, lldb::LanguageType language, ExecutionContext &exe_ctx)
Creates and installs a UtilityFunction for the given language.
const ArchSpec & GetArchitecture() const
lldb::ThreadSP GetExpressionExecutionThread()
static lldb::ExpressionResults Evaluate(ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, llvm::StringRef expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp, Status &error, std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Evaluate one expression in the scratch context of the target passed in the exe_ctx and return its res...
"lldb/Expression/UtilityFunction.h" Encapsulates a bit of source code that provides a function that i...
FunctionCaller * GetFunctionCaller()
void PushValue(const Value &value)
Value * GetValueAtIndex(size_t idx)
const Scalar & GetScalar() const
@ Scalar
A raw scalar value.
void SetCompilerType(const CompilerType &compiler_type)
void SetValueType(ValueType value_type)
#define LLDB_INVALID_IMAGE_TOKEN
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::Platform > PlatformSP
@ eLanguageTypeC_plus_plus
ISO C++:1998.
ExpressionResults
The results of expression evaluation.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::TypeSystemClang > TypeSystemClangSP
std::shared_ptr< lldb_private::Target > TargetSP