Skip to content

Commit 5159562

Browse files
committed
Added ProcessWindows and DynamicLoaderWindows plugins.
1 parent a5326a9 commit 5159562

19 files changed

+2593
-0
lines changed

source/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ endif ()
9595
if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
9696
list(APPEND LLDB_USED_LIBS
9797
lldbHostWindows
98+
lldbPluginProcessWindows
99+
lldbPluginDynamicLoaderWindows
98100
lldbPluginProcessElfCore
99101
lldbPluginJITLoaderGDB
100102
Ws2_32

source/Plugins/DynamicLoader/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ add_subdirectory(Static)
44

55
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
66
add_subdirectory(Darwin-Kernel)
7+
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
8+
add_subdirectory(Windows)
79
endif()
810

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
set(LLVM_NO_RTTI 1)
2+
3+
add_lldb_library(lldbPluginDynamicLoaderWindows
4+
DynamicLoaderWindows.cpp
5+
)
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
//===-- DynamicLoaderWindows.cpp --------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
// C Includes
11+
// C++ Includes
12+
// Other libraries and framework includes
13+
#include "lldb/Core/PluginManager.h"
14+
#include "lldb/Core/Disassembler.h"
15+
#include "lldb/Core/Log.h"
16+
#include "lldb/Core/Module.h"
17+
#include "lldb/Core/ModuleSpec.h"
18+
#include "lldb/Core/Section.h"
19+
#include "lldb/Symbol/ObjectFile.h"
20+
#include "lldb/Target/Process.h"
21+
#include "lldb/Target/RegisterContext.h"
22+
#include "lldb/Target/SectionLoadList.h"
23+
#include "lldb/Target/Target.h"
24+
#include "lldb/Target/Thread.h"
25+
#include "lldb/Target/ThreadPlanRunToAddress.h"
26+
27+
#include "DynamicLoaderWindows.h"
28+
29+
using namespace lldb;
30+
using namespace lldb_private;
31+
32+
void
33+
DynamicLoaderWindows::Initialize()
34+
{
35+
PluginManager::RegisterPlugin(GetPluginNameStatic(),
36+
GetPluginDescriptionStatic(),
37+
CreateInstance);
38+
}
39+
40+
void
41+
DynamicLoaderWindows::Terminate()
42+
{
43+
}
44+
45+
lldb_private::ConstString
46+
DynamicLoaderWindows::GetPluginName()
47+
{
48+
return GetPluginNameStatic();
49+
}
50+
51+
lldb_private::ConstString
52+
DynamicLoaderWindows::GetPluginNameStatic()
53+
{
54+
static ConstString g_name("windows-dyld");
55+
return g_name;
56+
}
57+
58+
const char *
59+
DynamicLoaderWindows::GetPluginDescriptionStatic()
60+
{
61+
return "Dynamic loader plug-in that watches for shared library "
62+
"loads/unloads in Windows processes.";
63+
}
64+
65+
void
66+
DynamicLoaderWindows::GetPluginCommandHelp(const char *command, Stream *strm)
67+
{
68+
}
69+
70+
uint32_t
71+
DynamicLoaderWindows::GetPluginVersion()
72+
{
73+
return 1;
74+
}
75+
76+
DynamicLoader *
77+
DynamicLoaderWindows::CreateInstance(Process *process, bool force)
78+
{
79+
bool create = force;
80+
if (!create)
81+
{
82+
const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
83+
if (triple_ref.getOS() == llvm::Triple::Win32 ||
84+
triple_ref.getOS() == llvm::Triple::MinGW32)
85+
create = true;
86+
}
87+
88+
if (create)
89+
return new DynamicLoaderWindows (process);
90+
return NULL;
91+
}
92+
93+
DynamicLoaderWindows::DynamicLoaderWindows(Process *process)
94+
: DynamicLoader(process),
95+
m_load_offset(LLDB_INVALID_ADDRESS),
96+
m_entry_point(LLDB_INVALID_ADDRESS)
97+
{
98+
}
99+
100+
DynamicLoaderWindows::~DynamicLoaderWindows()
101+
{
102+
}
103+
104+
void
105+
DynamicLoaderWindows::DidAttach()
106+
{
107+
}
108+
109+
void
110+
DynamicLoaderWindows::DidLaunch()
111+
{
112+
}
113+
114+
Error
115+
DynamicLoaderWindows::ExecutePluginCommand(Args &command, Stream *strm)
116+
{
117+
return Error();
118+
}
119+
120+
Log *
121+
DynamicLoaderWindows::EnablePluginLogging(Stream *strm, Args &command)
122+
{
123+
return NULL;
124+
}
125+
126+
Error
127+
DynamicLoaderWindows::CanLoadImage()
128+
{
129+
return Error();
130+
}
131+
132+
ThreadPlanSP
133+
DynamicLoaderWindows::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
134+
{
135+
ThreadPlanSP thread_plan_sp;
136+
137+
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
138+
139+
lldb::addr_t pc = reg_ctx->GetPC();
140+
ProcessSP process_sp(thread.GetProcess());
141+
Address pc_addr;
142+
bool addr_valid = false;
143+
uint8_t buffer[16] = { 0 }; // Must be big enough for any single instruction
144+
addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(pc, pc_addr);
145+
146+
// TODO: Cache it as in ThreadPlanAssemblyTracer::GetDisassembler ()
147+
DisassemblerSP disassembler = Disassembler::FindPlugin(thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
148+
if (disassembler)
149+
{
150+
Error err;
151+
process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);
152+
153+
if (err.Success())
154+
{
155+
DataExtractor extractor(buffer, sizeof(buffer),
156+
process_sp->GetByteOrder(),
157+
process_sp->GetAddressByteSize());
158+
159+
bool data_from_file = false;
160+
if (addr_valid)
161+
disassembler->DecodeInstructions(pc_addr, extractor, 0, 1, false, data_from_file);
162+
else
163+
disassembler->DecodeInstructions(Address(pc), extractor, 0, 1, false, data_from_file);
164+
165+
InstructionList &instruction_list = disassembler->GetInstructionList();
166+
167+
if (instruction_list.GetSize())
168+
{
169+
const bool show_bytes = true;
170+
const bool show_address = true;
171+
Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();
172+
173+
ExecutionContext exe_ctx(thread.GetProcess());
174+
const char* opcode = instruction->GetMnemonic(&exe_ctx);
175+
176+
if (strcmp(opcode, "jmpl") == 0)
177+
{
178+
const char* operands_str = instruction->GetOperands(&exe_ctx);
179+
180+
// Detect trampolines with pattern jmpl *0x400800 where 0x400800 contains the DLL function pointer
181+
// TODO1: Detect jmp address without string parsing (from MCInst)
182+
// TODO2: We should check import table for 0x400800 instead of fetching the pointer behind it (in PECOFF)
183+
unsigned long operand_ptr = strtoul(operands_str + 3, NULL, 16);
184+
Error error;
185+
unsigned long operand_value = process_sp->ReadPointerFromMemory(operand_ptr, error);
186+
187+
Address sc_addr;
188+
if (process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(operand_value, sc_addr))
189+
{
190+
SymbolContext sc;
191+
thread.GetProcess()->GetTarget().GetImages().ResolveSymbolContextForAddress(sc_addr, eSymbolContextSymbol, sc);
192+
if (sc.symbol != NULL)
193+
{
194+
thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, operand_value, false));
195+
}
196+
}
197+
}
198+
}
199+
}
200+
}
201+
202+
return thread_plan_sp;
203+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//===-- DynamicLoaderWindows.h ----------------------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef liblldb_DynamicLoaderWindows_H_
11+
#define liblldb_DynamicLoaderWindows_H_
12+
13+
// C Includes
14+
// C++ Includes
15+
// Other libraries and framework includes
16+
#include "lldb/Breakpoint/StoppointCallbackContext.h"
17+
#include "lldb/Target/DynamicLoader.h"
18+
19+
class AuxVector;
20+
21+
class DynamicLoaderWindows : public lldb_private::DynamicLoader
22+
{
23+
public:
24+
25+
static void
26+
Initialize();
27+
28+
static void
29+
Terminate();
30+
31+
static lldb_private::ConstString
32+
GetPluginNameStatic();
33+
34+
static const char *
35+
GetPluginDescriptionStatic();
36+
37+
static lldb_private::DynamicLoader *
38+
CreateInstance(lldb_private::Process *process, bool force);
39+
40+
DynamicLoaderWindows(lldb_private::Process *process);
41+
42+
virtual
43+
~DynamicLoaderWindows();
44+
45+
//------------------------------------------------------------------
46+
// DynamicLoader protocol
47+
//------------------------------------------------------------------
48+
49+
virtual void
50+
DidAttach();
51+
52+
virtual void
53+
DidLaunch();
54+
55+
virtual lldb::ThreadPlanSP
56+
GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
57+
bool stop_others);
58+
59+
virtual lldb_private::Error
60+
CanLoadImage();
61+
62+
//------------------------------------------------------------------
63+
// PluginInterface protocol
64+
//------------------------------------------------------------------
65+
virtual lldb_private::ConstString
66+
GetPluginName();
67+
68+
virtual uint32_t
69+
GetPluginVersion();
70+
71+
virtual void
72+
GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);
73+
74+
virtual lldb_private::Error
75+
ExecutePluginCommand(lldb_private::Args &command, lldb_private::Stream *strm);
76+
77+
virtual lldb_private::Log *
78+
EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command);
79+
80+
protected:
81+
/// Virtual load address of the inferior process.
82+
lldb::addr_t m_load_offset;
83+
84+
/// Virtual entry address of the inferior process.
85+
lldb::addr_t m_entry_point;
86+
87+
private:
88+
DISALLOW_COPY_AND_ASSIGN(DynamicLoaderWindows);
89+
};
90+
91+
#endif // liblldb_DynamicLoaderPOSIXDYLD_H_
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
##===- source/Plugins/DynamicLoader/Windows/Makefile -------*- Makefile -*-===##
2+
#
3+
# The LLVM Compiler Infrastructure
4+
#
5+
# This file is distributed under the University of Illinois Open Source
6+
# License. See LICENSE.TXT for details.
7+
#
8+
##===----------------------------------------------------------------------===##
9+
10+
LLDB_LEVEL := ../../../..
11+
LIBRARYNAME := lldbPluginDynamicLoaderWindows
12+
BUILD_ARCHIVE = 1
13+
14+
include $(LLDB_LEVEL)/Makefile

source/Plugins/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ DIRS += JITLoader/GDB
4343
endif
4444

4545
ifeq ($(HOST_OS),MingW)
46+
DIRS += Process/Windows
47+
DIRS += DynamicLoader/Windows
4648
DIRS += Process/elf-core
4749
DIRS += JITLoader/GDB
4850
endif

source/Plugins/Process/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
55
add_subdirectory(FreeBSD)
66
add_subdirectory(POSIX)
77
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
8+
add_subdirectory(Windows)
89
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
910
add_subdirectory(POSIX)
1011
add_subdirectory(MacOSX-Kernel)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
set(LLVM_NO_RTTI 1)
2+
3+
include_directories(.)
4+
include_directories(../Utility)
5+
6+
add_lldb_library(lldbPluginProcessWindows
7+
ProcessWindows.cpp
8+
ThreadWindows.cpp
9+
RegisterContextWindows_i386.cpp
10+
RegisterContextWindowsDebug_i386.cpp
11+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
##===- source/Plugins/Process/Windows/Makefile -------------*- Makefile -*-===##
2+
#
3+
# The LLVM Compiler Infrastructure
4+
#
5+
# This file is distributed under the University of Illinois Open Source
6+
# License. See LICENSE.TXT for details.
7+
#
8+
##===----------------------------------------------------------------------===##
9+
10+
LLDB_LEVEL := ../../../..
11+
LIBRARYNAME := lldbPluginProcessWindows
12+
BUILD_ARCHIVE = 1
13+
14+
include $(LLDB_LEVEL)/Makefile

0 commit comments

Comments
 (0)