compnerd updated this revision to Diff 254631.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D77287/new/
https://reviews.llvm.org/D77287
Files:
lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
lldb/source/Plugins/Platform/Windows/PlatformWindows.h
Index: lldb/source/Plugins/Platform/Windows/PlatformWindows.h
===================================================================
--- lldb/source/Plugins/Platform/Windows/PlatformWindows.h
+++ lldb/source/Plugins/Platform/Windows/PlatformWindows.h
@@ -49,6 +49,15 @@
lldb_private::Status DisconnectRemote() override;
+ uint32_t DoLoadImage(lldb_private::Process *process,
+ const lldb_private::FileSpec &remote_file,
+ const std::vector<std::string> *paths,
+ lldb_private::Status &error,
+ lldb_private::FileSpec *loaded_path) override;
+
+ lldb_private::Status UnloadImage(lldb_private::Process *process,
+ uint32_t image_token) override;
+
lldb::ProcessSP DebugProcess(lldb_private::ProcessLaunchInfo &launch_info,
lldb_private::Debugger &debugger,
lldb_private::Target *target,
@@ -73,6 +82,10 @@
private:
DISALLOW_COPY_AND_ASSIGN(PlatformWindows);
+
+ lldb_private::Status EvaluateLoaderExpression(lldb_private::Process *process,
+ const char *expression,
+ lldb::ValueObjectSP &value);
};
} // namespace lldb_private
Index: lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
===================================================================
--- lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
+++ lldb/source/Plugins/Platform/Windows/PlatformWindows.cpp
@@ -20,7 +20,10 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/Status.h"
@@ -306,6 +309,111 @@
return error;
}
+Status PlatformWindows::EvaluateLoaderExpression(Process *process,
+ const char *expression,
+ ValueObjectSP &value) {
+ // FIXME(compnerd) `-fdeclspec` is not passed to the clang instance?
+ static const char kLoaderDecls[] =
+ R"(
+ // libloaderapi.h
+
+ // WINBASEAPI BOOL WINAPI FreeModule(HMODULE);
+ extern "C" /* __declspec(dllimport) */ BOOL __stdcall FreeModule(void *hLibModule);
+
+ // WINBASEAPI HMODULE WINAPI LoadLibraryA(LPCSTR);
+ extern "C" /* __declspec(dllimport) */ void * __stdcall LoadLibraryA(const char *);
+ )";
+
+ if (DynamicLoader *loader = process->GetDynamicLoader()) {
+ Status result = loader->CanLoadImage();
+ if (result.Fail())
+ return result;
+ }
+
+ ThreadSP thread = process->GetThreadList().GetExpressionExecutionThread();
+ if (!thread)
+ return Status("selected thread is invalid");
+
+ StackFrameSP frame = thread->GetStackFrameAtIndex(0);
+ if (!frame)
+ return Status("frame 0 is invalid");
+
+ ExecutionContext context;
+ frame->CalculateExecutionContext(context);
+
+ EvaluateExpressionOptions options;
+ options.SetUnwindOnError(true);
+ options.SetIgnoreBreakpoints(true);
+ options.SetExecutionPolicy(eExecutionPolicyAlways);
+ options.SetLanguage(eLanguageTypeC_plus_plus);
+ // LoadLibrary{A,W}/FreeLibrary cannot raise exceptions which we can handle.
+ // They may potentially throw SEH exceptions which we do not know how to
+ // handle currently.
+ options.SetTrapExceptions(false);
+ options.SetTimeout(process->GetUtilityExpressionTimeout());
+
+ Status error;
+ ExpressionResults result = UserExpression::Evaluate(
+ context, options, expression, kLoaderDecls, value, error);
+ if (result != eExpressionCompleted)
+ return error;
+
+ if (value->GetError().Fail())
+ return value->GetError();
+
+ return Status();
+}
+
+uint32_t PlatformWindows::DoLoadImage(Process *process,
+ const FileSpec &remote_file,
+ const std::vector<std::string> *paths,
+ Status &error, FileSpec *loaded_path) {
+ if (loaded_path)
+ loaded_path->Clear();
+
+ StreamString expression;
+ expression.Printf("LoadLibraryA(\"%s\")", remote_file.GetPath().c_str());
+
+ ValueObjectSP value;
+ Status result =
+ EvaluateLoaderExpression(process, expression.GetData(), value);
+ if (result.Fail())
+ return LLDB_INVALID_IMAGE_TOKEN;
+
+ Scalar scalar;
+ if (value->ResolveValue(scalar)) {
+ lldb::addr_t address = scalar.ULongLong();
+ if (address == 0)
+ return LLDB_INVALID_IMAGE_TOKEN;
+ return process->AddImageToken(address);
+ }
+ return LLDB_INVALID_IMAGE_TOKEN;
+}
+
+Status PlatformWindows::UnloadImage(Process *process, uint32_t image_token) {
+ const addr_t address = process->GetImagePtrFromToken(image_token);
+ if (address == LLDB_INVALID_ADDRESS)
+ return Status("invalid image token");
+
+ StreamString expression;
+ expression.Printf("FreeLibrary((HMODULE)0x%" PRIx64 ")", address);
+
+ ValueObjectSP value;
+ Status result =
+ EvaluateLoaderExpression(process, expression.GetData(), value);
+ if (result.Fail())
+ return result;
+
+ Scalar scalar;
+ if (value->ResolveValue(scalar)) {
+ if (scalar.UInt(1))
+ return Status("expression failed: \"%s\"", expression.GetData());
+ process->ResetImageToken(image_token);
+ }
+
+ return Status();
+}
+
ProcessSP PlatformWindows::DebugProcess(ProcessLaunchInfo &launch_info,
Debugger &debugger, Target *target,
Status &error) {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits