diff options
Diffstat (limited to 'scripts')
31 files changed, 1058 insertions, 724 deletions
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt index 00bec0b2dae50..35b453aa1f105 100644 --- a/scripts/CMakeLists.txt +++ b/scripts/CMakeLists.txt @@ -9,6 +9,8 @@ set(SWIG_HEADERS ${LLDB_SOURCE_DIR}/include/lldb/lldb-versioning.h ) +include(FindPythonInterp) + find_package(SWIG REQUIRED) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp diff --git a/scripts/Makefile b/scripts/Makefile deleted file mode 100644 index 807823f43e444..0000000000000 --- a/scripts/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- scripts/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 := .. -include $(LLDB_LEVEL)/../../Makefile.config - -ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS))) -DIRS := Python -endif - -include $(LLDB_LEVEL)/Makefile diff --git a/scripts/Python/Makefile b/scripts/Python/Makefile deleted file mode 100644 index ad6c0af442b4d..0000000000000 --- a/scripts/Python/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -##===- scripts/Python/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 := ../.. -include $(LLDB_LEVEL)/../../Makefile.config - -DIRS := modules - -include $(LLDB_LEVEL)/Makefile diff --git a/scripts/Python/finishSwigPythonLLDB.py b/scripts/Python/finishSwigPythonLLDB.py index 435cb88c20f04..4d733a1643612 100644 --- a/scripts/Python/finishSwigPythonLLDB.py +++ b/scripts/Python/finishSwigPythonLLDB.py @@ -229,6 +229,23 @@ def make_symlink_windows(vstrSrcPath, vstrTargetPath): dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_windows()") bOk = True strErrMsg = "" + # If the src file doesn't exist, this is an error and we should throw. + src_stat = os.stat(vstrSrcPath) + + try: + target_stat = os.stat(vstrTargetPath) + # If the target file exists but refers to a different file, delete it so that we can + # re-create the link. This can happen if you run this script once (creating a link) + # and then delete the source file (so that a brand new file gets created the next time + # you compile and link), and then re-run this script, so that both the target hardlink + # and the source file exist, but the target refers to an old copy of the source. + if (target_stat.st_ino == src_stat.st_ino) and (target_stat.st_dev == src_stat.st_dev): + return (bOk, strErrMsg) + + os.remove(vstrTargetPath) + except: + # If the target file don't exist, ignore this exception, we will link it shortly. + pass try: csl = ctypes.windll.kernel32.CreateHardLinkW @@ -280,10 +297,6 @@ def make_symlink_native(vDictArgs, strSrc, strTarget): bOk = False strErrMsg = strErrMsgOsTypeUnknown elif eOSType == utilsOsType.EnumOsType.Windows: - if os.path.isfile(strTarget): - if bDbg: - print((strMsgSymlinkExists % target_filename)) - return (bOk, strErrMsg) if bDbg: print((strMsgSymlinkMk % (target_filename, strSrc, strTarget))) bOk, strErrMsg = make_symlink_windows(strSrc, @@ -345,11 +358,12 @@ def make_symlink(vDictArgs, vstrFrameworkPythonDir, vstrSrcFile, vstrTargetFile) # Args: vDictArgs - (R) Program input parameters. # vstrFrameworkPythonDir - (R) Python framework directory. # vstrLiblldbName - (R) File name for _lldb library. +# vstrLiblldbDir - (R) liblldb directory. # Returns: Bool - True = function success, False = failure. # Str - Error description on task failure. # Throws: None. #-- -def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName): +def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName, vstrLldbLibDir): dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_liblldb()") bOk = True strErrMsg = "" @@ -369,7 +383,7 @@ def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName) bMakeFileCalled = "-m" in vDictArgs if not bMakeFileCalled: - strSrc = os.path.join("lib", "LLDB") + strSrc = os.path.join(vstrLldbLibDir, "LLDB") else: strLibFileExtn = "" if eOSType == utilsOsType.EnumOsType.Windows: @@ -379,7 +393,7 @@ def make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, vstrLiblldbFileName) strLibFileExtn = ".dylib" else: strLibFileExtn = ".so" - strSrc = os.path.join("lib", "liblldb" + strLibFileExtn) + strSrc = os.path.join(vstrLldbLibDir, "liblldb" + strLibFileExtn) bOk, strErrMsg = make_symlink(vDictArgs, vstrFrameworkPythonDir, strSrc, strTarget) @@ -449,11 +463,12 @@ def make_symlink_lldb_argdumper(vDictArgs, vstrFrameworkPythonDir, vstrArgdumper # the Python framework directory. # Args: vDictArgs - (R) Program input parameters. # vstrFrameworkPythonDir - (R) Python framework directory. +# vstrLldbLibDir - (R) liblldb directory. # Returns: Bool - True = function success, False = failure. # strErrMsg - Error description on task failure. # Throws: None. #-- -def create_symlinks(vDictArgs, vstrFrameworkPythonDir): +def create_symlinks(vDictArgs, vstrFrameworkPythonDir, vstrLldbLibDir): dbg = utilsDebug.CDebugFnVerbose("Python script create_symlinks()") bOk = True strErrMsg = "" @@ -464,7 +479,8 @@ def create_symlinks(vDictArgs, vstrFrameworkPythonDir): if bOk: bOk, strErrMsg = make_symlink_liblldb(vDictArgs, vstrFrameworkPythonDir, - strLibLldbFileName) + strLibLldbFileName, + vstrLldbLibDir) # Make symlink for darwin-debug on Darwin strDarwinDebugFileName = "darwin-debug" @@ -659,6 +675,28 @@ def get_framework_python_dir(vDictArgs): return (bOk, strWkDir, strErrMsg) +#++--------------------------------------------------------------------------- +# Details: Retrieve the liblldb directory path, if it exists and is valid. +# Args: vDictArgs - (R) Program input parameters. +# Returns: Bool - True = function success, False = failure. +# Str - liblldb directory path. +# strErrMsg - Error description on task failure. +# Throws: None. +#-- +def get_liblldb_dir(vDictArgs): + dbg = utilsDebug.CDebugFnVerbose("Python script get_liblldb_dir()") + bOk = True + strErrMsg = "" + + strLldbLibDir = "" + bHaveLldbLibDir = "--lldbLibDir" in vDictArgs + if bHaveLldbLibDir: + strLldbLibDir = vDictArgs["--lldbLibDir"] + if (bHaveLldbLibDir == False) or (strLldbLibDir.__len__() == 0): + strLldbLibDir = "lib" + + return (bOk, strLldbLibDir, strErrMsg) + #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- @@ -684,6 +722,8 @@ def get_framework_python_dir(vDictArgs): be installed. Where non-Darwin systems want to put the .py and .so files so that Python can find them automatically. Python install directory. + --lldbLibDir The name of the directory containing liblldb.so. + (optional) "lib" by default. Results: 0 Success -100+ Error from this script to the caller script. -100 Error program failure with optional message. @@ -714,10 +754,13 @@ def main(vDictArgs): print((strMsgConfigBuildDir % strCfgBldDir)) if bOk: + bOk, strLldbLibDir, strMsg = get_liblldb_dir(vDictArgs) + + if bOk: bOk, strMsg = find_or_create_python_dir(vDictArgs, strFrameworkPythonDir) if bOk: - bOk, strMsg = create_symlinks(vDictArgs, strFrameworkPythonDir) + bOk, strMsg = create_symlinks(vDictArgs, strFrameworkPythonDir, strLldbLibDir) if bOk: bOk, strMsg = copy_six(vDictArgs, strFrameworkPythonDir) diff --git a/scripts/Python/modules/Makefile b/scripts/Python/modules/Makefile deleted file mode 100644 index b6989889858db..0000000000000 --- a/scripts/Python/modules/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -##===- scripts/Python/modules/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 := ../../.. -include $(LLDB_LEVEL)/../../Makefile.config - -DIRS:= - -# only build the readline suppression module on Linux, Kfreebsd & Hurd -ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD)) -DIRS += readline -endif - -include $(LLDB_LEVEL)/Makefile diff --git a/scripts/Python/modules/readline/Makefile b/scripts/Python/modules/readline/Makefile deleted file mode 100644 index dc0d757bc1752..0000000000000 --- a/scripts/Python/modules/readline/Makefile +++ /dev/null @@ -1,100 +0,0 @@ -##===- scripts/Python/modules/readline/Makefile ------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -# Skip this entire Makefile if python is disabled. -ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS))) - -LEVEL := ../../../../../.. -LLDB_LEVEL := ../../../.. - -LIBRARYNAME = readline - -NO_BUILD_ARCHIVE = 1 -LINK_LIBS_IN_SHARED = 1 -SHARED_LIBRARY = 1 -LOADABLE_MODULE = 1 - -PYTHON_CONFIG?= python-config -PYTHON_INC_DIR = $(shell $(PYTHON_CONFIG) --includes) - -# Include all archives in the shared lib -USEDLIBS := - -include $(LLDB_LEVEL)/../../Makefile.config - -LINK_COMPONENTS := - -include $(LEVEL)/Makefile.common - -# include python headers -CPP.Flags += $(PYTHON_INC_DIR) - -ifeq ($(HOST_OS),Darwin) - LLVMLibsOptions += -Wl,-all_load - # set dylib internal version number to llvmCore submission number - ifdef LLDB_SUBMIT_VERSION - LLVMLibsOptions += -Wl,-current_version \ - -Wl,$(LLDB_SUBMIT_VERSION).$(LLDB_SUBMIT_SUBVERSION) \ - -Wl,-compatibility_version -Wl,1 - endif - # extra options to override libtool defaults - LVMLibsOptions += -F/System/Library/Frameworks -F/System/Library/PrivateFrameworks - LLVMLibsOptions += -framework Foundation -framework CoreFoundation - LLVMLibsOptions += -framework CoreServices -framework Carbon -framework Security - LLVMLibsOptions += -framework DebugSymbols $(PYTHON_BUILD_FLAGS) -lobjc - # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line - DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') - ifneq ($(DARWIN_VERS),8) - LLVMLibsOptions += -Wl,-install_name \ - -Wl,"@executable_path/../lib/$(LIBRARYNAME)$(SHLIBEXT)" - endif -endif - -ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU GNU/kFreeBSD)) - # Include everything from the .a's into the shared library. - ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \ - -Wl,--no-whole-archive - # Link in libedit - # LLVMLibsOptions += -ledit - LLVMLibsOptions += -Wl,--soname,$(LIBRARYNAME)$(SHLIBEXT) -endif - -ifeq ($(HOST_OS),FreeBSD) - # Include everything from the .a's into the shared library. - ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \ - -Wl,--no-whole-archive - # Allow unresolved symbols. - LLVMLibsOptions += -Wl,--allow-shlib-undefined - # Link in libedit - # LLVMLibsOptions += -L/usr/local/lib -ledit -endif - -# FIXME: dynamically construct the version from `python -V` -PYTHON_VERSION:=2.7 -LLDB_PYTHON_MODULE_REL_DIR:=python$(PYTHON_VERSION)/site-packages -LLDB_PYTHON_MODULE_DIR:=$(LibDir)/$(LLDB_PYTHON_MODULE_REL_DIR) - -# Target to move readline module from shared lib build location to -# local python module directory. -all-local:: $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT) - -$(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT): $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT) - $(Echo) Staging $(BuildMode) $(LIBRARYNAME)$(SHLIBEXT) to $(LLDB_PYTHON_MODULE_DIR) - $(Verb) $(MKDIR) "$(LLDB_PYTHON_MODULE_DIR)" - $(Verb) $(ProgInstall) $(SharedLibDir)/$(LIBRARYNAME)$(SHLIBEXT) $(LLDB_PYTHON_MODULE_DIR) - -# Target to move the shared library from the build python lib dir to -# the install python lib dir. -install-local:: $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT) - $(Echo) Installing $(BuildMode) $(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT) to $(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR) - $(Verb) $(MKDIR) "$(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)" - $(Verb) $(ProgInstall) "$(LLDB_PYTHON_MODULE_DIR)/$(LIBRARYNAME)$(SHLIBEXT)" "$(DESTDIR)$(prefix)/lib/$(LLDB_PYTHON_MODULE_REL_DIR)" - $(Verb) $(RM) "$(DESTDIR)$(prefix)/lib/$(LIBRARYNAME)$(SHLIBEXT)" - -endif # if !defined(LLDB_DISABLE_PYTHON) diff --git a/scripts/Python/modules/readline/readline.cpp b/scripts/Python/modules/readline/readline.cpp index d66ccf4b6b7dc..d4b4962cc313f 100644 --- a/scripts/Python/modules/readline/readline.cpp +++ b/scripts/Python/modules/readline/readline.cpp @@ -20,11 +20,6 @@ // work around LLVM pr18841 to avoid seg faults in the stock Python // readline.so linked against GNU readline. -static struct PyMethodDef moduleMethods[] = -{ - {nullptr, nullptr, 0, nullptr} -}; - #ifndef LLDB_DISABLE_LIBEDIT PyDoc_STRVAR( moduleDocumentation, @@ -35,9 +30,33 @@ PyDoc_STRVAR( "Stub module meant to avoid linking GNU readline."); #endif +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef readline_module = +{ + PyModuleDef_HEAD_INIT, // m_base + "readline", // m_name + moduleDocumentation, // m_doc + -1, // m_size + nullptr, // m_methods + nullptr, // m_reload + nullptr, // m_traverse + nullptr, // m_clear + nullptr, // m_free +}; +#else +static struct PyMethodDef moduleMethods[] = +{ + {nullptr, nullptr, 0, nullptr} +}; +#endif + #ifndef LLDB_DISABLE_LIBEDIT static char* +#if PY_MAJOR_VERSION >= 3 +simple_readline(FILE *stdin, FILE *stdout, const char *prompt) +#else simple_readline(FILE *stdin, FILE *stdout, char *prompt) +#endif { rl_instream = stdin; rl_outstream = stdout; @@ -67,10 +86,15 @@ initreadline(void) #ifndef LLDB_DISABLE_LIBEDIT PyOS_ReadlineFunctionPointer = simple_readline; #endif + +#if PY_MAJOR_VERSION >= 3 + return PyModule_Create(&readline_module); +#else Py_InitModule4( "readline", moduleMethods, moduleDocumentation, static_cast<PyObject *>(NULL), PYTHON_API_VERSION); +#endif } diff --git a/scripts/Python/prepare_binding_Python.py b/scripts/Python/prepare_binding_Python.py index 1996841baf18e..28fc3e5bc7fc9 100644 --- a/scripts/Python/prepare_binding_Python.py +++ b/scripts/Python/prepare_binding_Python.py @@ -16,7 +16,7 @@ import re import shutil import subprocess import sys - +import platform class SwigSettings(object): """Provides a single object to represent swig files and settings.""" @@ -205,6 +205,8 @@ def do_swig_rebuild(options, dependency_file, config_build_dir, settings): "-I\"%s\"" % os.path.normcase("./."), "-D__STDC_LIMIT_MACROS", "-D__STDC_CONSTANT_MACROS"] + if options.target_platform == "Darwin": + command.append("-D__APPLE__") if options.generate_dependency_file: command.append("-MMD -MF \"%s\"" % temp_dep_file_path) command.extend([ diff --git a/scripts/Python/python-extensions.swig b/scripts/Python/python-extensions.swig index fae7f401bf134..693b06b9aab39 100644 --- a/scripts/Python/python-extensions.swig +++ b/scripts/Python/python-extensions.swig @@ -325,6 +325,22 @@ return getattr(_lldb,self.__class__.__name__+"___ne__")(self, rhs) %} } + +%extend lldb::SBMemoryRegionInfo { + PyObject *lldb::SBMemoryRegionInfo::__str__ (){ + lldb::SBStream description; + $self->GetDescription (description); + const char *desc = description.GetData(); + size_t desc_len = description.GetSize(); + if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r')) + --desc_len; + if (desc_len > 0) + return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release(); + else + return lldb_private::PythonString("").release(); + } +} + %extend lldb::SBModule { PyObject *lldb::SBModule::__str__ (){ lldb::SBStream description; @@ -810,6 +826,7 @@ def command(*args, **kwargs): import lldb + import inspect """A decorator function that registers an LLDB command line command that is bound to the function it is attached to.""" class obj(object): @@ -821,11 +838,15 @@ def command(*args, **kwargs): command = "command script add -f %s.%s %s" % (function.__module__, function.__name__, command_name) lldb.debugger.HandleCommand(command) self.function = function - def __call__(self, *args, **kwargs): - self.function(*args, **kwargs) + def __call__(self, debugger, command, exe_ctx, result, dict): + if len(inspect.getargspec(self.function).args) == 5: + self.function(debugger, command, exe_ctx, result, dict) + else: + self.function(debugger, command, result, dict) def callable(function): """Creates a callable object that gets used.""" - return obj(function, *args, **kwargs) + f = obj(function, *args, **kwargs) + return f.__call__ return callable class declaration(object): @@ -1024,11 +1045,13 @@ class value(object): return complex (int(self)) def __int__(self): + is_num,is_sign = is_numeric_type(self.sbvalue.GetType().GetCanonicalType().GetBasicType()) + if is_num and not is_sign: return self.sbvalue.GetValueAsUnsigned() return self.sbvalue.GetValueAsSigned() - + def __long__(self): - return self.sbvalue.GetValueAsSigned() - + return self.__int__() + def __float__(self): return float (self.sbvalue.GetValueAsSigned()) @@ -1084,4 +1107,47 @@ class SBSyntheticValueProvider(object): return False -%}
\ No newline at end of file +%} + +%pythoncode %{ + +# given an lldb.SBBasicType it returns a tuple +# (is_numeric, is_signed) +# the value of is_signed is undefined if is_numeric == false +def is_numeric_type(basic_type): + if basic_type == eBasicTypeInvalid: return (False,False) + if basic_type == eBasicTypeVoid: return (False,False) + if basic_type == eBasicTypeChar: return (True,False) + if basic_type == eBasicTypeSignedChar: return (True,True) + if basic_type == eBasicTypeUnsignedChar: return (True,False) + if basic_type == eBasicTypeWChar: return (True,False) + if basic_type == eBasicTypeSignedWChar: return (True,True) + if basic_type == eBasicTypeUnsignedWChar: return (True,False) + if basic_type == eBasicTypeChar16: return (True,False) + if basic_type == eBasicTypeChar32: return (True,False) + if basic_type == eBasicTypeShort: return (True,True) + if basic_type == eBasicTypeUnsignedShort: return (True,False) + if basic_type == eBasicTypeInt: return (True,True) + if basic_type == eBasicTypeUnsignedInt: return (True,False) + if basic_type == eBasicTypeLong: return (True,True) + if basic_type == eBasicTypeUnsignedLong: return (True,False) + if basic_type == eBasicTypeLongLong: return (True,True) + if basic_type == eBasicTypeUnsignedLongLong: return (True,False) + if basic_type == eBasicTypeInt128: return (True,True) + if basic_type == eBasicTypeUnsignedInt128: return (True,False) + if basic_type == eBasicTypeBool: return (False,False) + if basic_type == eBasicTypeHalf: return (True,True) + if basic_type == eBasicTypeFloat: return (True,True) + if basic_type == eBasicTypeDouble: return (True,True) + if basic_type == eBasicTypeLongDouble: return (True,True) + if basic_type == eBasicTypeFloatComplex: return (True,True) + if basic_type == eBasicTypeDoubleComplex: return (True,True) + if basic_type == eBasicTypeLongDoubleComplex: return (True,True) + if basic_type == eBasicTypeObjCID: return (False,False) + if basic_type == eBasicTypeObjCClass: return (False,False) + if basic_type == eBasicTypeObjCSel: return (False,False) + if basic_type == eBasicTypeNullPtr: return (False,False) + #if basic_type == eBasicTypeOther: + return (False,False) + +%} diff --git a/scripts/Python/python-typemaps.swig b/scripts/Python/python-typemaps.swig index 9c4e5cecb3639..df16a6d27b3b9 100644 --- a/scripts/Python/python-typemaps.swig +++ b/scripts/Python/python-typemaps.swig @@ -1,20 +1,22 @@ /* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */ %typemap(in) char ** { + using namespace lldb_private; /* Check if is a list */ - if (PyList_Check($input)) { - int size = PyList_Size($input); + if (PythonList::Check($input)) { + PythonList list(PyRefType::Borrowed, $input); + int size = list.GetSize(); int i = 0; - $1 = (char **) malloc((size+1) * sizeof(char*)); + $1 = (char**)malloc((size+1)*sizeof(char*)); for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (PyString_Check(o)) - $1[i] = PyString_AsString(o); - else { + PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>(); + if (!py_str.IsAllocated()) { PyErr_SetString(PyExc_TypeError,"list must contain strings"); free($1); - return NULL; + return nullptr; } + + $1[i] = const_cast<char*>(py_str.GetString().data()); } $1[i] = 0; } else if ($input == Py_None) { @@ -25,29 +27,17 @@ } } -%typemap(in) lldb::tid_t { - using namespace lldb_private; - if (PythonInteger::Check($input)) - { - PythonInteger py_int(PyRefType::Borrowed, $input); - $1 = static_cast<lldb::tid_t>(py_int.GetInteger()); - } - else - { - PyErr_SetString(PyExc_ValueError, "Expecting an integer"); - return nullptr; - } -} - %typemap(typecheck) char ** { /* Check if is a list */ $1 = 1; - if (PyList_Check($input)) { - int size = PyList_Size($input); + using namespace lldb_private; + if (PythonList::Check($input)) { + PythonList list(PyRefType::Borrowed, $input); + int size = list.GetSize(); int i = 0; for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (!PyString_Check(o)) { $1 = 0; } + PythonString s = list.GetItemAtIndex(i).AsType<PythonString>(); + if (!s.IsAllocated()) { $1 = 0; } } } else @@ -72,63 +62,18 @@ $result = list.release(); } -%typemap(in) char const ** { - /* Check if is a list */ - using namespace lldb_private; - if (PythonList::Check($input)) { - PythonList py_list(PyRefType::Borrowed, $input); - int size = py_list.GetSize(); - $1 = (char**)malloc((size+1)*sizeof(char*)); - for (int i = 0; i < size; i++) { - PythonObject o = py_list.GetItemAtIndex(i); - if (!PythonString::Check(o.get())) { - PyErr_SetString(PyExc_TypeError,"list must contain strings"); - free($1); - return nullptr; - } - auto py_str = o.AsType<PythonString>(); - $1[i] = const_cast<char*>(py_str.GetString().data()); - } - - $1[size] = 0; - } else if ($input == Py_None) { - $1 = nullptr; - } else { - PyErr_SetString(PyExc_TypeError,"not a list"); - return nullptr; - } -} - -%typemap(typecheck) char const ** { - /* Check if is a list */ - $1 = 1; - if (PyList_Check($input)) { - int size = PyList_Size($input); - int i = 0; - for (i = 0; i < size; i++) { - PyObject *o = PyList_GetItem($input,i); - if (!PyString_Check(o)) { $1 = 0; } - } +%typemap(in) lldb::tid_t { + using namespace lldb_private; + if (PythonInteger::Check($input)) + { + PythonInteger py_int(PyRefType::Borrowed, $input); + $1 = static_cast<lldb::tid_t>(py_int.GetInteger()); } else { - $1 = ( ($input == Py_None) ? 1 : 0); - } -} - -%typemap(freearg) char const ** { - free((char *) $1); -} - -%typemap(out) char const ** { - int len; - int i; - len = 0; - while ($1[len]) len++; - $result = PyList_New(len); - for (i = 0; i < len; i++) { - PyList_SetItem($result, i, PyString_FromString($1[i])); + PyErr_SetString(PyExc_ValueError, "Expecting an integer"); + return nullptr; } } @@ -148,6 +93,9 @@ } $1 = (char *) malloc($2); } +// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated +// as char data instead of byte data. +%typemap(in) (void *char_buf, size_t size) = (char *dst, size_t dst_len); // Return the char buffer. Discarding any previous return result // See also SBThread::GetStopDescription. @@ -163,18 +111,29 @@ } free($1); } +// SBProcess::ReadCStringFromMemory() uses a void*, but needs to be treated +// as char data instead of byte data. +%typemap(argout) (void *char_buf, size_t size) = (char *dst, size_t dst_len); // typemap for an outgoing buffer // See also SBEvent::SBEvent(uint32_t event, const char *cstr, uint32_t cstr_len). %typemap(in) (const char *cstr, uint32_t cstr_len) { - if (PyString_Check($input)) { - $1 = (char *) PyString_AsString($input); - $2 = PyString_Size($input); + using namespace lldb_private; + if (PythonString::Check($input)) { + PythonString str(PyRefType::Borrowed, $input); + $1 = (char*)str.GetString().data(); + $2 = str.GetSize(); + } + else if(PythonByteArray::Check($input)) { + PythonByteArray bytearray(PyRefType::Borrowed, $input); + $1 = (char*)bytearray.GetBytes().data(); + $2 = bytearray.GetSize(); } - else if(PyByteArray_Check($input)) { - $1 = (char *) PyByteArray_AsString($input); - $2 = PyByteArray_Size($input); + else if (PythonBytes::Check($input)) { + PythonBytes bytes(PyRefType::Borrowed, $input); + $1 = (char*)bytes.GetBytes().data(); + $2 = bytes.GetSize(); } else { PyErr_SetString(PyExc_ValueError, "Expecting a string"); @@ -183,13 +142,21 @@ } // Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len). %typemap(in) (const char *src, size_t src_len) { - if (PyString_Check($input)) { - $1 = (char *) PyString_AsString($input); - $2 = PyString_Size($input); + using namespace lldb_private; + if (PythonString::Check($input)) { + PythonString str(PyRefType::Borrowed, $input); + $1 = (char*)str.GetString().data(); + $2 = str.GetSize(); } - else if(PyByteArray_Check($input)) { - $1 = (char *) PyByteArray_AsString($input); - $2 = PyByteArray_Size($input); + else if(PythonByteArray::Check($input)) { + PythonByteArray bytearray(PyRefType::Borrowed, $input); + $1 = (char*)bytearray.GetBytes().data(); + $2 = bytearray.GetSize(); + } + else if (PythonBytes::Check($input)) { + PythonBytes bytes(PyRefType::Borrowed, $input); + $1 = (char*)bytes.GetBytes().data(); + $2 = bytes.GetSize(); } else { PyErr_SetString(PyExc_ValueError, "Expecting a string"); @@ -198,32 +165,48 @@ } // And SBProcess::WriteMemory. %typemap(in) (const void *buf, size_t size) { - if (PyString_Check($input)) { - $1 = (void *) PyString_AsString($input); - $2 = PyString_Size($input); + using namespace lldb_private; + if (PythonString::Check($input)) { + PythonString str(PyRefType::Borrowed, $input); + $1 = (void*)str.GetString().data(); + $2 = str.GetSize(); } - else if(PyByteArray_Check($input)) { - $1 = (void *) PyByteArray_AsString($input); - $2 = PyByteArray_Size($input); + else if(PythonByteArray::Check($input)) { + PythonByteArray bytearray(PyRefType::Borrowed, $input); + $1 = (void*)bytearray.GetBytes().data(); + $2 = bytearray.GetSize(); + } + else if (PythonBytes::Check($input)) { + PythonBytes bytes(PyRefType::Borrowed, $input); + $1 = (void*)bytes.GetBytes().data(); + $2 = bytes.GetSize(); } else { - PyErr_SetString(PyExc_ValueError, "Expecting a string"); + PyErr_SetString(PyExc_ValueError, "Expecting a buffer"); return NULL; } } // For SBDebugger::DispatchInput %typemap(in) (const void *data, size_t data_len) { - if (PyString_Check($input)) { - $1 = static_cast<void *>(PyString_AsString($input)); - $2 = PyString_Size($input); + using namespace lldb_private; + if (PythonString::Check($input)) { + PythonString str(PyRefType::Borrowed, $input); + $1 = (void*)str.GetString().data(); + $2 = str.GetSize(); } - else if(PyByteArray_Check($input)) { - $1 = static_cast<void *>(PyByteArray_AsString($input)); - $2 = PyByteArray_Size($input); + else if(PythonByteArray::Check($input)) { + PythonByteArray bytearray(PyRefType::Borrowed, $input); + $1 = (void*)bytearray.GetBytes().data(); + $2 = bytearray.GetSize(); + } + else if (PythonBytes::Check($input)) { + PythonBytes bytes(PyRefType::Borrowed, $input); + $1 = (void*)bytes.GetBytes().data(); + $2 = bytes.GetSize(); } else { - PyErr_SetString(PyExc_ValueError, "Expecting a string or byte array"); + PyErr_SetString(PyExc_ValueError, "Expecting a buffer"); return NULL; } } @@ -254,9 +237,8 @@ $result = Py_None; Py_INCREF($result); } else { - llvm::StringRef ref(static_cast<const char*>($1), result); - lldb_private::PythonString string(ref); - $result = string.release(); + lldb_private::PythonBytes bytes(static_cast<const uint8_t*>($1), result); + $result = bytes.release(); } free($1); } @@ -545,22 +527,27 @@ return nullptr; $1 = file.GetStream(); - } + if ($1) + file.Clear(); + } } %typemap(out) FILE * { char mode[4] = {0}; -#ifdef __MACOSX__ +%#ifdef __APPLE__ int i = 0; - short flags = $1->_flags; - - if (flags & __SRD) - mode[i++] = 'r'; - else if (flags & __SWR) - mode[i++] = 'w'; - else // if (flags & __SRW) - mode[i++] = 'a'; -#endif + if ($1) + { + short flags = $1->_flags; + + if (flags & __SRD) + mode[i++] = 'r'; + else if (flags & __SWR) + mode[i++] = 'w'; + else // if (flags & __SRW) + mode[i++] = 'a'; + } +%#endif using namespace lldb_private; File file($1, false); PythonFile py_file(file, mode); diff --git a/scripts/Python/python-wrapper.swig b/scripts/Python/python-wrapper.swig index 5d7bfaa89439b..a92102e328388 100644 --- a/scripts/Python/python-wrapper.swig +++ b/scripts/Python/python-wrapper.swig @@ -610,7 +610,7 @@ LLDBSwigPythonCallCommand PythonObject exe_ctx_arg(PyRefType::Owned, SBTypeToSWIGWrapper(exe_ctx_sb)); PythonObject cmd_retobj_arg(PyRefType::Owned, SBTypeToSWIGWrapper(&cmd_retobj_sb)); - if (argc.count == 5 || argc.has_varargs) + if (argc.count == 5 || argc.is_bound_method || argc.has_varargs) pfunc(debugger_arg, PythonString(args), exe_ctx_arg, cmd_retobj_arg, dict); else pfunc(debugger_arg, PythonString(args), cmd_retobj_arg, dict); diff --git a/scripts/Python/use_lldb_suite.py b/scripts/Python/use_lldb_suite.py index 63a098cea220f..f3e358af143bf 100644 --- a/scripts/Python/use_lldb_suite.py +++ b/scripts/Python/use_lldb_suite.py @@ -17,6 +17,9 @@ def find_lldb_root(): lldb_root = find_lldb_root() if lldb_root is not None: import imp - module = imp.find_module("use_lldb_suite_root", [lldb_root]) - if module is not None: - imp.load_module("use_lldb_suite_root", *module) + fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root]) + try: + imp.load_module("use_lldb_suite_root", fp, pathname, desc) + finally: + if fp: + fp.close() diff --git a/scripts/Xcode/build-llvm.py b/scripts/Xcode/build-llvm.py new file mode 100755 index 0000000000000..b594a8cfe17b6 --- /dev/null +++ b/scripts/Xcode/build-llvm.py @@ -0,0 +1,373 @@ +#!/usr/bin/env python + +import errno +import hashlib +import fnmatch +import os +import platform +import subprocess +import sys + +from lldbbuild import * + +#### SETTINGS #### + +def LLVM_HASH_INCLUDES_DIFFS (): + return False + +# The use of "x = "..."; return x" here is important because tooling looks for +# it with regexps. Only change how this works if you know what you are doing. + +def LLVM_REF (): + llvm_ref = "master" + return llvm_ref + +def CLANG_REF (): + clang_ref = "master" + return clang_ref + +# For use with Xcode-style builds + +def XCODE_REPOSITORIES (): + return [ + { 'name': "llvm", + 'vcs': VCS.git, + 'root': llvm_source_path(), + 'url': "http://llvm.org/git/llvm.git", + 'ref': LLVM_REF() }, + + { 'name': "clang", + 'vcs': VCS.git, + 'root': clang_source_path(), + 'url': "http://llvm.org/git/clang.git", + 'ref': CLANG_REF() }, + + { 'name': "ninja", + 'vcs': VCS.git, + 'root': ninja_source_path(), + 'url': "https://github.com/ninja-build/ninja.git", + 'ref': "master" } + ] + +def get_c_compiler (): + return subprocess.check_output([ + 'xcrun', + '--sdk', 'macosx', + '-find', 'clang' + ]).rstrip() + +def get_cxx_compiler (): + return subprocess.check_output([ + 'xcrun', + '--sdk', 'macosx', + '-find', 'clang++' + ]).rstrip() + +# CFLAGS="-isysroot $(xcrun --sdk macosx --show-sdk-path) -mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \ +# LDFLAGS="-mmacosx-version-min=${DARWIN_DEPLOYMENT_VERSION_OSX}" \ + +def get_deployment_target (): + return os.environ.get('MACOSX_DEPLOYMENT_TARGET', None) + +def get_c_flags (): + cflags = '' + # sdk_path = subprocess.check_output([ + # 'xcrun', + # '--sdk', 'macosx', + # '--show-sdk-path']).rstrip() + # cflags += '-isysroot {}'.format(sdk_path) + + deployment_target = get_deployment_target() + if deployment_target: + # cflags += ' -mmacosx-version-min={}'.format(deployment_target) + pass + + return cflags + +def get_cxx_flags (): + return get_c_flags() + +def get_common_linker_flags (): + linker_flags = "" + deployment_target = get_deployment_target() + if deployment_target: + # if len(linker_flags) > 0: + # linker_flags += ' ' + # linker_flags += '-mmacosx-version-min={}'.format(deployment_target) + pass + + return linker_flags + +def get_exe_linker_flags (): + return get_common_linker_flags() + +def get_shared_linker_flags (): + return get_common_linker_flags() + +def CMAKE_FLAGS (): + return { + "Debug": [ + "-DCMAKE_BUILD_TYPE=RelWithDebInfo", + "-DLLVM_ENABLE_ASSERTIONS=ON", + ], + "DebugClang": [ + "-DCMAKE_BUILD_TYPE=Debug", + "-DLLVM_ENABLE_ASSERTIONS=ON", + ], + "Release": [ + "-DCMAKE_BUILD_TYPE=Release", + "-DLLVM_ENABLE_ASSERTIONS=ON", + ], + "BuildAndIntegration": [ + "-DCMAKE_BUILD_TYPE=Release", + "-DLLVM_ENABLE_ASSERTIONS=OFF", + ], + } + +def CMAKE_ENVIRONMENT (): + return { + } + +#### COLLECTING ALL ARCHIVES #### + +def collect_archives_in_path (path): + files = os.listdir(path) + return [os.path.join(path, file) for file in files if file.endswith(".a")] + +def archive_list (): + paths = library_paths() + archive_lists = [collect_archives_in_path(path) for path in paths] + return [archive for archive_list in archive_lists for archive in archive_list] + +def write_archives_txt (): + f = open(archives_txt(), 'w') + for archive in archive_list(): + f.write(archive + "\n") + f.close() + +#### COLLECTING REPOSITORY MD5S #### + +def source_control_status (spec): + vcs_for_spec = vcs(spec) + if LLVM_HASH_INCLUDES_DIFFS(): + return vcs_for_spec.status() + vcs_for_spec.diff() + else: + return vcs_for_spec.status() + +def source_control_status_for_specs (specs): + statuses = [source_control_status(spec) for spec in specs] + return "".join(statuses) + +def all_source_control_status (): + return source_control_status_for_specs(XCODE_REPOSITORIES()) + +def md5 (string): + m = hashlib.md5() + m.update(string) + return m.hexdigest() + +def all_source_control_status_md5 (): + return md5(all_source_control_status()) + +#### CHECKING OUT AND BUILDING LLVM #### + +def apply_patches(spec): + files = os.listdir(os.path.join(lldb_source_path(), 'scripts')) + patches = [f for f in files if fnmatch.fnmatch(f, spec['name'] + '.*.diff')] + for p in patches: + run_in_directory(["patch", "-p0", "-i", os.path.join(lldb_source_path(), 'scripts', p)], spec['root']) + +def check_out_if_needed(spec): + if not os.path.isdir(spec['root']): + vcs(spec).check_out() + apply_patches(spec) + +def all_check_out_if_needed (): + map (check_out_if_needed, XCODE_REPOSITORIES()) + +def should_build_llvm (): + if build_type() == BuildType.Xcode: + # TODO use md5 sums + return True + +def do_symlink (source_path, link_path): + print "Symlinking " + source_path + " to " + link_path + if not os.path.exists(link_path): + os.symlink(source_path, link_path) + +def setup_source_symlink (repo): + source_path = repo["root"] + link_path = os.path.join(lldb_source_path(), os.path.basename(source_path)) + do_symlink(source_path, link_path) + +def setup_source_symlinks (): + map(setup_source_symlink, XCODE_REPOSITORIES()) + +def setup_build_symlink (): + # We don't use the build symlinks in llvm.org Xcode-based builds. + if build_type() != BuildType.Xcode: + source_path = package_build_path() + link_path = expected_package_build_path() + do_symlink(source_path, link_path) + +def should_run_cmake (cmake_build_dir): + # We need to run cmake if our llvm build directory doesn't yet exist. + if not os.path.exists(cmake_build_dir): + return True + + # Wee also need to run cmake if for some reason we don't have a ninja + # build file. (Perhaps the cmake invocation failed, which this current + # build may have fixed). + ninja_path = os.path.join(cmake_build_dir, "build.ninja") + return not os.path.exists(ninja_path) + +def cmake_environment (): + cmake_env = join_dicts(os.environ, CMAKE_ENVIRONMENT()) + return cmake_env + +def is_executable(path): + return os.path.isfile(path) and os.access(path, os.X_OK) + +def find_executable_in_paths (program, paths_to_check): + program_dir, program_name = os.path.split(program) + if program_dir: + if is_executable(program): + return program + else: + for path_dir in paths_to_check: + path_dir = path_dir.strip('"') + executable_file = os.path.join(path_dir, program) + if is_executable(executable_file): + return executable_file + return None + +def find_cmake (): + # First check the system PATH env var for cmake + cmake_binary = find_executable_in_paths("cmake", os.environ["PATH"].split(os.pathsep)) + if cmake_binary: + # We found it there, use it. + return cmake_binary + + # Check a few more common spots. Xcode launched from Finder + # will have the default environment, and may not have + # all the normal places present. + extra_cmake_dirs = [ + "/usr/local/bin", + "/opt/local/bin", + os.path.join(os.path.expanduser("~"), "bin") + ] + + if platform.system() == "Darwin": + # Add locations where an official CMake.app package may be installed. + extra_cmake_dirs.extend([ + os.path.join( + os.path.expanduser("~"), + "Applications", + "CMake.app", + "Contents", + "bin"), + os.path.join( + os.sep, + "Applications", + "CMake.app", + "Contents", + "bin")]) + + cmake_binary = find_executable_in_paths("cmake", extra_cmake_dirs) + if cmake_binary: + # We found it in one of the usual places. Use that. + return cmake_binary + + # We couldn't find cmake. Tell the user what to do. + raise Exception( + "could not find cmake in PATH ({}) or in any of these locations ({}), " + "please install cmake or add a link to it in one of those locations".format( + os.environ["PATH"], + extra_cmake_dirs)) + +def cmake_flags (): + cmake_flags = CMAKE_FLAGS()[lldb_configuration()] + cmake_flags += [ + "-GNinja", + "-DCMAKE_C_COMPILER={}".format(get_c_compiler()), + "-DCMAKE_CXX_COMPILER={}".format(get_cxx_compiler()), + "-DCMAKE_INSTALL_PREFIX={}".format(expected_package_build_path_for("llvm")), + "-DCMAKE_C_FLAGS={}".format(get_c_flags()), + "-DCMAKE_CXX_FLAGS={}".format(get_cxx_flags()), + "-DCMAKE_EXE_LINKER_FLAGS={}".format(get_exe_linker_flags()), + "-DCMAKE_SHARED_LINKER_FLAGS={}".format(get_shared_linker_flags()) + ] + deployment_target = get_deployment_target() + if deployment_target: + cmake_flags.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target)) + return cmake_flags + +def run_cmake (cmake_build_dir, ninja_binary_path): + cmake_binary = find_cmake() + print "found cmake binary: using \"{}\"".format(cmake_binary) + + command_line = [cmake_binary] + cmake_flags() + [ + "-DCMAKE_MAKE_PROGRAM={}".format(ninja_binary_path), + llvm_source_path()] + print "running cmake like so: ({}) in dir ({})".format(command_line, cmake_build_dir) + + subprocess.check_call(command_line, cwd=cmake_build_dir, env=cmake_environment()) + +def create_directories_as_needed (path): + try: + os.makedirs(path) + except OSError as error: + # An error indicating that the directory exists already is fine. + # Anything else should be passed along. + if error.errno != errno.EEXIST: + raise error + +def run_cmake_if_needed (ninja_binary_path): + cmake_build_dir = package_build_path() + if should_run_cmake(cmake_build_dir): + # Create the build directory as needed + create_directories_as_needed (cmake_build_dir) + run_cmake(cmake_build_dir, ninja_binary_path) + +def build_ninja_if_needed (): + # First check if ninja is in our path. If so, there's nothing to do. + ninja_binary_path = find_executable_in_paths("ninja", os.environ["PATH"].split(os.pathsep)) + if ninja_binary_path: + # It's on the path. cmake will find it. We're good. + print "found ninja here: \"{}\"".format(ninja_binary_path) + return ninja_binary_path + + # Figure out if we need to build it. + ninja_build_dir = ninja_source_path() + ninja_binary_path = os.path.join(ninja_build_dir, "ninja") + if not is_executable(ninja_binary_path): + # Build ninja + command_line = ["python", "configure.py", "--bootstrap"] + print "building ninja like so: ({}) in dir ({})".format(command_line, ninja_build_dir) + subprocess.check_call(command_line, cwd=ninja_build_dir, env=os.environ) + + return ninja_binary_path + +def join_dicts (dict1, dict2): + d = dict1.copy() + d.update(dict2) + return d + +def build_llvm (ninja_binary_path): + cmake_build_dir = package_build_path() + subprocess.check_call([ninja_binary_path], cwd=cmake_build_dir, env=cmake_environment()) + +def build_llvm_if_needed (): + if should_build_llvm(): + ninja_binary_path = build_ninja_if_needed() + run_cmake_if_needed(ninja_binary_path) + build_llvm(ninja_binary_path) + setup_build_symlink() + +#### MAIN LOGIC #### + +all_check_out_if_needed() +build_llvm_if_needed() +write_archives_txt() + +sys.exit(0) diff --git a/scripts/Xcode/lldbbuild.py b/scripts/Xcode/lldbbuild.py new file mode 100644 index 0000000000000..bb43315dc29de --- /dev/null +++ b/scripts/Xcode/lldbbuild.py @@ -0,0 +1,135 @@ +import os +import subprocess + +#### UTILITIES #### + +def enum (*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + return type('Enum', (), enums) + +#### SETTINGS #### + +#### INTERFACE TO THE XCODEPROJ #### + +def lldb_source_path (): + return os.environ.get('SRCROOT') + +def expected_llvm_build_path (): + if build_type() == BuildType.Xcode: + return package_build_path() + else: + return os.path.join(os.environ.get('LLDB_PATH_TO_LLVM_BUILD'), package_build_dir_name("llvm")) + +def archives_txt (): + return os.path.join(expected_package_build_path(), "archives.txt") + +def expected_package_build_path (): + return os.path.abspath(os.path.join(expected_llvm_build_path(), "..")) + +def architecture (): + platform_name = os.environ.get('RC_PLATFORM_NAME') + if not platform_name: + platform_name = os.environ.get('PLATFORM_NAME') + platform_arch = os.environ.get('ARCHS').split()[-1] + return platform_name + "-" + platform_arch + +def lldb_configuration (): + return os.environ.get('CONFIGURATION') + +def llvm_configuration (): + return os.environ.get('LLVM_CONFIGURATION') + +def llvm_build_dirtree (): + return os.environ.get('LLVM_BUILD_DIRTREE') + +# Edit the code below when adding build styles. + +BuildType = enum('Xcode') # (Debug,DebugClang,Release) + +def build_type (): + return BuildType.Xcode + +#### VCS UTILITIES #### + +VCS = enum('git', + 'svn') + +def run_in_directory(args, path): + return subprocess.check_output(args, cwd=path) + +class Git: + def __init__ (self, spec): + self.spec = spec + def status (self): + return run_in_directory(["git", "branch", "-v"], self.spec['root']) + def diff (self): + return run_in_directory(["git", "diff"], self.spec['root']) + def check_out (self): + run_in_directory(["git", "clone", "--depth=1", self.spec['url'], self.spec['root']], lldb_source_path()) + run_in_directory(["git", "fetch", "--all"], self.spec['root']) + run_in_directory(["git", "checkout", self.spec['ref']], self.spec['root']) + +class SVN: + def __init__ (self, spec): + self.spec = spec + def status (self): + return run_in_directory(["svn", "info"], self.spec['root']) + def diff (self): + return run_in_directory(["svn", "diff"], self.spec['root']) + # TODO implement check_out + +def vcs (spec): + if spec['vcs'] == VCS.git: + return Git(spec) + elif spec['vcs'] == VCS.svn: + return SVN(spec) + else: + return None + +#### SOURCE PATHS #### + +def llvm_source_path (): + if build_type() == BuildType.Xcode: + return os.path.join(lldb_source_path(), "llvm") + +def clang_source_path (): + if build_type() == BuildType.Xcode: + return os.path.join(llvm_source_path(), "tools", "clang") + +def ninja_source_path (): + if build_type() == BuildType.Xcode: + return os.path.join(lldb_source_path(), "ninja") + +#### BUILD PATHS #### + +def packages (): + return ["llvm"] + +def package_build_dir_name (package): + return package + "-" + architecture() + +def expected_package_build_path_for (package): + if build_type() == BuildType.Xcode: + if package != "llvm": + raise("On Xcode build, we only support the llvm package: requested {}".format(package)) + return package_build_path() + return os.path.join(expected_package_build_path(), package_build_dir_name(package)) + +def expected_package_build_paths (): + return [expected_package_build_path_for(package) for package in packages()] + +def library_path (build_path): + return build_path + "/lib" + +def library_paths (): + if build_type() == BuildType.Xcode: + package_build_paths = [package_build_path()] + else: + package_build_paths = expected_package_build_paths() + return [library_path(build_path) for build_path in package_build_paths] + +def package_build_path (): + return os.path.join( + llvm_build_dirtree(), + os.environ["LLVM_CONFIGURATION"], + os.environ["CURRENT_ARCH"]) diff --git a/scripts/package-clang-headers.py b/scripts/Xcode/package-clang-headers.py index b28ad0d343eca..55ecc90d357b8 100644 --- a/scripts/package-clang-headers.py +++ b/scripts/Xcode/package-clang-headers.py @@ -14,12 +14,14 @@ import re import shutil import sys +import lldbbuild + if len(sys.argv) != 3: print "usage: " + sys.argv[0] + " TARGET_DIR LLVM_BUILD_DIR" sys.exit(1) target_dir = sys.argv[1] -llvm_build_dir = sys.argv[2] +llvm_build_dir = lldbbuild.expected_package_build_path_for("llvm") if not os.path.isdir(target_dir): print target_dir + " doesn't exist" diff --git a/scripts/build-llvm.pl b/scripts/build-llvm.pl deleted file mode 100644 index f7a60d8d3d3e9..0000000000000 --- a/scripts/build-llvm.pl +++ /dev/null @@ -1,407 +0,0 @@ -#!/usr/bin/perl - -# This script will take a number ($ENV{SCRIPT_INPUT_FILE_COUNT}) of static archive files -# and pull them apart into object files. These object files will be placed in a directory -# named the same as the archive itself without the extension. Each object file will then -# get renamed to start with the archive name and a '-' character (for archive.a(object.o) -# the object file would becomde archive-object.o. Then all object files are re-made into -# a single static library. This can help avoid name collisions when different archive -# files might contain object files with the same name. - -use strict; -use Cwd 'abs_path'; -use File::Basename; -use File::Glob ':glob'; -use File::Slurp; -use List::Util qw[min max]; -use Digest::MD5 qw(md5_hex); - -our $llvm_srcroot = $ENV{SCRIPT_INPUT_FILE_0}; -our $llvm_dstroot = $ENV{SCRIPT_INPUT_FILE_1}; -our $archive_filelist_file = $ENV{SCRIPT_INPUT_FILE_2}; - -our $llvm_configuration = $ENV{LLVM_CONFIGURATION}; - -our $llvm_revision = "HEAD"; -our $clang_revision = "HEAD"; -our $compiler_rt_revision = "HEAD"; - -our $SRCROOT = "$ENV{SRCROOT}"; -our @archs = split (/\s+/, $ENV{ARCHS}); -my $os_release = 11; - -my $original_env_path = $ENV{PATH}; - -my $common_configure_options = "--disable-terminfo"; - -our %llvm_config_info = ( - 'Debug' => { configure_options => '--disable-optimized --disable-assertions --enable-cxx11 --enable-libcpp', make_options => 'DEBUG_SYMBOLS=1'}, - 'Debug+Asserts' => { configure_options => '--disable-optimized --enable-assertions --enable-cxx11 --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'}, - 'Release' => { configure_options => '--enable-optimized --disable-assertions --enable-cxx11 --enable-libcpp' , make_options => ''}, - 'Release+Debug' => { configure_options => '--enable-optimized --disable-assertions --enable-cxx11 --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'}, - 'Release+Asserts' => { configure_options => '--enable-optimized --enable-assertions --enable-cxx11 --enable-libcpp' , make_options => ''}, -); - -our $llvm_config_href = undef; -if (exists $llvm_config_info{"$llvm_configuration"}) -{ - $llvm_config_href = $llvm_config_info{$llvm_configuration}; -} -else -{ - die "Unsupported LLVM configuration: '$llvm_configuration'\n"; -} -our @llvm_repositories = ( - abs_path("$llvm_srcroot"), - abs_path("$llvm_srcroot/tools/clang"), -# abs_path("$llvm_srcroot/projects/compiler-rt") -); - -if (-e "$llvm_srcroot/lib") -{ - print "Using existing llvm sources in: '$llvm_srcroot'\n"; - print "Using standard LLVM build directory:\n SRC = '$llvm_srcroot'\n DST = '$llvm_dstroot'\n"; -} -else -{ - print "Checking out llvm sources from revision $llvm_revision...\n"; - do_command ("cd '$SRCROOT' && svn co --quiet --revision $llvm_revision http://llvm.org/svn/llvm-project/llvm/trunk llvm", "checking out llvm from repository", 1); - print "Checking out clang sources from revision $clang_revision...\n"; - do_command ("cd '$llvm_srcroot/tools' && svn co --quiet --revision $clang_revision http://llvm.org/svn/llvm-project/cfe/trunk clang", "checking out clang from repository", 1); -# print "Checking out compiler-rt sources from revision $compiler_rt_revision...\n"; -# do_command ("cd '$llvm_srcroot/projects' && svn co --quiet --revision $compiler_rt_revision http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt", "checking out compiler-rt from repository", 1); - print "Applying any local patches to LLVM/Clang..."; - - my @llvm_patches = bsd_glob("$ENV{SRCROOT}/scripts/llvm.*.diff"); - foreach my $patch (@llvm_patches) - { - do_command ("cd '$llvm_srcroot' && patch -p0 < $patch"); - } - - my @clang_patches = bsd_glob("$ENV{SRCROOT}/scripts/clang.*.diff"); - foreach my $patch (@clang_patches) - { - do_command ("cd '$llvm_srcroot/tools/clang' && patch -p0 < $patch"); - } - -# my @compiler_rt_patches = bsd_glob("$ENV{SRCROOT}/scripts/compiler-rt.*.diff"); -# foreach my $patch (@compiler_rt_patches) -# { -# do_command ("cd '$llvm_srcroot/projects/compiler-rt' && patch -p0 < $patch"); -# } -} - -# Get our options - -our $debug = 1; - -sub parallel_guess -{ - my $cpus = `sysctl -n hw.ncpu`; - chomp ($cpus); - my $memsize = `sysctl -n hw.memsize`; - chomp ($memsize); - my $max_cpus_by_memory = int($memsize / (750 * 1024 * 1024)); - return min($max_cpus_by_memory, $cpus); -} - -sub build_llvm -{ - #my $extra_svn_options = $debug ? "" : "--quiet"; - # Make the llvm build directory - my $arch_idx = 0; - - # Calculate if the current source digest so we can compare it to each architecture - # build folder - my @llvm_md5_strings; - foreach my $repo (@llvm_repositories) - { - if (-d "$repo/.svn") - { - push(@llvm_md5_strings, `cd '$repo'; svn info`); - push(@llvm_md5_strings, `cd '$repo'; svn diff`); - } - elsif (-d "$repo/.git") - { - push(@llvm_md5_strings, `cd '$repo'; git branch -v`); - push(@llvm_md5_strings, `cd '$repo'; git diff`); - } - } - - # open my $md5_data_file, '>', "/tmp/a.txt" or die "Can't open $! for writing...\n"; - # foreach my $md5_string (@llvm_md5_strings) - # { - # print $md5_data_file $md5_string; - # } - # close ($md5_data_file); - - #print "LLVM MD5 will be generated from:\n"; - #print @llvm_md5_strings; - my $llvm_hex_digest = md5_hex(@llvm_md5_strings); - my $did_make = 0; - - #print "llvm MD5: $llvm_hex_digest\n"; - - my @archive_dirs; - - foreach my $arch (@archs) - { - my $llvm_dstroot_arch = "${llvm_dstroot}/${arch}"; - - # if the arch destination root exists we have already built it - my $do_configure = 0; - my $do_make = 0; - my $is_arm = $arch =~ /^arm/; - my $save_arch_digest = 1; - my $arch_digest_file = "$llvm_dstroot_arch/md5"; - my $llvm_dstroot_arch_archive_dir = "$llvm_dstroot_arch/$llvm_configuration/lib"; - - push @archive_dirs, $llvm_dstroot_arch_archive_dir; - - print "LLVM architecture root for ${arch} exists at '$llvm_dstroot_arch'..."; - if (-e $llvm_dstroot_arch) - { - print "YES\n"; - $do_configure = !-e "$llvm_dstroot_arch/config.log"; - - my @archive_modtimes; - if ($do_make == 0) - { - if (-e $arch_digest_file) - { - my $arch_hex_digest = read_file($arch_digest_file); - if ($arch_hex_digest eq $llvm_hex_digest) - { - # No sources have been changed or updated - $save_arch_digest = 0; - } - else - { - # Sources have changed, or svn has been updated - print "Sources have changed, rebuilding...\n"; - $do_make = 1; - } - } - else - { - # No MD5 digest, we need to make - print "Missing MD5 digest file '$arch_digest_file', rebuilding...\n"; - $do_make = 1; - } - - if ($do_make == 0) - { - if (-e $archive_filelist_file) - { - # the final archive exists, check the modification times on all .a files that - # make the final archive to make sure we don't need to rebuild - my $archive_filelist_file_modtime = (stat($archive_filelist_file))[9]; - - our @archive_files = glob "$llvm_dstroot_arch_archive_dir/*.a"; - - for my $llvm_lib (@archive_files) - { - if (-e $llvm_lib) - { - if ($archive_filelist_file_modtime < (stat($llvm_lib))[9]) - { - print "'$llvm_dstroot_arch/$llvm_lib' is newer than '$archive_filelist_file', rebuilding...\n"; - $do_make = 1; - last; - } - } - } - } - else - { - $do_make = 1; - } - } - } - } - else - { - print "NO\n"; - do_command ("mkdir -p '$llvm_dstroot_arch'", "making llvm build directory '$llvm_dstroot_arch'", 1); - $do_configure = 1; - $do_make = 1; - - if ($is_arm) - { - my $llvm_dstroot_arch_bin = "${llvm_dstroot_arch}/bin"; - if (!-d $llvm_dstroot_arch_bin) - { - do_command ("mkdir -p '$llvm_dstroot_arch_bin'", "making llvm build arch bin directory '$llvm_dstroot_arch_bin'", 1); - my @tools = ("ar", "nm", "strip", "lipo", "ld", "as"); - my $script_mode = 0755; - my $prog; - for $prog (@tools) - { - chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`); - symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}"); - my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}"; - open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n"; - print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' \"\$\@\"\n"; - close (SCRIPT); - chmod($script_mode, $script_prog_path); - } - # Tools that must have the "-arch" and "-sysroot" specified - my @arch_sysroot_tools = ("clang", "clang++", "gcc", "g++"); - for $prog (@arch_sysroot_tools) - { - chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`); - symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}"); - my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}"; - open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n"; - print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' -arch ${arch} -isysroot '$ENV{SDKROOT}' \"\$\@\"\n"; - close (SCRIPT); - chmod($script_mode, $script_prog_path); - } - my $new_path = "$original_env_path:$llvm_dstroot_arch_bin"; - print "Setting new environment PATH = '$new_path'\n"; - $ENV{PATH} = $new_path; - } - } - } - - if ($save_arch_digest) - { - write_file($arch_digest_file, \$llvm_hex_digest); - } - - if ($do_configure) - { - # Build llvm and clang - print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n"; - my $lldb_configuration_options = "--enable-targets=x86_64,arm,arm64 $common_configure_options $llvm_config_href->{configure_options}"; - - # We're configuring llvm/clang with --enable-cxx11 and --enable-libcpp but llvm/configure doesn't - # pick up the right C++ standard library. If we have a MACOSX_DEPLOYMENT_TARGET of 10.7 or 10.8 - # (or are using actually building on those releases), we need to specify "-stdlib=libc++" at link - # time or llvm/configure will not see <atomic> as available and error out (v. llvm r199313). - $ENV{LDFLAGS} = $ENV{LDFLAGS} . " -stdlib=libc++"; - - if ($is_arm) - { - $lldb_configuration_options .= " --host=arm-apple-darwin${os_release} --target=arm-apple-darwin${os_release} --build=i686-apple-darwin${os_release} --program-prefix=\"\""; - } - else - { - $lldb_configuration_options .= " --build=$arch-apple-darwin${os_release}"; - } - if ($is_arm) - { - # Unset "SDKROOT" for ARM builds - do_command ("cd '$llvm_dstroot_arch' && unset SDKROOT && '$llvm_srcroot/configure' $lldb_configuration_options", - "configuring llvm build", 1); - } - else - { - do_command ("cd '$llvm_dstroot_arch' && '$llvm_srcroot/configure' $lldb_configuration_options", - "configuring llvm build", 1); - } - } - - if ($do_make) - { - $did_make = 1; - # Build llvm and clang - my $num_cpus = parallel_guess(); - print "Building clang using $num_cpus cpus ($arch)...\n"; - my $extra_make_flags = ''; - if ($is_arm) - { - $extra_make_flags = "UNIVERSAL=1 UNIVERSAL_ARCH=${arch} UNIVERSAL_SDK_PATH='$ENV{SDKROOT}' SDKROOT="; - } - do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus clang-only VERBOSE=1 $llvm_config_href->{make_options} PROJECT_NAME='llvm' $extra_make_flags", "making llvm and clang", 1); - do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus tools-only VERBOSE=1 $llvm_config_href->{make_options} PROJECT_NAME='llvm' $extra_make_flags EDIS_VERSION=1", "making libedis", 1); - - } - - ++$arch_idx; - } - - # If we did any makes update the archive filenames file with any .a files from - # each architectures "lib" folder... - if ($did_make) - { - open my $fh, '>', $archive_filelist_file or die "Can't open $! for writing...\n"; - foreach my $archive_dir (@archive_dirs) - { - append_all_archive_files ($archive_dir, $fh); - } - close($fh); - } -} - -#---------------------------------------------------------------------- -# quote the path if needed and realpath it if the -r option was -# specified -#---------------------------------------------------------------------- -sub finalize_path -{ - my $path = shift; - # Realpath all paths that don't start with "/" - $path =~ /^[^\/]/ and $path = abs_path($path); - - # Quote the path if asked to, or if there are special shell characters - # in the path name - my $has_double_quotes = $path =~ /["]/; - my $has_single_quotes = $path =~ /[']/; - my $needs_quotes = $path =~ /[ \$\&\*'"]/; - if ($needs_quotes) - { - # escape and double quotes in the path - $has_double_quotes and $path =~ s/"/\\"/g; - $path = "\"$path\""; - } - return $path; -} - -sub do_command -{ - my $cmd = shift; - my $description = @_ ? shift : "command"; - my $die_on_fail = @_ ? shift : undef; - $debug and print "% $cmd\n"; - system ($cmd); - if ($? == -1) - { - $debug and printf ("error: %s failed to execute: $!\n", $description); - $die_on_fail and $? and exit(1); - return $?; - } - elsif ($? & 127) - { - $debug and printf("error: %s child died with signal %d, %s coredump\n", - $description, - ($? & 127), - ($? & 128) ? 'with' : 'without'); - $die_on_fail and $? and exit(1); - return $?; - } - else - { - my $exit = $? >> 8; - if ($exit) - { - $debug and printf("error: %s child exited with value %d\n", $description, $exit); - $die_on_fail and exit(1); - } - return $exit; - } -} - -sub append_all_archive_files -{ - my $archive_dir = shift; - my $fh = shift; - - our @archive_files = glob "$archive_dir/*.a"; - for my $archive_fullpath (@archive_files) - { - print $fh "$archive_fullpath\n"; - } -} - -build_llvm(); diff --git a/scripts/finishSwigWrapperClasses.py b/scripts/finishSwigWrapperClasses.py index 8d7d19ef1bdfc..cce160df68e7a 100644 --- a/scripts/finishSwigWrapperClasses.py +++ b/scripts/finishSwigWrapperClasses.py @@ -72,6 +72,8 @@ Args: -h (optional) Print help information on this program.\n\ be installed. Where non-Darwin systems want to put\n\ the .py and .so files so that Python can find them\n\ automatically. Python install directory.\n\ + --lldbLibDir (optional) The name of the directory containing liblldb.so.\n\ + \"lib\" by default.\n\ --cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\ used to determine where the bin and lib directories are \n\ created for a Windows build.\n\ @@ -80,7 +82,7 @@ Args: -h (optional) Print help information on this program.\n\ \n\ Usage:\n\ finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath\n\ - --cfgBldDir=ADirPath --prefix=ADirPath -m -d\n\ + --cfgBldDir=ADirPath --prefix=ADirPath --lldbLibDir=ADirPath -m -d\n\ \n\ " #TAG_PROGRAM_HELP_INFO @@ -158,7 +160,7 @@ def validate_arguments(vArgv): nResult = 0 strListArgs = "hdm" # Format "hiox:" = -h -i -o -x <arg> listLongArgs = ["srcRoot=", "targetDir=", "cfgBldDir=", "prefix=", "cmakeBuildConfiguration=", - "argsFile"] + "lldbLibDir=", "argsFile"] dictArgReq = { "-h": "o", # o = optional, m = mandatory "-d": "o", "-m": "o", @@ -167,6 +169,7 @@ def validate_arguments(vArgv): "--cfgBldDir": "o", "--prefix": "o", "--cmakeBuildConfiguration": "o", + "--lldbLibDir": "o", "--argsFile": "o" } # Check for mandatory parameters @@ -337,11 +340,13 @@ def main(vArgv): --cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\ used to determine where the bin and lib directories are \n\ created for a Windows build.\n\ + --lldbLibDir= The name of the directory containing liblldb.so. + (optional) "lib" by default. --argsFile= The args are read from a file instead of the command line. Other command line args are ignored. Usage: finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath - --cfgBldDir=ADirPath --prefix=ADirPath -m -d + --cfgBldDir=ADirPath --prefix=ADirPath --lldbLibDir=ADirPath -m -d Results: 0 Success -1 Error - invalid parameters passed. diff --git a/scripts/interface/SBCommandReturnObject.i b/scripts/interface/SBCommandReturnObject.i index 5ade97bebfec4..ae32b79b5834c 100644 --- a/scripts/interface/SBCommandReturnObject.i +++ b/scripts/interface/SBCommandReturnObject.i @@ -84,11 +84,17 @@ public: bool GetDescription (lldb::SBStream &description); - void - SetImmediateOutputFile (FILE *fh); - - void - SetImmediateErrorFile (FILE *fh); + + // wrapping here so that lldb takes ownership of the + // new FILE* created inside of the swig interface + %extend { + void SetImmediateOutputFile(FILE *fh) { + self->SetImmediateOutputFile(fh, true); + } + void SetImmediateErrorFile(FILE *fh) { + self->SetImmediateErrorFile(fh, true); + } + } void PutCString(const char* string, int len); diff --git a/scripts/interface/SBDebugger.i b/scripts/interface/SBDebugger.i index 89b2882aeb91e..db774d350e9c5 100644 --- a/scripts/interface/SBDebugger.i +++ b/scripts/interface/SBDebugger.i @@ -105,6 +105,16 @@ if target: else: print('Unexpected process state: %s, killing process...' % debugger.StateAsCString (state)) process.Kill() + +Sometimes you need to create an empty target that will get filled in later. The most common use for this +is to attach to a process by name or pid where you don't know the executable up front. The most convenient way +to do this is: + +target = debugger.CreateTarget('') +error = lldb.SBError() +process = target.AttachToProcessWithName(debugger.GetListener(), 'PROCESS_NAME', False, error) + +or the equivalent arguments for AttachToProcessWithID. ") SBDebugger; class SBDebugger { diff --git a/scripts/interface/SBExpressionOptions.i b/scripts/interface/SBExpressionOptions.i index 1f423cf47e425..cb61dd9d9632c 100644 --- a/scripts/interface/SBExpressionOptions.i +++ b/scripts/interface/SBExpressionOptions.i @@ -118,6 +118,20 @@ public: %feature("docstring", "Sets the prefix to use for this expression. This prefix gets inserted after the 'target.expr-prefix' prefix contents, but before the wrapped expression function body.") SetPrefix; void SetPrefix (const char *prefix); + + %feature("docstring", "Sets whether to auto-apply fix-it hints to the expression being evaluated.") SetAutoApplyFixIts; + void + SetAutoApplyFixIts(bool b = true); + + %feature("docstring", "Gets whether to auto-apply fix-it hints to an expression.") GetAutoApplyFixIts; + bool + GetAutoApplyFixIts(); + + bool + GetTopLevel(); + + void + SetTopLevel(bool b = true); protected: diff --git a/scripts/interface/SBFileSpec.i b/scripts/interface/SBFileSpec.i index c153f2bd86f64..a0e5da21187df 100644 --- a/scripts/interface/SBFileSpec.i +++ b/scripts/interface/SBFileSpec.i @@ -72,7 +72,10 @@ public: bool GetDescription (lldb::SBStream &description) const; - + + void + AppendPathComponent (const char *file_or_directory); + %pythoncode %{ def __get_fullpath__(self): spec_dir = self.GetDirectory() diff --git a/scripts/interface/SBHostOS.i b/scripts/interface/SBHostOS.i index d9f42160bf09e..ed2e8b0477b1b 100644 --- a/scripts/interface/SBHostOS.i +++ b/scripts/interface/SBHostOS.i @@ -22,6 +22,9 @@ public: static lldb::SBFileSpec GetLLDBPath (lldb::PathType path_type); + static lldb::SBFileSpec + GetUserHomeDirectory (); + static void ThreadCreated (const char *name); diff --git a/scripts/interface/SBMemoryRegionInfo.i b/scripts/interface/SBMemoryRegionInfo.i new file mode 100644 index 0000000000000..d687708026189 --- /dev/null +++ b/scripts/interface/SBMemoryRegionInfo.i @@ -0,0 +1,58 @@ +//===-- SWIG Interface for SBMemoryRegionInfo -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +%feature("docstring", +"API clients can get information about memory regions in processes." +) SBMemoryRegionInfo; + +class SBMemoryRegionInfo +{ +public: + + SBMemoryRegionInfo (); + + SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs); + + ~SBMemoryRegionInfo (); + + void + Clear(); + + lldb::addr_t + GetRegionBase (); + + lldb::addr_t + GetRegionEnd (); + + bool + IsReadable (); + + bool + IsWritable (); + + bool + IsExecutable (); + + bool + IsMapped (); + + bool + operator == (const lldb::SBMemoryRegionInfo &rhs) const; + + bool + operator != (const lldb::SBMemoryRegionInfo &rhs) const; + + bool + GetDescription (lldb::SBStream &description); + +}; + +} // namespace lldb diff --git a/scripts/interface/SBMemoryRegionInfoList.i b/scripts/interface/SBMemoryRegionInfoList.i new file mode 100644 index 0000000000000..f462411455403 --- /dev/null +++ b/scripts/interface/SBMemoryRegionInfoList.i @@ -0,0 +1,38 @@ +//===-- SBMemoryRegionInfoList.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBMemoryRegionInfoList +{ +public: + + SBMemoryRegionInfoList (); + + SBMemoryRegionInfoList (const lldb::SBMemoryRegionInfoList &rhs); + + ~SBMemoryRegionInfoList (); + + uint32_t + GetSize () const; + + bool + GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_info); + + void + Append (lldb::SBMemoryRegionInfo ®ion); + + void + Append (lldb::SBMemoryRegionInfoList ®ion_list); + + void + Clear (); +}; + +} // namespace lldb diff --git a/scripts/interface/SBProcess.i b/scripts/interface/SBProcess.i index 1571ebc4cb68d..d9de9d0876853 100644 --- a/scripts/interface/SBProcess.i +++ b/scripts/interface/SBProcess.i @@ -296,7 +296,7 @@ public: ") ReadCStringFromMemory; size_t - ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error); + ReadCStringFromMemory (addr_t addr, void *char_buf, size_t size, lldb::SBError &error); %feature("autodoc", " Reads an unsigned integer from memory given a byte size and an address. @@ -401,6 +401,12 @@ public: lldb::SBError SaveCore(const char *file_name); + lldb::SBError + GetMemoryRegionInfo(lldb::addr_t load_addr, lldb::SBMemoryRegionInfo ®ion_info); + + lldb::SBMemoryRegionInfoList + GetMemoryRegions(); + %pythoncode %{ def __get_is_alive__(self): '''Returns "True" if the process is currently alive, "False" otherwise''' @@ -422,7 +428,7 @@ public: return True return False - def __get_is_running__(self): + def __get_is_stopped__(self): '''Returns "True" if the process is currently stopped, "False" otherwise''' state = self.GetState() if state == eStateStopped or state == eStateCrashed or state == eStateSuspended: @@ -468,8 +474,8 @@ public: __swig_getmethods__["is_running"] = __get_is_running__ if _newclass: is_running = property(__get_is_running__, None, doc='''A read only property that returns a boolean value that indicates if this process is currently running.''') - __swig_getmethods__["is_stopped"] = __get_is_running__ - if _newclass: is_stopped = property(__get_is_running__, None, doc='''A read only property that returns a boolean value that indicates if this process is currently stopped.''') + __swig_getmethods__["is_stopped"] = __get_is_stopped__ + if _newclass: is_stopped = property(__get_is_stopped__, None, doc='''A read only property that returns a boolean value that indicates if this process is currently stopped.''') __swig_getmethods__["id"] = GetProcessID if _newclass: id = property(GetProcessID, None, doc='''A read only property that returns the process ID as an integer.''') diff --git a/scripts/interface/SBTarget.i b/scripts/interface/SBTarget.i index 74e470d4b3fa1..6198c35fbd7b8 100644 --- a/scripts/interface/SBTarget.i +++ b/scripts/interface/SBTarget.i @@ -586,6 +586,9 @@ public: BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line); lldb::SBBreakpoint + BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset); + + lldb::SBBreakpoint BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL); lldb::SBBreakpoint @@ -601,18 +604,59 @@ public: const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list); +%typemap(in) (const char **symbol_name, uint32_t num_names) { + using namespace lldb_private; + /* Check if is a list */ + if (PythonList::Check($input)) { + PythonList list(PyRefType::Borrowed, $input); + $2 = list.GetSize(); + int i = 0; + $1 = (char**)malloc(($2+1)*sizeof(char*)); + for (i = 0; i < $2; i++) { + PythonString py_str = list.GetItemAtIndex(i).AsType<PythonString>(); + if (!py_str.IsAllocated()) { + PyErr_SetString(PyExc_TypeError,"list must contain strings and blubby"); + free($1); + return nullptr; + } + + $1[i] = const_cast<char*>(py_str.GetString().data()); + } + $1[i] = 0; + } else if ($input == Py_None) { + $1 = NULL; + } else { + PyErr_SetString(PyExc_TypeError,"not a list"); + return NULL; + } +} + +//%typecheck(SWIG_TYPECHECK_STRING_ARRAY) (const char *symbol_name[], uint32_t num_names) { +// $1 = 1; +// $2 = 1; +//} + + lldb::SBBreakpoint + BreakpointCreateByNames (const char **symbol_name, + uint32_t num_names, + uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + lldb::SBBreakpoint - BreakpointCreateByNames (const char *symbol_name[], + BreakpointCreateByNames (const char **symbol_name, uint32_t num_names, uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + lldb::LanguageType symbol_language, const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint - BreakpointCreateByNames (const char *symbol_name[], + BreakpointCreateByNames (const char **symbol_name, uint32_t num_names, uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits lldb::LanguageType symbol_language, + lldb::addr_t offset, const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list); @@ -632,6 +676,12 @@ public: BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpecList &module_list, const lldb::SBFileSpecList &file_list); lldb::SBBreakpoint + BreakpointCreateBySourceRegex (const char *source_regex, + const SBFileSpecList &module_list, + const SBFileSpecList &source_file, + const SBStringList &func_names); + + lldb::SBBreakpoint BreakpointCreateForException (lldb::LanguageType language, bool catch_bp, bool throw_bp); diff --git a/scripts/interface/SBThread.i b/scripts/interface/SBThread.i index f2b27565d4899..082805f42fd06 100644 --- a/scripts/interface/SBThread.i +++ b/scripts/interface/SBThread.i @@ -118,6 +118,15 @@ public: ") GetStopReasonExtendedInfoAsJSON; bool GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream); + + %feature("autodoc", " + Returns a collection of historical stack traces that are significant to the + current stop reason. Used by ThreadSanitizer, where we provide various stack + traces that were involved in a data race or other type of detected issue. + ") GetStopReasonExtendedBacktraces; + SBThreadCollection + GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type); + %feature("autodoc", " Pass only an (int)length and expect to get a Python string describing the @@ -206,6 +215,17 @@ public: void StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); + %feature("autodoc", " + Step the current thread from the current source line to the line given by end_line, stopping if + the thread steps into the function given by target_name. If target_name is None, then stepping will stop + in any of the places we would normally stop. + ") StepInto; + void + StepInto (const char *target_name, + uint32_t end_line, + SBError &error, + lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); + void StepOut (); @@ -239,6 +259,14 @@ public: SBError ReturnFromFrame (SBFrame &frame, SBValue &return_value); + %feature("autodoc", " + Unwind the stack frames from the innermost expression evaluation. + This API is equivalent to 'thread return -x'. + ") UnwindInnermostExpression; + + SBError + UnwindInnermostExpression(); + %feature("docstring", " //-------------------------------------------------------------------------- /// LLDB currently supports process centric debugging which means when any diff --git a/scripts/interface/SBValue.i b/scripts/interface/SBValue.i index 5049fd05794d5..ef9fe3c748516 100644 --- a/scripts/interface/SBValue.i +++ b/scripts/interface/SBValue.i @@ -157,6 +157,12 @@ public: bool IsSynthetic (); + + bool + IsSyntheticChildrenGenerated (); + + void + SetSyntheticChildrenGenerated (bool); const char * GetLocation (); @@ -533,6 +539,23 @@ public: __swig_getmethods__["path"] = get_expr_path if _newclass: path = property(get_expr_path, None, doc='''A read only property that returns the expression path that one can use to reach this value in an expression.''') + + def synthetic_child_from_expression(self, name, expr, options=None): + if options is None: options = lldb.SBExpressionOptions() + child = self.CreateValueFromExpression(name, expr, options) + child.SetSyntheticChildrenGenerated(True) + return child + + def synthetic_child_from_data(self, name, data, type): + child = self.CreateValueFromData(name, data, type) + child.SetSyntheticChildrenGenerated(True) + return child + + def synthetic_child_from_address(self, name, addr, type): + child = self.CreateValueFromAddress(name, addr, type) + child.SetSyntheticChildrenGenerated(True) + return child + %} }; diff --git a/scripts/lldb.swig b/scripts/lldb.swig index 1d333540728cc..ee34da30fc167 100644 --- a/scripts/lldb.swig +++ b/scripts/lldb.swig @@ -83,6 +83,8 @@ import six #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBListener.h" +#include "lldb/API/SBMemoryRegionInfo.h" +#include "lldb/API/SBMemoryRegionInfoList.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" @@ -163,6 +165,8 @@ import six %include "./interface/SBLaunchInfo.i" %include "./interface/SBLineEntry.i" %include "./interface/SBListener.i" +%include "./interface/SBMemoryRegionInfo.i" +%include "./interface/SBMemoryRegionInfoList.i" %include "./interface/SBModule.i" %include "./interface/SBModuleSpec.i" %include "./interface/SBPlatform.i" diff --git a/scripts/prepare_bindings.py b/scripts/prepare_bindings.py index 3165f232e5eca..6d70f5bf421ba 100755 --- a/scripts/prepare_bindings.py +++ b/scripts/prepare_bindings.py @@ -152,6 +152,11 @@ def process_args(args): "Specifies the build dir where the language binding " "should be placed")) + parser.add_argument( + "--target-platform", + help=( + "Specifies the platform we are building for." + "Should be the same as what platform.system() returns.")) # Process args. options = parser.parse_args(args) diff --git a/scripts/use_lldb_suite.py b/scripts/use_lldb_suite.py index 63a098cea220f..f3e358af143bf 100644 --- a/scripts/use_lldb_suite.py +++ b/scripts/use_lldb_suite.py @@ -17,6 +17,9 @@ def find_lldb_root(): lldb_root = find_lldb_root() if lldb_root is not None: import imp - module = imp.find_module("use_lldb_suite_root", [lldb_root]) - if module is not None: - imp.load_module("use_lldb_suite_root", *module) + fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root]) + try: + imp.load_module("use_lldb_suite_root", fp, pathname, desc) + finally: + if fp: + fp.close() |