Skip to content

Commit

Permalink
Added ProcessWindows and DynamicLoaderWindows plugins.
Browse files Browse the repository at this point in the history
  • Loading branch information
xen2 committed Apr 8, 2014
1 parent a5326a9 commit 5159562
Show file tree
Hide file tree
Showing 19 changed files with 2,593 additions and 0 deletions.
2 changes: 2 additions & 0 deletions source/CMakeLists.txt
Expand Up @@ -95,6 +95,8 @@ endif ()
if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
list(APPEND LLDB_USED_LIBS
lldbHostWindows
lldbPluginProcessWindows
lldbPluginDynamicLoaderWindows
lldbPluginProcessElfCore
lldbPluginJITLoaderGDB
Ws2_32
Expand Down
2 changes: 2 additions & 0 deletions source/Plugins/DynamicLoader/CMakeLists.txt
Expand Up @@ -4,5 +4,7 @@ add_subdirectory(Static)

if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(Darwin-Kernel)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_subdirectory(Windows)
endif()

5 changes: 5 additions & 0 deletions source/Plugins/DynamicLoader/Windows/CMakeLists.txt
@@ -0,0 +1,5 @@
set(LLVM_NO_RTTI 1)

add_lldb_library(lldbPluginDynamicLoaderWindows
DynamicLoaderWindows.cpp
)
203 changes: 203 additions & 0 deletions source/Plugins/DynamicLoader/Windows/DynamicLoaderWindows.cpp
@@ -0,0 +1,203 @@
//===-- DynamicLoaderWindows.cpp --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"

#include "DynamicLoaderWindows.h"

using namespace lldb;
using namespace lldb_private;

void
DynamicLoaderWindows::Initialize()
{
PluginManager::RegisterPlugin(GetPluginNameStatic(),
GetPluginDescriptionStatic(),
CreateInstance);
}

void
DynamicLoaderWindows::Terminate()
{
}

lldb_private::ConstString
DynamicLoaderWindows::GetPluginName()
{
return GetPluginNameStatic();
}

lldb_private::ConstString
DynamicLoaderWindows::GetPluginNameStatic()
{
static ConstString g_name("windows-dyld");
return g_name;
}

const char *
DynamicLoaderWindows::GetPluginDescriptionStatic()
{
return "Dynamic loader plug-in that watches for shared library "
"loads/unloads in Windows processes.";
}

void
DynamicLoaderWindows::GetPluginCommandHelp(const char *command, Stream *strm)
{
}

uint32_t
DynamicLoaderWindows::GetPluginVersion()
{
return 1;
}

DynamicLoader *
DynamicLoaderWindows::CreateInstance(Process *process, bool force)
{
bool create = force;
if (!create)
{
const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
if (triple_ref.getOS() == llvm::Triple::Win32 ||
triple_ref.getOS() == llvm::Triple::MinGW32)
create = true;
}

if (create)
return new DynamicLoaderWindows (process);
return NULL;
}

DynamicLoaderWindows::DynamicLoaderWindows(Process *process)
: DynamicLoader(process),
m_load_offset(LLDB_INVALID_ADDRESS),
m_entry_point(LLDB_INVALID_ADDRESS)
{
}

DynamicLoaderWindows::~DynamicLoaderWindows()
{
}

void
DynamicLoaderWindows::DidAttach()
{
}

void
DynamicLoaderWindows::DidLaunch()
{
}

Error
DynamicLoaderWindows::ExecutePluginCommand(Args &command, Stream *strm)
{
return Error();
}

Log *
DynamicLoaderWindows::EnablePluginLogging(Stream *strm, Args &command)
{
return NULL;
}

Error
DynamicLoaderWindows::CanLoadImage()
{
return Error();
}

ThreadPlanSP
DynamicLoaderWindows::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
{
ThreadPlanSP thread_plan_sp;

RegisterContext *reg_ctx = thread.GetRegisterContext().get();

lldb::addr_t pc = reg_ctx->GetPC();
ProcessSP process_sp(thread.GetProcess());
Address pc_addr;
bool addr_valid = false;
uint8_t buffer[16] = { 0 }; // Must be big enough for any single instruction
addr_valid = process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(pc, pc_addr);

// TODO: Cache it as in ThreadPlanAssemblyTracer::GetDisassembler ()
DisassemblerSP disassembler = Disassembler::FindPlugin(thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
if (disassembler)
{
Error err;
process_sp->ReadMemory(pc, buffer, sizeof(buffer), err);

if (err.Success())
{
DataExtractor extractor(buffer, sizeof(buffer),
process_sp->GetByteOrder(),
process_sp->GetAddressByteSize());

bool data_from_file = false;
if (addr_valid)
disassembler->DecodeInstructions(pc_addr, extractor, 0, 1, false, data_from_file);
else
disassembler->DecodeInstructions(Address(pc), extractor, 0, 1, false, data_from_file);

InstructionList &instruction_list = disassembler->GetInstructionList();

if (instruction_list.GetSize())
{
const bool show_bytes = true;
const bool show_address = true;
Instruction *instruction = instruction_list.GetInstructionAtIndex(0).get();

ExecutionContext exe_ctx(thread.GetProcess());
const char* opcode = instruction->GetMnemonic(&exe_ctx);

if (strcmp(opcode, "jmpl") == 0)
{
const char* operands_str = instruction->GetOperands(&exe_ctx);

// Detect trampolines with pattern jmpl *0x400800 where 0x400800 contains the DLL function pointer
// TODO1: Detect jmp address without string parsing (from MCInst)
// TODO2: We should check import table for 0x400800 instead of fetching the pointer behind it (in PECOFF)
unsigned long operand_ptr = strtoul(operands_str + 3, NULL, 16);
Error error;
unsigned long operand_value = process_sp->ReadPointerFromMemory(operand_ptr, error);

Address sc_addr;
if (process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(operand_value, sc_addr))
{
SymbolContext sc;
thread.GetProcess()->GetTarget().GetImages().ResolveSymbolContextForAddress(sc_addr, eSymbolContextSymbol, sc);
if (sc.symbol != NULL)
{
thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, operand_value, false));
}
}
}
}
}
}

return thread_plan_sp;
}
91 changes: 91 additions & 0 deletions source/Plugins/DynamicLoader/Windows/DynamicLoaderWindows.h
@@ -0,0 +1,91 @@
//===-- DynamicLoaderWindows.h ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_DynamicLoaderWindows_H_
#define liblldb_DynamicLoaderWindows_H_

// C Includes
// C++ Includes
// Other libraries and framework includes
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Target/DynamicLoader.h"

class AuxVector;

class DynamicLoaderWindows : public lldb_private::DynamicLoader
{
public:

static void
Initialize();

static void
Terminate();

static lldb_private::ConstString
GetPluginNameStatic();

static const char *
GetPluginDescriptionStatic();

static lldb_private::DynamicLoader *
CreateInstance(lldb_private::Process *process, bool force);

DynamicLoaderWindows(lldb_private::Process *process);

virtual
~DynamicLoaderWindows();

//------------------------------------------------------------------
// DynamicLoader protocol
//------------------------------------------------------------------

virtual void
DidAttach();

virtual void
DidLaunch();

virtual lldb::ThreadPlanSP
GetStepThroughTrampolinePlan(lldb_private::Thread &thread,
bool stop_others);

virtual lldb_private::Error
CanLoadImage();

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
virtual lldb_private::ConstString
GetPluginName();

virtual uint32_t
GetPluginVersion();

virtual void
GetPluginCommandHelp(const char *command, lldb_private::Stream *strm);

virtual lldb_private::Error
ExecutePluginCommand(lldb_private::Args &command, lldb_private::Stream *strm);

virtual lldb_private::Log *
EnablePluginLogging(lldb_private::Stream *strm, lldb_private::Args &command);

protected:
/// Virtual load address of the inferior process.
lldb::addr_t m_load_offset;

/// Virtual entry address of the inferior process.
lldb::addr_t m_entry_point;

private:
DISALLOW_COPY_AND_ASSIGN(DynamicLoaderWindows);
};

#endif // liblldb_DynamicLoaderPOSIXDYLD_H_
14 changes: 14 additions & 0 deletions source/Plugins/DynamicLoader/Windows/Makefile
@@ -0,0 +1,14 @@
##===- source/Plugins/DynamicLoader/Windows/Makefile -------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LLDB_LEVEL := ../../../..
LIBRARYNAME := lldbPluginDynamicLoaderWindows
BUILD_ARCHIVE = 1

include $(LLDB_LEVEL)/Makefile
2 changes: 2 additions & 0 deletions source/Plugins/Makefile
Expand Up @@ -43,6 +43,8 @@ DIRS += JITLoader/GDB
endif

ifeq ($(HOST_OS),MingW)
DIRS += Process/Windows
DIRS += DynamicLoader/Windows
DIRS += Process/elf-core
DIRS += JITLoader/GDB
endif
Expand Down
1 change: 1 addition & 0 deletions source/Plugins/Process/CMakeLists.txt
Expand Up @@ -5,6 +5,7 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
add_subdirectory(FreeBSD)
add_subdirectory(POSIX)
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_subdirectory(Windows)
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_subdirectory(POSIX)
add_subdirectory(MacOSX-Kernel)
Expand Down
11 changes: 11 additions & 0 deletions source/Plugins/Process/Windows/CMakeLists.txt
@@ -0,0 +1,11 @@
set(LLVM_NO_RTTI 1)

include_directories(.)
include_directories(../Utility)

add_lldb_library(lldbPluginProcessWindows
ProcessWindows.cpp
ThreadWindows.cpp
RegisterContextWindows_i386.cpp
RegisterContextWindowsDebug_i386.cpp
)
14 changes: 14 additions & 0 deletions source/Plugins/Process/Windows/Makefile
@@ -0,0 +1,14 @@
##===- source/Plugins/Process/Windows/Makefile -------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##

LLDB_LEVEL := ../../../..
LIBRARYNAME := lldbPluginProcessWindows
BUILD_ARCHIVE = 1

include $(LLDB_LEVEL)/Makefile

0 comments on commit 5159562

Please sign in to comment.