diff options
1612 files changed, 59348 insertions, 32458 deletions
diff --git a/.arcconfig b/.arcconfig index eb16f4cea996..e8fa2aaf0bd4 100644 --- a/.arcconfig +++ b/.arcconfig @@ -1,4 +1,4 @@ { "project_id" : "lldb", - "conduit_uri" : "http://reviews.llvm.org/" + "conduit_uri" : "https://reviews.llvm.org/" } diff --git a/.gitignore b/.gitignore index 06cb7040f33b..5ad21731aab5 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ DerivedData/ build/ pyproj/ llvm-build/ +ninja/ *xcuserdata test/20* __pycache__/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 82dd78c125a5..e092e0bd4abc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.4.3) include(cmake/modules/LLDBStandalone.cmake) include(cmake/modules/LLDBConfig.cmake) @@ -31,7 +31,7 @@ add_subdirectory(lit) if (NOT LLDB_DISABLE_PYTHON) # Add a Post-Build Event to copy over Python files and create the symlink to liblldb.so for the Python API(hardlink on Windows) add_custom_target( finish_swig ALL - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--prefix=${CMAKE_BINARY_DIR}" "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}" -m + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts" "--prefix=${CMAKE_BINARY_DIR}" "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}" "--lldbLibDir=lib${LLVM_LIBDIR_SUFFIX}" -m DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scripts/lldb.py COMMENT "Python script sym-linking LLDB Python API") diff --git a/Makefile b/Makefile deleted file mode 100644 index e794ae8e9a86..000000000000 --- a/Makefile +++ /dev/null @@ -1,112 +0,0 @@ -##===- Makefile --------------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -# If LLDB_LEVEL is not set, then we are the top-level Makefile. Otherwise, we -# are being included from a subdirectory makefile. - -ifndef LLDB_LEVEL - - -IS_TOP_LEVEL := 1 -LLDB_LEVEL := . -DIRS := include scripts source lib tools - -PARALLEL_DIRS := -endif - -### -# Common Makefile code, shared by all LLDB Makefiles. - -# Set LLVM source root level. -LEVEL := $(LLDB_LEVEL)/../.. - -# Include LLVM common makefile. -include $(LEVEL)/Makefile.common - -# Set common LLDB build flags. -CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/include -CPP.Flags += -I$(PROJ_OBJ_DIR)/$(LLDB_LEVEL)/include -CPP.Flags += -I$(LLVM_SRC_ROOT)/tools/clang/include -CPP.Flags += -I$(LLVM_OBJ_ROOT)/tools/clang/include -CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source -CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Utility -CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Utility -CPP.Flags += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/POSIX - -# Disable python and curses on mingw build -ifeq ($(HOST_OS),MingW) -CXXFLAGS += -DLLDB_DISABLE_PYTHON -DLLDB_DISABLE_CURSES -endif - -ifeq (,$(findstring -DLLDB_DISABLE_PYTHON,$(CXXFLAGS))) -# Set Python include directory -PYTHON_CONFIG?= python-config -PYTHON_INC_DIR = $(shell $(PYTHON_CONFIG) --includes) -CPP.Flags += $(PYTHON_INC_DIR) -endif - -ifeq ($(HOST_OS),Darwin) -CPP.Flags += $(subst -I,-I$(SDKROOT),$(PYTHON_INC_DIR)) -CPP.Flags += -F$(SDKROOT)/System/Library/Frameworks -CPP.Flags += -F$(SDKROOT)/System/Library/PrivateFrameworks -CPP.Flags += -I$(SDKROOT)/usr/include/libxml2 -endif -ifdef LLDB_VENDOR -CPP.Flags += -DLLDB_VENDOR='"$(LLDB_VENDOR) "' -endif - -# If building on a 32-bit system, make sure off_t can store offsets > 2GB -ifneq "$(HOST_ARCH)" "x86_64" -CPP.Flags += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -endif - -# Disable -fstrict-aliasing. Darwin disables it by default (and LLVM doesn't -# work with it enabled with GCC), Clang/llvm-gc don't support it yet, and newer -# GCC's have false positive warnings with it on Linux (which prove a pain to -# fix). For example: -# http://gcc.gnu.org/PR41874 -# http://gcc.gnu.org/PR41838 -# -# We can revisit this when LLVM/Clang support it. -CXX.Flags += -fno-strict-aliasing - -# Do not warn about pragmas. In particular, we are looking to ignore the -# "#pragma mark" construct which GCC warns about on platforms other than Darwin. -EXTRA_OPTIONS += -Wno-unknown-pragmas - -# Drop -Wsign-compare, which we are not currently clean with. -EXTRA_OPTIONS += -Wno-sign-compare - -### -# LLDB Top Level specific stuff. - -ifeq ($(IS_TOP_LEVEL),1) - -test:: - @ $(MAKE) -C test - -#report:: -# @ $(MAKE) -C test report - -#clean:: -# @ $(MAKE) -C test clean - -tags:: - $(Verb) etags `find . -type f -name '*.h' -or -name '*.cpp' | \ - grep -v /lib/Headers | grep -v /test/` - -cscope.files: - find tools lib include -name '*.cpp' \ - -or -name '*.def' \ - -or -name '*.td' \ - -or -name '*.h' > cscope.files - -.PHONY: test report clean cscope.files - -endif diff --git a/cmake/LLDBDependencies.cmake b/cmake/LLDBDependencies.cmake index 073fa28b2528..67d110e0a544 100644 --- a/cmake/LLDBDependencies.cmake +++ b/cmake/LLDBDependencies.cmake @@ -15,6 +15,7 @@ set( LLDB_USED_LIBS # Plugins lldbPluginDisassemblerLLVM lldbPluginSymbolFileDWARF + lldbPluginSymbolFilePDB lldbPluginSymbolFileSymtab lldbPluginDynamicLoaderStatic lldbPluginDynamicLoaderPosixDYLD @@ -23,6 +24,7 @@ set( LLDB_USED_LIBS lldbPluginCPlusPlusLanguage lldbPluginGoLanguage + lldbPluginJavaLanguage lldbPluginObjCLanguage lldbPluginObjCPlusPlusLanguage @@ -50,6 +52,7 @@ set( LLDB_USED_LIBS lldbPluginAppleObjCRuntime lldbPluginRenderScriptRuntime lldbPluginLanguageRuntimeGo + lldbPluginLanguageRuntimeJava lldbPluginCXXItaniumABI lldbPluginABIMacOSX_arm lldbPluginABIMacOSX_arm64 @@ -63,6 +66,7 @@ set( LLDB_USED_LIBS lldbPluginABISysV_ppc64 lldbPluginABISysV_mips lldbPluginABISysV_mips64 + lldbPluginABISysV_s390x lldbPluginInstructionARM lldbPluginInstructionARM64 lldbPluginInstructionMIPS @@ -72,6 +76,7 @@ set( LLDB_USED_LIBS lldbPluginOSPython lldbPluginMemoryHistoryASan lldbPluginInstrumentationRuntimeAddressSanitizer + lldbPluginInstrumentationRuntimeThreadSanitizer lldbPluginSystemRuntimeMacOSX lldbPluginProcessElfCore lldbPluginJITLoaderGDB @@ -152,6 +157,11 @@ if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows" AND NOT __ANDROID_NDK__) endif() endif() endif() + +if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB ) + list(APPEND LLDB_SYSTEM_LIBS atomic) +endif() + # On FreeBSD/NetBSD backtrace() is provided by libexecinfo, not libc. if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD") list(APPEND LLDB_SYSTEM_LIBS execinfo) @@ -172,7 +182,7 @@ if (LLVM_BUILD_STATIC) endif() endif() -set( LLVM_LINK_COMPONENTS +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} interpreter asmparser @@ -190,6 +200,7 @@ set( LLVM_LINK_COMPONENTS runtimedyld option support + coverage ) if ( NOT LLDB_DISABLE_PYTHON ) diff --git a/cmake/modules/AddLLDB.cmake b/cmake/modules/AddLLDB.cmake index 75c522f6522e..af16050769ad 100644 --- a/cmake/modules/AddLLDB.cmake +++ b/cmake/modules/AddLLDB.cmake @@ -68,7 +68,7 @@ macro(add_lldb_library name) target_link_libraries(${name} ${cmake_2_8_12_PUBLIC} ${CLANG_USED_LIBS}) endif() endif() - llvm_config(${name} ${LLVM_LINK_COMPONENTS}) + llvm_config(${name} ${LLVM_LINK_COMPONENTS} ${LLVM_PRIVATE_LINK_COMPONENTS}) if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "liblldb") if (PARAM_SHARED) diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake index f5247a269822..d0700b0c22e3 100644 --- a/cmake/modules/LLDBConfig.cmake +++ b/cmake/modules/LLDBConfig.cmake @@ -1,3 +1,5 @@ +include(CheckCXXSymbolExists) + set(LLDB_PROJECT_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) set(LLDB_SOURCE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/source") set(LLDB_INCLUDE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/include") @@ -245,6 +247,11 @@ if( MSVC ) ) endif() +# Use the Unicode (UTF-16) APIs by default on Win32 +if (CMAKE_SYSTEM_NAME MATCHES "Windows") + add_definitions( /D _UNICODE /D UNICODE ) +endif() + set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -331,28 +338,6 @@ if (HAVE_LIBDL) list(APPEND system_libs ${CMAKE_DL_LIBS}) endif() -if(LLDB_REQUIRES_EH) - set(LLDB_REQUIRES_RTTI ON) -else() - if(LLVM_COMPILER_IS_GCC_COMPATIBLE) - set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} -fno-exceptions") - elseif(MSVC) - add_definitions( -D_HAS_EXCEPTIONS=0 ) - set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} /EHs-c-") - endif() -endif() - -# Disable RTTI by default -if(NOT LLDB_REQUIRES_RTTI) - if (LLVM_COMPILER_IS_GCC_COMPATIBLE) - set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} -fno-rtti") - elseif(MSVC) - set(LLDB_COMPILE_FLAGS "${LLDB_COMPILE_FLAGS} /GR-") - endif() -endif() - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLDB_COMPILE_FLAGS}") - if (CMAKE_SYSTEM_NAME MATCHES "Linux") # Check for syscall used by lldb-server on linux. # If these are not found, it will fall back to ptrace (slow) for memory reads. @@ -410,3 +395,25 @@ if (NOT LLDB_DISABLE_CURSES) list(APPEND system_libs ${CURSES_LIBRARIES}) include_directories(${CURSES_INCLUDE_DIR}) endif () + +check_cxx_symbol_exists("__GLIBCXX__" "string" LLDB_USING_LIBSTDCXX) +if(LLDB_USING_LIBSTDCXX) + # There doesn't seem to be an easy way to check the library version. Instead, we rely on the + # fact that std::set did not have the allocator constructor available until version 4.9 + check_cxx_source_compiles(" + #include <set> + std::set<int> s = std::set<int>(std::allocator<int>()); + int main() { return 0; }" + LLDB_USING_LIBSTDCXX_4_9) + if (NOT LLDB_USING_LIBSTDCXX_4_9 AND NOT LLVM_ENABLE_EH) + message(WARNING + "You appear to be linking to libstdc++ version lesser than 4.9 without exceptions " + "enabled. These versions of the library have an issue, which causes occasional " + "lldb crashes. See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59656> for " + "details. Possible courses of action are:\n" + "- use libstdc++ version 4.9 or newer\n" + "- use libc++ (via LLVM_ENABLE_LIBCXX)\n" + "- enable exceptions (via LLVM_ENABLE_EH)\n" + "- ignore this warning and accept occasional instability") + endif() +endif() diff --git a/cmake/modules/LLDBStandalone.cmake b/cmake/modules/LLDBStandalone.cmake index d3955f1cdf6b..d849602c57b6 100644 --- a/cmake/modules/LLDBStandalone.cmake +++ b/cmake/modules/LLDBStandalone.cmake @@ -2,64 +2,91 @@ # standalone project, using LLVM as an external library: if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) project(lldb) - cmake_minimum_required(VERSION 2.8) + cmake_minimum_required(VERSION 2.8.12.2) - option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) + if (POLICY CMP0022) + cmake_policy(SET CMP0022 NEW) # automatic when 2.8.12 is required + endif() - set(LLDB_PATH_TO_LLVM_SOURCE "" CACHE PATH - "Path to LLVM source code. Not necessary if using an installed LLVM.") - set(LLDB_PATH_TO_LLVM_BUILD "" CACHE PATH - "Path to the directory where LLVM was built or installed.") + option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) - set(LLDB_PATH_TO_CLANG_SOURCE "" CACHE PATH - "Path to Clang source code. Not necessary if using an installed Clang.") - set(LLDB_PATH_TO_CLANG_BUILD "" CACHE PATH - "Path to the directory where Clang was built or installed.") + # Rely on llvm-config. + set(CONFIG_OUTPUT) + find_program(LLVM_CONFIG "llvm-config") + if(LLVM_CONFIG) + message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}") + set(CONFIG_COMMAND ${LLVM_CONFIG} + "--assertion-mode" + "--bindir" + "--libdir" + "--includedir" + "--prefix" + "--src-root") + execute_process( + COMMAND ${CONFIG_COMMAND} + RESULT_VARIABLE HAD_ERROR + OUTPUT_VARIABLE CONFIG_OUTPUT + ) + if(NOT HAD_ERROR) + string(REGEX REPLACE + "[ \t]*[\r\n]+[ \t]*" ";" + CONFIG_OUTPUT ${CONFIG_OUTPUT}) - if (LLDB_PATH_TO_LLVM_SOURCE) - if (NOT EXISTS "${LLDB_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake") - message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_SOURCE to the root " - "directory of LLVM source code.") else() - get_filename_component(LLVM_MAIN_SRC_DIR ${LLDB_PATH_TO_LLVM_SOURCE} - ABSOLUTE) - set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include") - list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") + string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") + message(STATUS "${CONFIG_COMMAND_STR}") + message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") endif() + else() + message(FATAL_ERROR "llvm-config not found -- ${LLVM_CONFIG}") endif() - if (LLDB_PATH_TO_CLANG_SOURCE) - get_filename_component(CLANG_MAIN_SRC_DIR ${LLDB_PATH_TO_CLANG_SOURCE} - ABSOLUTE) - set(CLANG_MAIN_INCLUDE_DIR "${CLANG_MAIN_SRC_DIR}/include") - endif() - - list(APPEND CMAKE_MODULE_PATH "${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake") - - if (LLDB_PATH_TO_LLVM_BUILD) - get_filename_component(PATH_TO_LLVM_BUILD ${LLDB_PATH_TO_LLVM_BUILD} - ABSOLUTE) - else() - message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_BUILD to the root " - "directory of LLVM build or install site.") + list(GET CONFIG_OUTPUT 0 ENABLE_ASSERTIONS) + list(GET CONFIG_OUTPUT 1 TOOLS_BINARY_DIR) + list(GET CONFIG_OUTPUT 2 LIBRARY_DIR) + list(GET CONFIG_OUTPUT 3 INCLUDE_DIR) + list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT) + list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR) + + if(NOT MSVC_IDE) + set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} + CACHE BOOL "Enable assertions") + # Assertions should follow llvm-config's. + mark_as_advanced(LLVM_ENABLE_ASSERTIONS) endif() - if (LLDB_PATH_TO_CLANG_BUILD) - get_filename_component(PATH_TO_CLANG_BUILD ${LLDB_PATH_TO_CLANG_BUILD} - ABSOLUTE) + set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin") + set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib") + set(LLVM_MAIN_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") + set(LLVM_DIR ${LLVM_OBJ_ROOT}/cmake/modules/CMakeFiles CACHE PATH "Path to LLVM build tree CMake files") + set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") + set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") + + find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} + NO_DEFAULT_PATH) + + set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") + set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake") + if(EXISTS ${LLVMCONFIG_FILE}) + list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") + include(${LLVMCONFIG_FILE}) else() - message(FATAL_ERROR "Please set LLDB_PATH_TO_CLANG_BUILD to the root " - "directory of Clang build or install site.") + message(FATAL_ERROR "Not found: ${LLVMCONFIG_FILE}") endif() - - # These variables are used by add_llvm_library. + # They are used as destination of target generators. set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) - set(LLVM_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + if(WIN32 OR CYGWIN) + # DLL platform -- put DLLs into bin. + set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) + else() + set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + endif() include(AddLLVM) include(HandleLLVMOptions) + include(CheckAtomic) if (PYTHON_EXECUTABLE STREQUAL "") set(Python_ADDITIONAL_VERSIONS 3.5 3.4 3.3 3.2 3.1 3.0 2.7 2.6 2.5) @@ -72,10 +99,12 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) else() message("-- Found PythonInterp: ${PYTHON_EXECUTABLE}") endif() + # Import CMake library targets from LLVM and Clang. - include("${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake") - if (EXISTS "${LLDB_PATH_TO_CLANG_BUILD}/share/clang/cmake/ClangConfig.cmake") - include("${LLDB_PATH_TO_CLANG_BUILD}/share/clang/cmake/ClangConfig.cmake") + include("${LLVM_OBJ_ROOT}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm/LLVMConfig.cmake") + # cmake/clang/ClangConfig.cmake is not created when LLVM and Cland are built together. + if (EXISTS "${LLVM_OBJ_ROOT}/lib${LLVM_LIBDIR_SUFFIX}/cmake/clang/ClangConfig.cmake") + include("${LLVM_OBJ_ROOT}/lib${LLVM_LIBDIR_SUFFIX}/cmake/clang/ClangConfig.cmake") endif() set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}") @@ -83,13 +112,19 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR}) set(CMAKE_INCLUDE_CURRENT_DIR ON) - include_directories("${PATH_TO_LLVM_BUILD}/include" - "${LLVM_MAIN_INCLUDE_DIR}" - "${PATH_TO_CLANG_BUILD}/include" - "${CLANG_MAIN_INCLUDE_DIR}" - "${CMAKE_CURRENT_SOURCE_DIR}/source") - link_directories("${PATH_TO_LLVM_BUILD}/lib${LLVM_LIBDIR_SUFFIX}" - "${PATH_TO_CLANG_BUILD}/lib${LLVM_LIBDIR_SUFFIX}") + include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_MAIN_INCLUDE_DIR}") + # Next three include directories are needed when llvm-config is located in build directory. + # LLVM and Cland are assumed to be built together + if (EXISTS "${LLVM_OBJ_ROOT}/include") + include_directories("${LLVM_OBJ_ROOT}/include") + endif() + if (EXISTS "${LLVM_MAIN_SRC_DIR}/tools/clang/include") + include_directories("${LLVM_MAIN_SRC_DIR}/tools/clang/include") + endif() + if (EXISTS "${LLVM_OBJ_ROOT}/tools/clang/include") + include_directories("${LLVM_OBJ_ROOT}/tools/clang/include") + endif() + link_directories("${LLVM_LIBRARY_DIR}") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}) diff --git a/cmake/platforms/Android.cmake b/cmake/platforms/Android.cmake index 98b695be6ef6..9aad65cbe13e 100644 --- a/cmake/platforms/Android.cmake +++ b/cmake/platforms/Android.cmake @@ -165,6 +165,15 @@ set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) ################# BEGIN EVIL HACK ################## +# In the android-arm NDK unwind.h and link.h contains 2 conflicting +# typedef for _Unwind_Ptr. Force HAVE_UNWIND_BACKTRACE to 0 to prevent +# LLVM from finding unwind.h what would break the build. +if ( ANDROID_ABI STREQUAL "armeabi" ) + set( HAVE_UNWIND_BACKTRACE 0 CACHE INTERNAL "Hack to disable the finding of unwind.h on Android arm" ) +endif() +################# END EVIL HACK #################### + +################# BEGIN EVIL HACK ################## # lldb-server links against libdl even though it's not being used and # libdl.a is currently missing from the toolchain (b.android.com/178517). # Therefore, in order to statically link lldb-server, we need a temporary @@ -178,7 +187,8 @@ if( LLVM_BUILD_STATIC ) void * dlopen (const char *filename, int flag) { return 0; } const char * dlerror (void) { return 0; } void * dlsym (void *handle, const char *symbol) { return 0; } -int dlclose (void *handle) { return 0; }") +int dlclose (void *handle) { return 0; } +int dladdr (const void *addr, Dl_info *info) { return 0; }") set( flags "${CMAKE_C_FLAGS}" ) separate_arguments( flags ) execute_process( COMMAND ${CMAKE_C_COMPILER} ${flags} -c ${libdl}/libdl.c -o ${libdl}/libdl.o ) diff --git a/docs/lldb-for-gdb-users.txt b/docs/lldb-for-gdb-users.txt index 216903a55db5..d505d639192d 100644 --- a/docs/lldb-for-gdb-users.txt +++ b/docs/lldb-for-gdb-users.txt @@ -222,7 +222,7 @@ Or you can attach to a process by name with: (lldb) process attach -n Sketch -the "attach by name" also supports the "-w" option which waits for the +The "attach by name" also supports the "-w" option which waits for the next process of that name to show up, and attaches to that. You can also attach by PID: diff --git a/docs/lldb-gdb-remote.txt b/docs/lldb-gdb-remote.txt index 5c4a10c82b49..a882c4abda09 100644 --- a/docs/lldb-gdb-remote.txt +++ b/docs/lldb-gdb-remote.txt @@ -1508,6 +1508,28 @@ for this region. // This packet asks the remote debug stub to send the details about libraries // being added/removed from the process as a performance optimization. // +// There are three ways this packet can be used. All three return a dictionary of +// binary images formatted the same way. +// +// On MacOS X 10.11, iOS 9, tvOS 9, watchOS 2 and earlier, the packet is used like +// jGetLoadedDynamicLibrariesInfos:{"image_count":1,"image_list_address":140734800075128} +// where the image_list_address is an array of {void* load_addr, void* mod_date, void* pathname} +// in the inferior process memory (and image_count is the number of elements in this array). +// lldb is using information from the dyld_all_image_infos structure to make these requests to +// debugserver. This use is not supported on macOS 10.12, iOS 10, tvOS 10, watchOS 3 or newer. +// +// On macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer, there are two calls. One requests information +// on all shared libraries: +// jGetLoadedDynamicLibrariesInfos:{"fetch_all_solibs":true} +// And the second requests information about a list of shared libraries, given their load addresses: +// jGetLoadedDynamicLibrariesInfos:{"solib_addresses":[8382824135,3258302053,830202858503]} +// +// The second call is both a performance optimization (instead of having lldb read the mach-o header/load commands +// out of memory with generic read packets) but also adds additional information in the form of the +// filename of the shared libraries (which is not available in the mach-o header/load commands.) +// +// An example using the Mac OS X 10.11 style call: +// // LLDB SENDS: jGetLoadedDynamicLibrariesInfos:{"image_count":1,"image_list_address":140734800075128} // STUB REPLIES: ${"images":[{"load_address":4294967296,"mod_date":0,"pathname":"/tmp/a.out","uuid":"02CF262C-ED6F-3965-9E14-63538B465CFF","mach_header":{"magic":4277009103,"cputype":16777223,"cpusubtype":18446744071562067971,"filetype":2},"segments":{"name":"__PAGEZERO","vmaddr":0,"vmsize":4294967296,"fileoff":0,"filesize":0,"maxprot":0},{"name":"__TEXT","vmaddr":4294967296,"vmsize":4096,"fileoff":0,"filesize":4096,"maxprot":7},{"name":"__LINKEDIT","vmaddr":4294971392,"vmsize":4096,"fileoff":4096,"filesize":152,"maxprot":7}}]}#00 // @@ -1562,26 +1584,12 @@ for this region. // quite a bit to provide all the information that the DynamicLoaderMacOSX // would need to work correctly on this platform. // -// On Mac OS X / iOS, when libraries are added or removed, a stub -// function is called which lldb puts a breakpoint on. The arguments -// to the stub function include the number of libraries being added -// or removed and the address where the list of libraries can be -// found. The information at this address is the load address of the -// library, the filename, and the mod date of the library if available. -// DynamicLoaderMacOSX then parses the load commands in the Mach-O header -// at the load address before it can decide what action to take. -// -// The purpose of this packet is to eliminate all of the memory reads needed -// to read the Mach-O header and load commands for these libraries. -// On a typical GUI app, there can be a couple hundred shared libraries -// which results in megabytes of read packets. That same information can -// be returned in a couple hundred kilobytes in JSON format from the remote -// debugserver. -// -// // PRIORITY TO IMPLEMENT -// Low. If this packet is absent, lldb will read the Mach-O headers/load -// commands out of memory. +// On Mac OS X 10.11, iOS 9, tvOS 9, watchOS 2 and older: Low. If this packet is absent, +// lldb will read the Mach-O headers/load commands out of memory. +// On macOS 10.12, iOS 10, tvOS 10, watchOS 3 and newer: High. If this packet is absent, +// lldb will not know anything about shared libraries in the inferior, or where the main +// executable loaded. //---------------------------------------------------------------------- //---------------------------------------------------------------------- @@ -1649,6 +1657,26 @@ the previous FP and PC), and follow the backchain. Most backtraces on MacOSX and iOS now don't require us to read any memory! //---------------------------------------------------------------------- +// "jGetSharedCacheInfo" +// +// BRIEF +// This packet asks the remote debug stub to send the details about the inferior's +// shared cache. The shared cache is a collection of common libraries/frameworks that +// are mapped into every process at the same address on Darwin systems, and can be +// identified by a load address and UUID. +// +// +// LLDB SENDS: jGetSharedCacheInfo:{} +// STUB REPLIES: ${"shared_cache_base_address":140735683125248,"shared_cache_uuid":"DDB8D70C-C9A2-3561-B2C8-BE48A4F33F96","no_shared_cache":false,"shared_cache_private_cache":false]}#00 +// +// PRIORITY TO IMPLEMENT +// Low. When both lldb and the inferior process are running on the same computer, and lldb +// and the inferior process have the same shared cache, lldb may (as an optimization) read +// the shared cache out of its own memory instead of using gdb-remote read packets to read +// them from the inferior process. +//---------------------------------------------------------------------- + +//---------------------------------------------------------------------- // "qQueryGDBServer" // // BRIEF diff --git a/examples/python/crashlog.py b/examples/python/crashlog.py index 60a6a1f50f00..a557b604afb4 100755 --- a/examples/python/crashlog.py +++ b/examples/python/crashlog.py @@ -452,7 +452,7 @@ class CrashLog(symbolication.Symbolicator): for image in self.images: if image.identifier == identifier: return image - regex_text = '^.*\.%s$' % (identifier) + regex_text = '^.*\.%s$' % (re.escape(identifier)) regex = re.compile(regex_text) for image in self.images: if regex.match(image.identifier): diff --git a/examples/python/scripted_step.py b/examples/python/scripted_step.py index 8affb9e83220..6be397188720 100644 --- a/examples/python/scripted_step.py +++ b/examples/python/scripted_step.py @@ -184,3 +184,28 @@ class StepCheckingCondition: def should_step (self): return True +# Here's an example that steps out of the current frame, gathers some information +# and then continues. The information in this case is rax. Currently the thread +# plans are not a safe place to call lldb command-line commands, so the information +# is gathered through SB API calls. + +class FinishPrintAndContinue: + def __init__ (self, thread_plan, dict): + self.thread_plan = thread_plan + self.step_out_thread_plan = thread_plan.QueueThreadPlanForStepOut(0, True) + self.thread = self.thread_plan.GetThread() + + def explains_stop (self, event): + return False + + def should_stop (self, event): + if self.step_out_thread_plan.IsPlanComplete(): + frame_0 = self.thread.frames[0] + rax_value = frame_0.FindRegister("rax") + if rax_value.GetError().Success(): + print "RAX on exit: ", rax_value.GetValue() + else: + print "Couldn't get rax value:", rax_value.GetError().GetCString() + + self.thread_plan.SetPlanComplete(True) + return False diff --git a/examples/python/shadow.py b/examples/python/shadow.py new file mode 100644 index 000000000000..d1a5878fcef8 --- /dev/null +++ b/examples/python/shadow.py @@ -0,0 +1,57 @@ +#!/usr/bin/python + +import lldb +import shlex + +@lldb.command("shadow") +def check_shadow_command(debugger, command, exe_ctx, result, dict): + '''Check the currently selected stack frame for shadowed variables''' + process = exe_ctx.GetProcess() + state = process.GetState() + if state != lldb.eStateStopped: + print >>result, "process must be stopped, state is %s" % lldb.SBDebugger.StateAsCString(state) + return + frame = exe_ctx.GetFrame() + if not frame: + print >>result, "invalid frame" + return + # Parse command line args + command_args = shlex.split(command) + # TODO: add support for using arguments that are passed to this command... + + # Make a dictionary of variable name to "SBBlock and SBValue" + shadow_dict = {} + + num_shadowed_variables = 0 + # Get the deepest most block from the current frame + block = frame.GetBlock() + # Iterate through the block and all of its parents + while block.IsValid(): + # Get block variables from the current block only + block_vars = block.GetVariables(frame, True, True, True, 0) + # Iterate through all variables in the current block + for block_var in block_vars: + # Since we can have multiple shadowed variables, we our variable + # name dictionary to have an array or "block + variable" pairs so + # We can correctly print out all shadowed variables and whow which + # blocks they come from + block_var_name = block_var.GetName() + if block_var_name in shadow_dict: + shadow_dict[block_var_name].append(block_var) + else: + shadow_dict[block_var_name] = [block_var] + # Get the parent block and continue + block = block.GetParent() + + num_shadowed_variables = 0 + if shadow_dict: + for name in shadow_dict.keys(): + shadow_vars = shadow_dict[name] + if len(shadow_vars) > 1: + print '"%s" is shadowed by the following declarations:' % (name) + num_shadowed_variables += 1 + for shadow_var in shadow_vars: + print >>result, str(shadow_var.GetDeclaration()) + if num_shadowed_variables == 0: + print >>result, 'no variables are shadowed' + diff --git a/examples/python/symbolication.py b/examples/python/symbolication.py index 2f2a274dbc41..88846c99b3a4 100755 --- a/examples/python/symbolication.py +++ b/examples/python/symbolication.py @@ -448,7 +448,7 @@ class Symbolicator: if image.identifier == identifier: images.append(image) if len(images) == 0: - regex_text = '^.*\.%s$' % (identifier) + regex_text = '^.*\.%s$' % (re.escape(identifier)) regex = re.compile(regex_text) for image in self.images: if regex.match(image.identifier): diff --git a/examples/synthetic/gnu_libstdcpp.py b/examples/synthetic/gnu_libstdcpp.py index b6bf42235acd..9f26282be01f 100644 --- a/examples/synthetic/gnu_libstdcpp.py +++ b/examples/synthetic/gnu_libstdcpp.py @@ -237,11 +237,12 @@ class StdVectorSynthProvider: def get_child_at_index(self, index): if index >= self.num_children(): return None - byte_offset = index / 8 - bit_offset = index % 8 - element_size = self.start_p.GetType().GetPointeeType().GetByteSize() - data = self.start_p.GetPointeeData(byte_offset / element_size) - bit = data.GetUnsignedInt8(lldb.SBError(), byte_offset % element_size) & (1 << bit_offset) + element_type = self.start_p.GetType().GetPointeeType() + element_bits = 8 * element_type.GetByteSize() + element_offset = (index / element_bits) * element_type.GetByteSize() + bit_offset = index % element_bits + element = self.start_p.CreateChildAtOffset('['+str(index)+']',element_offset,element_type) + bit = element.GetValueAsUnsigned(0) & (1 << bit_offset) if bit != 0: value_expr = "(bool)true" else: diff --git a/include/Makefile b/include/Makefile deleted file mode 100644 index 02acdce10271..000000000000 --- a/include/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- include/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 := .. -DIRS := lldb - -include $(LLDB_LEVEL)/Makefile diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h index eed10d08c6cc..b6278160dbc0 100644 --- a/include/lldb/API/LLDB.h +++ b/include/lldb/API/LLDB.h @@ -43,6 +43,8 @@ #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" diff --git a/include/lldb/API/SBCommandReturnObject.h b/include/lldb/API/SBCommandReturnObject.h index b45eb9c14c04..2b7cce5ded59 100644 --- a/include/lldb/API/SBCommandReturnObject.h +++ b/include/lldb/API/SBCommandReturnObject.h @@ -83,7 +83,9 @@ public: bool GetDescription (lldb::SBStream &description); - + + // deprecated, these two functions do not take + // ownership of file handle void SetImmediateOutputFile (FILE *fh); @@ -91,6 +93,12 @@ public: SetImmediateErrorFile (FILE *fh); void + SetImmediateOutputFile (FILE *fh, bool transfer_ownership); + + void + SetImmediateErrorFile (FILE *fh, bool transfer_ownership); + + void PutCString(const char* string, int len = -1); size_t diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index d81bba5a2e23..4a95903ec92c 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -59,6 +59,8 @@ class LLDB_API SBLanguageRuntime; class LLDB_API SBLaunchInfo; class LLDB_API SBLineEntry; class LLDB_API SBListener; +class LLDB_API SBMemoryRegionInfo; +class LLDB_API SBMemoryRegionInfoList; class LLDB_API SBModule; class LLDB_API SBModuleSpec; class LLDB_API SBModuleSpecList; diff --git a/include/lldb/API/SBExpressionOptions.h b/include/lldb/API/SBExpressionOptions.h index ed2f9187b3e0..051ed7220ac8 100644 --- a/include/lldb/API/SBExpressionOptions.h +++ b/include/lldb/API/SBExpressionOptions.h @@ -110,6 +110,19 @@ public: void SetPrefix (const char *prefix); + + void + SetAutoApplyFixIts(bool b = true); + + bool + GetAutoApplyFixIts(); + + bool + GetTopLevel (); + + void + SetTopLevel (bool b = true); + protected: diff --git a/include/lldb/API/SBFileSpec.h b/include/lldb/API/SBFileSpec.h index d6f38f5b2d74..2f9d6bab89f3 100644 --- a/include/lldb/API/SBFileSpec.h +++ b/include/lldb/API/SBFileSpec.h @@ -60,6 +60,9 @@ public: bool GetDescription (lldb::SBStream &description) const; + void + AppendPathComponent (const char *file_or_directory); + private: friend class SBAttachInfo; friend class SBBlock; diff --git a/include/lldb/API/SBHostOS.h b/include/lldb/API/SBHostOS.h index d9bc97365632..a3675856a136 100644 --- a/include/lldb/API/SBHostOS.h +++ b/include/lldb/API/SBHostOS.h @@ -28,6 +28,9 @@ public: static lldb::SBFileSpec GetLLDBPath (lldb::PathType path_type); + static lldb::SBFileSpec + GetUserHomeDirectory (); + static void ThreadCreated (const char *name); diff --git a/include/lldb/API/SBInstruction.h b/include/lldb/API/SBInstruction.h index 2bacc2b97746..cb0b2a32a829 100644 --- a/include/lldb/API/SBInstruction.h +++ b/include/lldb/API/SBInstruction.h @@ -18,6 +18,8 @@ // There's a lot to be fixed here, but need to wait for underlying insn implementation // to be revised & settle down first. +class InstructionImpl; + namespace lldb { class LLDB_API SBInstruction @@ -81,14 +83,17 @@ public: protected: friend class SBInstructionList; - SBInstruction (const lldb::InstructionSP &inst_sp); + SBInstruction(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP &inst_sp); void - SetOpaque (const lldb::InstructionSP &inst_sp); + SetOpaque(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP& inst_sp); + + lldb::InstructionSP + GetOpaque(); private: - lldb::InstructionSP m_opaque_sp; + std::shared_ptr<InstructionImpl> m_opaque_sp; }; diff --git a/include/lldb/API/SBLaunchInfo.h b/include/lldb/API/SBLaunchInfo.h index 68c0f386acde..38d598aec456 100644 --- a/include/lldb/API/SBLaunchInfo.h +++ b/include/lldb/API/SBLaunchInfo.h @@ -145,7 +145,7 @@ public: GetShellExpandArguments (); void - SetShellExpandArguments (bool glob); + SetShellExpandArguments (bool expand); uint32_t GetResumeCount (); diff --git a/include/lldb/API/SBListener.h b/include/lldb/API/SBListener.h index 924f8109f638..e74d318ea118 100644 --- a/include/lldb/API/SBListener.h +++ b/include/lldb/API/SBListener.h @@ -106,8 +106,6 @@ protected: friend class SBLaunchInfo; friend class SBTarget; - SBListener (lldb_private::Listener &listener); - SBListener (const lldb::ListenerSP &listener_sp); lldb::ListenerSP @@ -124,20 +122,11 @@ private: lldb_private::Listener * get() const; - lldb_private::Listener & - ref() const; - - lldb_private::Listener & - operator *(); - - const lldb_private::Listener & - operator *() const; - void - reset(lldb_private::Listener *listener, bool transfer_ownership); + reset(lldb::ListenerSP listener_sp); lldb::ListenerSP m_opaque_sp; - lldb_private::Listener *m_opaque_ptr; + lldb_private::Listener *m_unused_ptr; }; } // namespace lldb diff --git a/include/lldb/API/SBMemoryRegionInfo.h b/include/lldb/API/SBMemoryRegionInfo.h new file mode 100644 index 000000000000..fadd0760891b --- /dev/null +++ b/include/lldb/API/SBMemoryRegionInfo.h @@ -0,0 +1,117 @@ +//===-- SBMemoryRegionInfo.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBMemoryRegionInfo_h_ +#define LLDB_SBMemoryRegionInfo_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBData.h" + +namespace lldb { + +class LLDB_API SBMemoryRegionInfo +{ +public: + + SBMemoryRegionInfo (); + + SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs); + + ~SBMemoryRegionInfo (); + + const lldb::SBMemoryRegionInfo & + operator = (const lldb::SBMemoryRegionInfo &rhs); + + void + Clear(); + + //------------------------------------------------------------------ + /// Get the base address of this memory range. + /// + /// @return + /// The base address of this memory range. + //------------------------------------------------------------------ + lldb::addr_t + GetRegionBase (); + + //------------------------------------------------------------------ + /// Get the end address of this memory range. + /// + /// @return + /// The base address of this memory range. + //------------------------------------------------------------------ + lldb::addr_t + GetRegionEnd (); + + //------------------------------------------------------------------ + /// Check if this memory address is marked readable to the process. + /// + /// @return + /// true if this memory address is marked readable + //------------------------------------------------------------------ + bool + IsReadable (); + + //------------------------------------------------------------------ + /// Check if this memory address is marked writable to the process. + /// + /// @return + /// true if this memory address is marked writable + //------------------------------------------------------------------ + bool + IsWritable (); + + //------------------------------------------------------------------ + /// Check if this memory address is marked executable to the process. + /// + /// @return + /// true if this memory address is marked executable + //------------------------------------------------------------------ + bool + IsExecutable (); + + //------------------------------------------------------------------ + /// Check if this memory address is mapped into the process address + /// space. + /// + /// @return + /// true if this memory address is in the process address space. + //------------------------------------------------------------------ + bool + IsMapped (); + + bool + operator == (const lldb::SBMemoryRegionInfo &rhs) const; + + bool + operator != (const lldb::SBMemoryRegionInfo &rhs) const; + + bool + GetDescription (lldb::SBStream &description); + +private: + + friend class SBProcess; + friend class SBMemoryRegionInfoList; + + lldb_private::MemoryRegionInfo & + ref(); + + const lldb_private::MemoryRegionInfo & + ref() const; + + SBMemoryRegionInfo (const lldb_private::MemoryRegionInfo *lldb_object_ptr); + + lldb::MemoryRegionInfoUP m_opaque_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBMemoryRegionInfo_h_ diff --git a/include/lldb/API/SBMemoryRegionInfoList.h b/include/lldb/API/SBMemoryRegionInfoList.h new file mode 100644 index 000000000000..7723820897d8 --- /dev/null +++ b/include/lldb/API/SBMemoryRegionInfoList.h @@ -0,0 +1,63 @@ +//===-- SBMemoryRegionInfoList.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBMemoryRegionInfoList_h_ +#define LLDB_SBMemoryRegionInfoList_h_ + +#include "lldb/API/SBDefines.h" + +class MemoryRegionInfoListImpl; + +namespace lldb { + +class LLDB_API SBMemoryRegionInfoList +{ +public: + + SBMemoryRegionInfoList (); + + SBMemoryRegionInfoList (const lldb::SBMemoryRegionInfoList &rhs); + + const SBMemoryRegionInfoList & + operator = (const 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 (); + +protected: + + const MemoryRegionInfoListImpl * + operator->() const; + + const MemoryRegionInfoListImpl & + operator*() const; + +private: + + std::unique_ptr<MemoryRegionInfoListImpl> m_opaque_ap; + +}; + +} // namespace lldb + +#endif // LLDB_SBMemoryRegionInfoList_h_ diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index 1a9cc8022880..a8881ad898c0 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -393,6 +393,34 @@ public: lldb::SBError SaveCore(const char *file_name); + //------------------------------------------------------------------ + /// Query the address load_addr and store the details of the memory + /// region that contains it in the supplied SBMemoryRegionInfo object. + /// To iterate over all memory regions use GetMemoryRegionList. + /// + /// @param[in] load_addr + /// The address to be queried. + /// + /// @param[out] region_info + /// A reference to an SBMemoryRegionInfo object that will contain + /// the details of the memory region containing load_addr. + /// + /// @return + /// An error object describes any errors that occurred while + /// querying load_addr. + //------------------------------------------------------------------ + lldb::SBError + GetMemoryRegionInfo (lldb::addr_t load_addr, lldb::SBMemoryRegionInfo ®ion_info); + + //------------------------------------------------------------------ + /// Return the list of memory regions within the process. + /// + /// @return + /// A list of all witin the process memory regions. + //------------------------------------------------------------------ + lldb::SBMemoryRegionInfoList + GetMemoryRegions(); + protected: friend class SBAddress; friend class SBBreakpoint; diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h index e62723c2f37e..717979977d16 100644 --- a/include/lldb/API/SBStream.h +++ b/include/lldb/API/SBStream.h @@ -76,6 +76,7 @@ protected: friend class SBInstruction; friend class SBInstructionList; friend class SBLineEntry; + friend class SBMemoryRegionInfo; friend class SBModule; friend class SBModuleSpec; friend class SBModuleSpecList; diff --git a/include/lldb/API/SBStringList.h b/include/lldb/API/SBStringList.h index e0e58f765c6d..bc8ff935eda3 100644 --- a/include/lldb/API/SBStringList.h +++ b/include/lldb/API/SBStringList.h @@ -45,6 +45,9 @@ public: const char * GetStringAtIndex (size_t idx); + const char * + GetStringAtIndex (size_t idx) const; + void Clear (); diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index 723c433b521a..0bcabd043c9c 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -621,6 +621,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 = nullptr); // This version uses name_type_mask = eFunctionNameTypeAuto @@ -658,6 +661,15 @@ public: const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint + 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); + + lldb::SBBreakpoint BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = nullptr); lldb::SBBreakpoint @@ -682,6 +694,12 @@ public: const SBFileSpecList &source_file); 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/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h index 2c45fa8d5120..c1ce216f9be6 100644 --- a/include/lldb/API/SBThread.h +++ b/include/lldb/API/SBThread.h @@ -82,6 +82,9 @@ public: bool GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream); + SBThreadCollection + GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type); + size_t GetStopDescription (char *dst, size_t dst_len); @@ -116,6 +119,12 @@ public: StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); void + StepInto (const char *target_name, + uint32_t end_line, + SBError &error, + lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); + + void StepOut (); void @@ -141,6 +150,9 @@ public: SBError ReturnFromFrame (SBFrame &frame, SBValue &return_value); + SBError + UnwindInnermostExpression(); + //-------------------------------------------------------------------------- /// LLDB currently supports process centric debugging which means when any /// thread in a process stops, all other threads are stopped. The Suspend() diff --git a/include/lldb/API/SBThreadCollection.h b/include/lldb/API/SBThreadCollection.h index 996ee3cd22aa..79f977454497 100644 --- a/include/lldb/API/SBThreadCollection.h +++ b/include/lldb/API/SBThreadCollection.h @@ -58,6 +58,7 @@ protected: private: friend class SBProcess; + friend class SBThread; lldb::ThreadCollectionSP m_opaque_sp; }; diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h index a7e015064f96..b9f1e6f5c93f 100644 --- a/include/lldb/API/SBValue.h +++ b/include/lldb/API/SBValue.h @@ -125,6 +125,12 @@ public: bool IsSynthetic (); + + bool + IsSyntheticChildrenGenerated (); + + void + SetSyntheticChildrenGenerated (bool); const char * GetLocation (); diff --git a/include/lldb/Breakpoint/BreakpointList.h b/include/lldb/Breakpoint/BreakpointList.h index f4837e1ce956..5ddde7d837c4 100644 --- a/include/lldb/Breakpoint/BreakpointList.h +++ b/include/lldb/Breakpoint/BreakpointList.h @@ -13,10 +13,11 @@ // C Includes // C++ Includes #include <list> +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -116,7 +117,7 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_breakpoints.size(); } @@ -193,7 +194,7 @@ public: /// The locker object that is set. //------------------------------------------------------------------ void - GetListMutex (lldb_private::Mutex::Locker &locker); + GetListMutex(std::unique_lock<std::recursive_mutex> &lock); protected: typedef std::list<lldb::BreakpointSP> bp_collection; @@ -204,19 +205,20 @@ protected: bp_collection::const_iterator GetBreakpointIDConstIterator(lldb::break_id_t breakID) const; - Mutex & - GetMutex () const + std::recursive_mutex & + GetMutex() const { return m_mutex; } - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; bp_collection m_breakpoints; // The breakpoint list, currently a list. lldb::break_id_t m_next_break_id; bool m_is_internal; public: - typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter> BreakpointIterable; + typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter, std::recursive_mutex> + BreakpointIterable; BreakpointIterable Breakpoints() { diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h index 58d144cfb668..42eca73dbb22 100644 --- a/include/lldb/Breakpoint/BreakpointLocation.h +++ b/include/lldb/Breakpoint/BreakpointLocation.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <memory> +#include <mutex> // Other libraries and framework includes // Project includes @@ -20,7 +21,6 @@ #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Core/Address.h" #include "lldb/Core/UserID.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -460,7 +460,8 @@ private: std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, nullptr if we're using our breakpoint's options. lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.) lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition. - Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes. + std::mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by + /// multiple processes. size_t m_condition_hash; ///< For testing whether the condition source code changed. void diff --git a/include/lldb/Breakpoint/BreakpointLocationCollection.h b/include/lldb/Breakpoint/BreakpointLocationCollection.h index 004f8395122b..1a016544fa4c 100644 --- a/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -13,6 +13,8 @@ // C Includes // C++ Includes #include <vector> +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" @@ -201,7 +203,8 @@ private: collection::const_iterator GetIDPairConstIterator(lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const; - collection m_break_loc_collection; + collection m_break_loc_collection; + mutable std::mutex m_collection_mutex; public: typedef AdaptedIterable<collection, lldb::BreakpointLocationSP, vector_adapter> BreakpointLocationCollectionIterable; diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h index 81526089b427..1fbfa43a40f4 100644 --- a/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/include/lldb/Breakpoint/BreakpointLocationList.h @@ -13,13 +13,13 @@ // C Includes // C++ Includes #include <map> +#include <mutex> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/Address.h" -#include "lldb/Host/Mutex.h" #include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -270,7 +270,7 @@ protected: Breakpoint &m_owner; collection m_locations; // Vector of locations, sorted by ID addr_map m_address_to_location; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; lldb::break_id_t m_next_id; BreakpointLocationCollection *m_new_location_recorder; diff --git a/include/lldb/Breakpoint/BreakpointResolver.h b/include/lldb/Breakpoint/BreakpointResolver.h index 198abed841b2..b117e668a1bd 100644 --- a/include/lldb/Breakpoint/BreakpointResolver.h +++ b/include/lldb/Breakpoint/BreakpointResolver.h @@ -60,7 +60,7 @@ public: /// @result /// Returns breakpoint location id. //------------------------------------------------------------------ - BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType); + BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType, lldb::addr_t offset = 0); //------------------------------------------------------------------ /// The Destructor is virtual, all significant breakpoint resolvers derive @@ -78,6 +78,29 @@ public: SetBreakpoint (Breakpoint *bkpt); //------------------------------------------------------------------ + /// This updates the offset for this breakpoint. All the locations currently + /// set for this breakpoint will have their offset adjusted when this is called. + /// + /// @param[in] offset + /// The offset to add to all locations. + //------------------------------------------------------------------ + void + SetOffset (lldb::addr_t offset); + + //------------------------------------------------------------------ + /// This updates the offset for this breakpoint. All the locations currently + /// set for this breakpoint will have their offset adjusted when this is called. + /// + /// @param[in] offset + /// The offset to add to all locations. + //------------------------------------------------------------------ + lldb::addr_t + GetOffset () const + { + return m_offset; + } + + //------------------------------------------------------------------ /// In response to this method the resolver scans all the modules in the breakpoint's /// target, and adds any new locations it finds. /// @@ -145,8 +168,12 @@ protected: /// matching addresses to unique entries, and skip the prologue if asked to do so, and then set /// breakpoint locations in this breakpoint for all the resultant addresses. void SetSCMatchesByLine (SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, const char *log_ident); + + lldb::BreakpointLocationSP + AddLocation(Address loc_addr, bool *new_location = NULL); Breakpoint *m_breakpoint; // This is the breakpoint we add locations to. + lldb::addr_t m_offset; // A random offset the user asked us to add to any breakpoints we set. private: // Subclass identifier (for llvm isa/dyn_cast) diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h index 2dde1546f126..cea192b5edbf 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -31,6 +31,7 @@ public: BreakpointResolverFileLine (Breakpoint *bkpt, const FileSpec &resolver, uint32_t line_no, + lldb::addr_t m_offset, bool check_inlines, bool skip_prologue, bool exact_match); diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index a8d7a50b5d93..ce67c2dc98ec 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -12,9 +12,11 @@ // C Includes // C++ Includes +#include <set> // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/ConstString.h" namespace lldb_private { @@ -30,6 +32,7 @@ class BreakpointResolverFileRegex : public: BreakpointResolverFileRegex (Breakpoint *bkpt, RegularExpression ®ex, + const std::unordered_set<std::string> &func_name_set, bool exact_match); ~BreakpointResolverFileRegex() override; @@ -48,6 +51,9 @@ public: void Dump (Stream *s) const override; + + void + AddFunctionName(const char *func_name); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverFileRegex *) { return true; } @@ -61,7 +67,8 @@ public: protected: friend class Breakpoint; RegularExpression m_regex; // This is the line expression that we are looking for. - bool m_exact_match; + bool m_exact_match; // If true, then if the source we match is in a comment, we won't set a location there. + std::unordered_set<std::string> m_function_names; // Limit the search to functions in the comp_unit passed in. private: DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex); diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h index aaae9c1a12cf..a11359dd0094 100644 --- a/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/include/lldb/Breakpoint/BreakpointResolverName.h @@ -18,6 +18,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/Module.h" namespace lldb_private { @@ -37,6 +38,7 @@ public: uint32_t name_type_mask, lldb::LanguageType language, Breakpoint::MatchType type, + lldb::addr_t offset, bool skip_prologue); // This one takes an array of names. It is always MatchType = Exact. @@ -45,6 +47,7 @@ public: size_t num_names, uint32_t name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, bool skip_prologue); // This one takes a C++ array of names. It is always MatchType = Exact. @@ -52,18 +55,21 @@ public: std::vector<std::string> names, uint32_t name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, bool skip_prologue); // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex. BreakpointResolverName (Breakpoint *bkpt, RegularExpression &func_regex, lldb::LanguageType language, + lldb::addr_t offset, bool skip_prologue); BreakpointResolverName (Breakpoint *bkpt, const char *class_name, const char *method, Breakpoint::MatchType type, + lldb::addr_t offset, bool skip_prologue); ~BreakpointResolverName() override; @@ -95,26 +101,7 @@ public: protected: BreakpointResolverName(const BreakpointResolverName &rhs); - struct LookupInfo - { - ConstString name; - ConstString lookup_name; - uint32_t name_type_mask; // See FunctionNameType - bool match_name_after_lookup; - - LookupInfo () : - name(), - lookup_name(), - name_type_mask (0), - match_name_after_lookup (false) - { - } - - void - Prune (SymbolContextList &sc_list, - size_t start_idx) const; - }; - std::vector<LookupInfo> m_lookups; + std::vector<Module::LookupInfo> m_lookups; ConstString m_class_name; RegularExpression m_regex; Breakpoint::MatchType m_match_type; diff --git a/include/lldb/Breakpoint/BreakpointSite.h b/include/lldb/Breakpoint/BreakpointSite.h index 6cebcab8e2db..27a23527d9fa 100644 --- a/include/lldb/Breakpoint/BreakpointSite.h +++ b/include/lldb/Breakpoint/BreakpointSite.h @@ -14,12 +14,12 @@ // C++ Includes #include <list> +#include <mutex> // Other libraries and framework includes // Project includes #include "lldb/lldb-forward.h" -#include "lldb/Host/Mutex.h" #include "lldb/Core/UserID.h" #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" @@ -297,7 +297,7 @@ private: // Consider adding an optimization where if there is only one // owner, we don't store a list. The usual case will be only one owner... BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site. - Mutex m_owners_mutex; ///< This mutex protects the owners collection. + std::recursive_mutex m_owners_mutex; ///< This mutex protects the owners collection. static lldb::break_id_t GetNextID(); diff --git a/include/lldb/Breakpoint/BreakpointSiteList.h b/include/lldb/Breakpoint/BreakpointSiteList.h index d7bb8fd777ef..e681aa3599f7 100644 --- a/include/lldb/Breakpoint/BreakpointSiteList.h +++ b/include/lldb/Breakpoint/BreakpointSiteList.h @@ -12,12 +12,13 @@ // C Includes // C++ Includes -#include <map> #include <functional> +#include <map> +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointSite.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -189,16 +190,17 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_bp_site_list.size(); } bool IsEmpty() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_bp_site_list.empty(); } + protected: typedef std::map<lldb::addr_t, lldb::BreakpointSiteSP> collection; @@ -208,7 +210,7 @@ protected: collection::const_iterator GetIDConstIterator(lldb::break_id_t breakID) const; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; collection m_bp_site_list; // The breakpoint site list. }; diff --git a/include/lldb/Breakpoint/WatchpointList.h b/include/lldb/Breakpoint/WatchpointList.h index d16cb25e3b7d..7369623d1ce2 100644 --- a/include/lldb/Breakpoint/WatchpointList.h +++ b/include/lldb/Breakpoint/WatchpointList.h @@ -13,12 +13,13 @@ // C Includes // C++ Includes #include <list> +#include <mutex> #include <vector> + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/Address.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -217,7 +218,7 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_watchpoints.size(); } @@ -250,7 +251,7 @@ public: /// The locker object that is set. //------------------------------------------------------------------ void - GetListMutex (lldb_private::Mutex::Locker &locker); + GetListMutex(std::unique_lock<std::recursive_mutex> &lock); protected: typedef std::list<lldb::WatchpointSP> wp_collection; @@ -266,7 +267,7 @@ protected: GetIDConstIterator(lldb::watch_id_t watchID) const; wp_collection m_watchpoints; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; lldb::watch_id_t m_next_wp_id; }; diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h index 13ff436cf08f..be760637c03e 100644 --- a/include/lldb/Core/ArchSpec.h +++ b/include/lldb/Core/ArchSpec.h @@ -69,9 +69,33 @@ public: eMIPSABI_O32 = 0x00002000, eMIPSABI_N32 = 0x00004000, eMIPSABI_N64 = 0x00008000, + eMIPSABI_O64 = 0x00020000, + eMIPSABI_EABI32 = 0x00040000, + eMIPSABI_EABI64 = 0x00080000, eMIPSABI_mask = 0x000ff000 }; + // MIPS Floating point ABI Values + enum MIPS_ABI_FP + { + eMIPS_ABI_FP_ANY = 0x00000000, + eMIPS_ABI_FP_DOUBLE = 0x00100000, // hard float / -mdouble-float + eMIPS_ABI_FP_SINGLE = 0x00200000, // hard float / -msingle-float + eMIPS_ABI_FP_SOFT = 0x00300000, // soft float + eMIPS_ABI_FP_OLD_64 = 0x00400000, // -mips32r2 -mfp64 + eMIPS_ABI_FP_XX = 0x00500000, // -mfpxx + eMIPS_ABI_FP_64 = 0x00600000, // -mips32r2 -mfp64 + eMIPS_ABI_FP_64A = 0x00700000, // -mips32r2 -mfp64 -mno-odd-spreg + eMIPS_ABI_FP_mask = 0x00700000 + }; + + // ARM specific e_flags + enum ARMeflags + { + eARM_abi_soft_float = 0x00000200, + eARM_abi_hard_float = 0x00000400 + }; + enum Core { eCore_arm_generic, @@ -144,6 +168,8 @@ public: eCore_ppc64_generic, eCore_ppc64_ppc970_64, + eCore_s390x_generic, + eCore_sparc_generic, eCore_sparc9_generic, @@ -280,6 +306,24 @@ public: const char * GetArchitectureName () const; + //----------------------------------------------------------------- + /// if MIPS architecture return true. + /// + /// @return a boolean value. + //----------------------------------------------------------------- + bool + IsMIPS() const; + + //------------------------------------------------------------------ + /// Returns a string representing current architecture as a target CPU + /// for tools like compiler, disassembler etc. + /// + /// @return A string representing target CPU for the current + /// architecture. + //------------------------------------------------------------------ + std::string + GetClangTargetCPU (); + //------------------------------------------------------------------ /// Clears the object state. /// @@ -605,6 +649,22 @@ public: bool &os_version_different, bool &env_different); + //------------------------------------------------------------------ + /// Detect whether this architecture uses thumb code exclusively + /// + /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can + /// only execute the Thumb instructions, never Arm. We should normally + /// pick up arm/thumbness from their the processor status bits (cpsr/xpsr) + /// or hints on each function - but when doing bare-boards low level + /// debugging (especially common with these embedded processors), we may + /// not have those things easily accessible. + /// + /// @return true if this is an arm ArchSpec which can only execute Thumb + /// instructions + //------------------------------------------------------------------ + bool + IsAlwaysThumbInstructions () const; + uint32_t GetFlags () const { diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h index 8e59a41805ec..33172fa73780 100644 --- a/include/lldb/Core/Broadcaster.h +++ b/include/lldb/Core/Broadcaster.h @@ -12,16 +12,17 @@ // C Includes // C++ Includes +#include <functional> +#include <list> #include <map> +#include <mutex> #include <string> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -//#include "lldb/Core/Flags.h" #include "lldb/Core/ConstString.h" -#include "lldb/Core/Listener.h" namespace lldb_private { @@ -75,48 +76,58 @@ public: } bool operator< (const BroadcastEventSpec &rhs) const; - const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs); + BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs); private: ConstString m_broadcaster_class; uint32_t m_event_bits; }; -class BroadcasterManager +class BroadcasterManager : + public std::enable_shared_from_this<BroadcasterManager> { public: friend class Listener; +protected: BroadcasterManager (); - +public: + // Listeners hold onto weak pointers to their broadcaster managers. So they must be + // made into shared pointers, which you do with MakeBroadcasterManager. + + static lldb::BroadcasterManagerSP + MakeBroadcasterManager(); + ~BroadcasterManager() = default; uint32_t - RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec); + RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec); bool - UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec); + UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec); - Listener * + lldb::ListenerSP GetListenerForEventSpec (BroadcastEventSpec event_spec) const; void SignUpListenersForBroadcaster (Broadcaster &broadcaster); void - RemoveListener (Listener &Listener); + RemoveListener (const lldb::ListenerSP &listener_sp); + + void + RemoveListener (Listener *listener); -protected: void Clear(); private: - typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key; - typedef std::map<BroadcastEventSpec, Listener *> collection; - typedef std::set<Listener *> listener_collection; + typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; + typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; + typedef std::set<lldb::ListenerSP> listener_collection; collection m_event_map; listener_collection m_listeners; - - Mutex m_manager_mutex; + + mutable std::recursive_mutex m_manager_mutex; // A couple of comparator classes for find_if: @@ -161,10 +172,9 @@ private: class ListenerMatchesAndSharedBits { public: - ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, - const Listener &listener) : + explicit ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, const lldb::ListenerSP listener_sp) : m_broadcaster_spec (broadcaster_spec), - m_listener (&listener) + m_listener_sp (listener_sp) { } @@ -174,19 +184,19 @@ private: { return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass() && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0 - && input.second == m_listener); + && input.second == m_listener_sp); } private: BroadcastEventSpec m_broadcaster_spec; - const Listener *m_listener; + const lldb::ListenerSP m_listener_sp; }; class ListenerMatches { public: - ListenerMatches (const Listener &in_listener) : - m_listener (&in_listener) + explicit ListenerMatches (const lldb::ListenerSP in_listener_sp) : + m_listener_sp (in_listener_sp) { } @@ -194,15 +204,44 @@ private: bool operator () (const event_listener_key input) const { - if (input.second == m_listener) + if (input.second == m_listener_sp) return true; else return false; } private: - const Listener *m_listener; + const lldb::ListenerSP m_listener_sp; + }; + class ListenerMatchesPointer + { + public: + ListenerMatchesPointer (const Listener *in_listener) : + m_listener (in_listener) + { + } + + ~ListenerMatchesPointer() = default; + + bool operator () (const event_listener_key input) const + { + if (input.second.get() == m_listener) + return true; + else + return false; + } + + bool operator () (const lldb::ListenerSP input) const + { + if (input.get() == m_listener) + return true; + else + return false; + } + + private: + const Listener *m_listener; }; }; @@ -241,6 +280,8 @@ private: //---------------------------------------------------------------------- class Broadcaster { +friend class Listener; +friend class Event; public: //------------------------------------------------------------------ /// Construct with a broadcaster with a name. @@ -249,7 +290,7 @@ public: /// A NULL terminated C string that contains the name of the /// broadcaster object. //------------------------------------------------------------------ - Broadcaster (BroadcasterManager *manager, const char *name); + Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name); //------------------------------------------------------------------ /// Destructor. @@ -279,22 +320,43 @@ public: /// //------------------------------------------------------------------ void - BroadcastEvent (lldb::EventSP &event_sp); + BroadcastEvent (lldb::EventSP &event_sp) + { + m_broadcaster_sp->BroadcastEvent(event_sp); + } void - BroadcastEventIfUnique (lldb::EventSP &event_sp); + BroadcastEventIfUnique (lldb::EventSP &event_sp) + { + m_broadcaster_sp->BroadcastEventIfUnique(event_sp); + } void - BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); + BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp) + { + m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); + } void - BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr); + BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) + { + m_broadcaster_sp->BroadcastEvent(event_type, event_data); + } void - Clear(); + BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr) + { + m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data); + } + + void + Clear() + { + m_broadcaster_sp->Clear(); + } virtual void - AddInitialEventsToListener (Listener *listener, uint32_t requested_events); + AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events); //------------------------------------------------------------------ /// Listen for any events specified by \a event_mask. @@ -319,7 +381,10 @@ public: /// The actual event bits that were acquired by \a listener. //------------------------------------------------------------------ uint32_t - AddListener (Listener* listener, uint32_t event_mask); + AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask) + { + return m_broadcaster_sp->AddListener(listener_sp, event_mask); + } //------------------------------------------------------------------ /// Get the NULL terminated C string name of this Broadcaster @@ -329,7 +394,10 @@ public: /// The NULL terminated C string name of this Broadcaster. //------------------------------------------------------------------ const ConstString & - GetBroadcasterName (); + GetBroadcasterName () + { + return m_broadcaster_name; + } //------------------------------------------------------------------ /// Get the event name(s) for one or more event bits. @@ -341,7 +409,10 @@ public: /// The NULL terminated C string name of this Broadcaster. //------------------------------------------------------------------ bool - GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const; + GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const + { + return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name); + } //------------------------------------------------------------------ /// Set the name for an event bit. @@ -356,20 +427,20 @@ public: void SetEventName (uint32_t event_mask, const char *name) { - m_event_names[event_mask] = name; + m_broadcaster_sp->SetEventName(event_mask, name); } const char * GetEventName (uint32_t event_mask) const { - const auto pos = m_event_names.find (event_mask); - if (pos != m_event_names.end()) - return pos->second.c_str(); - return nullptr; + return m_broadcaster_sp->GetEventName(event_mask); } bool - EventTypeHasListeners (uint32_t event_type); + EventTypeHasListeners (uint32_t event_type) + { + return m_broadcaster_sp->EventTypeHasListeners(event_type); + } //------------------------------------------------------------------ /// Removes a Listener from this broadcasters list and frees the @@ -390,7 +461,10 @@ public: /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) //------------------------------------------------------------------ bool - RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX); + RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX) + { + return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); + } //------------------------------------------------------------------ /// Provides a simple mechanism to temporarily redirect events from @@ -414,17 +488,26 @@ public: /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) //------------------------------------------------------------------ bool - HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX); + HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX) + { + return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); + } bool - IsHijackedForEvent (uint32_t event_mask); + IsHijackedForEvent (uint32_t event_mask) + { + return m_broadcaster_sp->IsHijackedForEvent(event_mask); + } //------------------------------------------------------------------ /// Restore the state of the Broadcaster from a previous hijack attempt. /// //------------------------------------------------------------------ void - RestoreBroadcaster (); + RestoreBroadcaster () + { + m_broadcaster_sp->RestoreBroadcaster(); + } // This needs to be filled in if you are going to register the broadcaster with the broadcaster // manager and do broadcaster class matching. @@ -432,35 +515,158 @@ public: // with the BroadcasterManager, so that it is clearer how to add one. virtual ConstString &GetBroadcasterClass() const; - BroadcasterManager *GetManager(); + lldb::BroadcasterManagerSP GetManager(); protected: - void - PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); + // BroadcasterImpl contains the actual Broadcaster implementation. The Broadcaster makes a BroadcasterImpl + // which lives as long as it does. The Listeners & the Events hold a weak pointer to the BroadcasterImpl, + // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to + // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads + // simultaneously. + // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters + // (e.g. the Target and the Process) are shared in their own right. + // + // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the + // public Broadcaster API above. + + + class BroadcasterImpl + { + friend class Listener; + friend class Broadcaster; + public: + BroadcasterImpl (Broadcaster &broadcaster); + + ~BroadcasterImpl() = default; + + void + BroadcastEvent (lldb::EventSP &event_sp); + + void + BroadcastEventIfUnique (lldb::EventSP &event_sp); + void + BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); + + void + BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp); + + void + BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr); + + void + Clear(); + + uint32_t + AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask); + + const char * + GetBroadcasterName () const + { + return m_broadcaster.GetBroadcasterName().AsCString(); + } + + Broadcaster * + GetBroadcaster(); + + bool + GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const; + + void + SetEventName (uint32_t event_mask, const char *name) + { + m_event_names[event_mask] = name; + } + + const char * + GetEventName (uint32_t event_mask) const + { + const auto pos = m_event_names.find (event_mask); + if (pos != m_event_names.end()) + return pos->second.c_str(); + return nullptr; + } + + bool + EventTypeHasListeners (uint32_t event_type); + + bool + RemoveListener (lldb_private::Listener *listener, uint32_t event_mask = UINT32_MAX); + + bool + RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX); + + bool + HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX); + + bool + IsHijackedForEvent (uint32_t event_mask); + + void + RestoreBroadcaster (); + + protected: + void + PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); + + const char * + GetHijackingListenerName(); + + //------------------------------------------------------------------ + // + //------------------------------------------------------------------ + typedef std::list< std::pair<lldb::ListenerWP,uint32_t> > collection; + typedef std::map<uint32_t, std::string> event_names_map; + + void + ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback); + + + Broadcaster &m_broadcaster; ///< The broadcsater that this implements + event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit + collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. + std::recursive_mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners. + std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster + std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener + // collections, but for now this is just for private hijacking. + + private: + //------------------------------------------------------------------ + // For Broadcaster only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl); + }; + + typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; + typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; + + BroadcasterImplSP + GetBroadcasterImpl() + { + return m_broadcaster_sp; + } + + const char * + GetHijackingListenerName() + { + return m_broadcaster_sp->GetHijackingListenerName(); + } //------------------------------------------------------------------ // Classes that inherit from Broadcaster can see and modify these //------------------------------------------------------------------ - typedef std::vector< std::pair<Listener*,uint32_t> > collection; - typedef std::map<uint32_t, std::string> event_names_map; - // Prefix the name of our member variables with "m_broadcaster_" - // since this is a class that gets subclassed. - const ConstString m_broadcaster_name; ///< The name of this broadcaster object. - event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit - collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. - Mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners. - std::vector<Listener *> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster - std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener - // collections, but for now this is just for private hijacking. - BroadcasterManager *m_manager; + private: //------------------------------------------------------------------ // For Broadcaster only //------------------------------------------------------------------ + BroadcasterImplSP m_broadcaster_sp; + lldb::BroadcasterManagerSP m_manager_sp; + const ConstString m_broadcaster_name; ///< The name of this broadcaster object. + DISALLOW_COPY_AND_ASSIGN (Broadcaster); }; } // namespace lldb_private -#endif // liblldb_Broadcaster_h_ +#endif // liblldb_Broadcaster_h_ diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h index d29aaca9c2ea..8913f1631a8b 100644 --- a/include/lldb/Core/Communication.h +++ b/include/lldb/Core/Communication.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <atomic> +#include <mutex> #include <string> // Other libraries and framework includes @@ -21,7 +22,6 @@ #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" #include "lldb/Host/HostThread.h" -#include "lldb/Host/Mutex.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -358,10 +358,10 @@ protected: HostThread m_read_thread; ///< The read thread handle in case we need to cancel the thread. std::atomic<bool> m_read_thread_enabled; std::atomic<bool> m_read_thread_did_exit; - std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. - Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes. - Mutex m_write_mutex; ///< Don't let multiple threads write at the same time... - Mutex m_synchronize_mutex; + std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. + std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes. + std::mutex m_write_mutex; ///< Don't let multiple threads write at the same time... + std::mutex m_synchronize_mutex; ReadThreadBytesReceived m_callback; void *m_callback_baton; bool m_close_on_eof; diff --git a/include/lldb/Core/ConstString.h b/include/lldb/Core/ConstString.h index 6e234da0a595..c678168790a8 100644 --- a/include/lldb/Core/ConstString.h +++ b/include/lldb/Core/ConstString.h @@ -291,12 +291,37 @@ public: } //------------------------------------------------------------------ + /// Equal to operator + /// + /// Returns true if this string is equal to the string in \a rhs. + /// If case sensitive equality is tested, this operation is very + /// fast as it results in a pointer comparison since all strings + /// are in a uniqued in a global string pool. + /// + /// @param[in] rhs + /// The Left Hand Side const ConstString object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const ConstString object reference. + /// + /// @param[in] case_sensitive + /// Case sensitivity. If true, case sensitive equality + /// will be tested, otherwise character case will be ignored + /// + /// @return + /// @li \b true if this object is equal to \a rhs. + /// @li \b false if this object is not equal to \a rhs. + //------------------------------------------------------------------ + static bool + Equals(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive = true); + + //------------------------------------------------------------------ /// Compare two string objects. /// /// Compares the C string values contained in \a lhs and \a rhs and /// returns an integer result. /// - /// NOTE: only call this function when you want a true string + /// NOTE: only call this function when you want a true string /// comparison. If you want string equality use the, use the == /// operator as it is much more efficient. Also if you want string /// inequality, use the != operator for the same reasons. @@ -307,13 +332,17 @@ public: /// @param[in] rhs /// The Right Hand Side const ConstString object reference. /// + /// @param[in] case_sensitive + /// Case sensitivity of compare. If true, case sensitive compare + /// will be performed, otherwise character case will be ignored + /// /// @return /// @li -1 if lhs < rhs /// @li 0 if lhs == rhs /// @li 1 if lhs > rhs //------------------------------------------------------------------ static int - Compare (const ConstString& lhs, const ConstString& rhs); + Compare(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive = true); //------------------------------------------------------------------ /// Dump the object description to a stream. diff --git a/include/lldb/Core/DataExtractor.h b/include/lldb/Core/DataExtractor.h index d5cb5e8ba4bc..51ecade2d374 100644 --- a/include/lldb/Core/DataExtractor.h +++ b/include/lldb/Core/DataExtractor.h @@ -763,8 +763,10 @@ public: /// /// @param[in] bitfield_bit_offset /// The bit offset of the bitfield value in the extracted - /// integer (the number of bits to shift the integer to the - /// right). + /// integer. For little-endian data, this is the offset of + /// the LSB of the bitfield from the LSB of the integer. + /// For big-endian data, this is the offset of the MSB of the + /// bitfield from the MSB of the integer. /// /// @return /// The unsigned bitfield integer value that was extracted, or @@ -805,8 +807,10 @@ public: /// /// @param[in] bitfield_bit_offset /// The bit offset of the bitfield value in the extracted - /// integer (the number of bits to shift the integer to the - /// right). + /// integer. For little-endian data, this is the offset of + /// the LSB of the bitfield from the LSB of the integer. + /// For big-endian data, this is the offset of the MSB of the + /// bitfield from the MSB of the integer. /// /// @return /// The signed bitfield integer value that was extracted, or diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index 4ca648ca296e..7a969457eef6 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -16,6 +16,7 @@ // C++ Includes #include <memory> #include <map> +#include <mutex> #include <vector> // Other libraries and framework includes @@ -53,8 +54,7 @@ namespace lldb_private { class Debugger : public std::enable_shared_from_this<Debugger>, public UserID, - public Properties, - public BroadcasterManager + public Properties { friend class SourceManager; // For GetSourceFileCache. @@ -159,10 +159,10 @@ public: return *m_command_interpreter_ap; } - Listener & + lldb::ListenerSP GetListener () { - return m_listener; + return m_listener_sp; } // This returns the Debugger's scratch source manager. It won't be able to look up files in debug @@ -392,6 +392,12 @@ public: Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); Target *GetDummyTarget(); + lldb::BroadcasterManagerSP + GetBroadcasterManager() + { + return m_broadcaster_manager_sp; + } + protected: friend class CommandInterpreter; friend class REPL; @@ -446,15 +452,20 @@ protected: void InstanceInitialize (); - + lldb::StreamFileSP m_input_file_sp; lldb::StreamFileSP m_output_file_sp; lldb::StreamFileSP m_error_file_sp; + + lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a broadcaster manager of last resort. + // It needs to get constructed before the target_list or any other + // member that might want to broadcast through the debugger. + TerminalState m_terminal_state; TargetList m_target_list; PlatformList m_platform_list; - Listener m_listener; + lldb::ListenerSP m_listener_sp; std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets. SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared // source file cache. @@ -472,6 +483,7 @@ protected: HostThread m_io_handler_thread; Broadcaster m_sync_broadcaster; lldb::ListenerSP m_forward_listener_sp; + std::once_flag m_clear_once; //---------------------------------------------------------------------- // Events for m_sync_broadcaster diff --git a/include/lldb/Core/EmulateInstruction.h b/include/lldb/Core/EmulateInstruction.h index c5e60022fc96..36fff43bf6bc 100644 --- a/include/lldb/Core/EmulateInstruction.h +++ b/include/lldb/Core/EmulateInstruction.h @@ -384,6 +384,11 @@ public: const RegisterInfo *reg_info, const RegisterValue ®_value); + // Type to represent the condition of an instruction. The UINT32 value is reserved for the + // unconditional case and all other value can be used in an architecture dependent way. + typedef uint32_t InstructionCondition; + static const InstructionCondition UnconditionalCondition = UINT32_MAX; + EmulateInstruction (const ArchSpec &arch); ~EmulateInstruction() override = default; @@ -403,8 +408,8 @@ public: virtual bool EvaluateInstruction (uint32_t evaluate_options) = 0; - virtual bool - IsInstructionConditional() { return false; } + virtual InstructionCondition + GetInstructionCondition() { return UnconditionalCondition; } virtual bool TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0; diff --git a/include/lldb/Core/Event.h b/include/lldb/Core/Event.h index e8867c0e7e77..1ae0fc83b27e 100644 --- a/include/lldb/Core/Event.h +++ b/include/lldb/Core/Event.h @@ -20,6 +20,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" #include "lldb/Host/Predicate.h" +#include "lldb/Core/Broadcaster.h" namespace lldb_private { @@ -113,20 +114,66 @@ private: DISALLOW_COPY_AND_ASSIGN (EventDataBytes); }; +class EventDataReceipt : public EventData +{ +public: + EventDataReceipt() : + EventData(), + m_predicate(false) + { + } + + ~EventDataReceipt() override + { + } + + static const ConstString & + GetFlavorString () + { + static ConstString g_flavor("Process::ProcessEventData"); + return g_flavor; + } + + const ConstString & + GetFlavor () const override + { + return GetFlavorString(); + } + + bool + WaitForEventReceived (const TimeValue *abstime = nullptr, bool *timed_out = nullptr) + { + return m_predicate.WaitForValueEqualTo(true, abstime, timed_out); + } + +private: + Predicate<bool> m_predicate; + + void + DoOnRemoval (Event *event_ptr) override + { + m_predicate.SetValue(true, eBroadcastAlways); + } +}; + //---------------------------------------------------------------------- // lldb::Event //---------------------------------------------------------------------- class Event { - friend class Broadcaster; friend class Listener; friend class EventData; + friend class Broadcaster::BroadcasterImpl; public: Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data = nullptr); + Event(Broadcaster *broadcaster, uint32_t event_type, const lldb::EventDataSP &event_data_sp); + Event(uint32_t event_type, EventData *data = nullptr); + Event(uint32_t event_type, const lldb::EventDataSP &event_data_sp); + ~Event (); void @@ -135,19 +182,19 @@ public: EventData * GetData () { - return m_data_ap.get(); + return m_data_sp.get(); } const EventData * GetData () const { - return m_data_ap.get(); + return m_data_sp.get(); } void SetData (EventData *new_data) { - m_data_ap.reset (new_data); + m_data_sp.reset (new_data); } uint32_t @@ -165,19 +212,27 @@ public: Broadcaster * GetBroadcaster () const { - return m_broadcaster; + Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock(); + if (broadcaster_impl_sp) + return broadcaster_impl_sp->GetBroadcaster(); + else + return nullptr; } bool BroadcasterIs (Broadcaster *broadcaster) { - return broadcaster == m_broadcaster; + Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock(); + if (broadcaster_impl_sp) + return broadcaster_impl_sp->GetBroadcaster() == broadcaster; + else + return false; } void Clear() { - m_data_ap.reset(); + m_data_sp.reset(); } private: @@ -194,12 +249,12 @@ private: void SetBroadcaster (Broadcaster *broadcaster) { - m_broadcaster = broadcaster; + m_broadcaster_wp = broadcaster->GetBroadcasterImpl(); } - Broadcaster * m_broadcaster; // The broadcaster that sent this event - uint32_t m_type; // The bit describing this event - std::unique_ptr<EventData> m_data_ap; // User specific data for this event + Broadcaster::BroadcasterImplWP m_broadcaster_wp; // The broadcaster that sent this event + uint32_t m_type; // The bit describing this event + lldb::EventDataSP m_data_sp; // User specific data for this event DISALLOW_COPY_AND_ASSIGN (Event); diff --git a/include/lldb/Core/History.h b/include/lldb/Core/History.h index fbb7bd8b0c1a..164d1bfb651b 100644 --- a/include/lldb/Core/History.h +++ b/include/lldb/Core/History.h @@ -14,13 +14,13 @@ #include <stdint.h> // C++ Includes +#include <mutex> #include <stack> #include <string> // Other libraries and framework includes // Project includes #include "lldb/lldb-public.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -34,11 +34,7 @@ class HistorySource public: typedef const void * HistoryEvent; - HistorySource () : - m_mutex (Mutex::eMutexTypeRecursive), - m_events () - { - } + HistorySource() : m_mutex(), m_events() {} virtual ~HistorySource() @@ -50,20 +46,20 @@ public: // onto the end of the history stack. virtual HistoryEvent - CreateHistoryEvent () = 0; - + CreateHistoryEvent () = 0; + virtual void DeleteHistoryEvent (HistoryEvent event) = 0; - + virtual void DumpHistoryEvent (Stream &strm, HistoryEvent event) = 0; virtual size_t GetHistoryEventCount() = 0; - + virtual HistoryEvent GetHistoryEventAtIndex (uint32_t idx) = 0; - + virtual HistoryEvent GetCurrentHistoryEvent () = 0; @@ -71,16 +67,16 @@ public: virtual int CompareHistoryEvents (const HistoryEvent lhs, const HistoryEvent rhs) = 0; - + virtual bool IsCurrentHistoryEvent (const HistoryEvent event) = 0; private: typedef std::stack<HistoryEvent> collection; - Mutex m_mutex; + std::recursive_mutex m_mutex; collection m_events; - + DISALLOW_COPY_AND_ASSIGN (HistorySource); }; diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h index 3eba1c3cc9d8..1844df365158 100644 --- a/include/lldb/Core/IOHandler.h +++ b/include/lldb/Core/IOHandler.h @@ -15,6 +15,7 @@ // C++ Includes #include <memory> +#include <mutex> #include <string> #include <vector> @@ -28,7 +29,6 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/StringList.h" #include "lldb/Core/ValueObjectList.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/Predicate.h" namespace curses @@ -709,75 +709,70 @@ namespace lldb_private { class IOHandlerStack { public: - IOHandlerStack () : - m_stack(), - m_mutex(Mutex::eMutexTypeRecursive), - m_top (nullptr) - { - } - + IOHandlerStack() : m_stack(), m_mutex(), m_top(nullptr) {} + ~IOHandlerStack() = default; - + size_t - GetSize () const + GetSize() const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_stack.size(); } - + void - Push (const lldb::IOHandlerSP& sp) + Push(const lldb::IOHandlerSP &sp) { if (sp) { - Mutex::Locker locker (m_mutex); - sp->SetPopped (false); - m_stack.push_back (sp); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + sp->SetPopped(false); + m_stack.push_back(sp); // Set m_top the non-locking IsTop() call m_top = sp.get(); } } - + bool - IsEmpty () const + IsEmpty() const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_stack.empty(); } - + lldb::IOHandlerSP - Top () + Top() { lldb::IOHandlerSP sp; { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_stack.empty()) sp = m_stack.back(); } return sp; } - + void - Pop () + Pop() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_stack.empty()) { - lldb::IOHandlerSP sp (m_stack.back()); + lldb::IOHandlerSP sp(m_stack.back()); m_stack.pop_back(); - sp->SetPopped (true); + sp->SetPopped(true); } // Set m_top the non-locking IsTop() call m_top = (m_stack.empty() ? nullptr : m_stack.back().get()); } - Mutex & + std::recursive_mutex & GetMutex() { return m_mutex; } - + bool IsTop (const lldb::IOHandlerSP &io_handler_sp) const { @@ -785,13 +780,12 @@ namespace lldb_private { } bool - CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type) + CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const size_t num_io_handlers = m_stack.size(); - return (num_io_handlers >= 2 && - m_stack[num_io_handlers-1]->GetType() == top_type && - m_stack[num_io_handlers-2]->GetType() == second_top_type); + return (num_io_handlers >= 2 && m_stack[num_io_handlers - 1]->GetType() == top_type && + m_stack[num_io_handlers - 2]->GetType() == second_top_type); } ConstString @@ -818,9 +812,9 @@ namespace lldb_private { protected: typedef std::vector<lldb::IOHandlerSP> collection; collection m_stack; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; IOHandler *m_top; - + private: DISALLOW_COPY_AND_ASSIGN (IOHandlerStack); }; diff --git a/include/lldb/Core/Listener.h b/include/lldb/Core/Listener.h index b11c1644507b..1057cf35c6db 100644 --- a/include/lldb/Core/Listener.h +++ b/include/lldb/Core/Listener.h @@ -14,18 +14,21 @@ // C++ Includes #include <list> #include <map> +#include <mutex> #include <string> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -#include "lldb/Host/Predicate.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Host/Condition.h" #include "lldb/Core/Event.h" namespace lldb_private { -class Listener +class Listener : + public std::enable_shared_from_this<Listener> { public: typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton); @@ -36,8 +39,16 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ + // + // Listeners have to be constructed into shared pointers - at least if you want them to listen to + // Broadcasters, +protected: Listener (const char *name); +public: + static lldb::ListenerSP + MakeListener(const char *name); + ~Listener (); void @@ -53,11 +64,11 @@ public: } uint32_t - StartListeningForEventSpec (BroadcasterManager &manager, + StartListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp, const BroadcastEventSpec &event_spec); bool - StopListeningForEventSpec (BroadcasterManager &manager, + StopListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp, const BroadcastEventSpec &event_spec); uint32_t @@ -133,12 +144,15 @@ private: void *callback_user_data; }; - typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection; + typedef std::multimap<Broadcaster::BroadcasterImplWP, + BroadcasterInfo, + std::owner_less<Broadcaster::BroadcasterImplWP>> broadcaster_collection; typedef std::list<lldb::EventSP> event_collection; - typedef std::vector<BroadcasterManager *> broadcaster_manager_collection; + typedef std::vector<lldb::BroadcasterManagerWP> broadcaster_manager_collection; bool - FindNextEventInternal(Broadcaster *broadcaster, // nullptr for any broadcaster + FindNextEventInternal(Mutex::Locker& lock, + Broadcaster *broadcaster, // nullptr for any broadcaster const ConstString *sources, // nullptr for any event uint32_t num_sources, uint32_t event_type_mask, @@ -162,17 +176,17 @@ private: std::string m_name; broadcaster_collection m_broadcasters; - Mutex m_broadcasters_mutex; // Protects m_broadcasters + std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters event_collection m_events; Mutex m_events_mutex; // Protects m_broadcasters and m_events - Predicate<bool> m_cond_wait; + Condition m_events_condition; broadcaster_manager_collection m_broadcaster_managers; void BroadcasterWillDestruct (Broadcaster *); void - BroadcasterManagerWillDestruct (BroadcasterManager *manager); + BroadcasterManagerWillDestruct (lldb::BroadcasterManagerSP manager_sp); // broadcaster_collection::iterator diff --git a/include/lldb/Core/Logging.h b/include/lldb/Core/Logging.h index ca04c84b21a6..da8c0d8f5bb6 100644 --- a/include/lldb/Core/Logging.h +++ b/include/lldb/Core/Logging.h @@ -49,6 +49,7 @@ #define LIBLLDB_LOG_JIT_LOADER (1u << 27) #define LIBLLDB_LOG_LANGUAGE (1u << 28) #define LIBLLDB_LOG_DATAFORMATTERS (1u << 29) +#define LIBLLDB_LOG_DEMANGLE (1u << 30) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ diff --git a/include/lldb/Core/MappedHash.h b/include/lldb/Core/MappedHash.h index 5a52ab2b8b2d..b7cf3b02e01e 100644 --- a/include/lldb/Core/MappedHash.h +++ b/include/lldb/Core/MappedHash.h @@ -47,6 +47,9 @@ public: static uint32_t HashString (uint32_t hash_function, const char *s) { + if (!s) + return 0; + switch (hash_function) { case MappedHash::eHashFunctionDJB: @@ -434,6 +437,9 @@ public: bool Find (const char *name, Pair &pair) const { + if (!name || !name[0]) + return false; + if (IsValid ()) { const uint32_t bucket_count = m_header.bucket_count; diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h index 35b182aa9801..46fa330fb19c 100644 --- a/include/lldb/Core/Module.h +++ b/include/lldb/Core/Module.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <atomic> +#include <mutex> #include <string> #include <vector> @@ -22,11 +23,11 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/UUID.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/TimeValue.h" #include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/PathMappingList.h" +#include "llvm/ADT/DenseSet.h" namespace lldb_private { @@ -67,7 +68,7 @@ public: static Module * GetAllocatedModuleAtIndex (size_t idx); - static Mutex * + static std::recursive_mutex & GetAllocationModuleCollectionMutex(); //------------------------------------------------------------------ @@ -498,6 +499,7 @@ public: const ConstString &type_name, bool exact_match, size_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeList& types); lldb::TypeSP @@ -984,8 +986,8 @@ public: // SymbolVendor, SymbolFile and ObjectFile member objects should // lock the module mutex to avoid deadlocks. //------------------------------------------------------------------ - Mutex & - GetMutex () const + std::recursive_mutex & + GetMutex() const { return m_mutex; } @@ -1046,65 +1048,96 @@ public: bool RemapSourceFile (const char *path, std::string &new_path) const; - //------------------------------------------------------------------ - /// Prepare to do a function name lookup. - /// - /// Looking up functions by name can be a tricky thing. LLDB requires - /// that accelerator tables contain full names for functions as well - /// as function basenames which include functions, class methods and - /// class functions. When the user requests that an action use a - /// function by name, we are sometimes asked to automatically figure - /// out what a name could possibly map to. A user might request a - /// breakpoint be set on "count". If no options are supplied to limit - /// the scope of where to search for count, we will by default match - /// any function names named "count", all class and instance methods - /// named "count" (no matter what the namespace or contained context) - /// and any selectors named "count". If a user sp |