Index: packages/Python/lldbsuite/test/functionalities/windows_dyld/Makefile =================================================================== --- packages/Python/lldbsuite/test/functionalities/windows_dyld/Makefile +++ packages/Python/lldbsuite/test/functionalities/windows_dyld/Makefile @@ -0,0 +1,14 @@ +LEVEL := ../../make + +LD_EXTRAS := -ldllfunc +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules + +a.out: dllfunc + +dllfunc: + $(MAKE) VERBOSE=1 VPATH=$(SRCDIR) -I $(SRCDIR) -f $(SRCDIR)/dllfunc.mk + +clean:: + $(MAKE) -f $(SRCDIR)/dllfunc.mk clean Index: packages/Python/lldbsuite/test/functionalities/windows_dyld/TestWindowsDYLD.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/windows_dyld/TestWindowsDYLD.py +++ packages/Python/lldbsuite/test/functionalities/windows_dyld/TestWindowsDYLD.py @@ -0,0 +1,42 @@ +""" +Test that breakpoints work in a DLL +""" + +from __future__ import print_function + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessWindows +class WindowsDLLTestCase(TestBase): + def setUP(self): + TestBase.setUp(self) + self.build() + + def test_dll_linking(self): + """test that the debugger works with DLLs""" + + exe = self.getBuildArtifact("a.out") + target = self.dbg.CreateTarget(exe) + self.assertTrue(target and target.IsValid(), "Target is valid") + + self.runCmd("breakpoint set --file main.c --line 16") + self.runCmd("breakpoint set --file dllfunc.c --line 18") + + process = target.LaunchSimple(None, None, self.get_process_working_directory()) + + self.expect("p x", "16") + self.runCmd("thread step-out") + self.expect("p x", "16") + self.expect("thread step-in") + self.expect("thread step-in") + self.expect("p n", "8") + self.runCmd("c") + self.expect("p x", "64") + self.runCmd("breakpoint delete 2") + self.runCmd("c") + + self.assertEqual(process.GetExitStatus(), 336, PROCESS_EXITED) Index: packages/Python/lldbsuite/test/functionalities/windows_dyld/dllfunc.c =================================================================== --- packages/Python/lldbsuite/test/functionalities/windows_dyld/dllfunc.c +++ packages/Python/lldbsuite/test/functionalities/windows_dyld/dllfunc.c @@ -0,0 +1,19 @@ +//===-- a.c -----------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include + +BOOL WINAPI DllMain(HINSTANCE h, DWORD reason, void* reserved) { + return TRUE; +} + +int __declspec(dllexport) DllFunc(int n) { + int x = n * n; + return x; // set breakpoint here +} Index: packages/Python/lldbsuite/test/functionalities/windows_dyld/dllfunc.mk =================================================================== --- packages/Python/lldbsuite/test/functionalities/windows_dyld/dllfunc.mk +++ packages/Python/lldbsuite/test/functionalities/windows_dyld/dllfunc.mk @@ -0,0 +1,7 @@ +LEVEL := ../../make + +DYLIB_NAME := dllfunc +DYLIB_C_SOURCES := dllfunc.c +DYLIB_ONLY := YES + +include $(LEVEL)/Makefile.rules Index: packages/Python/lldbsuite/test/functionalities/windows_dyld/main.c =================================================================== --- packages/Python/lldbsuite/test/functionalities/windows_dyld/main.c +++ packages/Python/lldbsuite/test/functionalities/windows_dyld/main.c @@ -0,0 +1,19 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include + +int __declspec(dllimport) DllFunc(int n); + +int main(int argc, char ** argv) { + int x = DllFunc(4); + int y = DllFunc(8); // set breakpoint here + int z = DllFunc(16); + return x + y + z; +} Index: packages/Python/lldbsuite/test/make/Makefile.rules =================================================================== --- packages/Python/lldbsuite/test/make/Makefile.rules +++ packages/Python/lldbsuite/test/make/Makefile.rules @@ -525,7 +525,7 @@ endif else $(EXE) : $(OBJECTS) $(ARCHIVE_NAME) - $(LD) $(OBJECTS) $(LDFLAGS) $(ARCHIVE_NAME) -o "$(EXE)" + "$(LD)" $(OBJECTS) $(LDFLAGS) $(ARCHIVE_NAME) -o "$(EXE)" ifneq "$(CODESIGN)" "" $(CODESIGN) -s - "$(EXE)" endif @@ -582,7 +582,7 @@ endif endif else - $(LD) $(DYLIB_OBJECTS) $(LDFLAGS) -shared -o "$(DYLIB_FILENAME)" + "$(LD)" $(DYLIB_OBJECTS) $(LDFLAGS) -shared -o "$(DYLIB_FILENAME)" ifeq "$(SPLIT_DEBUG_SYMBOLS)" "YES" $(OBJCOPY) --only-keep-debug "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME).debug" $(OBJCOPY) --strip-debug --add-gnu-debuglink="$(DYLIB_FILENAME).debug" "$(DYLIB_FILENAME)" "$(DYLIB_FILENAME)" Index: source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp =================================================================== --- source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -10,12 +10,14 @@ #include "DynamicLoaderWindowsDYLD.h" +#include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanStepInstruction.h" +#include "lldb/Utility/Log.h" #include "llvm/ADT/Triple.h" @@ -60,9 +62,49 @@ return nullptr; } -void DynamicLoaderWindowsDYLD::DidAttach() {} +void DynamicLoaderWindowsDYLD::DidAttach() { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (log) + log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); + + DidLaunch(); + + m_process->LoadModules(); +} + +void DynamicLoaderWindowsDYLD::DidLaunch() { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (log) + log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); + + ModuleSP executable = GetTargetExecutable(); + + if (!executable.get()) + return; + + // Try to fetch the load address of the file from the process, since there + // could be randomization of the load address. + + // It might happen that the remote has a different dir for the file, so we + // only send the basename of the executable in the query. I think this is safe + // because I doubt that two executables with the same basenames are loaded in + // memory... + FileSpec file_spec( + executable->GetPlatformFileSpec().GetFilename().GetCString()); + bool is_loaded; + addr_t base_addr = 0; + lldb::addr_t load_addr; + Status error = m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr); + if (error.Success() && is_loaded) { + base_addr = load_addr; + } + + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, base_addr, false); -void DynamicLoaderWindowsDYLD::DidLaunch() {} + ModuleList module_list; + module_list.Append(executable); + m_process->GetTarget().ModulesDidLoad(module_list); +} Status DynamicLoaderWindowsDYLD::CanLoadImage() { return Status(); }