Vendor import of lldb trunk r338150:
https://llvm.org/svn/llvm-project/lldb/trunk@338150
This commit is contained in:
parent
160ee69dd7
commit
f73363f1dd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/lldb/dist/; revision=336823 svn path=/vendor/lldb/lldb-trunk-r338150/; revision=336824; tag=vendor/lldb/lldb-trunk-r338150
6
.gitignore
vendored
6
.gitignore
vendored
@ -37,8 +37,6 @@ ninja/
|
||||
*xcuserdata
|
||||
test/20*
|
||||
__pycache__/
|
||||
*.lock
|
||||
*.so
|
||||
|
||||
clang-module-cache
|
||||
|
||||
@ -53,7 +51,3 @@ tags
|
||||
# Ignore test trace directories.
|
||||
20??-??-??-??_??_??/
|
||||
|
||||
# Ignore crashlog support files.
|
||||
crashinfo.lock
|
||||
crashinfo.so
|
||||
|
||||
|
109
CMakeLists.txt
109
CMakeLists.txt
@ -29,13 +29,39 @@ endif ()
|
||||
set(LLDB_DISABLE_LIBEDIT ${LLDB_DEFAULT_DISABLE_LIBEDIT} CACHE BOOL "Disables the use of editline.")
|
||||
if (LLDB_DISABLE_LIBEDIT)
|
||||
add_definitions( -DLLDB_DISABLE_LIBEDIT )
|
||||
else()
|
||||
find_package(LibEdit REQUIRED)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
add_definitions(-DLLDB_USE_OS_LOG)
|
||||
endif()
|
||||
|
||||
# add_subdirectory(include)
|
||||
# lldb-suite is a dummy target that encompasses all the necessary tools and
|
||||
# libraries for building a fully-functioning liblldb.
|
||||
add_custom_target(lldb-suite)
|
||||
set(LLDB_SUITE_TARGET lldb-suite)
|
||||
|
||||
option(LLDB_BUILD_FRAMEWORK "Build the Darwin LLDB.framework" Off)
|
||||
if(LLDB_BUILD_FRAMEWORK)
|
||||
if (CMAKE_VERSION VERSION_LESS 3.7)
|
||||
message(FATAL_ERROR "LLDB_BUILD_FRAMEWORK is not supported on CMake < 3.7")
|
||||
endif()
|
||||
if (NOT APPLE)
|
||||
message(FATAL_ERROR "LLDB.framework can only be generated when targeting Apple platforms")
|
||||
endif()
|
||||
|
||||
# These are used to fill out LLDB-Info.plist. These are relevant when building
|
||||
# the framework, and must be defined before building liblldb.
|
||||
set(PRODUCT_NAME "LLDB")
|
||||
set(EXECUTABLE_NAME "LLDB")
|
||||
set(CURRENT_PROJECT_VERSION "360.99.0")
|
||||
set(LLDB_SUITE_TARGET lldb-framework)
|
||||
|
||||
set(LLDB_FRAMEWORK_DIR
|
||||
${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR})
|
||||
endif()
|
||||
|
||||
add_subdirectory(docs)
|
||||
if (NOT LLDB_DISABLE_PYTHON)
|
||||
if(LLDB_USE_SYSTEM_SIX)
|
||||
@ -45,8 +71,7 @@ if (NOT LLDB_DISABLE_PYTHON)
|
||||
set(LLDB_PYTHON_TARGET_DIR ${LLDB_BINARY_DIR}/scripts)
|
||||
set(LLDB_WRAP_PYTHON ${LLDB_BINARY_DIR}/scripts/LLDBWrapPython.cpp)
|
||||
if(LLDB_BUILD_FRAMEWORK)
|
||||
set(LLDB_PYTHON_TARGET_DIR
|
||||
${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_FRAMEWORK_INSTALL_DIR})
|
||||
set(LLDB_PYTHON_TARGET_DIR ${LLDB_FRAMEWORK_DIR})
|
||||
set(LLDB_WRAP_PYTHON ${LLDB_PYTHON_TARGET_DIR}/LLDBWrapPython.cpp)
|
||||
else()
|
||||
# Don't set -m when building the framework.
|
||||
@ -56,31 +81,90 @@ if (NOT LLDB_DISABLE_PYTHON)
|
||||
|
||||
add_subdirectory(scripts)
|
||||
endif ()
|
||||
|
||||
add_subdirectory(source)
|
||||
add_subdirectory(tools)
|
||||
|
||||
option(LLDB_INCLUDE_TESTS "Generate build targets for the LLDB unit tests."
|
||||
${LLVM_INCLUDE_TESTS})
|
||||
option(LLDB_TEST_USE_CUSTOM_C_COMPILER "Use the C compiler provided via LLDB_TEST_C_COMPILER for building test inferiors (instead of the just-built compiler). Defaults to OFF." OFF)
|
||||
option(LLDB_TEST_USE_CUSTOM_CXX_COMPILER "Use the C++ compiler provided via LLDB_TEST_CXX_COMPILER for building test inferiors (instead of the just-built compiler). Defaults to OFF." OFF)
|
||||
if(LLDB_INCLUDE_TESTS)
|
||||
if (TARGET clang)
|
||||
set(LLDB_DEFAULT_TEST_C_COMPILER "${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
set(LLDB_DEFAULT_TEST_CXX_COMPILER "${LLVM_BINARY_DIR}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
|
||||
# The difference between the following two paths is significant. The path to
|
||||
# LLDB will point to LLDB's binary directory, while the other will point to
|
||||
# LLVM's binary directory in case the two differ.
|
||||
set(LLDB_DEFAULT_TEST_EXECUTABLE "${LLVM_RUNTIME_OUTPUT_INTDIR}/lldb${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
set(LLDB_DEFAULT_TEST_DSYMUTIL "${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/dsymutil${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
|
||||
if (NOT LLDB_TEST_USE_CUSTOM_C_COMPILER AND TARGET clang)
|
||||
set(LLDB_DEFAULT_TEST_C_COMPILER "${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
else()
|
||||
set(LLDB_DEFAULT_TEST_C_COMPILER "")
|
||||
endif()
|
||||
|
||||
if (NOT LLDB_TEST_USE_CUSTOM_CXX_COMPILER AND TARGET clang)
|
||||
set(LLDB_DEFAULT_TEST_CXX_COMPILER "${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
else()
|
||||
set(LLDB_DEFAULT_TEST_CXX_COMPILER "")
|
||||
endif()
|
||||
|
||||
set(LLDB_TEST_EXECUTABLE "${LLDB_DEFAULT_TEST_EXECUTABLE}" CACHE PATH "lldb executable used for testing")
|
||||
set(LLDB_TEST_C_COMPILER "${LLDB_DEFAULT_TEST_C_COMPILER}" CACHE PATH "C Compiler to use for building LLDB test inferiors")
|
||||
set(LLDB_TEST_CXX_COMPILER "${LLDB_DEFAULT_TEST_CXX_COMPILER}" CACHE PATH "C++ Compiler to use for building LLDB test inferiors")
|
||||
set(LLDB_TEST_DSYMUTIL "${LLDB_DEFAULT_TEST_DSYMUTIL}" CACHE PATH "dsymutil used for generating dSYM bundles")
|
||||
|
||||
if (("${LLDB_TEST_C_COMPILER}" STREQUAL "") OR
|
||||
("${LLDB_TEST_CXX_COMPILER}" STREQUAL ""))
|
||||
message(FATAL_ERROR "LLDB test compilers not specified. Tests will not run")
|
||||
endif()
|
||||
|
||||
set(LLDB_TEST_DEPS lldb)
|
||||
|
||||
# darwin-debug is an hard dependency for the testsuite.
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
list(APPEND LLDB_TEST_DEPS darwin-debug)
|
||||
endif()
|
||||
|
||||
if(TARGET lldb-server)
|
||||
list(APPEND LLDB_TEST_DEPS lldb-server)
|
||||
endif()
|
||||
|
||||
if(TARGET debugserver)
|
||||
if(NOT CMAKE_HOST_APPLE OR LLDB_CODESIGN_IDENTITY)
|
||||
list(APPEND LLDB_TEST_DEPS debugserver)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(TARGET lldb-mi)
|
||||
list(APPEND LLDB_TEST_DEPS lldb-mi)
|
||||
endif()
|
||||
|
||||
if(NOT LLDB_BUILT_STANDALONE)
|
||||
list(APPEND LLDB_TEST_DEPS yaml2obj)
|
||||
endif()
|
||||
|
||||
if(TARGET liblldb)
|
||||
list(APPEND LLDB_TEST_DEPS liblldb)
|
||||
endif()
|
||||
|
||||
if(TARGET clang)
|
||||
list(APPEND LLDB_TEST_DEPS clang)
|
||||
endif()
|
||||
|
||||
if(TARGET dsymutil)
|
||||
list(APPEND LLDB_TEST_DEPS dsymutil)
|
||||
endif()
|
||||
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(unittests)
|
||||
add_subdirectory(lit)
|
||||
add_subdirectory(utils/lldb-dotest)
|
||||
endif()
|
||||
|
||||
if (LLDB_BUILD_FRAMEWORK)
|
||||
add_custom_target(lldb-framework)
|
||||
include(LLDBFramework)
|
||||
endif()
|
||||
|
||||
if (NOT LLDB_DISABLE_PYTHON)
|
||||
@ -91,7 +175,7 @@ if (NOT LLDB_DISABLE_PYTHON)
|
||||
${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
|
||||
--srcRoot=${LLDB_SOURCE_DIR}
|
||||
--targetDir=${LLDB_PYTHON_TARGET_DIR}
|
||||
--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}/scripts
|
||||
--cfgBldDir=${LLDB_PYTHON_TARGET_DIR}
|
||||
--prefix=${CMAKE_BINARY_DIR}
|
||||
--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}
|
||||
--lldbLibDir=lib${LLVM_LIBDIR_SUFFIX}
|
||||
@ -99,10 +183,11 @@ if (NOT LLDB_DISABLE_PYTHON)
|
||||
${FINISH_EXTRA_ARGS}
|
||||
VERBATIM
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scripts/lldb.py
|
||||
DEPENDS ${LLDB_PYTHON_TARGET_DIR}/lldb.py
|
||||
COMMENT "Python script sym-linking LLDB Python API")
|
||||
# We depend on liblldb being built before we can do this step.
|
||||
add_dependencies(finish_swig liblldb lldb-argdumper)
|
||||
|
||||
# We depend on liblldb and lldb-argdumper being built before we can do this step.
|
||||
add_dependencies(finish_swig ${LLDB_SUITE_TARGET})
|
||||
|
||||
# If we build the readline module, we depend on that happening
|
||||
# first.
|
||||
@ -113,8 +198,8 @@ if (NOT LLDB_DISABLE_PYTHON)
|
||||
# Ensure we do the python post-build step when building lldb.
|
||||
add_dependencies(lldb finish_swig)
|
||||
|
||||
if(LLDB_BUILD_FRAMEWORK)
|
||||
# The target to install libLLDB needs to depend on finish swig so that the
|
||||
if (LLDB_BUILD_FRAMEWORK)
|
||||
# The target to install libLLDB needs to depend on finish_swig so that the
|
||||
# framework build properly copies over the Python files.
|
||||
add_dependencies(install-liblldb finish_swig)
|
||||
endif()
|
||||
|
@ -17,7 +17,7 @@ D: Build scripts, Test suite, Platform, gdb-remote, Anything not covered by this
|
||||
N: Jim Ingham
|
||||
E: jingham@apple.com
|
||||
D: Overall LLDB architecture, Thread plans, Expression parser, ValueObject, Breakpoints, ABI
|
||||
D: Watchpoints, Trampolines, Target, Command Interpreter, C++ / Objective C Language runtime
|
||||
D: Watchpoints, Trampolines, Target, Command Interpreter, C++ / Objective-C Language runtime
|
||||
D: Expression evaluator, IR interpreter, Clang integration
|
||||
D: Data Formatters
|
||||
|
||||
|
@ -86,7 +86,7 @@ endfunction(add_lldb_library)
|
||||
|
||||
function(add_lldb_executable name)
|
||||
cmake_parse_arguments(ARG
|
||||
"INCLUDE_IN_FRAMEWORK;GENERATE_INSTALL"
|
||||
"INCLUDE_IN_SUITE;GENERATE_INSTALL"
|
||||
""
|
||||
"LINK_LIBS;LINK_COMPONENTS"
|
||||
${ARGN}
|
||||
@ -99,8 +99,9 @@ function(add_lldb_executable name)
|
||||
set_target_properties(${name} PROPERTIES
|
||||
FOLDER "lldb executables")
|
||||
|
||||
if(LLDB_BUILD_FRAMEWORK)
|
||||
if(ARG_INCLUDE_IN_FRAMEWORK)
|
||||
if(ARG_INCLUDE_IN_SUITE)
|
||||
add_dependencies(lldb-suite ${name})
|
||||
if(LLDB_BUILD_FRAMEWORK)
|
||||
if(NOT IOS)
|
||||
set(resource_dir "/Resources")
|
||||
set(resource_dots "../")
|
||||
@ -110,29 +111,23 @@ function(add_lldb_executable name)
|
||||
RUNTIME_OUTPUT_DIRECTORY $<TARGET_FILE_DIR:liblldb>${resource_dir}
|
||||
BUILD_WITH_INSTALL_RPATH On
|
||||
INSTALL_RPATH "@loader_path/../../../${resource_dots}${_dots}/${LLDB_FRAMEWORK_INSTALL_DIR}")
|
||||
# For things inside the framework we don't need functional install targets
|
||||
# because CMake copies the resources and headers from the build directory.
|
||||
# But we still need this target to exist in order to use the
|
||||
# LLVM_DISTRIBUTION_COMPONENTS build option. We also need the
|
||||
# install-liblldb target to depend on this tool, so that it gets put into
|
||||
# the Resources directory before the framework is installed.
|
||||
if(ARG_GENERATE_INSTALL)
|
||||
add_custom_target(install-${name} DEPENDS ${name})
|
||||
add_dependencies(install-liblldb ${name})
|
||||
add_custom_target(install-${name}-stripped DEPENDS ${name})
|
||||
add_dependencies(install-liblldb-stripped ${name})
|
||||
endif()
|
||||
else()
|
||||
set_target_properties(${name} PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH On
|
||||
INSTALL_RPATH "@loader_path/../${LLDB_FRAMEWORK_INSTALL_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ARG_GENERATE_INSTALL AND NOT (ARG_INCLUDE_IN_FRAMEWORK AND LLDB_BUILD_FRAMEWORK ))
|
||||
if(LLDB_BUILD_FRAMEWORK AND NOT ARG_INCLUDE_IN_SUITE)
|
||||
set_target_properties(${name} PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH On
|
||||
INSTALL_RPATH "@loader_path/../${LLDB_FRAMEWORK_INSTALL_DIR}")
|
||||
endif()
|
||||
|
||||
if(ARG_GENERATE_INSTALL)
|
||||
set(out_dir "bin")
|
||||
if (LLDB_BUILD_FRAMEWORK AND ARG_INCLUDE_IN_SUITE)
|
||||
set(out_dir ${LLDB_FRAMEWORK_INSTALL_DIR}/${LLDB_FRAMEWORK_RESOURCE_DIR})
|
||||
endif()
|
||||
install(TARGETS ${name}
|
||||
COMPONENT ${name}
|
||||
RUNTIME DESTINATION bin)
|
||||
RUNTIME DESTINATION ${out_dir})
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_llvm_install_targets(install-${name}
|
||||
DEPENDS ${name}
|
||||
@ -140,7 +135,7 @@ function(add_lldb_executable name)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ARG_INCLUDE_IN_FRAMEWORK AND LLDB_BUILD_FRAMEWORK)
|
||||
if(ARG_INCLUDE_IN_SUITE AND LLDB_BUILD_FRAMEWORK)
|
||||
add_llvm_tool_symlink(${name} ${name} ALWAYS_GENERATE SKIP_INSTALL
|
||||
OUTPUT_DIR ${LLVM_RUNTIME_OUTPUT_INTDIR})
|
||||
endif()
|
||||
|
62
cmake/modules/FindLibEdit.cmake
Normal file
62
cmake/modules/FindLibEdit.cmake
Normal file
@ -0,0 +1,62 @@
|
||||
#.rst:
|
||||
# FindLibEdit
|
||||
# -----------
|
||||
#
|
||||
# Find libedit library and headers
|
||||
#
|
||||
# The module defines the following variables:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# libedit_FOUND - true if libedit was found
|
||||
# libedit_INCLUDE_DIRS - include search path
|
||||
# libedit_LIBRARIES - libraries to link
|
||||
# libedit_VERSION - version number
|
||||
|
||||
if(libedit_INCLUDE_DIRS AND libedit_LIBRARIES)
|
||||
set(libedit_FOUND TRUE)
|
||||
else()
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_LIBEDIT QUIET libedit)
|
||||
|
||||
find_path(libedit_INCLUDE_DIRS
|
||||
NAMES
|
||||
histedit.h
|
||||
HINTS
|
||||
${PC_LIBEDIT_INCLUDEDIR}
|
||||
${PC_LIBEDIT_INCLUDE_DIRS}
|
||||
${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
find_library(libedit_LIBRARIES
|
||||
NAMES
|
||||
edit libedit
|
||||
HINTS
|
||||
${PC_LIBEDIT_LIBDIR}
|
||||
${PC_LIBEDIT_LIBRARY_DIRS}
|
||||
${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
|
||||
if(libedit_INCLUDE_DIRS AND EXISTS "${libedit_INCLUDE_DIRS}/histedit.h")
|
||||
file(STRINGS "${libedit_INCLUDE_DIRS}/histedit.h"
|
||||
libedit_major_version_str
|
||||
REGEX "^#define[ \t]+LIBEDIT_MAJOR[ \t]+[0-9]+")
|
||||
string(REGEX REPLACE "^#define[ \t]+LIBEDIT_MAJOR[ \t]+([0-9]+)" "\\1"
|
||||
LIBEDIT_MAJOR_VERSION "${libedit_major_version_str}")
|
||||
|
||||
file(STRINGS "${libedit_INCLUDE_DIRS}/histedit.h"
|
||||
libedit_minor_version_str
|
||||
REGEX "^#define[ \t]+LIBEDIT_MINOR[ \t]+[0-9]+")
|
||||
string(REGEX REPLACE "^#define[ \t]+LIBEDIT_MINOR[ \t]+([0-9]+)" "\\1"
|
||||
LIBEDIT_MINOR_VERSION "${libedit_minor_version_str}")
|
||||
|
||||
set(libedit_VERSION_STRING "${libedit_major_version}.${libedit_minor_version}")
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(libedit
|
||||
REQUIRED_VARS
|
||||
libedit_INCLUDE_DIRS
|
||||
libedit_LIBRARIES
|
||||
VERSION_VAR
|
||||
libedit_VERSION_STRING)
|
||||
mark_as_advanced(libedit_INCLUDE_DIRS libedit_LIBRARIES)
|
||||
endif()
|
||||
|
@ -277,27 +277,31 @@ include_directories(BEFORE
|
||||
|
||||
if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||
install(DIRECTORY include/
|
||||
COMPONENT lldb_headers
|
||||
COMPONENT lldb-headers
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN ".cmake" EXCLUDE
|
||||
PATTERN "Config.h" EXCLUDE
|
||||
PATTERN "lldb-*.h" EXCLUDE
|
||||
PATTERN "API/*.h" EXCLUDE
|
||||
)
|
||||
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/
|
||||
COMPONENT lldb_headers
|
||||
COMPONENT lldb-headers
|
||||
DESTINATION include
|
||||
FILES_MATCHING
|
||||
PATTERN "*.h"
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN ".cmake" EXCLUDE
|
||||
PATTERN "lldb-*.h" EXCLUDE
|
||||
PATTERN "API/*.h" EXCLUDE
|
||||
)
|
||||
|
||||
add_custom_target(lldb-headers)
|
||||
set_target_properties(lldb-headers PROPERTIES FOLDER "Misc")
|
||||
|
||||
if (NOT CMAKE_CONFIGURATION_TYPES)
|
||||
add_llvm_install_targets(install-lldb-headers
|
||||
COMPONENT lldb-headers)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT LIBXML2_FOUND AND NOT (CMAKE_SYSTEM_NAME MATCHES "Windows"))
|
||||
@ -342,14 +346,18 @@ else()
|
||||
|
||||
endif()
|
||||
|
||||
if (HAVE_LIBPTHREAD)
|
||||
list(APPEND system_libs pthread)
|
||||
endif(HAVE_LIBPTHREAD)
|
||||
|
||||
if (HAVE_LIBDL)
|
||||
list(APPEND system_libs ${CMAKE_DL_LIBS})
|
||||
if( WIN32 AND NOT CYGWIN )
|
||||
set(PURE_WINDOWS 1)
|
||||
endif()
|
||||
|
||||
if(NOT PURE_WINDOWS)
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
find_package(Threads REQUIRED)
|
||||
list(APPEND system_libs ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
|
||||
list(APPEND system_libs ${CMAKE_DL_LIBS})
|
||||
|
||||
# Figure out if lldb could use lldb-server. If so, then we'll
|
||||
# ensure we build lldb-server when an lldb target is being built.
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|FreeBSD|Linux|NetBSD")
|
||||
@ -403,15 +411,6 @@ if(LLDB_USING_LIBSTDCXX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set(LLDB_USE_BUILTIN_DEMANGLER ON)
|
||||
else()
|
||||
option(LLDB_USE_BUILTIN_DEMANGLER "Use lldb's builtin demangler instead of the system one" ON)
|
||||
endif()
|
||||
if(LLDB_USE_BUILTIN_DEMANGLER)
|
||||
add_definitions(-DLLDB_USE_BUILTIN_DEMANGLER)
|
||||
endif()
|
||||
|
||||
if ((CMAKE_SYSTEM_NAME MATCHES "Android") AND LLVM_BUILD_STATIC AND
|
||||
((ANDROID_ABI MATCHES "armeabi") OR (ANDROID_ABI MATCHES "mips")))
|
||||
add_definitions(-DANDROID_USE_ACCEPT_WORKAROUND)
|
||||
|
44
cmake/modules/LLDBFramework.cmake
Normal file
44
cmake/modules/LLDBFramework.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
file(GLOB public_headers ${LLDB_SOURCE_DIR}/include/lldb/API/*.h)
|
||||
file(GLOB root_public_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-*.h)
|
||||
file(GLOB root_private_headers ${LLDB_SOURCE_DIR}/include/lldb/lldb-private*.h)
|
||||
list(REMOVE_ITEM root_public_headers ${root_private_headers})
|
||||
foreach(header
|
||||
${public_headers}
|
||||
${root_public_headers}
|
||||
${LLDB_SOURCE_DIR}/include/lldb/Utility/SharingPtr.h)
|
||||
get_filename_component(basename ${header} NAME)
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename}
|
||||
DEPENDS ${header}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${header} ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename})
|
||||
list(APPEND framework_headers ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders/${basename})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(lldb-framework-headers DEPENDS ${framework_headers})
|
||||
|
||||
add_custom_command(TARGET lldb-framework POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/FrameworkHeaders $<TARGET_FILE_DIR:liblldb>/Headers
|
||||
COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.sh $<TARGET_FILE_DIR:liblldb>/Headers ${LLDB_VERSION}
|
||||
)
|
||||
|
||||
if (NOT IOS)
|
||||
if (NOT LLDB_BUILT_STANDALONE)
|
||||
add_dependencies(lldb-framework clang-headers)
|
||||
endif()
|
||||
add_custom_command(TARGET lldb-framework POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink Versions/Current/Headers ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Headers
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLDB_FRAMEWORK_VERSION} ${LLDB_FRAMEWORK_DIR}/LLDB.framework/Versions/Current
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLDB_VERSION} $<TARGET_FILE_DIR:liblldb>/Resources/Clang
|
||||
)
|
||||
endif()
|
||||
|
||||
set_target_properties(liblldb PROPERTIES
|
||||
OUTPUT_NAME LLDB
|
||||
FRAMEWORK On
|
||||
FRAMEWORK_VERSION ${LLDB_FRAMEWORK_VERSION}
|
||||
MACOSX_FRAMEWORK_INFO_PLIST ${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_FRAMEWORK_INSTALL_DIR}
|
||||
PUBLIC_HEADER "${framework_headers}")
|
||||
|
||||
add_dependencies(lldb-framework
|
||||
lldb-framework-headers
|
||||
lldb-suite)
|
@ -4,6 +4,7 @@ include(CheckSymbolExists)
|
||||
include(CheckIncludeFile)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckTypeSize)
|
||||
|
||||
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
|
||||
check_symbol_exists(ppoll poll.h HAVE_PPOLL)
|
||||
@ -14,14 +15,8 @@ check_cxx_symbol_exists(accept4 "sys/socket.h" HAVE_ACCEPT4)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_files("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <sys/uio.h>
|
||||
int main() { process_vm_readv(0, nullptr, 0, nullptr, 0, 0); return 0; }"
|
||||
HAVE_PROCESS_VM_READV)
|
||||
check_cxx_source_compiles("
|
||||
#include <sys/syscall.h>
|
||||
int main() { return __NR_process_vm_readv; }"
|
||||
HAVE_NR_PROCESS_VM_READV)
|
||||
check_cxx_symbol_exists(process_vm_readv "sys/uio.h" HAVE_PROCESS_VM_READV)
|
||||
check_cxx_symbol_exists(__NR_process_vm_readv "sys/syscall.h" HAVE_NR_PROCESS_VM_READV)
|
||||
|
||||
check_library_exists(compression compression_encode_buffer "" HAVE_LIBCOMPRESSION)
|
||||
|
||||
@ -33,6 +28,24 @@ if(NOT UNIX)
|
||||
set(LLDB_DISABLE_POSIX 1)
|
||||
endif()
|
||||
|
||||
if (NOT LLDB_DISABLE_LIBEDIT)
|
||||
# Check if we libedit capable of handling wide characters (built with
|
||||
# '--enable-widec').
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${libedit_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_INCLUDES ${libedit_INCLUDE_DIRS})
|
||||
check_symbol_exists(el_winsertstr histedit.h LLDB_EDITLINE_USE_WCHAR)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES histedit.h)
|
||||
check_type_size(el_rfunc_t LLDB_EL_RFUNC_T_SIZE)
|
||||
if (LLDB_EL_RFUNC_T_SIZE STREQUAL "")
|
||||
set(LLDB_HAVE_EL_RFUNC_T 0)
|
||||
else()
|
||||
set(LLDB_HAVE_EL_RFUNC_T 1)
|
||||
endif()
|
||||
set(CMAKE_REQUIRED_LIBRARIES)
|
||||
set(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
endif()
|
||||
|
||||
if(NOT LLDB_CONFIG_HEADER_INPUT)
|
||||
set(LLDB_CONFIG_HEADER_INPUT ${LLDB_INCLUDE_ROOT}/lldb/Host/Config.h.cmake)
|
||||
endif()
|
||||
|
@ -58,6 +58,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
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")
|
||||
set(LLVM_EXTERNAL_LIT ${LLVM_TOOLS_BINARY_DIR}/llvm-lit CACHE PATH "Path to llvm-lit")
|
||||
|
||||
find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}
|
||||
NO_DEFAULT_PATH)
|
||||
@ -99,7 +100,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
|
||||
# Import CMake library targets from LLVM and Clang.
|
||||
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.
|
||||
# cmake/clang/ClangConfig.cmake is not created when LLVM and Clang 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()
|
||||
@ -111,7 +112,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
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
|
||||
# LLVM and Clang are assumed to be built together
|
||||
if (EXISTS "${LLVM_OBJ_ROOT}/include")
|
||||
include_directories("${LLVM_OBJ_ROOT}/include")
|
||||
endif()
|
||||
|
@ -1,6 +1,11 @@
|
||||
On MacOSX lldb needs to be code signed. The Debug, DebugClang and Release
|
||||
builds are set to code sign using a code signing certificate named
|
||||
"lldb_codesign".
|
||||
To use the in-tree debug server on macOS, lldb needs to be code signed. The
|
||||
Debug, DebugClang and Release builds are set to code sign using a code signing
|
||||
certificate named "lldb_codesign". This document explains how to set up the
|
||||
signing certificate.
|
||||
|
||||
Note that it's possible to build and use lldb on macOS without setting up code
|
||||
signing by using the system's debug server. To configure lldb in this way with
|
||||
cmake, specify -DLLDB_CODESIGN_IDENTITY=''.
|
||||
|
||||
If you have re-installed a new OS, please delete all old lldb_codesign items
|
||||
from your keychain. There will be a code signing certification and a public
|
||||
|
@ -137,7 +137,7 @@ SHORT_NAMES = NO
|
||||
# comments will behave just like regular Qt-style comments
|
||||
# (thus requiring an explicit @brief command for a brief description.)
|
||||
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
|
||||
# interpret the first line (until the first dot) of a Qt-style
|
||||
@ -145,7 +145,7 @@ JAVADOC_AUTOBRIEF = NO
|
||||
# will behave just like regular Qt-style comments (thus requiring
|
||||
# an explicit \brief command for a brief description.)
|
||||
|
||||
QT_AUTOBRIEF = NO
|
||||
QT_AUTOBRIEF = YES
|
||||
|
||||
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
|
||||
# treat a multi-line C++ special comment block (i.e. a block of //! or ///
|
||||
|
@ -148,7 +148,7 @@ This packet can be sent one or more times _prior_ to sending a "A" packet.
|
||||
// are human readable along with an error code.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
send packet: $QErrorStringInPacketSupported
|
||||
send packet: $QEnableErrorStrings
|
||||
read packet: $OK#00
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -135,15 +135,16 @@ see test/array_types/TestArrayTypes.py:
|
||||
self.array_types()
|
||||
|
||||
This method is decorated with a skipUnless decorator so that it will only gets
|
||||
included into the test suite if the platform it is running on is 'darwin', aka
|
||||
Mac OS X.
|
||||
included into the test suite if the platform it is running on is 'darwin', a.k.a.
|
||||
macOS.
|
||||
|
||||
Type 'man dsymutil' for more details.
|
||||
|
||||
After the binary is built, it is time to specify the file to be used as the main
|
||||
executable by lldb:
|
||||
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
# Construct the path to a file "a.out" inside the test's build folder.
|
||||
exe = self.getBuildArtifact("a.out")
|
||||
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
|
||||
|
||||
This is where the attribute assignment:
|
||||
@ -174,10 +175,11 @@ execution. This can be accomplished by passing the keyword argument pair
|
||||
After the current executable is set, we'll then execute two more commands:
|
||||
|
||||
# Set the output-path and verify it is set.
|
||||
self.runCmd("settings set target.process.output-path 'stdout.txt'")
|
||||
stdout = self.getBuildArtifact('stdout.txt')
|
||||
self.runCmd("settings set target.process.output-path '%s'" %stdout)
|
||||
self.expect("settings show target.process.output-path",
|
||||
SETTING_MSG("target.process.output-path"),
|
||||
startstr = "target.process.output-path (string) = 'stdout.txt'")
|
||||
startstr = "target.process.output-path (string) = '.*stdout.txt'")
|
||||
|
||||
The first uses the 'settings set' command to set the static setting
|
||||
target.process.output-path to be 'stdout.txt', instead of the default
|
||||
@ -188,7 +190,7 @@ door and grabs the output from the command execution and expects to match the
|
||||
start string of the output against what we pass in as the value of the keyword
|
||||
argument pair:
|
||||
|
||||
startstr = "target.process.output-path (string) = 'stdout.txt'"
|
||||
startstr = "target.process.output-path (string) = '%s'" %stdout
|
||||
|
||||
Take a look at TestBase.expect() within lldbtest.py for more details. Among
|
||||
other things, it can also match against a list of regexp patterns as well as a
|
||||
@ -204,15 +206,15 @@ And this asserts that the file 'stdout.txt' should be present after running the
|
||||
program.
|
||||
|
||||
# The 'stdout.txt' file should now exist.
|
||||
self.assertTrue(os.path.isfile("stdout.txt"),
|
||||
"'stdout.txt' exists due to target.process.output-path.")
|
||||
self.assertTrue(os.path.isfile(stdout),
|
||||
"stdout.txt' exists due to target.process.output-path.")
|
||||
|
||||
Also take a look at main.cpp which emits some message to the stdout. Now, if we
|
||||
pass this assertion, it's time to examine the contents of the file to make sure
|
||||
it contains the same message as programmed in main.cpp:
|
||||
|
||||
# Read the output file produced by running the program.
|
||||
with open('stdout.txt', 'r') as f:
|
||||
with open(stdout, 'r') as f:
|
||||
output = f.read()
|
||||
|
||||
self.expect(output, exe=False,
|
||||
@ -235,8 +237,8 @@ file:
|
||||
|
||||
@classmethod
|
||||
def classCleanup(cls):
|
||||
system(["/bin/sh", "-c", "rm -f output.txt"])
|
||||
system(["/bin/sh", "-c", "rm -f stdout.txt"])
|
||||
system(["/bin/sh", "-c", "rm -f "+self.getBuildArtifact("output.txt")])
|
||||
system(["/bin/sh", "-c", "rm -f "+self.getBuildArtifact("stdout.txt")])
|
||||
|
||||
This is a classmethod (as shown by the @classmethod decorator) which allows the
|
||||
individual test class to perform cleanup actions after the test harness finishes
|
||||
|
@ -410,7 +410,7 @@ class ObjCClassInfo {
|
||||
m_sort_type = eSortTypeBytes;
|
||||
}
|
||||
if (print && m_size > 0) {
|
||||
puts("Objective C objects by total bytes:");
|
||||
puts("Objective-C objects by total bytes:");
|
||||
puts("Total Bytes Class Name");
|
||||
puts("----------- "
|
||||
"-----------------------------------------------------------------");
|
||||
@ -427,7 +427,7 @@ class ObjCClassInfo {
|
||||
m_sort_type = eSortTypeCount;
|
||||
}
|
||||
if (print && m_size > 0) {
|
||||
puts("Objective C objects by total count:");
|
||||
puts("Objective-C objects by total count:");
|
||||
puts("Count Class Name");
|
||||
puts("-------- "
|
||||
"-----------------------------------------------------------------");
|
||||
|
481
examples/python/bsd.py
Executable file
481
examples/python/bsd.py
Executable file
@ -0,0 +1,481 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import shlex
|
||||
import struct
|
||||
import sys
|
||||
|
||||
ARMAG = "!<arch>\n"
|
||||
SARMAG = 8
|
||||
ARFMAG = "`\n"
|
||||
AR_EFMT1 = "#1/"
|
||||
|
||||
|
||||
def memdump(src, bytes_per_line=16, address=0):
|
||||
FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.'
|
||||
for x in range(256)])
|
||||
for i in range(0, len(src), bytes_per_line):
|
||||
s = src[i:i+bytes_per_line]
|
||||
hex_bytes = ' '.join(["%02x" % (ord(x)) for x in s])
|
||||
ascii = s.translate(FILTER)
|
||||
print("%#08.8x: %-*s %s" % (address+i, bytes_per_line*3, hex_bytes,
|
||||
ascii))
|
||||
|
||||
|
||||
class Object(object):
|
||||
def __init__(self, file):
|
||||
def read_str(file, str_len):
|
||||
return file.read(str_len).rstrip('\0 ')
|
||||
|
||||
def read_int(file, str_len, base):
|
||||
return int(read_str(file, str_len), base)
|
||||
|
||||
self.offset = file.tell()
|
||||
self.file = file
|
||||
self.name = read_str(file, 16)
|
||||
self.date = read_int(file, 12, 10)
|
||||
self.uid = read_int(file, 6, 10)
|
||||
self.gid = read_int(file, 6, 10)
|
||||
self.mode = read_int(file, 8, 8)
|
||||
self.size = read_int(file, 10, 10)
|
||||
if file.read(2) != ARFMAG:
|
||||
raise ValueError('invalid BSD object at offset %#08.8x' % (
|
||||
self.offset))
|
||||
# If we have an extended name read it. Extended names start with
|
||||
name_len = 0
|
||||
if self.name.startswith(AR_EFMT1):
|
||||
name_len = int(self.name[len(AR_EFMT1):], 10)
|
||||
self.name = read_str(file, name_len)
|
||||
self.obj_offset = file.tell()
|
||||
self.obj_size = self.size - name_len
|
||||
file.seek(self.obj_size, 1)
|
||||
|
||||
def dump(self, f=sys.stdout, flat=True):
|
||||
if flat:
|
||||
f.write('%#08.8x: %#08.8x %5u %5u %6o %#08.8x %s\n' % (self.offset,
|
||||
self.date, self.uid, self.gid, self.mode, self.size,
|
||||
self.name))
|
||||
else:
|
||||
f.write('%#08.8x: \n' % self.offset)
|
||||
f.write(' name = "%s"\n' % self.name)
|
||||
f.write(' date = %#08.8x\n' % self.date)
|
||||
f.write(' uid = %i\n' % self.uid)
|
||||
f.write(' gid = %i\n' % self.gid)
|
||||
f.write(' mode = %o\n' % self.mode)
|
||||
f.write(' size = %#08.8x\n' % (self.size))
|
||||
self.file.seek(self.obj_offset, 0)
|
||||
first_bytes = self.file.read(4)
|
||||
f.write('bytes = ')
|
||||
memdump(first_bytes)
|
||||
|
||||
def get_bytes(self):
|
||||
saved_pos = self.file.tell()
|
||||
self.file.seek(self.obj_offset, 0)
|
||||
bytes = self.file.read(self.obj_size)
|
||||
self.file.seek(saved_pos, 0)
|
||||
return bytes
|
||||
|
||||
|
||||
class StringTable(object):
|
||||
def __init__(self, bytes):
|
||||
self.bytes = bytes
|
||||
|
||||
def get_string(self, offset):
|
||||
length = len(self.bytes)
|
||||
if offset >= length:
|
||||
return None
|
||||
return self.bytes[offset:self.bytes.find('\0', offset)]
|
||||
|
||||
|
||||
class Archive(object):
|
||||
def __init__(self, path):
|
||||
self.path = path
|
||||
self.file = open(path, 'r')
|
||||
self.objects = []
|
||||
self.offset_to_object = {}
|
||||
if self.file.read(SARMAG) != ARMAG:
|
||||
print("error: file isn't a BSD archive")
|
||||
while True:
|
||||
try:
|
||||
self.objects.append(Object(self.file))
|
||||
except ValueError:
|
||||
break
|
||||
|
||||
def get_object_at_offset(self, offset):
|
||||
if offset in self.offset_to_object:
|
||||
return self.offset_to_object[offset]
|
||||
for obj in self.objects:
|
||||
if obj.offset == offset:
|
||||
self.offset_to_object[offset] = obj
|
||||
return obj
|
||||
return None
|
||||
|
||||
def find(self, name, mtime=None, f=sys.stdout):
|
||||
'''
|
||||
Find an object(s) by name with optional modification time. There
|
||||
can be multple objects with the same name inside and possibly with
|
||||
the same modification time within a BSD archive so clients must be
|
||||
prepared to get multiple results.
|
||||
'''
|
||||
matches = []
|
||||
for obj in self.objects:
|
||||
if obj.name == name and (mtime is None or mtime == obj.date):
|
||||
matches.append(obj)
|
||||
return matches
|
||||
|
||||
@classmethod
|
||||
def dump_header(self, f=sys.stdout):
|
||||
f.write(' DATE UID GID MODE SIZE NAME\n')
|
||||
f.write(' ---------- ----- ----- ------ ---------- '
|
||||
'--------------\n')
|
||||
|
||||
def get_symdef(self):
|
||||
def get_uint32(file):
|
||||
'''Extract a uint32_t from the current file position.'''
|
||||
v, = struct.unpack('=I', file.read(4))
|
||||
return v
|
||||
|
||||
for obj in self.objects:
|
||||
symdef = []
|
||||
if obj.name.startswith("__.SYMDEF"):
|
||||
self.file.seek(obj.obj_offset, 0)
|
||||
ranlib_byte_size = get_uint32(self.file)
|
||||
num_ranlib_structs = ranlib_byte_size/8
|
||||
str_offset_pairs = []
|
||||
for _ in range(num_ranlib_structs):
|
||||
strx = get_uint32(self.file)
|
||||
offset = get_uint32(self.file)
|
||||
str_offset_pairs.append((strx, offset))
|
||||
strtab_len = get_uint32(self.file)
|
||||
strtab = StringTable(self.file.read(strtab_len))
|
||||
for s in str_offset_pairs:
|
||||
symdef.append((strtab.get_string(s[0]), s[1]))
|
||||
return symdef
|
||||
|
||||
def get_object_dicts(self):
|
||||
'''
|
||||
Returns an array of object dictionaries that contain they following
|
||||
keys:
|
||||
'object': the actual bsd.Object instance
|
||||
'symdefs': an array of symbol names that the object contains
|
||||
as found in the "__.SYMDEF" item in the archive
|
||||
'''
|
||||
symdefs = self.get_symdef()
|
||||
symdef_dict = {}
|
||||
if symdefs:
|
||||
for (name, offset) in symdefs:
|
||||
if offset in symdef_dict:
|
||||
object_dict = symdef_dict[offset]
|
||||
else:
|
||||
object_dict = {
|
||||
'object': self.get_object_at_offset(offset),
|
||||
'symdefs': []
|
||||
}
|
||||
symdef_dict[offset] = object_dict
|
||||
object_dict['symdefs'].append(name)
|
||||
object_dicts = []
|
||||
for offset in sorted(symdef_dict):
|
||||
object_dicts.append(symdef_dict[offset])
|
||||
return object_dicts
|
||||
|
||||
def dump(self, f=sys.stdout, flat=True):
|
||||
f.write('%s:\n' % self.path)
|
||||
if flat:
|
||||
self.dump_header(f=f)
|
||||
for obj in self.objects:
|
||||
obj.dump(f=f, flat=flat)
|
||||
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser(
|
||||
prog='bsd',
|
||||
description='Utility for BSD archives')
|
||||
parser.add_option(
|
||||
'--object',
|
||||
type='string',
|
||||
dest='object_name',
|
||||
default=None,
|
||||
help=('Specify the name of a object within the BSD archive to get '
|
||||
'information on'))
|
||||
parser.add_option(
|
||||
'-s', '--symbol',
|
||||
type='string',
|
||||
dest='find_symbol',
|
||||
default=None,
|
||||
help=('Specify the name of a symbol within the BSD archive to get '
|
||||
'information on from SYMDEF'))
|
||||
parser.add_option(
|
||||
'--symdef',
|
||||
action='store_true',
|
||||
dest='symdef',
|
||||
default=False,
|
||||
help=('Dump the information in the SYMDEF.'))
|
||||
parser.add_option(
|
||||
'-v', '--verbose',
|
||||
action='store_true',
|
||||
dest='verbose',
|
||||
default=False,
|
||||
help='Enable verbose output')
|
||||
parser.add_option(
|
||||
'-e', '--extract',
|
||||
action='store_true',
|
||||
dest='extract',
|
||||
default=False,
|
||||
help=('Specify this to extract the object specified with the --object '
|
||||
'option. There must be only one object with a matching name or '
|
||||
'the --mtime option must be specified to uniquely identify a '
|
||||
'single object.'))
|
||||
parser.add_option(
|
||||
'-m', '--mtime',
|
||||
type='int',
|
||||
dest='mtime',
|
||||
default=None,
|
||||
help=('Specify the modification time of the object an object. This '
|
||||
'option is used with either the --object or --extract options.'))
|
||||
parser.add_option(
|
||||
'-o', '--outfile',
|
||||
type='string',
|
||||
dest='outfile',
|
||||
default=None,
|
||||
help=('Specify a different name or path for the file to extract when '
|
||||
'using the --extract option. If this option isn\'t specified, '
|
||||
'then the extracted object file will be extracted into the '
|
||||
'current working directory if a file doesn\'t already exist '
|
||||
'with that name.'))
|
||||
|
||||
(options, args) = parser.parse_args(sys.argv[1:])
|
||||
|
||||
for path in args:
|
||||
archive = Archive(path)
|
||||
if options.object_name:
|
||||
print('%s:\n' % (path))
|
||||
matches = archive.find(options.object_name, options.mtime)
|
||||
if matches:
|
||||
dump_all = True
|
||||
if options.extract:
|
||||
if len(matches) == 1:
|
||||
dump_all = False
|
||||
if options.outfile is None:
|
||||
outfile_path = matches[0].name
|
||||
else:
|
||||
outfile_path = options.outfile
|
||||
if os.path.exists(outfile_path):
|
||||
print('error: outfile "%s" already exists' % (
|
||||
outfile_path))
|
||||
else:
|
||||
print('Saving file to "%s"...' % (outfile_path))
|
||||
with open(outfile_path, 'w') as outfile:
|
||||
outfile.write(matches[0].get_bytes())
|
||||
else:
|
||||
print('error: multiple objects match "%s". Specify '
|
||||
'the modification time using --mtime.' % (
|
||||
options.object_name))
|
||||
if dump_all:
|
||||
for obj in matches:
|
||||
obj.dump(flat=False)
|
||||
else:
|
||||
print('error: object "%s" not found in archive' % (
|
||||
options.object_name))
|
||||
elif options.find_symbol:
|
||||
symdefs = archive.get_symdef()
|
||||
if symdefs:
|
||||
success = False
|
||||
for (name, offset) in symdefs:
|
||||
obj = archive.get_object_at_offset(offset)
|
||||
if name == options.find_symbol:
|
||||
print('Found "%s" in:' % (options.find_symbol))
|
||||
obj.dump(flat=False)
|
||||
success = True
|
||||
if not success:
|
||||
print('Didn\'t find "%s" in any objects' % (
|
||||
options.find_symbol))
|
||||
else:
|
||||
print("error: no __.SYMDEF was found")
|
||||
elif options.symdef:
|
||||
object_dicts = archive.get_object_dicts()
|
||||
for object_dict in object_dicts:
|
||||
object_dict['object'].dump(flat=False)
|
||||
print("symbols:")
|
||||
for name in object_dict['symdefs']:
|
||||
print(" %s" % (name))
|
||||
else:
|
||||
archive.dump(flat=not options.verbose)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
||||
def print_mtime_error(result, dmap_mtime, actual_mtime):
|
||||
print >>result, ("error: modification time in debug map (%#08.8x) doesn't "
|
||||
"match the .o file modification time (%#08.8x)" % (
|
||||
dmap_mtime, actual_mtime))
|
||||
|
||||
|
||||
def print_file_missing_error(result, path):
|
||||
print >>result, "error: file \"%s\" doesn't exist" % (path)
|
||||
|
||||
|
||||
def print_multiple_object_matches(result, object_name, mtime, matches):
|
||||
print >>result, ("error: multiple matches for object '%s' with with "
|
||||
"modification time %#08.8x:" % (object_name, mtime))
|
||||
Archive.dump_header(f=result)
|
||||
for match in matches:
|
||||
match.dump(f=result, flat=True)
|
||||
|
||||
|
||||
def print_archive_object_error(result, object_name, mtime, archive):
|
||||
matches = archive.find(object_name, f=result)
|
||||
if len(matches) > 0:
|
||||
print >>result, ("error: no objects have a modification time that "
|
||||
"matches %#08.8x for '%s'. Potential matches:" % (
|
||||
mtime, object_name))
|
||||
Archive.dump_header(f=result)
|
||||
for match in matches:
|
||||
match.dump(f=result, flat=True)
|
||||
else:
|
||||
print >>result, "error: no object named \"%s\" found in archive:" % (
|
||||
object_name)
|
||||
Archive.dump_header(f=result)
|
||||
for match in archive.objects:
|
||||
match.dump(f=result, flat=True)
|
||||
# archive.dump(f=result, flat=True)
|
||||
|
||||
|
||||
class VerifyDebugMapCommand:
|
||||
name = "verify-debug-map-objects"
|
||||
|
||||
def create_options(self):
|
||||
usage = "usage: %prog [options]"
|
||||
description = '''This command reports any .o files that are missing
|
||||
or whose modification times don't match in the debug map of an executable.'''
|
||||
|
||||
self.parser = optparse.OptionParser(
|
||||
description=description,
|
||||
prog=self.name,
|
||||
usage=usage,
|
||||
add_help_option=False)
|
||||
|
||||
self.parser.add_option(
|
||||
'-e', '--errors',
|
||||
action='store_true',
|
||||
dest='errors',
|
||||
default=False,
|
||||
help="Only show errors")
|
||||
|
||||
def get_short_help(self):
|
||||
return "Verify debug map object files."
|
||||
|
||||
def get_long_help(self):
|
||||
return self.help_string
|
||||
|
||||
def __init__(self, debugger, unused):
|
||||
self.create_options()
|
||||
self.help_string = self.parser.format_help()
|
||||
|
||||
def __call__(self, debugger, command, exe_ctx, result):
|
||||
import lldb
|
||||
# Use the Shell Lexer to properly parse up command options just like a
|
||||
# shell would
|
||||
command_args = shlex.split(command)
|
||||
|
||||
try:
|
||||
(options, args) = self.parser.parse_args(command_args)
|
||||
except:
|
||||
result.SetError("option parsing failed")
|
||||
return
|
||||
|
||||
# Always get program state from the SBExecutionContext passed in
|
||||
target = exe_ctx.GetTarget()
|
||||
if not target.IsValid():
|
||||
result.SetError("invalid target")
|
||||
return
|
||||
archives = {}
|
||||
for module_spec in args:
|
||||
module = target.module[module_spec]
|
||||
if not (module and module.IsValid()):
|
||||
result.SetError('error: invalid module specification: "%s". '
|
||||
'Specify the full path, basename, or UUID of '
|
||||
'a module ' % (module_spec))
|
||||
return
|
||||
num_symbols = module.GetNumSymbols()
|
||||
num_errors = 0
|
||||
for i in range(num_symbols):
|
||||
symbol = module.GetSymbolAtIndex(i)
|
||||
if symbol.GetType() != lldb.eSymbolTypeObjectFile:
|
||||
continue
|
||||
path = symbol.GetName()
|
||||
if not path:
|
||||
continue
|
||||
# Extract the value of the symbol by dumping the
|
||||
# symbol. The value is the mod time.
|
||||
dmap_mtime = int(str(symbol).split('value = ')
|
||||
[1].split(',')[0], 16)
|
||||
if not options.errors:
|
||||
print >>result, '%s' % (path)
|
||||
if os.path.exists(path):
|
||||
actual_mtime = int(os.stat(path).st_mtime)
|
||||
if dmap_mtime != actual_mtime:
|
||||
num_errors += 1
|
||||
if options.errors:
|
||||
print >>result, '%s' % (path),
|
||||
print_mtime_error(result, dmap_mtime,
|
||||
actual_mtime)
|
||||
elif path[-1] == ')':
|
||||
(archive_path, object_name) = path[0:-1].split('(')
|
||||
if not archive_path and not object_name:
|
||||
num_errors += 1
|
||||
if options.errors:
|
||||
print >>result, '%s' % (path),
|
||||
print_file_missing_error(path)
|
||||
continue
|
||||
if not os.path.exists(archive_path):
|
||||
num_errors += 1
|
||||
if options.errors:
|
||||
print >>result, '%s' % (path),
|
||||
print_file_missing_error(archive_path)
|
||||
continue
|
||||
if archive_path in archives:
|
||||
archive = archives[archive_path]
|
||||
else:
|
||||
archive = Archive(archive_path)
|
||||
archives[archive_path] = archive
|
||||
matches = archive.find(object_name, dmap_mtime)
|
||||
num_matches = len(matches)
|
||||
if num_matches == 1:
|
||||
print >>result, '1 match'
|
||||
obj = matches[0]
|
||||
if obj.date != dmap_mtime:
|
||||
num_errors += 1
|
||||
if options.errors:
|
||||
print >>result, '%s' % (path),
|
||||
print_mtime_error(result, dmap_mtime, obj.date)
|
||||
elif num_matches == 0:
|
||||
num_errors += 1
|
||||
if options.errors:
|
||||
print >>result, '%s' % (path),
|
||||
print_archive_object_error(result, object_name,
|
||||
dmap_mtime, archive)
|
||||
elif num_matches > 1:
|
||||
num_errors += 1
|
||||
if options.errors:
|
||||
print >>result, '%s' % (path),
|
||||
print_multiple_object_matches(result,
|
||||
object_name,
|
||||
dmap_mtime, matches)
|
||||
if num_errors > 0:
|
||||
print >>result, "%u errors found" % (num_errors)
|
||||
else:
|
||||
print >>result, "No errors detected in debug map"
|
||||
|
||||
|
||||
def __lldb_init_module(debugger, dict):
|
||||
# This initializer is being run from LLDB in the embedded command
|
||||
# interpreter.
|
||||
# Add any commands contained in this module to LLDB
|
||||
debugger.HandleCommand(
|
||||
'command script add -c %s.VerifyDebugMapCommand %s' % (
|
||||
__name__, VerifyDebugMapCommand.name))
|
||||
print('The "%s" command has been installed, type "help %s" for detailed '
|
||||
'help.' % (VerifyDebugMapCommand.name, VerifyDebugMapCommand.name))
|
@ -1,69 +1,91 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------
|
||||
# Be sure to add the python path that points to the LLDB shared library.
|
||||
#
|
||||
# # To use this in the embedded python interpreter using "lldb" just
|
||||
# import it with the full path using the "command script import"
|
||||
# command
|
||||
# (lldb) command script import /path/to/cmdtemplate.py
|
||||
#----------------------------------------------------------------------
|
||||
# ---------------------------------------------------------------------
|
||||
|
||||
import inspect
|
||||
import lldb
|
||||
import commands
|
||||
import optparse
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
|
||||
class FrameStatCommand:
|
||||
def create_options(self):
|
||||
program = 'framestats'
|
||||
|
||||
@classmethod
|
||||
def register_lldb_command(cls, debugger, module_name):
|
||||
parser = cls.create_options()
|
||||
cls.__doc__ = parser.format_help()
|
||||
# Add any commands contained in this module to LLDB
|
||||
command = 'command script add -c %s.%s %s' % (module_name,
|
||||
cls.__name__,
|
||||
cls.program)
|
||||
debugger.HandleCommand(command)
|
||||
print('The "{0}" command has been installed, type "help {0}" or "{0} '
|
||||
'--help" for detailed help.'.format(cls.program))
|
||||
|
||||
@classmethod
|
||||
def create_options(cls):
|
||||
|
||||
usage = "usage: %prog [options]"
|
||||
description = '''This command is meant to be an example of how to make an LLDB command that
|
||||
does something useful, follows best practices, and exploits the SB API.
|
||||
Specifically, this command computes the aggregate and average size of the variables in the current frame
|
||||
and allows you to tweak exactly which variables are to be accounted in the computation.
|
||||
'''
|
||||
description = ('This command is meant to be an example of how to make '
|
||||
'an LLDB command that does something useful, follows '
|
||||
'best practices, and exploits the SB API. '
|
||||
'Specifically, this command computes the aggregate '
|
||||
'and average size of the variables in the current '
|
||||
'frame and allows you to tweak exactly which variables '
|
||||
'are to be accounted in the computation.')
|
||||
|
||||
# Pass add_help_option = False, since this keeps the command in line with lldb commands,
|
||||
# and we wire up "help command" to work by providing the long & short help methods below.
|
||||
self.parser = optparse.OptionParser(
|
||||
description = description,
|
||||
prog = 'framestats',
|
||||
usage = usage,
|
||||
add_help_option = False)
|
||||
# Pass add_help_option = False, since this keeps the command in line
|
||||
# with lldb commands, and we wire up "help command" to work by
|
||||
# providing the long & short help methods below.
|
||||
parser = optparse.OptionParser(
|
||||
description=description,
|
||||
prog=cls.program,
|
||||
usage=usage,
|
||||
add_help_option=False)
|
||||
|
||||
self.parser.add_option(
|
||||
parser.add_option(
|
||||
'-i',
|
||||
'--in-scope',
|
||||
action = 'store_true',
|
||||
dest = 'inscope',
|
||||
help = 'in_scope_only = True',
|
||||
default = True)
|
||||
action='store_true',
|
||||
dest='inscope',
|
||||
help='in_scope_only = True',
|
||||
default=True)
|
||||
|
||||
self.parser.add_option(
|
||||
parser.add_option(
|
||||
'-a',
|
||||
'--arguments',
|
||||
action = 'store_true',
|
||||
dest = 'arguments',
|
||||
help = 'arguments = True',
|
||||
default = True)
|
||||
action='store_true',
|
||||
dest='arguments',
|
||||
help='arguments = True',
|
||||
default=True)
|
||||
|
||||
self.parser.add_option(
|
||||
parser.add_option(
|
||||
'-l',
|
||||
'--locals',
|
||||
action = 'store_true',
|
||||
dest = 'locals',
|
||||
help = 'locals = True',
|
||||
default = True)
|
||||
action='store_true',
|
||||
dest='locals',
|
||||
help='locals = True',
|
||||
default=True)
|
||||
|
||||
self.parser.add_option(
|
||||
parser.add_option(
|
||||
'-s',
|
||||
'--statics',
|
||||
action = 'store_true',
|
||||
dest = 'statics',
|
||||
help = 'statics = True',
|
||||
default = True)
|
||||
|
||||
action='store_true',
|
||||
dest='statics',
|
||||
help='statics = True',
|
||||
default=True)
|
||||
|
||||
return parser
|
||||
|
||||
def get_short_help(self):
|
||||
return "Example command for use in debugging"
|
||||
|
||||
@ -71,23 +93,25 @@ def get_long_help(self):
|
||||
return self.help_string
|
||||
|
||||
def __init__(self, debugger, unused):
|
||||
self.create_options()
|
||||
self.parser = self.create_options()
|
||||
self.help_string = self.parser.format_help()
|
||||
|
||||
def __call__(self, debugger, command, exe_ctx, result):
|
||||
# Use the Shell Lexer to properly parse up command options just like a
|
||||
# shell would
|
||||
command_args = shlex.split(command)
|
||||
|
||||
|
||||
try:
|
||||
(options, args) = self.parser.parse_args(command_args)
|
||||
except:
|
||||
# if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
|
||||
# (courtesy of OptParse dealing with argument errors by throwing SystemExit)
|
||||
# if you don't handle exceptions, passing an incorrect argument to
|
||||
# the OptionParser will cause LLDB to exit (courtesy of OptParse
|
||||
# dealing with argument errors by throwing SystemExit)
|
||||
result.SetError("option parsing failed")
|
||||
return
|
||||
|
||||
# Always get program state from the SBExecutionContext passed in as exe_ctx
|
||||
# Always get program state from the lldb.SBExecutionContext passed
|
||||
# in as exe_ctx
|
||||
frame = exe_ctx.GetFrame()
|
||||
if not frame.IsValid():
|
||||
result.SetError("invalid frame")
|
||||
@ -108,15 +132,16 @@ def __call__(self, debugger, command, exe_ctx, result):
|
||||
variable_type = variable.GetType()
|
||||
total_size = total_size + variable_type.GetByteSize()
|
||||
average_size = float(total_size) / variables_count
|
||||
print >>result, "Your frame has %d variables. Their total size is %d bytes. The average size is %f bytes" % (
|
||||
variables_count, total_size, average_size)
|
||||
# not returning anything is akin to returning success
|
||||
print >>result, ("Your frame has %d variables. Their total size "
|
||||
"is %d bytes. The average size is %f bytes") % (
|
||||
variables_count, total_size, average_size)
|
||||
# not returning anything is akin to returning success
|
||||
|
||||
|
||||
def __lldb_init_module(debugger, dict):
|
||||
# This initializer is being run from LLDB in the embedded command interpreter
|
||||
|
||||
# Add any commands contained in this module to LLDB
|
||||
debugger.HandleCommand(
|
||||
'command script add -c cmdtemplate.FrameStatCommand framestats')
|
||||
print 'The "framestats" command has been installed, type "help framestats" for detailed help.'
|
||||
# Register all classes that have a register_lldb_command method
|
||||
for _name, cls in inspect.getmembers(sys.modules[__name__]):
|
||||
if inspect.isclass(cls) and callable(getattr(cls,
|
||||
"register_lldb_command",
|
||||
None)):
|
||||
cls.register_lldb_command(debugger, __name__)
|
||||
|
@ -54,9 +54,9 @@ class LLDB_API SBAddress {
|
||||
lldb::SBSymbolContext GetSymbolContext(uint32_t resolve_scope);
|
||||
|
||||
// The following functions grab individual objects for a given address and
|
||||
// are less efficient if you want more than one symbol related objects.
|
||||
// Use one of the following when you want multiple debug symbol related
|
||||
// objects for an address:
|
||||
// are less efficient if you want more than one symbol related objects. Use
|
||||
// one of the following when you want multiple debug symbol related objects
|
||||
// for an address:
|
||||
// lldb::SBSymbolContext SBAddress::GetSymbolContext (uint32_t
|
||||
// resolve_scope);
|
||||
// lldb::SBSymbolContext SBTarget::ResolveSymbolContextForAddress (const
|
||||
@ -80,8 +80,6 @@ class LLDB_API SBAddress {
|
||||
|
||||
lldb::SBLineEntry GetLineEntry();
|
||||
|
||||
lldb::AddressClass GetAddressClass();
|
||||
|
||||
protected:
|
||||
friend class SBBlock;
|
||||
friend class SBBreakpointLocation;
|
||||
@ -103,7 +101,7 @@ class LLDB_API SBAddress {
|
||||
|
||||
const lldb_private::Address *operator->() const;
|
||||
|
||||
friend bool operator==(const SBAddress &lhs, const SBAddress &rhs);
|
||||
friend bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs);
|
||||
|
||||
lldb_private::Address *get();
|
||||
|
||||
@ -119,7 +117,7 @@ class LLDB_API SBAddress {
|
||||
std::unique_ptr<lldb_private::Address> m_opaque_ap;
|
||||
};
|
||||
|
||||
bool operator==(const SBAddress &lhs, const SBAddress &rhs);
|
||||
bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs);
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
|
@ -46,17 +46,17 @@ class LLDB_API SBBroadcaster {
|
||||
bool RemoveListener(const lldb::SBListener &listener,
|
||||
uint32_t event_mask = UINT32_MAX);
|
||||
|
||||
// This comparison is checking if the internal opaque pointer value
|
||||
// is equal to that in "rhs".
|
||||
// This comparison is checking if the internal opaque pointer value is equal
|
||||
// to that in "rhs".
|
||||
bool operator==(const lldb::SBBroadcaster &rhs) const;
|
||||
|
||||
// This comparison is checking if the internal opaque pointer value
|
||||
// is not equal to that in "rhs".
|
||||
// This comparison is checking if the internal opaque pointer value is not
|
||||
// equal to that in "rhs".
|
||||
bool operator!=(const lldb::SBBroadcaster &rhs) const;
|
||||
|
||||
// This comparison is checking if the internal opaque pointer value
|
||||
// is less than that in "rhs" so SBBroadcaster objects can be contained
|
||||
// in ordered containers.
|
||||
// This comparison is checking if the internal opaque pointer value is less
|
||||
// than that in "rhs" so SBBroadcaster objects can be contained in ordered
|
||||
// containers.
|
||||
bool operator<(const lldb::SBBroadcaster &rhs) const;
|
||||
|
||||
protected:
|
||||
|
@ -138,23 +138,20 @@ class SBCommandInterpreter {
|
||||
lldb::SBCommandReturnObject result);
|
||||
|
||||
// The pointer based interface is not useful in SWIG, since the cursor &
|
||||
// last_char arguments are string pointers INTO current_line
|
||||
// and you can't do that in a scripting language interface in general...
|
||||
// last_char arguments are string pointers INTO current_line and you can't do
|
||||
// that in a scripting language interface in general...
|
||||
|
||||
// In either case, the way this works is that the you give it a line and
|
||||
// cursor position in the line. The function
|
||||
// will return the number of completions. The matches list will contain
|
||||
// number_of_completions + 1 elements. The first
|
||||
// element is the common substring after the cursor position for all the
|
||||
// matches. The rest of the elements are the
|
||||
// matches. The first element is useful if you are emulating the common shell
|
||||
// behavior where the tab completes
|
||||
// to the string that is common among all the matches, then you should first
|
||||
// check if the first element is non-empty,
|
||||
// cursor position in the line. The function will return the number of
|
||||
// completions. The matches list will contain number_of_completions + 1
|
||||
// elements. The first element is the common substring after the cursor
|
||||
// position for all the matches. The rest of the elements are the matches.
|
||||
// The first element is useful if you are emulating the common shell behavior
|
||||
// where the tab completes to the string that is common among all the
|
||||
// matches, then you should first check if the first element is non-empty,
|
||||
// and if so just insert it and move the cursor to the end of the insertion.
|
||||
// The next tab will return an empty
|
||||
// common substring, and a list of choices (if any), at which point you should
|
||||
// display the choices and let the user
|
||||
// The next tab will return an empty common substring, and a list of choices
|
||||
// (if any), at which point you should display the choices and let the user
|
||||
// type further to disambiguate.
|
||||
|
||||
int HandleCompletion(const char *current_line, const char *cursor,
|
||||
@ -167,9 +164,9 @@ class SBCommandInterpreter {
|
||||
|
||||
bool WasInterrupted() const;
|
||||
|
||||
// Catch commands before they execute by registering a callback that will
|
||||
// get called when the command gets executed. This allows GUI or command
|
||||
// line interfaces to intercept a command and stop it from happening
|
||||
// Catch commands before they execute by registering a callback that will get
|
||||
// called when the command gets executed. This allows GUI or command line
|
||||
// interfaces to intercept a command and stop it from happening
|
||||
bool SetCommandOverrideCallback(const char *command_name,
|
||||
lldb::CommandOverrideCallback callback,
|
||||
void *baton);
|
||||
@ -210,6 +207,25 @@ class SBCommandInterpreter {
|
||||
|
||||
void SetPromptOnQuit(bool b);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Sets whether the command interpreter should allow custom exit codes
|
||||
/// for the 'quit' command.
|
||||
//----------------------------------------------------------------------
|
||||
void AllowExitCodeOnQuit(bool allow);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Returns true if the user has called the 'quit' command with a custom exit
|
||||
/// code.
|
||||
//----------------------------------------------------------------------
|
||||
bool HasCustomQuitExitCode();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Returns the exit code that the user has specified when running the
|
||||
/// 'quit' command. Returns 0 if the user hasn't called 'quit' at all or
|
||||
/// without a custom exit code.
|
||||
//----------------------------------------------------------------------
|
||||
int GetQuitStatus();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Resolve the command just as HandleCommand would, expanding abbreviations
|
||||
/// and aliases. If successful, result->GetOutput has the full expansion.
|
||||
|
@ -67,8 +67,7 @@ class LLDB_API SBCommandReturnObject {
|
||||
|
||||
bool GetDescription(lldb::SBStream &description);
|
||||
|
||||
// deprecated, these two functions do not take
|
||||
// ownership of file handle
|
||||
// deprecated, these two functions do not take ownership of file handle
|
||||
void SetImmediateOutputFile(FILE *fh);
|
||||
|
||||
void SetImmediateErrorFile(FILE *fh);
|
||||
|
@ -71,11 +71,10 @@ class LLDB_API SBData {
|
||||
lldb::addr_t base_addr = LLDB_INVALID_ADDRESS);
|
||||
|
||||
// it would be nice to have SetData(SBError, const void*, size_t) when
|
||||
// endianness and address size can be
|
||||
// inferred from the existing DataExtractor, but having two SetData()
|
||||
// signatures triggers a SWIG bug where
|
||||
// the typemap isn't applied before resolving the overload, and thus the right
|
||||
// function never gets called
|
||||
// endianness and address size can be inferred from the existing
|
||||
// DataExtractor, but having two SetData() signatures triggers a SWIG bug
|
||||
// where the typemap isn't applied before resolving the overload, and thus
|
||||
// the right function never gets called
|
||||
void SetData(lldb::SBError &error, const void *buf, size_t size,
|
||||
lldb::ByteOrder endian, uint8_t addr_size);
|
||||
|
||||
@ -87,9 +86,8 @@ class LLDB_API SBData {
|
||||
const char *data);
|
||||
|
||||
// in the following CreateData*() and SetData*() prototypes, the two
|
||||
// parameters array and array_len
|
||||
// should not be renamed or rearranged, because doing so will break the SWIG
|
||||
// typemap
|
||||
// parameters array and array_len should not be renamed or rearranged,
|
||||
// because doing so will break the SWIG typemap
|
||||
static lldb::SBData CreateDataFromUInt64Array(lldb::ByteOrder endian,
|
||||
uint32_t addr_byte_size,
|
||||
uint64_t *array,
|
||||
|
@ -181,6 +181,8 @@ class LLDB_API SBDebugger {
|
||||
|
||||
static const char *StateAsCString(lldb::StateType state);
|
||||
|
||||
static SBStructuredData GetBuildConfiguration();
|
||||
|
||||
static bool StateIsRunningState(lldb::StateType state);
|
||||
|
||||
static bool StateIsStoppedState(lldb::StateType state);
|
||||
|
@ -51,10 +51,8 @@ class LLDB_API SBExpressionOptions {
|
||||
uint32_t GetOneThreadTimeoutInMicroSeconds() const;
|
||||
|
||||
// Set the timeout for running on one thread, 0 means use the default
|
||||
// behavior.
|
||||
// If you set this higher than the overall timeout, you'll get an error when
|
||||
// you
|
||||
// try to run the expression.
|
||||
// behavior. If you set this higher than the overall timeout, you'll get an
|
||||
// error when you try to run the expression.
|
||||
void SetOneThreadTimeoutInMicroSeconds(uint32_t timeout = 0);
|
||||
|
||||
bool GetTryAllThreads() const;
|
||||
|
@ -153,10 +153,10 @@ class LLDB_API SBFrame {
|
||||
lldb::DynamicValueType use_dynamic);
|
||||
|
||||
// Find a value for a variable expression path like "rect.origin.x" or
|
||||
// "pt_ptr->x", "*self", "*this->obj_ptr". The returned value is _not_
|
||||
// and expression result and is not a constant object like
|
||||
// SBFrame::EvaluateExpression(...) returns, but a child object of
|
||||
// the variable value.
|
||||
// "pt_ptr->x", "*self", "*this->obj_ptr". The returned value is _not_ and
|
||||
// expression result and is not a constant object like
|
||||
// SBFrame::EvaluateExpression(...) returns, but a child object of the
|
||||
// variable value.
|
||||
lldb::SBValue GetValueForVariablePath(const char *var_expr_cstr,
|
||||
DynamicValueType use_dynamic);
|
||||
|
||||
|
@ -16,8 +16,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
// There's a lot to be fixed here, but need to wait for underlying insn
|
||||
// implementation
|
||||
// to be revised & settle down first.
|
||||
// implementation to be revised & settle down first.
|
||||
|
||||
class InstructionImpl;
|
||||
|
||||
@ -37,8 +36,6 @@ class LLDB_API SBInstruction {
|
||||
|
||||
SBAddress GetAddress();
|
||||
|
||||
lldb::AddressClass GetAddressClass();
|
||||
|
||||
const char *GetMnemonic(lldb::SBTarget target);
|
||||
|
||||
const char *GetOperands(lldb::SBTarget target);
|
||||
|
@ -33,8 +33,8 @@ class LLDB_API SBInstructionList {
|
||||
lldb::SBInstruction GetInstructionAtIndex(uint32_t idx);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Returns the number of instructions between the start and end address.
|
||||
// If canSetBreakpoint is true then the count will be the number of
|
||||
// Returns the number of instructions between the start and end address. If
|
||||
// canSetBreakpoint is true then the count will be the number of
|
||||
// instructions on which a breakpoint can be set.
|
||||
// ----------------------------------------------------------------------
|
||||
size_t GetInstructionsCount(const SBAddress &start,
|
||||
|
@ -12,6 +12,10 @@
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class SBLaunchInfoImpl;
|
||||
}
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class SBPlatform;
|
||||
@ -141,11 +145,10 @@ class LLDB_API SBLaunchInfo {
|
||||
friend class SBPlatform;
|
||||
friend class SBTarget;
|
||||
|
||||
lldb_private::ProcessLaunchInfo &ref();
|
||||
|
||||
const lldb_private::ProcessLaunchInfo &ref() const;
|
||||
void set_ref(const lldb_private::ProcessLaunchInfo &info);
|
||||
|
||||
ProcessLaunchInfoSP m_opaque_sp;
|
||||
std::shared_ptr<lldb_private::SBLaunchInfoImpl> m_opaque_sp;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
@ -129,6 +129,21 @@ class LLDB_API SBModule {
|
||||
|
||||
lldb::SBCompileUnit GetCompileUnitAtIndex(uint32_t);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find compile units related to *this module and passed source
|
||||
/// file.
|
||||
///
|
||||
/// @param[in] sb_file_spec
|
||||
/// A lldb::SBFileSpec object that contains source file
|
||||
/// specification.
|
||||
///
|
||||
/// @return
|
||||
/// A lldb::SBSymbolContextList that gets filled in with all of
|
||||
/// the symbol contexts for all the matches.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBSymbolContextList
|
||||
FindCompileUnits(const lldb::SBFileSpec &sb_file_spec);
|
||||
|
||||
size_t GetNumSymbols();
|
||||
|
||||
lldb::SBSymbol GetSymbolAtIndex(size_t idx);
|
||||
|
@ -98,10 +98,10 @@ class LLDB_API SBProcess {
|
||||
lldb::SBThread GetSelectedThread() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Function for lazily creating a thread using the current OS
|
||||
// plug-in. This function will be removed in the future when there
|
||||
// are APIs to create SBThread objects through the interface and add
|
||||
// them to the process through the SBProcess API.
|
||||
// Function for lazily creating a thread using the current OS plug-in. This
|
||||
// function will be removed in the future when there are APIs to create
|
||||
// SBThread objects through the interface and add them to the process through
|
||||
// the SBProcess API.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBThread CreateOSPluginThread(lldb::tid_t tid, lldb::addr_t context);
|
||||
|
||||
@ -313,6 +313,40 @@ class LLDB_API SBProcess {
|
||||
const lldb::SBFileSpec &remote_image_spec,
|
||||
lldb::SBError &error);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Load a shared library into this process, starting with a
|
||||
/// library name and a list of paths, searching along the list of
|
||||
/// paths till you find a matching library.
|
||||
///
|
||||
/// @param[in] local_spec
|
||||
/// The name of the shared library that you want to load.
|
||||
/// If local_spec is a relative path, the relative path will be
|
||||
/// appended to the search paths.
|
||||
/// If the local_spec is an absolute path, just the basename is used.
|
||||
///
|
||||
/// @param[in] paths
|
||||
/// A list of paths to search for the library whose basename is
|
||||
/// local_spec.
|
||||
///
|
||||
/// @param[out] loaded_path
|
||||
/// If the library was found along the paths, this will store the
|
||||
/// full path to the found library.
|
||||
///
|
||||
/// @param[out] error
|
||||
/// An error object that gets filled in with any errors that
|
||||
/// might occur when trying to search for the shared library.
|
||||
///
|
||||
/// @return
|
||||
/// A token that represents the shared library that can be
|
||||
/// later passed to UnloadImage. A value of
|
||||
/// LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
|
||||
/// library can't be opened.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t LoadImageUsingPaths(const lldb::SBFileSpec &image_spec,
|
||||
SBStringList &paths,
|
||||
lldb::SBFileSpec &loaded_path,
|
||||
lldb::SBError &error);
|
||||
|
||||
lldb::SBError UnloadImage(uint32_t image_token);
|
||||
|
||||
lldb::SBError SendEventData(const char *data);
|
||||
|
@ -26,13 +26,12 @@ class LLDB_API SBStream {
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
// If this stream is not redirected to a file, it will maintain a local
|
||||
// cache for the stream data which can be accessed using this accessor.
|
||||
// If this stream is not redirected to a file, it will maintain a local cache
|
||||
// for the stream data which can be accessed using this accessor.
|
||||
const char *GetData();
|
||||
|
||||
// If this stream is not redirected to a file, it will maintain a local
|
||||
// cache for the stream output whose length can be accessed using this
|
||||
// accessor.
|
||||
// If this stream is not redirected to a file, it will maintain a local cache
|
||||
// for the stream output whose length can be accessed using this accessor.
|
||||
size_t GetSize();
|
||||
|
||||
void Printf(const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||
@ -44,8 +43,8 @@ class LLDB_API SBStream {
|
||||
void RedirectToFileDescriptor(int fd, bool transfer_fh_ownership);
|
||||
|
||||
// If the stream is redirected to a file, forget about the file and if
|
||||
// ownership of the file was transferred to this object, close the file.
|
||||
// If the stream is backed by a local cache, clear this cache.
|
||||
// ownership of the file was transferred to this object, close the file. If
|
||||
// the stream is backed by a local cache, clear this cache.
|
||||
void Clear();
|
||||
|
||||
protected:
|
||||
|
@ -99,6 +99,7 @@ class SBStructuredData {
|
||||
protected:
|
||||
friend class SBTraceOptions;
|
||||
friend class SBDebugger;
|
||||
friend class SBTarget;
|
||||
|
||||
StructuredDataImplUP m_impl_up;
|
||||
};
|
||||
|
@ -55,8 +55,8 @@ class LLDB_API SBSymbol {
|
||||
bool GetDescription(lldb::SBStream &description);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Returns true if the symbol is externally visible in the module that
|
||||
// it is defined in
|
||||
// Returns true if the symbol is externally visible in the module that it is
|
||||
// defined in
|
||||
//----------------------------------------------------------------------
|
||||
bool IsExternal();
|
||||
|
||||
|
@ -75,6 +75,8 @@ class LLDB_API SBTarget {
|
||||
|
||||
lldb::SBProcess GetProcess();
|
||||
|
||||
lldb::SBStructuredData GetStatistics();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the platform object associated with the target.
|
||||
///
|
||||
@ -163,6 +165,7 @@ class LLDB_API SBTarget {
|
||||
bool stop_at_entry, lldb::SBError &error);
|
||||
|
||||
SBProcess LoadCore(const char *core_file);
|
||||
SBProcess LoadCore(const char *core_file, lldb::SBError &error);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Launch a new process with sensible defaults.
|
||||
@ -289,6 +292,21 @@ class LLDB_API SBTarget {
|
||||
|
||||
lldb::SBModule FindModule(const lldb::SBFileSpec &file_spec);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find compile units related to *this target and passed source
|
||||
/// file.
|
||||
///
|
||||
/// @param[in] sb_file_spec
|
||||
/// A lldb::SBFileSpec object that contains source file
|
||||
/// specification.
|
||||
///
|
||||
/// @return
|
||||
/// A lldb::SBSymbolContextList that gets filled in with all of
|
||||
/// the symbol contexts for all the matches.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBSymbolContextList
|
||||
FindCompileUnits(const lldb::SBFileSpec &sb_file_spec);
|
||||
|
||||
lldb::ByteOrder GetByteOrder();
|
||||
|
||||
uint32_t GetAddressByteSize();
|
||||
@ -716,9 +734,9 @@ class LLDB_API SBTarget {
|
||||
// Finds all breakpoints by name, returning the list in bkpt_list. Returns
|
||||
// false if the name is not a valid breakpoint name, true otherwise.
|
||||
bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);
|
||||
|
||||
|
||||
void GetBreakpointNames(SBStringList &names);
|
||||
|
||||
|
||||
void DeleteBreakpointName(const char *name);
|
||||
|
||||
bool EnableAllBreakpoints();
|
||||
@ -773,8 +791,7 @@ class LLDB_API SBTarget {
|
||||
const void *buf, size_t size);
|
||||
|
||||
// The "WithFlavor" is necessary to keep SWIG from getting confused about
|
||||
// overloaded arguments when
|
||||
// using the buf + size -> Python Object magic.
|
||||
// overloaded arguments when using the buf + size -> Python Object magic.
|
||||
|
||||
lldb::SBInstructionList GetInstructionsWithFlavor(lldb::SBAddress base_addr,
|
||||
const char *flavor_string,
|
||||
@ -827,8 +844,8 @@ class LLDB_API SBTarget {
|
||||
friend class SBValue;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors are private, use static Target::Create function to
|
||||
// create an instance of this class.
|
||||
// Constructors are private, use static Target::Create function to create an
|
||||
// instance of this class.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
lldb::TargetSP GetSP() const;
|
||||
|
@ -93,6 +93,8 @@ class LLDB_API SBThread {
|
||||
|
||||
void StepOver(lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
|
||||
|
||||
void StepOver(lldb::RunMode stop_other_threads, SBError &error);
|
||||
|
||||
void StepInto(lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
|
||||
|
||||
void StepInto(const char *target_name,
|
||||
@ -103,10 +105,16 @@ class LLDB_API SBThread {
|
||||
|
||||
void StepOut();
|
||||
|
||||
void StepOutOfFrame(lldb::SBFrame &frame);
|
||||
void StepOut(SBError &error);
|
||||
|
||||
void StepOutOfFrame(SBFrame &frame);
|
||||
|
||||
void StepOutOfFrame(SBFrame &frame, SBError &error);
|
||||
|
||||
void StepInstruction(bool step_over);
|
||||
|
||||
void StepInstruction(bool step_over, SBError &error);
|
||||
|
||||
SBError StepOverUntil(lldb::SBFrame &frame, lldb::SBFileSpec &file_spec,
|
||||
uint32_t line);
|
||||
|
||||
@ -119,6 +127,8 @@ class LLDB_API SBThread {
|
||||
|
||||
void RunToAddress(lldb::addr_t addr);
|
||||
|
||||
void RunToAddress(lldb::addr_t addr, SBError &error);
|
||||
|
||||
SBError ReturnFromFrame(SBFrame &frame, SBValue &return_value);
|
||||
|
||||
SBError UnwindInnermostExpression();
|
||||
@ -146,8 +156,12 @@ class LLDB_API SBThread {
|
||||
//--------------------------------------------------------------------------
|
||||
bool Suspend();
|
||||
|
||||
bool Suspend(SBError &error);
|
||||
|
||||
bool Resume();
|
||||
|
||||
bool Resume(SBError &error);
|
||||
|
||||
bool IsSuspended();
|
||||
|
||||
bool IsStopped();
|
||||
|
@ -134,8 +134,7 @@ class LLDB_API SBValue {
|
||||
lldb::SBType type);
|
||||
|
||||
// this has no address! GetAddress() and GetLoadAddress() as well as
|
||||
// AddressOf()
|
||||
// on the return of this call all return invalid
|
||||
// AddressOf() on the return of this call all return invalid
|
||||
lldb::SBValue CreateValueFromData(const char *name, lldb::SBData data,
|
||||
lldb::SBType type);
|
||||
|
||||
|
@ -43,8 +43,8 @@ class LLDB_API SBValueList {
|
||||
const lldb::SBValueList &operator=(const lldb::SBValueList &rhs);
|
||||
|
||||
protected:
|
||||
// only useful for visualizing the pointer or comparing two SBValueLists
|
||||
// to see if they are backed by the same underlying Impl.
|
||||
// only useful for visualizing the pointer or comparing two SBValueLists to
|
||||
// see if they are backed by the same underlying Impl.
|
||||
void *opaque_ptr();
|
||||
|
||||
private:
|
||||
|
@ -33,8 +33,8 @@
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Breakpoint Breakpoint.h "lldb/Breakpoint/Breakpoint.h"
|
||||
/// @brief Class that manages logical breakpoint setting.
|
||||
/// @class Breakpoint Breakpoint.h "lldb/Breakpoint/Breakpoint.h" Class that
|
||||
/// manages logical breakpoint setting.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -42,33 +42,28 @@ namespace lldb_private {
|
||||
/// A breakpoint has four main parts, a filter, a resolver, the list of
|
||||
/// breakpoint
|
||||
/// locations that have been determined for the filter/resolver pair, and
|
||||
/// finally
|
||||
/// a set of options for the breakpoint.
|
||||
/// finally a set of options for the breakpoint.
|
||||
///
|
||||
/// \b Filter:
|
||||
/// This is an object derived from SearchFilter. It manages the search
|
||||
/// for breakpoint location matches through the symbols in the module list of
|
||||
/// the target
|
||||
/// that owns it. It also filters out locations based on whatever logic it
|
||||
/// wants.
|
||||
/// This is an object derived from SearchFilter. It manages the search for
|
||||
/// breakpoint location matches through the symbols in the module list of the
|
||||
/// target that owns it. It also filters out locations based on whatever
|
||||
/// logic it wants.
|
||||
///
|
||||
/// \b Resolver:
|
||||
/// This is an object derived from BreakpointResolver. It provides a
|
||||
/// callback to the filter that will find breakpoint locations. How it does
|
||||
/// this is
|
||||
/// This is an object derived from BreakpointResolver. It provides a callback
|
||||
/// to the filter that will find breakpoint locations. How it does this is
|
||||
/// determined by what kind of resolver it is.
|
||||
///
|
||||
/// The Breakpoint class also provides constructors for the common breakpoint
|
||||
/// cases
|
||||
/// which make the appropriate filter and resolver for you.
|
||||
/// cases which make the appropriate filter and resolver for you.
|
||||
///
|
||||
/// \b Location List:
|
||||
/// This stores the breakpoint locations that have been determined
|
||||
/// to date. For a given breakpoint, there will be only one location with a
|
||||
/// given
|
||||
/// address. Adding a location at an already taken address will just return the
|
||||
/// location
|
||||
/// already at that address. Locations can be looked up by ID, or by address.
|
||||
/// This stores the breakpoint locations that have been determined to date.
|
||||
/// For a given breakpoint, there will be only one location with a given
|
||||
/// address. Adding a location at an already taken address will just return
|
||||
/// the location already at that address. Locations can be looked up by ID,
|
||||
/// or by address.
|
||||
///
|
||||
/// \b Options:
|
||||
/// This includes:
|
||||
@ -77,25 +72,17 @@ namespace lldb_private {
|
||||
/// \b Callback
|
||||
/// \b Condition
|
||||
/// Note, these options can be set on the breakpoint, and they can also be set
|
||||
/// on the
|
||||
/// individual locations. The options set on the breakpoint take precedence
|
||||
/// over the
|
||||
/// options set on the individual location.
|
||||
/// So for instance disabling the breakpoint will cause NONE of the locations to
|
||||
/// get hit.
|
||||
/// But if the breakpoint is enabled, then the location's enabled state will be
|
||||
/// checked
|
||||
/// to determine whether to insert that breakpoint location.
|
||||
/// on the individual locations. The options set on the breakpoint take
|
||||
/// precedence over the options set on the individual location. So for
|
||||
/// instance disabling the breakpoint will cause NONE of the locations to get
|
||||
/// hit. But if the breakpoint is enabled, then the location's enabled state
|
||||
/// will be checked to determine whether to insert that breakpoint location.
|
||||
/// Similarly, if the breakpoint condition says "stop", we won't check the
|
||||
/// location's condition.
|
||||
/// But if the breakpoint condition says "continue", then we will check the
|
||||
/// location for whether
|
||||
/// to actually stop or not.
|
||||
/// One subtle point worth observing here is that you don't actually stop at a
|
||||
/// Breakpoint, you
|
||||
/// always stop at one of its locations. So the "should stop" tests are done by
|
||||
/// the location,
|
||||
/// not by the breakpoint.
|
||||
/// location's condition. But if the breakpoint condition says "continue",
|
||||
/// then we will check the location for whether to actually stop or not. One
|
||||
/// subtle point worth observing here is that you don't actually stop at a
|
||||
/// Breakpoint, you always stop at one of its locations. So the "should stop"
|
||||
/// tests are done by the location, not by the breakpoint.
|
||||
//----------------------------------------------------------------------
|
||||
class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
public Stoppoint {
|
||||
@ -103,8 +90,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
static const ConstString &GetEventIdentifier();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// An enum specifying the match style for breakpoint settings. At
|
||||
/// present only used for function name style breakpoints.
|
||||
/// An enum specifying the match style for breakpoint settings. At present
|
||||
/// only used for function name style breakpoints.
|
||||
//------------------------------------------------------------------
|
||||
typedef enum { Exact, Regexp, Glob } MatchType;
|
||||
|
||||
@ -191,9 +178,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
///
|
||||
/// The destructor is not virtual since there should be no reason to subclass
|
||||
/// breakpoints. The varieties of breakpoints are specified instead by
|
||||
/// providing different resolvers & filters.
|
||||
/// The destructor is not virtual since there should be no reason to
|
||||
/// subclass breakpoints. The varieties of breakpoints are specified
|
||||
/// instead by providing different resolvers & filters.
|
||||
//------------------------------------------------------------------
|
||||
~Breakpoint() override;
|
||||
|
||||
@ -202,8 +189,7 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell whether this breakpoint is an "internal" breakpoint.
|
||||
/// @return
|
||||
/// Tell whether this breakpoint is an "internal" breakpoint. @return
|
||||
/// Returns \b true if this is an internal breakpoint, \b false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
bool IsInternal() const;
|
||||
@ -214,13 +200,13 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
void Dump(Stream *s) override;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// The next set of methods provide ways to tell the breakpoint to update
|
||||
// it's location list - usually done when modules appear or disappear.
|
||||
// The next set of methods provide ways to tell the breakpoint to update it's
|
||||
// location list - usually done when modules appear or disappear.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell this breakpoint to clear all its breakpoint sites. Done
|
||||
/// when the process holding the breakpoint sites is destroyed.
|
||||
/// Tell this breakpoint to clear all its breakpoint sites. Done when the
|
||||
/// process holding the breakpoint sites is destroyed.
|
||||
//------------------------------------------------------------------
|
||||
void ClearAllBreakpointSites();
|
||||
|
||||
@ -231,8 +217,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
void ResolveBreakpoint();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell this breakpoint to scan a given module list and resolve any
|
||||
/// new locations that match the breakpoint's specifications.
|
||||
/// Tell this breakpoint to scan a given module list and resolve any new
|
||||
/// locations that match the breakpoint's specifications.
|
||||
///
|
||||
/// @param[in] module_list
|
||||
/// The list of modules to look in for new locations.
|
||||
@ -245,8 +231,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
bool send_event = true);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell this breakpoint to scan a given module list and resolve any
|
||||
/// new locations that match the breakpoint's specifications.
|
||||
/// Tell this breakpoint to scan a given module list and resolve any new
|
||||
/// locations that match the breakpoint's specifications.
|
||||
///
|
||||
/// @param[in] changed_modules
|
||||
/// The list of modules to look in for new locations.
|
||||
@ -274,9 +260,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
bool delete_locations = false);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tells the breakpoint the old module \a old_module_sp has been
|
||||
/// replaced by new_module_sp (usually because the underlying file has been
|
||||
/// rebuilt, and the old version is gone.)
|
||||
/// Tells the breakpoint the old module \a old_module_sp has been replaced
|
||||
/// by new_module_sp (usually because the underlying file has been rebuilt,
|
||||
/// and the old version is gone.)
|
||||
///
|
||||
/// @param[in] old_module_sp
|
||||
/// The old module that is going away.
|
||||
@ -287,13 +273,13 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
lldb::ModuleSP new_module_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// The next set of methods provide access to the breakpoint locations
|
||||
// for this breakpoint.
|
||||
// The next set of methods provide access to the breakpoint locations for
|
||||
// this breakpoint.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Add a location to the breakpoint's location list. This is only meant
|
||||
/// to be called by the breakpoint's resolver. FIXME: how do I ensure that?
|
||||
/// Add a location to the breakpoint's location list. This is only meant to
|
||||
/// be called by the breakpoint's resolver. FIXME: how do I ensure that?
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The Address specifying the new location.
|
||||
@ -359,12 +345,12 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
/// Removes all invalid breakpoint locations.
|
||||
///
|
||||
/// Removes all breakpoint locations with architectures that aren't
|
||||
/// compatible with \a arch. Also remove any breakpoint locations
|
||||
/// with whose locations have address where the section has been
|
||||
/// deleted (module and object files no longer exist).
|
||||
/// compatible with \a arch. Also remove any breakpoint locations with whose
|
||||
/// locations have address where the section has been deleted (module and
|
||||
/// object files no longer exist).
|
||||
///
|
||||
/// This is typically used after the process calls exec, or anytime
|
||||
/// the architecture of the target changes.
|
||||
/// This is typically used after the process calls exec, or anytime the
|
||||
/// architecture of the target changes.
|
||||
///
|
||||
/// @param[in] arch
|
||||
/// If valid, check the module in each breakpoint to make sure
|
||||
@ -403,8 +389,7 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
uint32_t GetIgnoreCount() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the current hit count for all locations.
|
||||
/// @return
|
||||
/// Return the current hit count for all locations. @return
|
||||
/// The current hit count for all locations.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t GetHitCount() const;
|
||||
@ -422,7 +407,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
bool IsOneShot() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// If \a auto_continue is \b true, breakpoint will auto-continue when on hit.
|
||||
/// If \a auto_continue is \b true, breakpoint will auto-continue when on
|
||||
/// hit.
|
||||
//------------------------------------------------------------------
|
||||
void SetAutoContinue(bool auto_continue);
|
||||
|
||||
@ -508,8 +494,8 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the number of breakpoint locations that have resolved to
|
||||
/// actual breakpoint sites.
|
||||
/// Return the number of breakpoint locations that have resolved to actual
|
||||
/// breakpoint sites.
|
||||
///
|
||||
/// @return
|
||||
/// The number locations resolved breakpoint sites.
|
||||
@ -541,10 +527,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the "kind" description for a breakpoint. If the breakpoint is hit
|
||||
/// the stop info will show this "kind" description instead of the breakpoint
|
||||
/// number. Mostly useful for internal breakpoints, where the breakpoint
|
||||
/// number
|
||||
/// doesn't have meaning to the user.
|
||||
/// the stop info will show this "kind" description instead of the
|
||||
/// breakpoint number. Mostly useful for internal breakpoints, where the
|
||||
/// breakpoint number doesn't have meaning to the user.
|
||||
///
|
||||
/// @param[in] kind
|
||||
/// New "kind" description.
|
||||
@ -574,10 +559,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find breakpoint locations which match the (filename, line_number)
|
||||
/// description.
|
||||
/// The breakpoint location collection is to be filled with the matching
|
||||
/// locations.
|
||||
/// It should be initialized with 0 size by the API client.
|
||||
/// description. The breakpoint location collection is to be filled with the
|
||||
/// matching locations. It should be initialized with 0 size by the API
|
||||
/// client.
|
||||
///
|
||||
/// @return
|
||||
/// True if there is a match
|
||||
@ -661,13 +645,12 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
/// Set a pre-condition filter that overrides all user provided
|
||||
/// filters/callbacks etc.
|
||||
///
|
||||
/// Used to define fancy breakpoints that can do dynamic hit detection without
|
||||
/// taking up the condition slot -
|
||||
/// which really belongs to the user anyway...
|
||||
/// Used to define fancy breakpoints that can do dynamic hit detection
|
||||
/// without taking up the condition slot - which really belongs to the user
|
||||
/// anyway...
|
||||
///
|
||||
/// The Precondition should not continue the target, it should return true if
|
||||
/// the condition says to stop and
|
||||
/// false otherwise.
|
||||
/// The Precondition should not continue the target, it should return true
|
||||
/// if the condition says to stop and false otherwise.
|
||||
///
|
||||
//------------------------------------------------------------------
|
||||
void SetPrecondition(BreakpointPreconditionSP precondition_sp) {
|
||||
@ -706,10 +689,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
//------------------------------------------------------------------
|
||||
/// Constructors and Destructors
|
||||
/// Only the Target can make a breakpoint, and it owns the breakpoint
|
||||
/// lifespans.
|
||||
/// The constructor takes a filter and a resolver. Up in Target there are
|
||||
/// convenience
|
||||
/// variants that make breakpoints for some common cases.
|
||||
/// lifespans. The constructor takes a filter and a resolver. Up in Target
|
||||
/// there are convenience variants that make breakpoints for some common
|
||||
/// cases.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// The target in which the breakpoint will be set.
|
||||
@ -744,10 +726,10 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
void DecrementIgnoreCount();
|
||||
|
||||
// BreakpointLocation::IgnoreCountShouldStop &
|
||||
// Breakpoint::IgnoreCountShouldStop can only be called once per stop,
|
||||
// and BreakpointLocation::IgnoreCountShouldStop should be tested first, and
|
||||
// if it returns false we should
|
||||
// continue, otherwise we should test Breakpoint::IgnoreCountShouldStop.
|
||||
// Breakpoint::IgnoreCountShouldStop can only be called once per stop, and
|
||||
// BreakpointLocation::IgnoreCountShouldStop should be tested first, and if
|
||||
// it returns false we should continue, otherwise we should test
|
||||
// Breakpoint::IgnoreCountShouldStop.
|
||||
|
||||
bool IgnoreCountShouldStop();
|
||||
|
||||
@ -760,8 +742,7 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
|
||||
private:
|
||||
// This one should only be used by Target to copy breakpoints from target to
|
||||
// target - primarily from the dummy
|
||||
// target to prime new targets.
|
||||
// target - primarily from the dummy target to prime new targets.
|
||||
Breakpoint(Target &new_target, Breakpoint &bp_to_copy_from);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -782,9 +763,9 @@ class Breakpoint : public std::enable_shared_from_this<Breakpoint>,
|
||||
BreakpointPreconditionSP m_precondition_sp; // The precondition is a
|
||||
// breakpoint-level hit filter
|
||||
// that can be used
|
||||
// to skip certain breakpoint hits. For instance, exception breakpoints
|
||||
// use this to limit the stop to certain exception classes, while leaving
|
||||
// the condition & callback free for user specification.
|
||||
// to skip certain breakpoint hits. For instance, exception breakpoints use
|
||||
// this to limit the stop to certain exception classes, while leaving the
|
||||
// condition & callback free for user specification.
|
||||
std::unique_ptr<BreakpointOptions>
|
||||
m_options_up; // Settable breakpoint options
|
||||
BreakpointLocationList
|
||||
|
@ -57,7 +57,7 @@ class BreakpointID {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Takes an input string containing the description of a breakpoint or
|
||||
/// breakpoint and location and returns the a BreakpointID filled out with
|
||||
/// breakpoint and location and returns a BreakpointID filled out with
|
||||
/// the proper id and location.
|
||||
///
|
||||
/// @param[in] input
|
||||
|
@ -55,7 +55,7 @@ class BreakpointIDList {
|
||||
|
||||
bool FindBreakpointID(const char *bp_id, size_t *position) const;
|
||||
|
||||
void InsertStringArray(const char **string_array, size_t array_size,
|
||||
void InsertStringArray(llvm::ArrayRef<const char *> string_array,
|
||||
CommandReturnObject &result);
|
||||
|
||||
// Returns a pair consisting of the beginning and end of a breakpoint
|
||||
|
@ -23,7 +23,7 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointList BreakpointList.h "lldb/Breakpoint/BreakpointList.h"
|
||||
/// @brief This class manages a list of breakpoints.
|
||||
/// This class manages a list of breakpoints.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -91,7 +91,8 @@ class BreakpointList {
|
||||
lldb::BreakpointSP GetBreakpointAtIndex(size_t i);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint with index \a i, const version
|
||||
/// Returns a shared pointer to the breakpoint with index \a i, const
|
||||
/// version
|
||||
///
|
||||
/// @param[in] i
|
||||
/// The breakpoint index to seek for.
|
||||
@ -138,13 +139,13 @@ class BreakpointList {
|
||||
//------------------------------------------------------------------
|
||||
/// Removes all invalid breakpoint locations.
|
||||
///
|
||||
/// Removes all breakpoint locations in the list with architectures
|
||||
/// that aren't compatible with \a arch. Also remove any breakpoint
|
||||
/// locations with whose locations have address where the section
|
||||
/// has been deleted (module and object files no longer exist).
|
||||
/// Removes all breakpoint locations in the list with architectures that
|
||||
/// aren't compatible with \a arch. Also remove any breakpoint locations
|
||||
/// with whose locations have address where the section has been deleted
|
||||
/// (module and object files no longer exist).
|
||||
///
|
||||
/// This is typically used after the process calls exec, or anytime
|
||||
/// the architecture of the target changes.
|
||||
/// This is typically used after the process calls exec, or anytime the
|
||||
/// architecture of the target changes.
|
||||
///
|
||||
/// @param[in] arch
|
||||
/// If valid, check the module in each breakpoint to make sure
|
||||
@ -163,8 +164,8 @@ class BreakpointList {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Removes all the breakpoints from this list - first checking the
|
||||
/// ePermDelete on the breakpoints. This call should be used unless you
|
||||
/// are shutting down and need to actually clear them all.
|
||||
/// ePermDelete on the breakpoints. This call should be used unless you are
|
||||
/// shutting down and need to actually clear them all.
|
||||
//------------------------------------------------------------------
|
||||
void RemoveAllowed(bool notify);
|
||||
|
||||
|
@ -27,22 +27,20 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointLocation BreakpointLocation.h
|
||||
/// "lldb/Breakpoint/BreakpointLocation.h"
|
||||
/// @brief Class that manages one unique (by address) instance of a logical
|
||||
/// breakpoint.
|
||||
/// "lldb/Breakpoint/BreakpointLocation.h" Class that manages one unique (by
|
||||
/// address) instance of a logical breakpoint.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// General Outline:
|
||||
/// A breakpoint location is defined by the breakpoint that produces it,
|
||||
/// and the address that resulted in this particular instantiation.
|
||||
/// Each breakpoint location also may have a breakpoint site if its
|
||||
/// address has been loaded into the program.
|
||||
/// Finally it has a settable options object.
|
||||
/// and the address that resulted in this particular instantiation. Each
|
||||
/// breakpoint location also may have a breakpoint site if its address has
|
||||
/// been loaded into the program. Finally it has a settable options object.
|
||||
///
|
||||
/// FIXME: Should we also store some fingerprint for the location, so
|
||||
/// we can map one location to the "equivalent location" on rerun? This
|
||||
/// would be useful if you've set options on the locations.
|
||||
/// we can map one location to the "equivalent location" on rerun? This would
|
||||
/// be useful if you've set options on the locations.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointLocation
|
||||
@ -52,22 +50,19 @@ class BreakpointLocation
|
||||
~BreakpointLocation() override;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Gets the load address for this breakpoint location
|
||||
/// @return
|
||||
/// Gets the load address for this breakpoint location @return
|
||||
/// Returns breakpoint location load address, \b
|
||||
/// LLDB_INVALID_ADDRESS if not yet set.
|
||||
//------------------------------------------------------------------
|
||||
lldb::addr_t GetLoadAddress() const override;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Gets the Address for this breakpoint location
|
||||
/// @return
|
||||
/// Gets the Address for this breakpoint location @return
|
||||
/// Returns breakpoint location Address.
|
||||
//------------------------------------------------------------------
|
||||
Address &GetAddress();
|
||||
//------------------------------------------------------------------
|
||||
/// Gets the Breakpoint that created this breakpoint location
|
||||
/// @return
|
||||
/// Gets the Breakpoint that created this breakpoint location @return
|
||||
/// Returns the owning breakpoint.
|
||||
//------------------------------------------------------------------
|
||||
Breakpoint &GetBreakpoint();
|
||||
@ -75,12 +70,11 @@ class BreakpointLocation
|
||||
Target &GetTarget();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Determines whether we should stop due to a hit at this
|
||||
/// breakpoint location.
|
||||
/// Determines whether we should stop due to a hit at this breakpoint
|
||||
/// location.
|
||||
///
|
||||
/// Side Effects: This may evaluate the breakpoint condition, and
|
||||
/// run the callback. So this command may do a considerable amount
|
||||
/// of work.
|
||||
/// Side Effects: This may evaluate the breakpoint condition, and run the
|
||||
/// callback. So this command may do a considerable amount of work.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if this breakpoint location thinks we should stop,
|
||||
@ -93,8 +87,7 @@ class BreakpointLocation
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// If \a enable is \b true, enable the breakpoint, if \b false
|
||||
/// disable it.
|
||||
/// If \a enable is \b true, enable the breakpoint, if \b false disable it.
|
||||
//------------------------------------------------------------------
|
||||
void SetEnabled(bool enabled);
|
||||
|
||||
@ -138,8 +131,8 @@ class BreakpointLocation
|
||||
//------------------------------------------------------------------
|
||||
/// Set the callback action invoked when the breakpoint is hit.
|
||||
///
|
||||
/// The callback will return a bool indicating whether the target
|
||||
/// should stop at this breakpoint or not.
|
||||
/// The callback will return a bool indicating whether the target should
|
||||
/// stop at this breakpoint or not.
|
||||
///
|
||||
/// @param[in] callback
|
||||
/// The method that will get called when the breakpoint is hit.
|
||||
@ -213,8 +206,8 @@ class BreakpointLocation
|
||||
bool ResolveBreakpointSite();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Clear this breakpoint location's breakpoint site - for instance
|
||||
/// when disabling the breakpoint.
|
||||
/// Clear this breakpoint location's breakpoint site - for instance when
|
||||
/// disabling the breakpoint.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if there was a breakpoint site to be cleared, \b false
|
||||
@ -223,8 +216,7 @@ class BreakpointLocation
|
||||
bool ClearBreakpointSite();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return whether this breakpoint location has a breakpoint site.
|
||||
/// @return
|
||||
/// Return whether this breakpoint location has a breakpoint site. @return
|
||||
/// \b true if there was a breakpoint site for this breakpoint
|
||||
/// location, \b false otherwise.
|
||||
//------------------------------------------------------------------
|
||||
@ -237,8 +229,7 @@ class BreakpointLocation
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Print a description of this breakpoint location to the stream
|
||||
/// \a s.
|
||||
/// Print a description of this breakpoint location to the stream \a s.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to print the description.
|
||||
@ -259,8 +250,8 @@ class BreakpointLocation
|
||||
//------------------------------------------------------------------
|
||||
/// Use this to set location specific breakpoint options.
|
||||
///
|
||||
/// It will create a copy of the containing breakpoint's options if
|
||||
/// that hasn't been done already
|
||||
/// It will create a copy of the containing breakpoint's options if that
|
||||
/// hasn't been done already
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to the breakpoint options.
|
||||
@ -302,8 +293,7 @@ class BreakpointLocation
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether we should resolve Indirect functions in setting the
|
||||
/// breakpoint site
|
||||
/// for this location.
|
||||
/// breakpoint site for this location.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if the breakpoint SITE for this location should be set on the
|
||||
@ -315,8 +305,7 @@ class BreakpointLocation
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether the address set in the breakpoint site for this location
|
||||
/// was found by resolving
|
||||
/// an indirect symbol.
|
||||
/// was found by resolving an indirect symbol.
|
||||
///
|
||||
/// @return
|
||||
/// \b true or \b false as given in the description above.
|
||||
@ -327,8 +316,7 @@ class BreakpointLocation
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether the address set in the breakpoint location was re-routed
|
||||
/// to the target of a
|
||||
/// re-exported symbol.
|
||||
/// to the target of a re-exported symbol.
|
||||
///
|
||||
/// @return
|
||||
/// \b true or \b false as given in the description above.
|
||||
@ -339,10 +327,8 @@ class BreakpointLocation
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns whether the two breakpoint locations might represent "equivalent
|
||||
/// locations".
|
||||
/// This is used when modules changed to determine if a Location in the old
|
||||
/// module might
|
||||
/// be the "same as" the input location.
|
||||
/// locations". This is used when modules changed to determine if a Location
|
||||
/// in the old module might be the "same as" the input location.
|
||||
///
|
||||
/// @param[in] location
|
||||
/// The location to compare against.
|
||||
@ -384,8 +370,7 @@ class BreakpointLocation
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//
|
||||
// Only the Breakpoint can make breakpoint locations, and it owns
|
||||
// them.
|
||||
// Only the Breakpoint can make breakpoint locations, and it owns them.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
@ -178,8 +178,8 @@ class BreakpointLocationCollection {
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from BreakpointLocationCollection can see
|
||||
// and modify these
|
||||
// Classes that inherit from BreakpointLocationCollection can see and modify
|
||||
// these
|
||||
//------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
@ -26,21 +26,16 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointLocationList BreakpointLocationList.h
|
||||
/// "lldb/Breakpoint/BreakpointLocationList.h"
|
||||
/// @brief This class is used by Breakpoint to manage a list of breakpoint
|
||||
/// locations,
|
||||
// each breakpoint location in the list
|
||||
/// has a unique ID, and is unique by Address as well.
|
||||
/// "lldb/Breakpoint/BreakpointLocationList.h" This class is used by
|
||||
/// Breakpoint to manage a list of breakpoint locations, each breakpoint
|
||||
/// location in the list has a unique ID, and is unique by Address as well.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointLocationList {
|
||||
// Only Breakpoints can make the location list, or add elements to it.
|
||||
// This is not just some random collection of locations. Rather, the act of
|
||||
// adding the location
|
||||
// to this list sets its ID, and implicitly all the locations have the same
|
||||
// breakpoint ID as
|
||||
// well. If you need a generic container for breakpoint locations, use
|
||||
// BreakpointLocationCollection.
|
||||
// Only Breakpoints can make the location list, or add elements to it. This
|
||||
// is not just some random collection of locations. Rather, the act of
|
||||
// adding the location to this list sets its ID, and implicitly all the
|
||||
// locations have the same breakpoint ID as well. If you need a generic
|
||||
// container for breakpoint locations, use BreakpointLocationCollection.
|
||||
friend class Breakpoint;
|
||||
|
||||
public:
|
||||
@ -52,8 +47,8 @@ class BreakpointLocationList {
|
||||
void Dump(Stream *s) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint location at address
|
||||
/// \a addr - const version.
|
||||
/// Returns a shared pointer to the breakpoint location at address \a addr -
|
||||
/// const version.
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The address to look for.
|
||||
@ -65,8 +60,8 @@ class BreakpointLocationList {
|
||||
const lldb::BreakpointLocationSP FindByAddress(const Address &addr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint location with id
|
||||
/// \a breakID, const version.
|
||||
/// Returns a shared pointer to the breakpoint location with id \a breakID,
|
||||
/// const version.
|
||||
///
|
||||
/// @param[in] breakID
|
||||
/// The breakpoint location ID to seek for.
|
||||
@ -78,8 +73,8 @@ class BreakpointLocationList {
|
||||
lldb::BreakpointLocationSP FindByID(lldb::break_id_t breakID) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the breakpoint location id to the breakpoint location
|
||||
/// at address \a addr.
|
||||
/// Returns the breakpoint location id to the breakpoint location at address
|
||||
/// \a addr.
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The address to match.
|
||||
@ -90,9 +85,8 @@ class BreakpointLocationList {
|
||||
lldb::break_id_t FindIDByAddress(const Address &addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a breakpoint location list of the breakpoint locations
|
||||
/// in the module \a module. This list is allocated, and owned by
|
||||
/// the caller.
|
||||
/// Returns a breakpoint location list of the breakpoint locations in the
|
||||
/// module \a module. This list is allocated, and owned by the caller.
|
||||
///
|
||||
/// @param[in] module
|
||||
/// The module to seek in.
|
||||
@ -108,8 +102,7 @@ class BreakpointLocationList {
|
||||
BreakpointLocationCollection &bp_loc_list);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint location with
|
||||
/// index \a i.
|
||||
/// Returns a shared pointer to the breakpoint location with index \a i.
|
||||
///
|
||||
/// @param[in] i
|
||||
/// The breakpoint location index to seek for.
|
||||
@ -121,8 +114,8 @@ class BreakpointLocationList {
|
||||
lldb::BreakpointLocationSP GetByIndex(size_t i);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint location with index
|
||||
/// \a i, const version.
|
||||
/// Returns a shared pointer to the breakpoint location with index \a i,
|
||||
/// const version.
|
||||
///
|
||||
/// @param[in] i
|
||||
/// The breakpoint location index to seek for.
|
||||
@ -134,20 +127,20 @@ class BreakpointLocationList {
|
||||
const lldb::BreakpointLocationSP GetByIndex(size_t i) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Removes all the locations in this list from their breakpoint site
|
||||
/// owners list.
|
||||
/// Removes all the locations in this list from their breakpoint site owners
|
||||
/// list.
|
||||
//------------------------------------------------------------------
|
||||
void ClearAllBreakpointSites();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tells all the breakpoint locations in this list to attempt to
|
||||
/// resolve any possible breakpoint sites.
|
||||
/// Tells all the breakpoint locations in this list to attempt to resolve
|
||||
/// any possible breakpoint sites.
|
||||
//------------------------------------------------------------------
|
||||
void ResolveAllBreakpointSites();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the number of breakpoint locations in this list with
|
||||
/// resolved breakpoints.
|
||||
/// Returns the number of breakpoint locations in this list with resolved
|
||||
/// breakpoints.
|
||||
///
|
||||
/// @result
|
||||
/// Number of qualifying breakpoint locations.
|
||||
@ -163,8 +156,8 @@ class BreakpointLocationList {
|
||||
uint32_t GetHitCount() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Enquires of the breakpoint location in this list with ID \a
|
||||
/// breakID whether we should stop.
|
||||
/// Enquires of the breakpoint location in this list with ID \a breakID
|
||||
/// whether we should stop.
|
||||
///
|
||||
/// @param[in] context
|
||||
/// This contains the information about this stop.
|
||||
@ -186,8 +179,8 @@ class BreakpointLocationList {
|
||||
size_t GetSize() const { return m_locations.size(); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Print a description of the breakpoint locations in this list to
|
||||
/// the stream \a s.
|
||||
/// Print a description of the breakpoint locations in this list to the
|
||||
/// stream \a s.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to print the description.
|
||||
@ -204,9 +197,9 @@ class BreakpointLocationList {
|
||||
//------------------------------------------------------------------
|
||||
/// This is the standard constructor.
|
||||
///
|
||||
/// It creates an empty breakpoint location list. It is protected
|
||||
/// here because only Breakpoints are allowed to create the
|
||||
/// breakpoint location list.
|
||||
/// It creates an empty breakpoint location list. It is protected here
|
||||
/// because only Breakpoints are allowed to create the breakpoint location
|
||||
/// list.
|
||||
//------------------------------------------------------------------
|
||||
BreakpointLocationList(Breakpoint &owner);
|
||||
|
||||
@ -235,6 +228,8 @@ class BreakpointLocationList {
|
||||
lldb::BreakpointLocationSP from_location_sp);
|
||||
|
||||
bool RemoveLocation(const lldb::BreakpointLocationSP &bp_loc_sp);
|
||||
|
||||
void RemoveLocationByIndex(size_t idx);
|
||||
|
||||
void RemoveInvalidLocations(const ArchSpec &arch);
|
||||
|
||||
|
@ -80,8 +80,8 @@ class BreakpointName {
|
||||
*this = Permissions();
|
||||
}
|
||||
|
||||
// Merge the permissions from incoming into this set of permissions.
|
||||
// Only merge set permissions, and most restrictive permission wins.
|
||||
// Merge the permissions from incoming into this set of permissions. Only
|
||||
// merge set permissions, and most restrictive permission wins.
|
||||
void MergeInto(const Permissions &incoming)
|
||||
{
|
||||
MergePermission(incoming, listPerm);
|
||||
|
@ -27,9 +27,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointOptions BreakpointOptions.h
|
||||
/// "lldb/Breakpoint/BreakpointOptions.h"
|
||||
/// @brief Class that manages the options on a breakpoint or breakpoint
|
||||
/// location.
|
||||
/// "lldb/Breakpoint/BreakpointOptions.h" Class that manages the options on a
|
||||
/// breakpoint or breakpoint location.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointOptions {
|
||||
@ -106,9 +105,8 @@ friend class Breakpoint;
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This constructor allows you to specify all the breakpoint options
|
||||
/// except the callback. That one is more complicated, and better
|
||||
/// to do by hand.
|
||||
/// This constructor allows you to specify all the breakpoint options except
|
||||
/// the callback. That one is more complicated, and better to do by hand.
|
||||
///
|
||||
/// @param[in] condition
|
||||
/// The expression which if it evaluates to \b true if we are to stop
|
||||
@ -125,8 +123,8 @@ friend class Breakpoint;
|
||||
bool auto_continue = false);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Breakpoints make options with all flags set. Locations and Names make options
|
||||
/// with no flags set.
|
||||
/// Breakpoints make options with all flags set. Locations and Names make
|
||||
/// options with no flags set.
|
||||
//------------------------------------------------------------------
|
||||
BreakpointOptions(bool all_flags_set);
|
||||
BreakpointOptions(const BreakpointOptions &rhs);
|
||||
@ -156,18 +154,16 @@ friend class Breakpoint;
|
||||
// Callbacks
|
||||
//
|
||||
// Breakpoint callbacks come in two forms, synchronous and asynchronous.
|
||||
// Synchronous callbacks will get
|
||||
// run before any of the thread plans are consulted, and if they return false
|
||||
// the target will continue
|
||||
// "under the radar" of the thread plans. There are a couple of restrictions
|
||||
// to synchronous callbacks:
|
||||
// 1) They should NOT resume the target themselves. Just return false if you
|
||||
// want the target to restart.
|
||||
// 2) Breakpoints with synchronous callbacks can't have conditions (or rather,
|
||||
// they can have them, but they
|
||||
// won't do anything. Ditto with ignore counts, etc... You are supposed
|
||||
// to control that all through the
|
||||
// callback.
|
||||
// Synchronous callbacks will get run before any of the thread plans are
|
||||
// consulted, and if they return false the target will continue "under the
|
||||
// radar" of the thread plans. There are a couple of restrictions to
|
||||
// synchronous callbacks:
|
||||
// 1) They should NOT resume the target themselves.
|
||||
// Just return false if you want the target to restart.
|
||||
// 2) Breakpoints with synchronous callbacks can't have conditions
|
||||
// (or rather, they can have them, but they won't do anything.
|
||||
// Ditto with ignore counts, etc... You are supposed to control that all
|
||||
// through the callback.
|
||||
// Asynchronous callbacks get run as part of the "ShouldStop" logic in the
|
||||
// thread plan. The logic there is:
|
||||
// a) If the breakpoint is thread specific and not for this thread, continue
|
||||
@ -181,12 +177,10 @@ friend class Breakpoint;
|
||||
// b) If the ignore count says we shouldn't stop, then ditto.
|
||||
// c) If the condition says we shouldn't stop, then ditto.
|
||||
// d) Otherwise, the callback will get run, and if it returns true we will
|
||||
// stop, and if false we won't.
|
||||
// stop, and if false we won't.
|
||||
// The asynchronous callback can run the target itself, but at present that
|
||||
// should be the last action the
|
||||
// callback does. We will relax this condition at some point, but it will
|
||||
// take a bit of plumbing to get
|
||||
// that to work.
|
||||
// should be the last action the callback does. We will relax this condition
|
||||
// at some point, but it will take a bit of plumbing to get that to work.
|
||||
//
|
||||
//------------------------------------------------------------------
|
||||
|
||||
@ -227,8 +221,8 @@ friend class Breakpoint;
|
||||
//------------------------------------------------------------------
|
||||
void ClearCallback();
|
||||
|
||||
// The rest of these functions are meant to be used only within the breakpoint
|
||||
// handling mechanism.
|
||||
// The rest of these functions are meant to be used only within the
|
||||
// breakpoint handling mechanism.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Use this function to invoke the callback for a specific stop.
|
||||
@ -367,8 +361,7 @@ friend class Breakpoint;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the current thread spec for this option. This will return nullptr
|
||||
/// if the no thread
|
||||
/// specifications have been set for this Option yet.
|
||||
/// if the no thread specifications have been set for this Option yet.
|
||||
/// @return
|
||||
/// The thread specification pointer for this option, or nullptr if none
|
||||
/// has
|
||||
@ -377,8 +370,8 @@ friend class Breakpoint;
|
||||
const ThreadSpec *GetThreadSpecNoCreate() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a pointer to the ThreadSpec for this option, creating it.
|
||||
/// if it hasn't been created already. This API is used for setting the
|
||||
/// Returns a pointer to the ThreadSpec for this option, creating it. if it
|
||||
/// hasn't been created already. This API is used for setting the
|
||||
/// ThreadSpec items for this option.
|
||||
//------------------------------------------------------------------
|
||||
ThreadSpec *GetThreadSpec();
|
||||
@ -400,8 +393,8 @@ friend class Breakpoint;
|
||||
lldb::user_id_t break_loc_id);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set a callback based on BreakpointOptions::CommandData.
|
||||
/// @param[in] cmd_data
|
||||
/// Set a callback based on BreakpointOptions::CommandData. @param[in]
|
||||
/// cmd_data
|
||||
/// A UP holding the new'ed CommandData object.
|
||||
/// The breakpoint will take ownership of pointer held by this object.
|
||||
//------------------------------------------------------------------
|
||||
|
@ -26,24 +26,19 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointResolver BreakpointResolver.h
|
||||
/// "lldb/Breakpoint/BreakpointResolver.h"
|
||||
/// @brief This class works with SearchFilter to resolve logical breakpoints to
|
||||
/// their
|
||||
/// of concrete breakpoint locations.
|
||||
/// "lldb/Breakpoint/BreakpointResolver.h" This class works with SearchFilter
|
||||
/// to resolve logical breakpoints to their of concrete breakpoint locations.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// General Outline:
|
||||
/// The BreakpointResolver is a Searcher. In that protocol,
|
||||
/// the SearchFilter asks the question "At what depth of the symbol context
|
||||
/// descent do you want your callback to get called?" of the filter. The
|
||||
/// resolver
|
||||
/// answers this question (in the GetDepth method) and provides the resolution
|
||||
/// callback.
|
||||
/// The BreakpointResolver is a Searcher. In that protocol, the SearchFilter
|
||||
/// asks the question "At what depth of the symbol context descent do you want
|
||||
/// your callback to get called?" of the filter. The resolver answers this
|
||||
/// question (in the GetDepth method) and provides the resolution callback.
|
||||
/// Each Breakpoint has a BreakpointResolver, and it calls either
|
||||
/// ResolveBreakpoint
|
||||
/// or ResolveBreakpointInModules to tell it to look for new breakpoint
|
||||
/// locations.
|
||||
/// ResolveBreakpoint or ResolveBreakpointInModules to tell it to look for new
|
||||
/// breakpoint locations.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointResolver : public Searcher {
|
||||
@ -53,8 +48,7 @@ class BreakpointResolver : public Searcher {
|
||||
//------------------------------------------------------------------
|
||||
/// The breakpoint resolver need to have a breakpoint for "ResolveBreakpoint
|
||||
/// to make sense. It can be constructed without a breakpoint, but you have
|
||||
/// to
|
||||
/// call SetBreakpoint before ResolveBreakpoint.
|
||||
/// to call SetBreakpoint before ResolveBreakpoint.
|
||||
///
|
||||
/// @param[in] bkpt
|
||||
/// The breakpoint that owns this resolver.
|
||||
@ -82,9 +76,9 @@ class BreakpointResolver : public Searcher {
|
||||
void 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.
|
||||
/// 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.
|
||||
@ -92,9 +86,9 @@ class BreakpointResolver : public Searcher {
|
||||
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.
|
||||
/// 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.
|
||||
@ -103,8 +97,7 @@ class BreakpointResolver : public Searcher {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// In response to this method the resolver scans all the modules in the
|
||||
/// breakpoint's
|
||||
/// target, and adds any new locations it finds.
|
||||
/// breakpoint's target, and adds any new locations it finds.
|
||||
///
|
||||
/// @param[in] filter
|
||||
/// The filter that will manage the search for this resolver.
|
||||
@ -113,8 +106,7 @@ class BreakpointResolver : public Searcher {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// In response to this method the resolver scans the modules in the module
|
||||
/// list
|
||||
/// \a modules, and adds any new locations it finds.
|
||||
/// list \a modules, and adds any new locations it finds.
|
||||
///
|
||||
/// @param[in] filter
|
||||
/// The filter that will manage the search for this resolver.
|
||||
@ -157,8 +149,8 @@ class BreakpointResolver : public Searcher {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
/// An enumeration for keeping track of the concrete subclass that
|
||||
/// is actually instantiated. Values of this enumeration are kept in the
|
||||
/// An enumeration for keeping track of the concrete subclass that is
|
||||
/// actually instantiated. Values of this enumeration are kept in the
|
||||
/// BreakpointResolver's SubclassID field. They are used for concrete type
|
||||
/// identification.
|
||||
enum ResolverTy {
|
||||
@ -171,8 +163,8 @@ class BreakpointResolver : public Searcher {
|
||||
UnknownResolver
|
||||
};
|
||||
|
||||
// Translate the Ty to name for serialization,
|
||||
// the "+2" is one for size vrs. index, and one for UnknownResolver.
|
||||
// Translate the Ty to name for serialization, the "+2" is one for size vrs.
|
||||
// index, and one for UnknownResolver.
|
||||
static const char *g_ty_to_name[LastKnownResolverType + 2];
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -199,8 +191,8 @@ class BreakpointResolver : public Searcher {
|
||||
|
||||
protected:
|
||||
// Used for serializing resolver options:
|
||||
// The options in this enum and the strings in the
|
||||
// g_option_names must be kept in sync.
|
||||
// The options in this enum and the strings in the g_option_names must be
|
||||
// kept in sync.
|
||||
enum class OptionNames : uint32_t {
|
||||
AddressOffset = 0,
|
||||
ExactMatch,
|
||||
@ -227,12 +219,10 @@ class BreakpointResolver : public Searcher {
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
/// SetSCMatchesByLine - Takes a symbol context list of matches which
|
||||
/// supposedly represent the same file and
|
||||
/// line number in a CU, and find the nearest actual line number that matches,
|
||||
/// and then filter down the
|
||||
/// matching addresses to unique entries, and skip the prologue if asked to do
|
||||
/// so, and then set
|
||||
/// Takes a symbol context list of matches which supposedly represent the
|
||||
/// same file and line number in a CU, and find the nearest actual line
|
||||
/// number that matches, and then filter down the 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, llvm::StringRef log_ident);
|
||||
|
@ -21,10 +21,9 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointResolverAddress BreakpointResolverAddress.h
|
||||
/// "lldb/Breakpoint/BreakpointResolverAddress.h"
|
||||
/// @brief This class sets breakpoints on a given Address. This breakpoint only
|
||||
/// takes
|
||||
/// once, and then it won't attempt to reset itself.
|
||||
/// "lldb/Breakpoint/BreakpointResolverAddress.h" This class sets breakpoints
|
||||
/// on a given Address. This breakpoint only takes once, and then it won't
|
||||
/// attempt to reset itself.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointResolverAddress : public BreakpointResolver {
|
||||
@ -74,8 +73,7 @@ class BreakpointResolverAddress : public BreakpointResolver {
|
||||
FileSpec m_module_filespec; // If this filespec is Valid, and m_addr is an
|
||||
// offset, then it will be converted
|
||||
// to a Section+Offset address in this module, whenever that module gets
|
||||
// around to
|
||||
// being loaded.
|
||||
// around to being loaded.
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BreakpointResolverAddress);
|
||||
};
|
||||
|
@ -20,10 +20,9 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointResolverFileLine BreakpointResolverFileLine.h
|
||||
/// "lldb/Breakpoint/BreakpointResolverFileLine.h"
|
||||
/// @brief This class sets breakpoints by file and line. Optionally, it will
|
||||
/// look for inlined
|
||||
/// instances of the file and line specification.
|
||||
/// "lldb/Breakpoint/BreakpointResolverFileLine.h" This class sets breakpoints
|
||||
/// by file and line. Optionally, it will look for inlined instances of the
|
||||
/// file and line specification.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointResolverFileLine : public BreakpointResolver {
|
||||
@ -63,7 +62,7 @@ class BreakpointResolverFileLine : public BreakpointResolver {
|
||||
lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override;
|
||||
|
||||
protected:
|
||||
void FilterContexts(SymbolContextList &sc_list);
|
||||
void FilterContexts(SymbolContextList &sc_list, bool is_relative);
|
||||
|
||||
friend class Breakpoint;
|
||||
FileSpec m_file_spec; // This is the file spec we are looking for.
|
||||
|
@ -23,9 +23,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointResolverFileRegex BreakpointResolverFileRegex.h
|
||||
/// "lldb/Breakpoint/BreakpointResolverFileRegex.h"
|
||||
/// @brief This class sets breakpoints by file and line. Optionally, it will
|
||||
/// look for inlined
|
||||
/// "lldb/Breakpoint/BreakpointResolverFileRegex.h" This class sets
|
||||
/// breakpoints by file and line. Optionally, it will look for inlined
|
||||
/// instances of the file and line specification.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
@ -24,10 +24,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointResolverName BreakpointResolverName.h
|
||||
/// "lldb/Breakpoint/BreakpointResolverName.h"
|
||||
/// @brief This class sets breakpoints on a given function name, either by exact
|
||||
/// match
|
||||
/// or by regular expression.
|
||||
/// "lldb/Breakpoint/BreakpointResolverName.h" This class sets breakpoints on
|
||||
/// a given function name, either by exact match or by regular expression.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointResolverName : public BreakpointResolver {
|
||||
@ -48,8 +46,8 @@ class BreakpointResolverName : public BreakpointResolver {
|
||||
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.
|
||||
// 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);
|
||||
|
@ -28,15 +28,15 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointSite BreakpointSite.h "lldb/Breakpoint/BreakpointSite.h"
|
||||
/// @brief Class that manages the actual breakpoint that will be inserted
|
||||
/// into the running program.
|
||||
/// Class that manages the actual breakpoint that will be inserted into the
|
||||
/// running program.
|
||||
///
|
||||
/// The BreakpointSite class handles the physical breakpoint that is
|
||||
/// actually inserted in the target program. As such, it is also the
|
||||
/// one that gets hit, when the program stops. It keeps a list of all
|
||||
/// BreakpointLocations that share this physical site. When the
|
||||
/// breakpoint is hit, all the locations are informed by the breakpoint
|
||||
/// site. Breakpoint sites are owned by the process.
|
||||
/// The BreakpointSite class handles the physical breakpoint that is actually
|
||||
/// inserted in the target program. As such, it is also the one that gets
|
||||
/// hit, when the program stops. It keeps a list of all BreakpointLocations
|
||||
/// that share this physical site. When the breakpoint is hit, all the
|
||||
/// locations are informed by the breakpoint site. Breakpoint sites are owned
|
||||
/// by the process.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
@ -101,10 +101,9 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
/// Tells whether the current breakpoint site is enabled or not
|
||||
///
|
||||
/// This is a low-level enable bit for the breakpoint sites. If a
|
||||
/// breakpoint site has no enabled owners, it should just get
|
||||
/// removed. This enable/disable is for the low-level target code
|
||||
/// to enable and disable breakpoint sites when single stepping,
|
||||
/// etc.
|
||||
/// breakpoint site has no enabled owners, it should just get removed. This
|
||||
/// enable/disable is for the low-level target code to enable and disable
|
||||
/// breakpoint sites when single stepping, etc.
|
||||
//------------------------------------------------------------------
|
||||
bool IsEnabled() const;
|
||||
|
||||
@ -118,8 +117,7 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Enquires of the breakpoint locations that produced this breakpoint site
|
||||
/// whether
|
||||
/// we should stop at this location.
|
||||
/// whether we should stop at this location.
|
||||
///
|
||||
/// @param[in] context
|
||||
/// This contains the information about this stop.
|
||||
@ -138,9 +136,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
void Dump(Stream *s) const override;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// The "Owners" are the breakpoint locations that share this
|
||||
/// breakpoint site. The method adds the \a owner to this breakpoint
|
||||
/// site's owner list.
|
||||
/// The "Owners" are the breakpoint locations that share this breakpoint
|
||||
/// site. The method adds the \a owner to this breakpoint site's owner list.
|
||||
///
|
||||
/// @param[in] context
|
||||
/// \a owner is the Breakpoint Location to add.
|
||||
@ -148,8 +145,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
void AddOwner(const lldb::BreakpointLocationSP &owner);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This method returns the number of breakpoint locations currently
|
||||
/// located at this breakpoint site.
|
||||
/// This method returns the number of breakpoint locations currently located
|
||||
/// at this breakpoint site.
|
||||
///
|
||||
/// @return
|
||||
/// The number of owners.
|
||||
@ -157,10 +154,10 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
size_t GetNumberOfOwners();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This method returns the breakpoint location at index \a index
|
||||
/// located at this breakpoint site. The owners are listed ordinally
|
||||
/// from 0 to GetNumberOfOwners() - 1 so you can use this method to iterate
|
||||
/// over the owners
|
||||
/// This method returns the breakpoint location at index \a index located at
|
||||
/// this breakpoint site. The owners are listed ordinally from 0 to
|
||||
/// GetNumberOfOwners() - 1 so you can use this method to iterate over the
|
||||
/// owners
|
||||
///
|
||||
/// @param[in] index
|
||||
/// The index in the list of owners for which you wish the owner location.
|
||||
@ -183,9 +180,9 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
size_t CopyOwnersList(BreakpointLocationCollection &out_collection);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check whether the owners of this breakpoint site have any
|
||||
/// thread specifiers, and if yes, is \a thread contained in any
|
||||
/// of these specifiers.
|
||||
/// Check whether the owners of this breakpoint site have any thread
|
||||
/// specifiers, and if yes, is \a thread contained in any of these
|
||||
/// specifiers.
|
||||
///
|
||||
/// @param[in] thread
|
||||
/// The thread against which to test.
|
||||
@ -198,9 +195,9 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Print a description of this breakpoint site to the stream \a s.
|
||||
/// GetDescription tells you about the breakpoint site's owners.
|
||||
/// Use BreakpointSite::Dump(Stream *) to get information about the
|
||||
/// breakpoint site itself.
|
||||
/// GetDescription tells you about the breakpoint site's owners. Use
|
||||
/// BreakpointSite::Dump(Stream *) to get information about the breakpoint
|
||||
/// site itself.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to print the description.
|
||||
@ -226,7 +223,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
bool IsBreakpointAtThisSite(lldb::break_id_t bp_id);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell whether ALL the breakpoints in the location collection are internal.
|
||||
/// Tell whether ALL the breakpoints in the location collection are
|
||||
/// internal.
|
||||
///
|
||||
/// @result
|
||||
/// \b true if all breakpoint locations are owned by internal breakpoints,
|
||||
@ -241,15 +239,16 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
private:
|
||||
friend class Process;
|
||||
friend class BreakpointLocation;
|
||||
// The StopInfoBreakpoint knows when it is processing a hit for a thread for a
|
||||
// site, so let it be the
|
||||
// one to manage setting the location hit count once and only once.
|
||||
// The StopInfoBreakpoint knows when it is processing a hit for a thread for
|
||||
// a site, so let it be the one to manage setting the location hit count once
|
||||
// and only once.
|
||||
friend class StopInfoBreakpoint;
|
||||
|
||||
void BumpHitCounts();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// The method removes the owner at \a break_loc_id from this breakpoint list.
|
||||
/// The method removes the owner at \a break_loc_id from this breakpoint
|
||||
/// list.
|
||||
///
|
||||
/// @param[in] context
|
||||
/// \a break_loc_id is the Breakpoint Location to remove.
|
||||
@ -264,8 +263,8 @@ class BreakpointSite : public std::enable_shared_from_this<BreakpointSite>,
|
||||
bool
|
||||
m_enabled; ///< Boolean indicating if this breakpoint site enabled or not.
|
||||
|
||||
// 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...
|
||||
// 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.
|
||||
std::recursive_mutex
|
||||
|
@ -24,8 +24,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class BreakpointSiteList BreakpointSiteList.h
|
||||
/// "lldb/Breakpoint/BreakpointSiteList.h"
|
||||
/// @brief Class that manages lists of BreakpointSite shared pointers.
|
||||
/// "lldb/Breakpoint/BreakpointSiteList.h" Class that manages lists of
|
||||
/// BreakpointSite shared pointers.
|
||||
//----------------------------------------------------------------------
|
||||
class BreakpointSiteList {
|
||||
// At present Process directly accesses the map of BreakpointSites so it can
|
||||
@ -56,15 +56,13 @@ class BreakpointSiteList {
|
||||
lldb::break_id_t Add(const lldb::BreakpointSiteSP &bp_site_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Standard Dump routine, doesn't do anything at present.
|
||||
/// @param[in] s
|
||||
/// Standard Dump routine, doesn't do anything at present. @param[in] s
|
||||
/// Stream into which to dump the description.
|
||||
//------------------------------------------------------------------
|
||||
void Dump(Stream *s) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint site at address
|
||||
/// \a addr.
|
||||
/// Returns a shared pointer to the breakpoint site at address \a addr.
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The address to look for.
|
||||
@ -89,8 +87,8 @@ class BreakpointSiteList {
|
||||
lldb::BreakpointSiteSP FindByID(lldb::break_id_t breakID);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the breakpoint site with id \a breakID - const
|
||||
/// version.
|
||||
/// Returns a shared pointer to the breakpoint site with id \a breakID -
|
||||
/// const version.
|
||||
///
|
||||
/// @param[in] breakID
|
||||
/// The breakpoint site ID to seek for.
|
||||
@ -103,7 +101,8 @@ class BreakpointSiteList {
|
||||
const lldb::BreakpointSiteSP FindByID(lldb::break_id_t breakID) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the breakpoint site id to the breakpoint site at address \a addr.
|
||||
/// Returns the breakpoint site id to the breakpoint site at address \a
|
||||
/// addr.
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The address to match.
|
||||
@ -161,8 +160,8 @@ class BreakpointSiteList {
|
||||
void *baton);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Enquires of the breakpoint site on in this list with ID \a breakID whether
|
||||
/// we should stop for the breakpoint or not.
|
||||
/// Enquires of the breakpoint site on in this list with ID \a breakID
|
||||
/// whether we should stop for the breakpoint or not.
|
||||
///
|
||||
/// @param[in] context
|
||||
/// This contains the information about this stop.
|
||||
|
@ -17,18 +17,15 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class StoppointCallbackContext StoppointCallbackContext.h
|
||||
/// "lldb/Breakpoint/StoppointCallbackContext.h"
|
||||
/// @brief Class holds the information that a breakpoint callback needs to
|
||||
/// evaluate this stop.
|
||||
/// "lldb/Breakpoint/StoppointCallbackContext.h" Class holds the information
|
||||
/// that a breakpoint callback needs to evaluate this stop.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// General Outline:
|
||||
/// When we hit a breakpoint we need to package up whatever information is
|
||||
/// needed
|
||||
/// to evaluate breakpoint commands and conditions. This class is the container
|
||||
/// of
|
||||
/// that information.
|
||||
/// needed to evaluate breakpoint commands and conditions. This class is the
|
||||
/// container of that information.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class StoppointCallbackContext {
|
||||
|
@ -77,8 +77,8 @@ class StoppointLocation {
|
||||
// breakpoint/watchpoint
|
||||
uint32_t m_byte_size; // The size in bytes of stop location. e.g. the length
|
||||
// of the trap opcode for
|
||||
// software breakpoints, or the optional length in bytes for
|
||||
// hardware breakpoints, or the length of the watchpoint.
|
||||
// software breakpoints, or the optional length in bytes for hardware
|
||||
// breakpoints, or the length of the watchpoint.
|
||||
uint32_t
|
||||
m_hit_count; // Number of times this breakpoint/watchpoint has been hit
|
||||
|
||||
|
@ -71,9 +71,9 @@ class Watchpoint : public std::enable_shared_from_this<Watchpoint>,
|
||||
|
||||
bool IsEnabled() const;
|
||||
|
||||
// This doesn't really enable/disable the watchpoint.
|
||||
// It is currently just for use in the Process plugin's
|
||||
// {Enable,Disable}Watchpoint, which should be used instead.
|
||||
// This doesn't really enable/disable the watchpoint. It is currently just
|
||||
// for use in the Process plugin's {Enable,Disable}Watchpoint, which should
|
||||
// be used instead.
|
||||
|
||||
void SetEnabled(bool enabled, bool notify = true);
|
||||
|
||||
@ -197,10 +197,8 @@ class Watchpoint : public std::enable_shared_from_this<Watchpoint>,
|
||||
uint32_t m_disabled_count; // Keep track of the count that the watchpoint is
|
||||
// disabled while in ephemeral mode.
|
||||
// At the end of the ephemeral mode when the watchpoint is to be enabled
|
||||
// again,
|
||||
// we check the count, if it is more than 1, it means the user-supplied
|
||||
// actions
|
||||
// actually want the watchpoint to be disabled!
|
||||
// again, we check the count, if it is more than 1, it means the user-
|
||||
// supplied actions actually want the watchpoint to be disabled!
|
||||
uint32_t m_watch_read : 1, // 1 if we stop when the watched data is read from
|
||||
m_watch_write : 1, // 1 if we stop when the watched data is written to
|
||||
m_watch_was_read : 1, // Set to 1 when watchpoint is hit for a read access
|
||||
|
@ -25,15 +25,15 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class WatchpointList WatchpointList.h "lldb/Breakpoint/WatchpointList.h"
|
||||
/// @brief This class is used by Watchpoint to manage a list of watchpoints,
|
||||
/// This class is used by Watchpoint to manage a list of watchpoints,
|
||||
// each watchpoint in the list has a unique ID, and is unique by Address as
|
||||
// well.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class WatchpointList {
|
||||
// Only Target can make the watchpoint list, or add elements to it.
|
||||
// This is not just some random collection of watchpoints. Rather, the act of
|
||||
// adding the watchpoint to this list sets its ID.
|
||||
// Only Target can make the watchpoint list, or add elements to it. This is
|
||||
// not just some random collection of watchpoints. Rather, the act of adding
|
||||
// the watchpoint to this list sets its ID.
|
||||
friend class Watchpoint;
|
||||
friend class Target;
|
||||
|
||||
@ -70,9 +70,8 @@ class WatchpointList {
|
||||
void DumpWithLevel(Stream *s, lldb::DescriptionLevel description_level) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the watchpoint at address
|
||||
/// \a addr -
|
||||
/// const version.
|
||||
/// Returns a shared pointer to the watchpoint at address \a addr - const
|
||||
/// version.
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The address to look for.
|
||||
@ -84,9 +83,8 @@ class WatchpointList {
|
||||
const lldb::WatchpointSP FindByAddress(lldb::addr_t addr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the watchpoint with watchpoint spec
|
||||
/// \a spec -
|
||||
/// const version.
|
||||
/// Returns a shared pointer to the watchpoint with watchpoint spec \a spec
|
||||
/// - const version.
|
||||
///
|
||||
/// @param[in] spec
|
||||
/// The watchpoint spec to look for.
|
||||
@ -98,8 +96,7 @@ class WatchpointList {
|
||||
const lldb::WatchpointSP FindBySpec(std::string spec) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a shared pointer to the watchpoint with id
|
||||
/// \a watchID, const
|
||||
/// Returns a shared pointer to the watchpoint with id \a watchID, const
|
||||
/// version.
|
||||
///
|
||||
/// @param[in] watchID
|
||||
@ -112,8 +109,7 @@ class WatchpointList {
|
||||
lldb::WatchpointSP FindByID(lldb::watch_id_t watchID) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the watchpoint id to the watchpoint
|
||||
/// at address \a addr.
|
||||
/// Returns the watchpoint id to the watchpoint at address \a addr.
|
||||
///
|
||||
/// @param[in] addr
|
||||
/// The address to match.
|
||||
@ -124,8 +120,8 @@ class WatchpointList {
|
||||
lldb::watch_id_t FindIDByAddress(lldb::addr_t addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the watchpoint id to the watchpoint
|
||||
/// with watchpoint spec \a spec.
|
||||
/// Returns the watchpoint id to the watchpoint with watchpoint spec \a
|
||||
/// spec.
|
||||
///
|
||||
/// @param[in] spec
|
||||
/// The watchpoint spec to match.
|
||||
|
@ -25,8 +25,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class WatchpointOptions WatchpointOptions.h
|
||||
/// "lldb/Breakpoint/WatchpointOptions.h"
|
||||
/// @brief Class that manages the options on a watchpoint.
|
||||
/// "lldb/Breakpoint/WatchpointOptions.h" Class that manages the options on a
|
||||
/// watchpoint.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class WatchpointOptions {
|
||||
@ -69,15 +69,13 @@ class WatchpointOptions {
|
||||
// Callbacks
|
||||
//
|
||||
// Watchpoint callbacks come in two forms, synchronous and asynchronous.
|
||||
// Synchronous callbacks will get
|
||||
// run before any of the thread plans are consulted, and if they return false
|
||||
// the target will continue
|
||||
// "under the radar" of the thread plans. There are a couple of restrictions
|
||||
// to synchronous callbacks:
|
||||
// 1) They should NOT resume the target themselves. Just return false if you
|
||||
// want the target to restart.
|
||||
// 2) Watchpoints with synchronous callbacks can't have conditions (or rather,
|
||||
// they can have them, but they
|
||||
// Synchronous callbacks will get run before any of the thread plans are
|
||||
// consulted, and if they return false the target will continue "under the
|
||||
// radar" of the thread plans. There are a couple of restrictions to
|
||||
// synchronous callbacks: 1) They should NOT resume the target themselves.
|
||||
// Just return false if you want the target to restart. 2) Watchpoints with
|
||||
// synchronous callbacks can't have conditions (or rather, they can have
|
||||
// them, but they
|
||||
// won't do anything. Ditto with ignore counts, etc... You are supposed
|
||||
// to control that all through the
|
||||
// callback.
|
||||
@ -118,8 +116,8 @@ class WatchpointOptions {
|
||||
//------------------------------------------------------------------
|
||||
void ClearCallback();
|
||||
|
||||
// The rest of these functions are meant to be used only within the watchpoint
|
||||
// handling mechanism.
|
||||
// The rest of these functions are meant to be used only within the
|
||||
// watchpoint handling mechanism.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Use this function to invoke the callback for a specific stop.
|
||||
@ -168,8 +166,7 @@ class WatchpointOptions {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the current thread spec for this option. This will return nullptr
|
||||
/// if the no thread
|
||||
/// specifications have been set for this Option yet.
|
||||
/// if the no thread specifications have been set for this Option yet.
|
||||
/// @return
|
||||
/// The thread specification pointer for this option, or nullptr if none
|
||||
/// has
|
||||
@ -178,8 +175,8 @@ class WatchpointOptions {
|
||||
const ThreadSpec *GetThreadSpecNoCreate() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns a pointer to the ThreadSpec for this option, creating it.
|
||||
/// if it hasn't been created already. This API is used for setting the
|
||||
/// Returns a pointer to the ThreadSpec for this option, creating it. if it
|
||||
/// hasn't been created already. This API is used for setting the
|
||||
/// ThreadSpec items for this option.
|
||||
//------------------------------------------------------------------
|
||||
ThreadSpec *GetThreadSpec();
|
||||
|
@ -11,8 +11,8 @@
|
||||
#define liblldb_Address_h_
|
||||
|
||||
#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS
|
||||
#include "lldb/lldb-enumerations.h" // for AddressClass::eAddressClassInvalid
|
||||
#include "lldb/lldb-forward.h" // for SectionWP, SectionSP, ModuleSP
|
||||
#include "lldb/lldb-private-enumerations.h" // for AddressClass
|
||||
#include "lldb/lldb-types.h" // for addr_t
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
@ -53,54 +53,50 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Address Address.h "lldb/Core/Address.h"
|
||||
/// @brief A section + offset based address class.
|
||||
/// A section + offset based address class.
|
||||
///
|
||||
/// The Address class allows addresses to be relative to a section
|
||||
/// that can move during runtime due to images (executables, shared
|
||||
/// libraries, bundles, frameworks) being loaded at different
|
||||
/// addresses than the addresses found in the object file that
|
||||
/// represents them on disk. There are currently two types of addresses
|
||||
/// for a section:
|
||||
/// The Address class allows addresses to be relative to a section that can
|
||||
/// move during runtime due to images (executables, shared libraries, bundles,
|
||||
/// frameworks) being loaded at different addresses than the addresses found
|
||||
/// in the object file that represents them on disk. There are currently two
|
||||
/// types of addresses for a section:
|
||||
/// @li file addresses
|
||||
/// @li load addresses
|
||||
///
|
||||
/// File addresses represent the virtual addresses that are in the "on
|
||||
/// disk" object files. These virtual addresses are converted to be
|
||||
/// relative to unique sections scoped to the object file so that
|
||||
/// when/if the addresses slide when the images are loaded/unloaded
|
||||
/// in memory, we can easily track these changes without having to
|
||||
/// update every object (compile unit ranges, line tables, function
|
||||
/// address ranges, lexical block and inlined subroutine address
|
||||
/// ranges, global and static variables) each time an image is loaded or
|
||||
/// unloaded.
|
||||
/// File addresses represent the virtual addresses that are in the "on disk"
|
||||
/// object files. These virtual addresses are converted to be relative to
|
||||
/// unique sections scoped to the object file so that when/if the addresses
|
||||
/// slide when the images are loaded/unloaded in memory, we can easily track
|
||||
/// these changes without having to update every object (compile unit ranges,
|
||||
/// line tables, function address ranges, lexical block and inlined subroutine
|
||||
/// address ranges, global and static variables) each time an image is loaded
|
||||
/// or unloaded.
|
||||
///
|
||||
/// Load addresses represent the virtual addresses where each section
|
||||
/// ends up getting loaded at runtime. Before executing a program, it
|
||||
/// is common for all of the load addresses to be unresolved. When a
|
||||
/// DynamicLoader plug-in receives notification that shared libraries
|
||||
/// have been loaded/unloaded, the load addresses of the main executable
|
||||
/// and any images (shared libraries) will be resolved/unresolved. When
|
||||
/// this happens, breakpoints that are in one of these sections can be
|
||||
/// set/cleared.
|
||||
/// Load addresses represent the virtual addresses where each section ends up
|
||||
/// getting loaded at runtime. Before executing a program, it is common for
|
||||
/// all of the load addresses to be unresolved. When a DynamicLoader plug-in
|
||||
/// receives notification that shared libraries have been loaded/unloaded, the
|
||||
/// load addresses of the main executable and any images (shared libraries)
|
||||
/// will be resolved/unresolved. When this happens, breakpoints that are in
|
||||
/// one of these sections can be set/cleared.
|
||||
//----------------------------------------------------------------------
|
||||
class Address {
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
/// Dump styles allow the Address::Dump(Stream *,DumpStyle) const
|
||||
/// function to display Address contents in a variety of ways.
|
||||
/// Dump styles allow the Address::Dump(Stream *,DumpStyle) const function
|
||||
/// to display Address contents in a variety of ways.
|
||||
//------------------------------------------------------------------
|
||||
typedef enum {
|
||||
DumpStyleInvalid, ///< Invalid dump style
|
||||
DumpStyleSectionNameOffset, ///< Display as the section name + offset.
|
||||
///< \code
|
||||
/// // address for printf in libSystem.B.dylib as a section name + offset
|
||||
/// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf
|
||||
/// \endcode
|
||||
/// libSystem.B.dylib.__TEXT.__text + 0x0005cfdf \endcode
|
||||
DumpStyleSectionPointerOffset, ///< Display as the section pointer + offset
|
||||
///(debug output).
|
||||
///< \code
|
||||
/// // address for printf in libSystem.B.dylib as a section pointer + offset
|
||||
/// (lldb::Section *)0x35cc50 + 0x000000000005cfdf \endcode
|
||||
/// // address for printf in libSystem.B.dylib as a section pointer +
|
||||
/// offset (lldb::Section *)0x35cc50 + 0x000000000005cfdf \endcode
|
||||
DumpStyleFileAddress, ///< Display as the file address (if any).
|
||||
///< \code
|
||||
/// // address for printf in libSystem.B.dylib as a file address
|
||||
@ -135,8 +131,8 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Default constructor.
|
||||
///
|
||||
/// Initialize with a invalid section (NULL) and an invalid
|
||||
/// offset (LLDB_INVALID_ADDRESS).
|
||||
/// Initialize with a invalid section (NULL) and an invalid offset
|
||||
/// (LLDB_INVALID_ADDRESS).
|
||||
//------------------------------------------------------------------
|
||||
Address() : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {}
|
||||
|
||||
@ -154,8 +150,7 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with a section pointer and offset.
|
||||
///
|
||||
/// Initialize the address with the supplied \a section and \a
|
||||
/// offset.
|
||||
/// Initialize the address with the supplied \a section and \a offset.
|
||||
///
|
||||
/// @param[in] section
|
||||
/// A section pointer to a valid lldb::Section, or NULL if the
|
||||
@ -175,8 +170,8 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with a virtual address and section list.
|
||||
///
|
||||
/// Initialize and resolve the address with the supplied virtual
|
||||
/// address \a file_addr.
|
||||
/// Initialize and resolve the address with the supplied virtual address \a
|
||||
/// file_addr.
|
||||
///
|
||||
/// @param[in] file_addr
|
||||
/// A virtual file address.
|
||||
@ -191,8 +186,8 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Assignment operator.
|
||||
///
|
||||
/// Copies the address value from another Address object \a rhs
|
||||
/// into \a this object.
|
||||
/// Copies the address value from another Address object \a rhs into \a this
|
||||
/// object.
|
||||
///
|
||||
/// @param[in] rhs
|
||||
/// A const Address object reference to copy.
|
||||
@ -207,8 +202,8 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Clear the object's state.
|
||||
///
|
||||
/// Sets the section to an invalid value (NULL) and an invalid
|
||||
/// offset (LLDB_INVALID_ADDRESS).
|
||||
/// Sets the section to an invalid value (NULL) and an invalid offset
|
||||
/// (LLDB_INVALID_ADDRESS).
|
||||
//------------------------------------------------------------------
|
||||
void Clear() {
|
||||
m_section_wp.reset();
|
||||
@ -250,9 +245,9 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Dump a description of this object to a Stream.
|
||||
///
|
||||
/// Dump a description of the contents of this object to the
|
||||
/// supplied stream \a s. There are many ways to display a section
|
||||
/// offset based address, and \a style lets the user choose.
|
||||
/// Dump a description of the contents of this object to the supplied stream
|
||||
/// \a s. There are many ways to display a section offset based address, and
|
||||
/// \a style lets the user choose.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to dump the object description.
|
||||
@ -275,14 +270,14 @@ class Address {
|
||||
DumpStyle fallback_style = DumpStyleInvalid,
|
||||
uint32_t addr_byte_size = UINT32_MAX) const;
|
||||
|
||||
lldb::AddressClass GetAddressClass() const;
|
||||
AddressClass GetAddressClass() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the file address.
|
||||
///
|
||||
/// If an address comes from a file on disk that has section
|
||||
/// relative addresses, then it has a virtual address that is
|
||||
/// relative to unique section in the object file.
|
||||
/// If an address comes from a file on disk that has section relative
|
||||
/// addresses, then it has a virtual address that is relative to unique
|
||||
/// section in the object file.
|
||||
///
|
||||
/// @return
|
||||
/// The valid file virtual address, or LLDB_INVALID_ADDRESS if
|
||||
@ -294,12 +289,12 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Get the load address.
|
||||
///
|
||||
/// If an address comes from a file on disk that has section
|
||||
/// relative addresses, then it has a virtual address that is
|
||||
/// relative to unique section in the object file. Sections get
|
||||
/// resolved at runtime by DynamicLoader plug-ins as images
|
||||
/// (executables and shared libraries) get loaded/unloaded. If a
|
||||
/// section is loaded, then the load address can be resolved.
|
||||
/// If an address comes from a file on disk that has section relative
|
||||
/// addresses, then it has a virtual address that is relative to unique
|
||||
/// section in the object file. Sections get resolved at runtime by
|
||||
/// DynamicLoader plug-ins as images (executables and shared libraries) get
|
||||
/// loaded/unloaded. If a section is loaded, then the load address can be
|
||||
/// resolved.
|
||||
///
|
||||
/// @return
|
||||
/// The valid load virtual address, or LLDB_INVALID_ADDRESS if
|
||||
@ -310,12 +305,12 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Get the load address as a callable code load address.
|
||||
///
|
||||
/// This function will first resolve its address to a load address.
|
||||
/// Then, if the address turns out to be in code address, return the
|
||||
/// load address that would be required to call or return to. The
|
||||
/// address might have extra bits set (bit zero will be set to Thumb
|
||||
/// functions for an ARM target) that are required when changing the
|
||||
/// program counter to setting a return address.
|
||||
/// This function will first resolve its address to a load address. Then, if
|
||||
/// the address turns out to be in code address, return the load address
|
||||
/// that would be required to call or return to. The address might have
|
||||
/// extra bits set (bit zero will be set to Thumb functions for an ARM
|
||||
/// target) that are required when changing the program counter to setting a
|
||||
/// return address.
|
||||
///
|
||||
/// @return
|
||||
/// The valid load virtual address, or LLDB_INVALID_ADDRESS if
|
||||
@ -327,14 +322,14 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Get the load address as an opcode load address.
|
||||
///
|
||||
/// This function will first resolve its address to a load address.
|
||||
/// Then, if the address turns out to be in code address, return the
|
||||
/// load address for an opcode. This address object might have
|
||||
/// extra bits set (bit zero will be set to Thumb functions for an
|
||||
/// This function will first resolve its address to a load address. Then, if
|
||||
/// the address turns out to be in code address, return the load address for
|
||||
/// an opcode. This address object might have extra bits set (bit zero will
|
||||
/// be set to Thumb functions for an
|
||||
/// ARM target) that are required for changing the program counter
|
||||
/// and this function will remove any bits that are intended for
|
||||
/// these special purposes. The result of this function can be used
|
||||
/// to safely write a software breakpoint trap to memory.
|
||||
/// and this function will remove any bits that are intended for these
|
||||
/// special purposes. The result of this function can be used to safely
|
||||
/// write a software breakpoint trap to memory.
|
||||
///
|
||||
/// @return
|
||||
/// The valid load virtual address with extra callable bits
|
||||
@ -343,7 +338,7 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
lldb::addr_t GetOpcodeLoadAddress(
|
||||
Target *target,
|
||||
lldb::AddressClass addr_class = lldb::eAddressClassInvalid) const;
|
||||
AddressClass addr_class = AddressClass::eInvalid) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the section relative offset value.
|
||||
@ -357,11 +352,11 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Check if an address is section offset.
|
||||
///
|
||||
/// When converting a virtual file or load address into a section
|
||||
/// offset based address, we often need to know if, given a section
|
||||
/// list, if the address was able to be converted to section offset.
|
||||
/// This function returns true if the current value contained in
|
||||
/// this object is section offset based.
|
||||
/// When converting a virtual file or load address into a section offset
|
||||
/// based address, we often need to know if, given a section list, if the
|
||||
/// address was able to be converted to section offset. This function
|
||||
/// returns true if the current value contained in this object is section
|
||||
/// offset based.
|
||||
///
|
||||
/// @return
|
||||
/// Returns \b true if the address has a valid section and
|
||||
@ -375,8 +370,8 @@ class Address {
|
||||
/// Check if the object state is valid.
|
||||
///
|
||||
/// A valid Address object contains either a section pointer and
|
||||
/// and offset (for section offset based addresses), or just a valid
|
||||
/// offset (for absolute addresses that have no section).
|
||||
/// offset (for section offset based addresses), or just a valid offset
|
||||
/// (for absolute addresses that have no section).
|
||||
///
|
||||
/// @return
|
||||
/// Returns \b true if the offset is valid, \b false
|
||||
@ -395,8 +390,8 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve a file virtual address using a section list.
|
||||
///
|
||||
/// Given a list of sections, attempt to resolve \a addr as a
|
||||
/// an offset into one of the file sections.
|
||||
/// Given a list of sections, attempt to resolve \a addr as an offset into
|
||||
/// one of the file sections.
|
||||
///
|
||||
/// @return
|
||||
/// Returns \b true if \a addr was able to be resolved, \b false
|
||||
@ -408,11 +403,10 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Set the address to represent \a load_addr.
|
||||
///
|
||||
/// The address will attempt to find a loaded section within
|
||||
/// \a target that contains \a load_addr. If successful, this
|
||||
/// address object will have a valid section and offset. Else this
|
||||
/// address object will have no section (NULL) and the offset will
|
||||
/// be \a load_addr.
|
||||
/// The address will attempt to find a loaded section within \a target that
|
||||
/// contains \a load_addr. If successful, this address object will have a
|
||||
/// valid section and offset. Else this address object will have no section
|
||||
/// (NULL) and the offset will be \a load_addr.
|
||||
///
|
||||
/// @param[in] load_addr
|
||||
/// A load address from a current process.
|
||||
@ -438,7 +432,7 @@ class Address {
|
||||
|
||||
bool SetOpcodeLoadAddress(
|
||||
lldb::addr_t load_addr, Target *target,
|
||||
lldb::AddressClass addr_class = lldb::eAddressClassInvalid,
|
||||
AddressClass addr_class = AddressClass::eInvalid,
|
||||
bool allow_section_end = false);
|
||||
|
||||
bool SetCallableLoadAddress(lldb::addr_t load_addr, Target *target);
|
||||
@ -507,10 +501,10 @@ class Address {
|
||||
//------------------------------------------------------------------
|
||||
/// Reconstruct a symbol context from an address.
|
||||
///
|
||||
/// This class doesn't inherit from SymbolContextScope because many
|
||||
/// address objects have short lifespans. Address objects that are
|
||||
/// section offset can reconstruct their symbol context by looking
|
||||
/// up the address in the module found in the section.
|
||||
/// This class doesn't inherit from SymbolContextScope because many address
|
||||
/// objects have short lifespans. Address objects that are section offset
|
||||
/// can reconstruct their symbol context by looking up the address in the
|
||||
/// module found in the section.
|
||||
///
|
||||
/// @see SymbolContextScope::CalculateSymbolContext(SymbolContext*)
|
||||
//------------------------------------------------------------------
|
||||
@ -531,11 +525,11 @@ class Address {
|
||||
bool CalculateSymbolContextLineEntry(LineEntry &line_entry) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Returns true if the section should be valid, but isn't because
|
||||
// the shared pointer to the section can't be reconstructed from
|
||||
// a weak pointer that contains a valid weak reference to a section.
|
||||
// Returns false if the section weak pointer has no reference to
|
||||
// a section, or if the section is still valid
|
||||
// Returns true if the section should be valid, but isn't because the shared
|
||||
// pointer to the section can't be reconstructed from a weak pointer that
|
||||
// contains a valid weak reference to a section. Returns false if the section
|
||||
// weak pointer has no reference to a section, or if the section is still
|
||||
// valid
|
||||
//------------------------------------------------------------------
|
||||
bool SectionWasDeleted() const;
|
||||
|
||||
@ -547,29 +541,27 @@ class Address {
|
||||
lldb::addr_t m_offset; ///< Offset into section if \a m_section_wp is valid...
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Returns true if the m_section_wp once had a reference to a valid
|
||||
// section shared pointer, but no longer does. This can happen if
|
||||
// we have an address from a module that gets unloaded and deleted.
|
||||
// This function should only be called if GetSection() returns an
|
||||
// empty shared pointer and you want to know if this address used to
|
||||
// have a valid section.
|
||||
// Returns true if the m_section_wp once had a reference to a valid section
|
||||
// shared pointer, but no longer does. This can happen if we have an address
|
||||
// from a module that gets unloaded and deleted. This function should only be
|
||||
// called if GetSection() returns an empty shared pointer and you want to
|
||||
// know if this address used to have a valid section.
|
||||
//------------------------------------------------------------------
|
||||
bool SectionWasDeletedPrivate() const;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// NOTE: Be careful using this operator. It can correctly compare two
|
||||
// addresses from the same Module correctly. It can't compare two
|
||||
// addresses from different modules in any meaningful way, but it will
|
||||
// compare the module pointers.
|
||||
// addresses from the same Module correctly. It can't compare two addresses
|
||||
// from different modules in any meaningful way, but it will compare the module
|
||||
// pointers.
|
||||
//
|
||||
// To sum things up:
|
||||
// - works great for addresses within the same module
|
||||
// - it works for addresses across multiple modules, but don't expect the
|
||||
// - works great for addresses within the same module - it works for addresses
|
||||
// across multiple modules, but don't expect the
|
||||
// address results to make much sense
|
||||
//
|
||||
// This basically lets Address objects be used in ordered collection
|
||||
// classes.
|
||||
// This basically lets Address objects be used in ordered collection classes.
|
||||
//----------------------------------------------------------------------
|
||||
bool operator<(const Address &lhs, const Address &rhs);
|
||||
bool operator>(const Address &lhs, const Address &rhs);
|
||||
|
@ -30,23 +30,23 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class AddressRange AddressRange.h "lldb/Core/AddressRange.h"
|
||||
/// @brief A section + offset based address range class.
|
||||
/// A section + offset based address range class.
|
||||
//----------------------------------------------------------------------
|
||||
class AddressRange {
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
/// Default constructor.
|
||||
///
|
||||
/// Initialize with a invalid section (NULL), an invalid
|
||||
/// offset (LLDB_INVALID_ADDRESS), and zero byte size.
|
||||
/// Initialize with a invalid section (NULL), an invalid offset
|
||||
/// (LLDB_INVALID_ADDRESS), and zero byte size.
|
||||
//------------------------------------------------------------------
|
||||
AddressRange();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with a section pointer, offset, and byte_size.
|
||||
///
|
||||
/// Initialize the address with the supplied \a section, \a
|
||||
/// offset and \a byte_size.
|
||||
/// Initialize the address with the supplied \a section, \a offset and \a
|
||||
/// byte_size.
|
||||
///
|
||||
/// @param[in] section
|
||||
/// A section pointer to a valid lldb::Section, or NULL if the
|
||||
@ -64,8 +64,8 @@ class AddressRange {
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with a virtual address, section list and byte size.
|
||||
///
|
||||
/// Initialize and resolve the address with the supplied virtual
|
||||
/// address \a file_addr, and byte size \a byte_size.
|
||||
/// Initialize and resolve the address with the supplied virtual address \a
|
||||
/// file_addr, and byte size \a byte_size.
|
||||
///
|
||||
/// @param[in] file_addr
|
||||
/// A virtual address.
|
||||
@ -82,8 +82,8 @@ class AddressRange {
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with a Address object address and byte size.
|
||||
///
|
||||
/// Initialize by copying the section offset address in \a so_addr,
|
||||
/// and setting the byte size to \a byte_size.
|
||||
/// Initialize by copying the section offset address in \a so_addr, and
|
||||
/// setting the byte size to \a byte_size.
|
||||
///
|
||||
/// @param[in] so_addr
|
||||
/// A section offset address object.
|
||||
@ -135,8 +135,8 @@ class AddressRange {
|
||||
// Contains (const Address *so_addr_ptr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if a section offset \a so_addr when represented as a file
|
||||
/// address is contained within this object's file address range.
|
||||
/// Check if a section offset \a so_addr when represented as a file address
|
||||
/// is contained within this object's file address range.
|
||||
///
|
||||
/// @param[in] so_addr
|
||||
/// A section offset address object reference.
|
||||
@ -149,8 +149,8 @@ class AddressRange {
|
||||
bool ContainsFileAddress(const Address &so_addr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if the resolved file address \a file_addr is contained
|
||||
/// within this object's file address range.
|
||||
/// Check if the resolved file address \a file_addr is contained within this
|
||||
/// object's file address range.
|
||||
///
|
||||
/// @param[in] so_addr
|
||||
/// A section offset address object reference.
|
||||
@ -163,8 +163,8 @@ class AddressRange {
|
||||
bool ContainsFileAddress(lldb::addr_t file_addr) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if a section offset \a so_addr when represented as a load
|
||||
/// address is contained within this object's load address range.
|
||||
/// Check if a section offset \a so_addr when represented as a load address
|
||||
/// is contained within this object's load address range.
|
||||
///
|
||||
/// @param[in] so_addr
|
||||
/// A section offset address object reference.
|
||||
@ -177,8 +177,8 @@ class AddressRange {
|
||||
bool ContainsLoadAddress(const Address &so_addr, Target *target) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Check if the resolved load address \a load_addr is contained
|
||||
/// within this object's load address range.
|
||||
/// Check if the resolved load address \a load_addr is contained within this
|
||||
/// object's load address range.
|
||||
///
|
||||
/// @param[in] so_addr
|
||||
/// A section offset address object reference.
|
||||
@ -193,10 +193,10 @@ class AddressRange {
|
||||
//------------------------------------------------------------------
|
||||
/// Dump a description of this object to a Stream.
|
||||
///
|
||||
/// Dump a description of the contents of this object to the
|
||||
/// supplied stream \a s. There are many ways to display a section
|
||||
/// offset based address range, and \a style lets the user choose
|
||||
/// how the base address gets displayed.
|
||||
/// Dump a description of the contents of this object to the supplied stream
|
||||
/// \a s. There are many ways to display a section offset based address
|
||||
/// range, and \a style lets the user choose how the base address gets
|
||||
/// displayed.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to dump the object description.
|
||||
@ -219,11 +219,11 @@ class AddressRange {
|
||||
//------------------------------------------------------------------
|
||||
/// Dump a debug description of this object to a Stream.
|
||||
///
|
||||
/// Dump a debug description of the contents of this object to the
|
||||
/// supplied stream \a s.
|
||||
/// Dump a debug description of the contents of this object to the supplied
|
||||
/// stream \a s.
|
||||
///
|
||||
/// The debug description contains verbose internal state such
|
||||
/// and pointer values, reference counts, etc.
|
||||
/// The debug description contains verbose internal state such and pointer
|
||||
/// values, reference counts, etc.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to dump the object description.
|
||||
@ -261,8 +261,8 @@ class AddressRange {
|
||||
/// The number of bytes that this object occupies in memory.
|
||||
//------------------------------------------------------------------
|
||||
size_t MemorySize() const {
|
||||
// Noting special for the memory size of a single AddressRange object,
|
||||
// it is just the size of itself.
|
||||
// Noting special for the memory size of a single AddressRange object, it
|
||||
// is just the size of itself.
|
||||
return sizeof(AddressRange);
|
||||
}
|
||||
|
||||
|
@ -27,18 +27,16 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class AddressResolver AddressResolver.h "lldb/Core/AddressResolver.h"
|
||||
/// @brief This class works with SearchFilter to resolve function names and
|
||||
/// source file locations to their concrete addresses.
|
||||
/// This class works with SearchFilter to resolve function names and source
|
||||
/// file locations to their concrete addresses.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// General Outline:
|
||||
/// The AddressResolver is a Searcher. In that protocol,
|
||||
/// the SearchFilter asks the question "At what depth of the symbol context
|
||||
/// descent do you want your callback to get called?" of the filter. The
|
||||
/// resolver
|
||||
/// answers this question (in the GetDepth method) and provides the resolution
|
||||
/// callback.
|
||||
/// The AddressResolver is a Searcher. In that protocol, the SearchFilter
|
||||
/// asks the question "At what depth of the symbol context descent do you want
|
||||
/// your callback to get called?" of the filter. The resolver answers this
|
||||
/// question (in the GetDepth method) and provides the resolution callback.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class AddressResolver : public Searcher {
|
||||
|
@ -31,10 +31,9 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class AddressResolverFileLine AddressResolverFileLine.h
|
||||
/// "lldb/Core/AddressResolverFileLine.h"
|
||||
/// @brief This class finds address for source file and line. Optionally, it
|
||||
/// will look for inlined
|
||||
/// instances of the file and line specification.
|
||||
/// "lldb/Core/AddressResolverFileLine.h" This class finds address for source
|
||||
/// file and line. Optionally, it will look for inlined instances of the file
|
||||
/// and line specification.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class AddressResolverFileLine : public AddressResolver {
|
||||
|
@ -30,10 +30,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class AddressResolverName AddressResolverName.h
|
||||
/// "lldb/Core/AddressResolverName.h"
|
||||
/// @brief This class finds addresses for a given function name, either by exact
|
||||
/// match
|
||||
/// or by regular expression.
|
||||
/// "lldb/Core/AddressResolverName.h" This class finds addresses for a given
|
||||
/// function name, either by exact match or by regular expression.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class AddressResolverName : public AddressResolver {
|
||||
@ -41,8 +39,8 @@ class AddressResolverName : public AddressResolver {
|
||||
AddressResolverName(const char *func_name,
|
||||
AddressResolver::MatchType type = Exact);
|
||||
|
||||
// Creates a function breakpoint by regular expression. Takes over control of
|
||||
// the lifespan of func_regex.
|
||||
// Creates a function breakpoint by regular expression. Takes over control
|
||||
// of the lifespan of func_regex.
|
||||
AddressResolverName(RegularExpression &func_regex);
|
||||
|
||||
AddressResolverName(const char *class_name, const char *method,
|
||||
|
@ -31,7 +31,41 @@ class Architecture : public PluginInterface {
|
||||
/// stopped at the current PC. The code is generic and applies to all
|
||||
/// ARM CPUs.
|
||||
//------------------------------------------------------------------
|
||||
virtual void OverrideStopInfo(Thread &thread) = 0;
|
||||
virtual void OverrideStopInfo(Thread &thread) const = 0;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This method is used to get the number of bytes that should be
|
||||
/// skipped, from function start address, to reach the first
|
||||
/// instruction after the prologue. If overrode, it must return
|
||||
/// non-zero only if the current address matches one of the known
|
||||
/// function entry points.
|
||||
///
|
||||
/// This method is called only if the standard platform-independent
|
||||
/// code fails to get the number of bytes to skip, giving the plugin
|
||||
/// a chance to try to find the missing info.
|
||||
///
|
||||
/// This is specifically used for PPC64, where functions may have
|
||||
/// more than one entry point, global and local, so both should
|
||||
/// be compared with current address, in order to find out the
|
||||
/// number of bytes that should be skipped, in case we are stopped
|
||||
/// at either function entry point.
|
||||
//------------------------------------------------------------------
|
||||
virtual size_t GetBytesToSkip(Symbol &func, const Address &curr_addr) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Adjust function breakpoint address, if needed. In some cases,
|
||||
/// the function start address is not the right place to set the
|
||||
/// breakpoint, specially in functions with multiple entry points.
|
||||
///
|
||||
/// This is specifically used for PPC64, for functions that have
|
||||
/// both a global and a local entry point. In this case, the
|
||||
/// breakpoint is adjusted to the first function address reached
|
||||
/// by both entry points.
|
||||
//------------------------------------------------------------------
|
||||
virtual void AdjustBreakpointAddress(const Symbol &func,
|
||||
Address &addr) const {}
|
||||
|
||||
private:
|
||||
Architecture(const Architecture &) = delete;
|
||||
|
@ -59,10 +59,9 @@ class BroadcastEventSpec {
|
||||
|
||||
uint32_t GetEventBits() const { return m_event_bits; }
|
||||
|
||||
// Tell whether this BroadcastEventSpec is contained in in_spec.
|
||||
// That is:
|
||||
// (a) the two spec's share the same broadcaster class
|
||||
// (b) the event bits of this spec are wholly contained in those of in_spec.
|
||||
// Tell whether this BroadcastEventSpec is contained in in_spec. That is: (a)
|
||||
// the two spec's share the same broadcaster class (b) the event bits of this
|
||||
// spec are wholly contained in those of in_spec.
|
||||
bool IsContainedIn(BroadcastEventSpec in_spec) const {
|
||||
if (m_broadcaster_class != in_spec.GetBroadcasterClass())
|
||||
return false;
|
||||
@ -224,21 +223,21 @@ class BroadcasterManager
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h"
|
||||
/// @brief An event broadcasting class.
|
||||
/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h" An event
|
||||
/// broadcasting class.
|
||||
///
|
||||
/// The Broadcaster class is designed to be subclassed by objects that
|
||||
/// wish to vend events in a multi-threaded environment. Broadcaster
|
||||
/// objects can each vend 32 events. Each event is represented by a bit
|
||||
/// in a 32 bit value and these bits can be set:
|
||||
/// The Broadcaster class is designed to be subclassed by objects that wish to
|
||||
/// vend events in a multi-threaded environment. Broadcaster objects can each
|
||||
/// vend 32 events. Each event is represented by a bit in a 32 bit value and
|
||||
/// these bits can be set:
|
||||
/// @see Broadcaster::SetEventBits(uint32_t)
|
||||
/// or cleared:
|
||||
/// @see Broadcaster::ResetEventBits(uint32_t)
|
||||
/// When an event gets set the Broadcaster object will notify the
|
||||
/// Listener object that is listening for the event (if there is one).
|
||||
/// When an event gets set the Broadcaster object will notify the Listener
|
||||
/// object that is listening for the event (if there is one).
|
||||
///
|
||||
/// Subclasses should provide broadcast bit definitions for any events
|
||||
/// they vend, typically using an enumeration:
|
||||
/// Subclasses should provide broadcast bit definitions for any events they
|
||||
/// vend, typically using an enumeration:
|
||||
/// \code
|
||||
/// class Foo : public Broadcaster
|
||||
/// {
|
||||
@ -324,12 +323,11 @@ class Broadcaster {
|
||||
//------------------------------------------------------------------
|
||||
/// Listen for any events specified by \a event_mask.
|
||||
///
|
||||
/// Only one listener can listen to each event bit in a given
|
||||
/// Broadcaster. Once a listener has acquired an event bit, no
|
||||
/// other broadcaster will have access to it until it is
|
||||
/// relinquished by the first listener that gets it. The actual
|
||||
/// event bits that get acquired by \a listener may be different
|
||||
/// from what is requested in \a event_mask, and to track this the
|
||||
/// Only one listener can listen to each event bit in a given Broadcaster.
|
||||
/// Once a listener has acquired an event bit, no other broadcaster will
|
||||
/// have access to it until it is relinquished by the first listener that
|
||||
/// gets it. The actual event bits that get acquired by \a listener may be
|
||||
/// different from what is requested in \a event_mask, and to track this the
|
||||
/// actual event bits that are acquired get returned.
|
||||
///
|
||||
/// @param[in] listener
|
||||
@ -349,8 +347,7 @@ class Broadcaster {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the NULL terminated C string name of this Broadcaster
|
||||
/// object.
|
||||
/// Get the NULL terminated C string name of this Broadcaster object.
|
||||
///
|
||||
/// @return
|
||||
/// The NULL terminated C string name of this Broadcaster.
|
||||
@ -395,10 +392,10 @@ class Broadcaster {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Removes a Listener from this broadcasters list and frees the
|
||||
/// event bits specified by \a event_mask that were previously
|
||||
/// acquired by \a listener (assuming \a listener was listening to
|
||||
/// this object) for other listener objects to use.
|
||||
/// Removes a Listener from this broadcasters list and frees the event bits
|
||||
/// specified by \a event_mask that were previously acquired by \a listener
|
||||
/// (assuming \a listener was listening to this object) for other listener
|
||||
/// objects to use.
|
||||
///
|
||||
/// @param[in] listener
|
||||
/// A Listener object that previously called AddListener.
|
||||
@ -420,10 +417,9 @@ class Broadcaster {
|
||||
//------------------------------------------------------------------
|
||||
/// Provides a simple mechanism to temporarily redirect events from
|
||||
/// broadcaster. When you call this function passing in a listener and
|
||||
/// event type mask, all events from the broadcaster matching the mask
|
||||
/// will now go to the hijacking listener.
|
||||
/// Only one hijack can occur at a time. If we need more than this we
|
||||
/// will have to implement a Listener stack.
|
||||
/// event type mask, all events from the broadcaster matching the mask will
|
||||
/// now go to the hijacking listener. Only one hijack can occur at a time.
|
||||
/// If we need more than this we will have to implement a Listener stack.
|
||||
///
|
||||
/// @param[in] listener
|
||||
/// A Listener object. You do not need to call StartListeningForEvents
|
||||
@ -454,8 +450,7 @@ class Broadcaster {
|
||||
void 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.
|
||||
// with the broadcaster manager and do broadcaster class matching.
|
||||
// FIXME: Probably should make a ManagedBroadcaster subclass with all the bits
|
||||
// needed to work
|
||||
// with the BroadcasterManager, so that it is clearer how to add one.
|
||||
@ -465,21 +460,17 @@ class Broadcaster {
|
||||
|
||||
protected:
|
||||
// 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.
|
||||
// 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.
|
||||
// BroadcasterImpl, and are documented in the public Broadcaster API above.
|
||||
|
||||
class BroadcasterImpl {
|
||||
friend class Listener;
|
||||
@ -557,7 +548,7 @@ class Broadcaster {
|
||||
llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
|
||||
GetListeners();
|
||||
|
||||
Broadcaster &m_broadcaster; ///< The broadcsater that this implements
|
||||
Broadcaster &m_broadcaster; ///< The broadcaster 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
|
||||
|
@ -39,60 +39,57 @@ class Status;
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Communication Communication.h "lldb/Core/Communication.h"
|
||||
/// @brief An abstract communications class.
|
||||
/// @class Communication Communication.h "lldb/Core/Communication.h" An
|
||||
/// abstract communications class.
|
||||
///
|
||||
/// Communication is an class that handles data communication
|
||||
/// between two data sources. It uses a Connection class to do the
|
||||
/// real communication. This approach has a couple of advantages: it
|
||||
/// allows a single instance of this class to be used even though its
|
||||
/// connection can change. Connections could negotiate for different
|
||||
/// connections based on abilities like starting with Bluetooth and
|
||||
/// negotiating up to WiFi if available. It also allows this class to be
|
||||
/// subclassed by any interfaces that don't want to give bytes but want
|
||||
/// to validate and give out packets. This can be done by overriding:
|
||||
/// Communication is an class that handles data communication between two data
|
||||
/// sources. It uses a Connection class to do the real communication. This
|
||||
/// approach has a couple of advantages: it allows a single instance of this
|
||||
/// class to be used even though its connection can change. Connections could
|
||||
/// negotiate for different connections based on abilities like starting with
|
||||
/// Bluetooth and negotiating up to WiFi if available. It also allows this
|
||||
/// class to be subclassed by any interfaces that don't want to give bytes but
|
||||
/// want to validate and give out packets. This can be done by overriding:
|
||||
///
|
||||
/// AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast);
|
||||
///
|
||||
/// Communication inherits from Broadcaster which means it can be
|
||||
/// used in conjunction with Listener to wait for multiple broadcaster
|
||||
/// objects and multiple events from each of those objects.
|
||||
/// Communication defines a set of pre-defined event bits (see
|
||||
/// enumerations definitions that start with "eBroadcastBit" below).
|
||||
/// Communication inherits from Broadcaster which means it can be used in
|
||||
/// conjunction with Listener to wait for multiple broadcaster objects and
|
||||
/// multiple events from each of those objects. Communication defines a set of
|
||||
/// pre-defined event bits (see enumerations definitions that start with
|
||||
/// "eBroadcastBit" below).
|
||||
///
|
||||
/// There are two modes in which communications can occur:
|
||||
/// @li single-threaded
|
||||
/// @li multi-threaded
|
||||
///
|
||||
/// In single-threaded mode, all reads and writes happen synchronously
|
||||
/// on the calling thread.
|
||||
/// In single-threaded mode, all reads and writes happen synchronously on the
|
||||
/// calling thread.
|
||||
///
|
||||
/// In multi-threaded mode, a read thread is spawned that continually
|
||||
/// reads data and caches any received bytes. To start the read thread
|
||||
/// clients call:
|
||||
/// In multi-threaded mode, a read thread is spawned that continually reads
|
||||
/// data and caches any received bytes. To start the read thread clients call:
|
||||
///
|
||||
/// bool Communication::StartReadThread (Status *);
|
||||
///
|
||||
/// If true is returned a read thread has been spawned that will
|
||||
/// continually execute a call to the pure virtual DoRead function:
|
||||
/// If true is returned a read thread has been spawned that will continually
|
||||
/// execute a call to the pure virtual DoRead function:
|
||||
///
|
||||
/// size_t Communication::ReadFromConnection (void *, size_t, uint32_t);
|
||||
///
|
||||
/// When bytes are received the data gets cached in \a m_bytes and this
|
||||
/// class will broadcast a \b eBroadcastBitReadThreadGotBytes event.
|
||||
/// Clients that want packet based communication should override
|
||||
/// AppendBytesToCache. The subclasses can choose to call the
|
||||
/// built in AppendBytesToCache with the \a broadcast parameter set to
|
||||
/// false. This will cause the \b eBroadcastBitReadThreadGotBytes event
|
||||
/// not get broadcast, and then the subclass can post a \b
|
||||
/// eBroadcastBitPacketAvailable event when a full packet of data has
|
||||
/// been received.
|
||||
/// When bytes are received the data gets cached in \a m_bytes and this class
|
||||
/// will broadcast a \b eBroadcastBitReadThreadGotBytes event. Clients that
|
||||
/// want packet based communication should override AppendBytesToCache. The
|
||||
/// subclasses can choose to call the built in AppendBytesToCache with the \a
|
||||
/// broadcast parameter set to false. This will cause the \b
|
||||
/// eBroadcastBitReadThreadGotBytes event not get broadcast, and then the
|
||||
/// subclass can post a \b eBroadcastBitPacketAvailable event when a full
|
||||
/// packet of data has been received.
|
||||
///
|
||||
/// If the connection is disconnected a \b eBroadcastBitDisconnected
|
||||
/// event gets broadcast. If the read thread exits a \b
|
||||
/// eBroadcastBitReadThreadDidExit event will be broadcast. Clients
|
||||
/// can also post a \b eBroadcastBitReadThreadShouldExit event to this
|
||||
/// object which will cause the read thread to exit.
|
||||
/// If the connection is disconnected a \b eBroadcastBitDisconnected event
|
||||
/// gets broadcast. If the read thread exits a \b
|
||||
/// eBroadcastBitReadThreadDidExit event will be broadcast. Clients can also
|
||||
/// post a \b eBroadcastBitReadThreadShouldExit event to this object which
|
||||
/// will cause the read thread to exit.
|
||||
//----------------------------------------------------------------------
|
||||
class Communication : public Broadcaster {
|
||||
public:
|
||||
@ -120,8 +117,8 @@ class Communication : public Broadcaster {
|
||||
size_t src_len);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Construct the Communication object with the specified name for
|
||||
/// the Broadcaster that this object inherits from.
|
||||
/// Construct the Communication object with the specified name for the
|
||||
/// Broadcaster that this object inherits from.
|
||||
///
|
||||
/// @param[in] broadcaster_name
|
||||
/// The name of the broadcaster object. This name should be as
|
||||
@ -141,9 +138,8 @@ class Communication : public Broadcaster {
|
||||
void Clear();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Connect using the current connection by passing \a url to its
|
||||
/// connect function.
|
||||
/// string.
|
||||
/// Connect using the current connection by passing \a url to its connect
|
||||
/// function. string.
|
||||
///
|
||||
/// @param[in] url
|
||||
/// A string that contains all information needed by the
|
||||
@ -160,8 +156,7 @@ class Communication : public Broadcaster {
|
||||
lldb::ConnectionStatus Connect(const char *url, Status *error_ptr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Disconnect the communications connection if one is currently
|
||||
/// connected.
|
||||
/// Disconnect the communications connection if one is currently connected.
|
||||
///
|
||||
/// @return
|
||||
/// \b True if the disconnect succeeded, \b false otherwise. The
|
||||
@ -189,16 +184,15 @@ class Communication : public Broadcaster {
|
||||
//------------------------------------------------------------------
|
||||
/// Read bytes from the current connection.
|
||||
///
|
||||
/// If no read thread is running, this function call the
|
||||
/// connection's Connection::Read(...) function to get any available.
|
||||
/// If no read thread is running, this function call the connection's
|
||||
/// Connection::Read(...) function to get any available.
|
||||
///
|
||||
/// If a read thread has been started, this function will check for
|
||||
/// any cached bytes that have already been read and return any
|
||||
/// currently available bytes. If no bytes are cached, it will wait
|
||||
/// for the bytes to become available by listening for the \a
|
||||
/// eBroadcastBitReadThreadGotBytes event. If this function consumes
|
||||
/// all of the bytes in the cache, it will reset the
|
||||
/// \a eBroadcastBitReadThreadGotBytes event bit.
|
||||
/// If a read thread has been started, this function will check for any
|
||||
/// cached bytes that have already been read and return any currently
|
||||
/// available bytes. If no bytes are cached, it will wait for the bytes to
|
||||
/// become available by listening for the \a eBroadcastBitReadThreadGotBytes
|
||||
/// event. If this function consumes all of the bytes in the cache, it will
|
||||
/// reset the \a eBroadcastBitReadThreadGotBytes event bit.
|
||||
///
|
||||
/// @param[in] dst
|
||||
/// A destination buffer that must be at least \a dst_len bytes
|
||||
@ -220,8 +214,8 @@ class Communication : public Broadcaster {
|
||||
lldb::ConnectionStatus &status, Status *error_ptr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// The actual write function that attempts to write to the
|
||||
/// communications protocol.
|
||||
/// The actual write function that attempts to write to the communications
|
||||
/// protocol.
|
||||
///
|
||||
/// Subclasses must override this function.
|
||||
///
|
||||
@ -242,11 +236,10 @@ class Communication : public Broadcaster {
|
||||
//------------------------------------------------------------------
|
||||
/// Sets the connection that it to be used by this class.
|
||||
///
|
||||
/// By making a communication class that uses different connections
|
||||
/// it allows a single communication interface to negotiate and
|
||||
/// change its connection without any interruption to the client.
|
||||
/// It also allows the Communication class to be subclassed for
|
||||
/// packet based communication.
|
||||
/// By making a communication class that uses different connections it
|
||||
/// allows a single communication interface to negotiate and change its
|
||||
/// connection without any interruption to the client. It also allows the
|
||||
/// Communication class to be subclassed for packet based communication.
|
||||
///
|
||||
/// @param[in] connection
|
||||
/// A connection that this class will own and destroy.
|
||||
@ -257,19 +250,19 @@ class Communication : public Broadcaster {
|
||||
void SetConnection(Connection *connection);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Starts a read thread whose sole purpose it to read bytes from
|
||||
/// the current connection. This function will call connection's
|
||||
/// read function:
|
||||
/// Starts a read thread whose sole purpose it to read bytes from the
|
||||
/// current connection. This function will call connection's read function:
|
||||
///
|
||||
/// size_t Connection::Read (void *, size_t);
|
||||
///
|
||||
/// When bytes are read and cached, this function will call:
|
||||
///
|
||||
/// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool
|
||||
/// Communication::AppendBytesToCache (const uint8_t * bytes, size_t len,
|
||||
/// bool
|
||||
/// broadcast);
|
||||
///
|
||||
/// Subclasses should override this function if they wish to override
|
||||
/// the default action of caching the bytes and broadcasting a \b
|
||||
/// Subclasses should override this function if they wish to override the
|
||||
/// default action of caching the bytes and broadcasting a \b
|
||||
/// eBroadcastBitReadThreadGotBytes event.
|
||||
///
|
||||
/// @return
|
||||
@ -277,8 +270,8 @@ class Communication : public Broadcaster {
|
||||
/// false otherwise.
|
||||
///
|
||||
/// @see size_t Connection::Read (void *, size_t);
|
||||
/// @see void Communication::AppendBytesToCache (const uint8_t * bytes, size_t
|
||||
/// len, bool broadcast);
|
||||
/// @see void Communication::AppendBytesToCache (const uint8_t * bytes,
|
||||
/// size_t len, bool broadcast);
|
||||
//------------------------------------------------------------------
|
||||
virtual bool StartReadThread(Status *error_ptr = nullptr);
|
||||
|
||||
@ -301,11 +294,10 @@ class Communication : public Broadcaster {
|
||||
bool ReadThreadIsRunning();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// The static read thread function. This function will call
|
||||
/// the "DoRead" function continuously and wait for data to become
|
||||
/// available. When data is received it will append the available
|
||||
/// data to the internal cache and broadcast a
|
||||
/// \b eBroadcastBitReadThreadGotBytes event.
|
||||
/// The static read thread function. This function will call the "DoRead"
|
||||
/// function continuously and wait for data to become available. When data
|
||||
/// is received it will append the available data to the internal cache and
|
||||
/// broadcast a \b eBroadcastBitReadThreadGotBytes event.
|
||||
///
|
||||
/// @param[in] comm_ptr
|
||||
/// A pointer to an instance of this class.
|
||||
@ -364,18 +356,17 @@ class Communication : public Broadcaster {
|
||||
lldb::ConnectionStatus &status, Status *error_ptr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Append new bytes that get read from the read thread into the
|
||||
/// internal object byte cache. This will cause a \b
|
||||
/// eBroadcastBitReadThreadGotBytes event to be broadcast if \a
|
||||
/// broadcast is true.
|
||||
/// Append new bytes that get read from the read thread into the internal
|
||||
/// object byte cache. This will cause a \b eBroadcastBitReadThreadGotBytes
|
||||
/// event to be broadcast if \a broadcast is true.
|
||||
///
|
||||
/// Subclasses can override this function in order to inspect the
|
||||
/// received data and check if a packet is available.
|
||||
/// Subclasses can override this function in order to inspect the received
|
||||
/// data and check if a packet is available.
|
||||
///
|
||||
/// Subclasses can also still call this function from the
|
||||
/// overridden method to allow the caching to correctly happen and
|
||||
/// suppress the broadcasting of the \a eBroadcastBitReadThreadGotBytes
|
||||
/// event by setting \a broadcast to false.
|
||||
/// Subclasses can also still call this function from the overridden method
|
||||
/// to allow the caching to correctly happen and suppress the broadcasting
|
||||
/// of the \a eBroadcastBitReadThreadGotBytes event by setting \a broadcast
|
||||
/// to false.
|
||||
///
|
||||
/// @param[in] src
|
||||
/// A source buffer that must be at least \a src_len bytes
|
||||
@ -389,9 +380,9 @@ class Communication : public Broadcaster {
|
||||
lldb::ConnectionStatus status);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get any available bytes from our data cache. If this call
|
||||
/// empties the data cache, the \b eBroadcastBitReadThreadGotBytes event
|
||||
/// will be reset to signify no more bytes are available.
|
||||
/// Get any available bytes from our data cache. If this call empties the
|
||||
/// data cache, the \b eBroadcastBitReadThreadGotBytes event will be reset
|
||||
/// to signify no more bytes are available.
|
||||
///
|
||||
/// @param[in] dst
|
||||
/// A destination buffer that must be at least \a dst_len bytes
|
||||
|
@ -76,7 +76,7 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Debugger Debugger.h "lldb/Core/Debugger.h"
|
||||
/// @brief A class to manage flag bits.
|
||||
/// A class to manage flag bits.
|
||||
///
|
||||
/// Provides a global root objects for the debugger core.
|
||||
//----------------------------------------------------------------------
|
||||
@ -156,11 +156,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
|
||||
lldb::ListenerSP GetListener() { return m_listener_sp; }
|
||||
|
||||
// This returns the Debugger's scratch source manager. It won't be able to
|
||||
// look up files in debug
|
||||
// information, but it can look up files by absolute path and display them to
|
||||
// you.
|
||||
// To get the target's source manager, call GetSourceManager on the target
|
||||
// instead.
|
||||
// look up files in debug information, but it can look up files by absolute
|
||||
// path and display them to you. To get the target's source manager, call
|
||||
// GetSourceManager on the target instead.
|
||||
SourceManager &GetSourceManager();
|
||||
|
||||
lldb::TargetSP GetSelectedTarget() {
|
||||
@ -171,10 +169,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor for the target list.
|
||||
///
|
||||
/// The target list is part of the global debugger object. This
|
||||
/// the single debugger shared instance to control where targets
|
||||
/// get created and to allow for tracking and searching for targets
|
||||
/// based on certain criteria.
|
||||
/// The target list is part of the global debugger object. This the single
|
||||
/// debugger shared instance to control where targets get created and to
|
||||
/// allow for tracking and searching for targets based on certain criteria.
|
||||
///
|
||||
/// @return
|
||||
/// A global shared target list.
|
||||
@ -188,9 +185,8 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
|
||||
void DispatchInputEndOfFile();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// If any of the streams are not set, set them to the in/out/err
|
||||
// stream of the top most input reader to ensure they at least have
|
||||
// something
|
||||
// If any of the streams are not set, set them to the in/out/err stream of
|
||||
// the top most input reader to ensure they at least have something
|
||||
//------------------------------------------------------------------
|
||||
void AdoptTopIOHandlerFilesIfInvalid(lldb::StreamFileSP &in,
|
||||
lldb::StreamFileSP &out,
|
||||
@ -323,9 +319,8 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
|
||||
Status RunREPL(lldb::LanguageType language, const char *repl_options);
|
||||
|
||||
// This is for use in the command interpreter, when you either want the
|
||||
// selected target, or if no target
|
||||
// is present you want to prime the dummy target with entities that will be
|
||||
// copied over to new targets.
|
||||
// selected target, or if no target is present you want to prime the dummy
|
||||
// target with entities that will be copied over to new targets.
|
||||
Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
|
||||
Target *GetDummyTarget();
|
||||
|
||||
@ -378,8 +373,8 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
|
||||
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.
|
||||
// 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;
|
||||
@ -418,8 +413,8 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
|
||||
};
|
||||
|
||||
private:
|
||||
// Use Debugger::CreateInstance() to get a shared pointer to a new
|
||||
// debugger object
|
||||
// Use Debugger::CreateInstance() to get a shared pointer to a new debugger
|
||||
// object
|
||||
Debugger(lldb::LogOutputCallback m_log_callback, void *baton);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Debugger);
|
||||
|
@ -22,8 +22,8 @@
|
||||
#include "lldb/Utility/ConstString.h" // for ConstString
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN
|
||||
#include "lldb/lldb-enumerations.h" // for AddressClass, AddressClass...
|
||||
#include "lldb/lldb-forward.h" // for InstructionSP, DisassemblerSP
|
||||
#include "lldb/lldb-private-enumerations.h" // for AddressClass
|
||||
#include "lldb/lldb-types.h" // for addr_t, offset_t
|
||||
|
||||
#include "llvm/ADT/StringRef.h" // for StringRef
|
||||
@ -78,7 +78,7 @@ namespace lldb_private {
|
||||
class Instruction {
|
||||
public:
|
||||
Instruction(const Address &address,
|
||||
lldb::AddressClass addr_class = lldb::eAddressClassInvalid);
|
||||
AddressClass addr_class = AddressClass::eInvalid);
|
||||
|
||||
virtual ~Instruction();
|
||||
|
||||
@ -102,12 +102,11 @@ class Instruction {
|
||||
virtual void
|
||||
CalculateMnemonicOperandsAndComment(const ExecutionContext *exe_ctx) = 0;
|
||||
|
||||
lldb::AddressClass GetAddressClass();
|
||||
AddressClass GetAddressClass();
|
||||
|
||||
void SetAddress(const Address &addr) {
|
||||
// Invalidate the address class to lazily discover
|
||||
// it if we need to.
|
||||
m_address_class = lldb::eAddressClassInvalid;
|
||||
// Invalidate the address class to lazily discover it if we need to.
|
||||
m_address_class = AddressClass::eInvalid;
|
||||
m_address = addr;
|
||||
}
|
||||
|
||||
@ -235,14 +234,15 @@ class Instruction {
|
||||
protected:
|
||||
Address m_address; // The section offset address of this instruction
|
||||
// We include an address class in the Instruction class to
|
||||
// allow the instruction specify the eAddressClassCodeAlternateISA
|
||||
// (currently used for thumb), and also to specify data (eAddressClassData).
|
||||
// The usual value will be eAddressClassCode, but often when
|
||||
// disassembling memory, you might run into data. This can
|
||||
// help us to disassemble appropriately.
|
||||
// allow the instruction specify the
|
||||
// AddressClass::eCodeAlternateISA (currently used for
|
||||
// thumb), and also to specify data (AddressClass::eData).
|
||||
// The usual value will be AddressClass::eCode, but often
|
||||
// when disassembling memory, you might run into data.
|
||||
// This can help us to disassemble appropriately.
|
||||
private:
|
||||
lldb::AddressClass
|
||||
m_address_class; // Use GetAddressClass () accessor function!
|
||||
AddressClass m_address_class; // Use GetAddressClass () accessor function!
|
||||
|
||||
protected:
|
||||
Opcode m_opcode; // The opcode for this instruction
|
||||
std::string m_opcode_name;
|
||||
@ -365,12 +365,10 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
|
||||
};
|
||||
|
||||
// FindPlugin should be lax about the flavor string (it is too annoying to
|
||||
// have various internal uses of the
|
||||
// disassembler fail because the global flavor string gets set wrong.
|
||||
// Instead, if you get a flavor string you
|
||||
// have various internal uses of the disassembler fail because the global
|
||||
// flavor string gets set wrong. Instead, if you get a flavor string you
|
||||
// don't understand, use the default. Folks who care to check can use the
|
||||
// FlavorValidForArchSpec method on the
|
||||
// disassembler they got back.
|
||||
// FlavorValidForArchSpec method on the disassembler they got back.
|
||||
static lldb::DisassemblerSP
|
||||
FindPlugin(const ArchSpec &arch, const char *flavor, const char *plugin_name);
|
||||
|
||||
@ -470,8 +468,8 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
|
||||
const char *flavor) = 0;
|
||||
|
||||
protected:
|
||||
// SourceLine and SourceLinesToDisplay structures are only used in
|
||||
// the mixed source and assembly display methods internal to this class.
|
||||
// SourceLine and SourceLinesToDisplay structures are only used in the mixed
|
||||
// source and assembly display methods internal to this class.
|
||||
|
||||
struct SourceLine {
|
||||
FileSpec file;
|
||||
@ -494,9 +492,9 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
|
||||
struct SourceLinesToDisplay {
|
||||
std::vector<SourceLine> lines;
|
||||
|
||||
// index of the "current" source line, if we want to highlight that
|
||||
// when displaying the source lines. (as opposed to the surrounding
|
||||
// source lines provided to give context)
|
||||
// index of the "current" source line, if we want to highlight that when
|
||||
// displaying the source lines. (as opposed to the surrounding source
|
||||
// lines provided to give context)
|
||||
size_t current_source_line;
|
||||
|
||||
// Whether to print a blank line at the end of the source lines.
|
||||
@ -507,8 +505,8 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
|
||||
}
|
||||
};
|
||||
|
||||
// Get the function's declaration line number, hopefully a line number earlier
|
||||
// than the opening curly brace at the start of the function body.
|
||||
// Get the function's declaration line number, hopefully a line number
|
||||
// earlier than the opening curly brace at the start of the function body.
|
||||
static SourceLine GetFunctionDeclLineEntry(const SymbolContext &sc);
|
||||
|
||||
// Add the provided SourceLine to the map of filenames-to-source-lines-seen.
|
||||
@ -517,14 +515,13 @@ class Disassembler : public std::enable_shared_from_this<Disassembler>,
|
||||
std::map<FileSpec, std::set<uint32_t>> &source_lines_seen);
|
||||
|
||||
// Given a source line, determine if we should print it when we're doing
|
||||
// mixed source & assembly output.
|
||||
// We're currently using the target.process.thread.step-avoid-regexp setting
|
||||
// (which is used for stepping over inlined STL functions by default) to
|
||||
// determine what source lines to avoid showing.
|
||||
// mixed source & assembly output. We're currently using the
|
||||
// target.process.thread.step-avoid-regexp setting (which is used for
|
||||
// stepping over inlined STL functions by default) to determine what source
|
||||
// lines to avoid showing.
|
||||
//
|
||||
// Returns true if this source line should be elided (if the source line
|
||||
// should
|
||||
// not be displayed).
|
||||
// should not be displayed).
|
||||
static bool
|
||||
ElideMixedSourceAndDisassemblyLine(const ExecutionContext &exe_ctx,
|
||||
const SymbolContext &sc, SourceLine &line);
|
||||
|
31
include/lldb/Core/DumpRegisterValue.h
Normal file
31
include/lldb/Core/DumpRegisterValue.h
Normal file
@ -0,0 +1,31 @@
|
||||
//===-- DumpRegisterValue.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_CORE_DUMPREGISTERVALUE_H
|
||||
#define LLDB_CORE_DUMPREGISTERVALUE_H
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class RegisterValue;
|
||||
struct RegisterInfo;
|
||||
class Stream;
|
||||
|
||||
// The default value of 0 for reg_name_right_align_at means no alignment at
|
||||
// all.
|
||||
bool DumpRegisterValue(const RegisterValue ®_val, Stream *s,
|
||||
const RegisterInfo *reg_info, bool prefix_with_name,
|
||||
bool prefix_with_alt_name, lldb::Format format,
|
||||
uint32_t reg_name_right_align_at = 0);
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // LLDB_CORE_DUMPREGISTERVALUE_H
|
@ -48,62 +48,61 @@ namespace lldb_private {
|
||||
//----------------------------------------------------------------------
|
||||
/// @class EmulateInstruction EmulateInstruction.h
|
||||
/// "lldb/Core/EmulateInstruction.h"
|
||||
/// @brief A class that allows emulation of CPU opcodes.
|
||||
/// A class that allows emulation of CPU opcodes.
|
||||
///
|
||||
/// This class is a plug-in interface that is accessed through the
|
||||
/// standard static FindPlugin function call in the EmulateInstruction
|
||||
/// class. The FindPlugin takes a target triple and returns a new object
|
||||
/// if there is a plug-in that supports the architecture and OS. Four
|
||||
/// callbacks and a baton are provided. The four callbacks are read
|
||||
/// register, write register, read memory and write memory.
|
||||
/// This class is a plug-in interface that is accessed through the standard
|
||||
/// static FindPlugin function call in the EmulateInstruction class. The
|
||||
/// FindPlugin takes a target triple and returns a new object if there is a
|
||||
/// plug-in that supports the architecture and OS. Four callbacks and a baton
|
||||
/// are provided. The four callbacks are read register, write register, read
|
||||
/// memory and write memory.
|
||||
///
|
||||
/// This class is currently designed for these main use cases:
|
||||
/// - Auto generation of Call Frame Information (CFI) from assembly code
|
||||
/// - Predicting single step breakpoint locations
|
||||
/// - Emulating instructions for breakpoint traps
|
||||
/// This class is currently designed for these main use cases: - Auto
|
||||
/// generation of Call Frame Information (CFI) from assembly code - Predicting
|
||||
/// single step breakpoint locations - Emulating instructions for breakpoint
|
||||
/// traps
|
||||
///
|
||||
/// Objects can be asked to read an instruction which will cause a call
|
||||
/// to the read register callback to get the PC, followed by a read
|
||||
/// memory call to read the opcode. If ReadInstruction () returns true,
|
||||
/// then a call to EmulateInstruction::EvaluateInstruction () can be
|
||||
/// made. At this point the EmulateInstruction subclass will use all of
|
||||
/// the callbacks to emulate an instruction.
|
||||
/// Objects can be asked to read an instruction which will cause a call to the
|
||||
/// read register callback to get the PC, followed by a read memory call to
|
||||
/// read the opcode. If ReadInstruction () returns true, then a call to
|
||||
/// EmulateInstruction::EvaluateInstruction () can be made. At this point the
|
||||
/// EmulateInstruction subclass will use all of the callbacks to emulate an
|
||||
/// instruction.
|
||||
///
|
||||
/// Clients that provide the callbacks can either do the read/write
|
||||
/// registers/memory to actually emulate the instruction on a real or
|
||||
/// virtual CPU, or watch for the EmulateInstruction::Context which
|
||||
/// is context for the read/write register/memory which explains why
|
||||
/// the callback is being called. Examples of a context are:
|
||||
/// "pushing register 3 onto the stack at offset -12", or "adjusting
|
||||
/// stack pointer by -16". This extra context allows the generation of
|
||||
/// registers/memory to actually emulate the instruction on a real or virtual
|
||||
/// CPU, or watch for the EmulateInstruction::Context which is context for the
|
||||
/// read/write register/memory which explains why the callback is being
|
||||
/// called. Examples of a context are: "pushing register 3 onto the stack at
|
||||
/// offset -12", or "adjusting stack pointer by -16". This extra context
|
||||
/// allows the generation of
|
||||
/// CFI information from assembly code without having to actually do
|
||||
/// the read/write register/memory.
|
||||
///
|
||||
/// Clients must be prepared that not all instructions for an
|
||||
/// Instruction Set Architecture (ISA) will be emulated.
|
||||
/// Clients must be prepared that not all instructions for an Instruction Set
|
||||
/// Architecture (ISA) will be emulated.
|
||||
///
|
||||
/// Subclasses at the very least should implement the instructions that
|
||||
/// save and restore registers onto the stack and adjustment to the stack
|
||||
/// pointer. By just implementing a few instructions for an ISA that are
|
||||
/// the typical prologue opcodes, you can then generate CFI using a
|
||||
/// class that will soon be available.
|
||||
/// Subclasses at the very least should implement the instructions that save
|
||||
/// and restore registers onto the stack and adjustment to the stack pointer.
|
||||
/// By just implementing a few instructions for an ISA that are the typical
|
||||
/// prologue opcodes, you can then generate CFI using a class that will soon
|
||||
/// be available.
|
||||
///
|
||||
/// Implementing all of the instructions that affect the PC can then
|
||||
/// allow single step prediction support.
|
||||
/// Implementing all of the instructions that affect the PC can then allow
|
||||
/// single step prediction support.
|
||||
///
|
||||
/// Implementing all of the instructions allows for emulation of opcodes
|
||||
/// for breakpoint traps and will pave the way for "thread centric"
|
||||
/// debugging. The current debugging model is "process centric" where
|
||||
/// all threads must be stopped when any thread is stopped; when
|
||||
/// hitting software breakpoints we must disable the breakpoint by
|
||||
/// restoring the original breakpoint opcode, single stepping and
|
||||
/// restoring the breakpoint trap. If all threads were allowed to run
|
||||
/// then other threads could miss the breakpoint.
|
||||
/// Implementing all of the instructions allows for emulation of opcodes for
|
||||
/// breakpoint traps and will pave the way for "thread centric" debugging. The
|
||||
/// current debugging model is "process centric" where all threads must be
|
||||
/// stopped when any thread is stopped; when hitting software breakpoints we
|
||||
/// must disable the breakpoint by restoring the original breakpoint opcode,
|
||||
/// single stepping and restoring the breakpoint trap. If all threads were
|
||||
/// allowed to run then other threads could miss the breakpoint.
|
||||
///
|
||||
/// This class centralizes the code that usually is done in separate
|
||||
/// code paths in a debugger (single step prediction, finding save
|
||||
/// restore locations of registers for unwinding stack frame variables)
|
||||
/// and emulating the instruction is just a bonus.
|
||||
/// This class centralizes the code that usually is done in separate code
|
||||
/// paths in a debugger (single step prediction, finding save restore
|
||||
/// locations of registers for unwinding stack frame variables) and emulating
|
||||
/// the instruction is just a bonus.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class EmulateInstruction : public PluginInterface {
|
||||
@ -125,8 +124,8 @@ class EmulateInstruction : public PluginInterface {
|
||||
// prologue
|
||||
eContextPushRegisterOnStack,
|
||||
|
||||
// Exclusively used when restoring a register off the stack as part of
|
||||
// the epilogue
|
||||
// Exclusively used when restoring a register off the stack as part of the
|
||||
// epilogue
|
||||
eContextPopRegisterOffStack,
|
||||
|
||||
// Add or subtract a value from the stack
|
||||
@ -135,8 +134,8 @@ class EmulateInstruction : public PluginInterface {
|
||||
// Adjust the frame pointer for the current frame
|
||||
eContextSetFramePointer,
|
||||
|
||||
// Typically in an epilogue sequence. Copy the frame pointer back
|
||||
// into the stack pointer, use SP for CFA calculations again.
|
||||
// Typically in an epilogue sequence. Copy the frame pointer back into the
|
||||
// stack pointer, use SP for CFA calculations again.
|
||||
eContextRestoreStackPointer,
|
||||
|
||||
// Add or subtract a value from a base address register (other than SP)
|
||||
@ -159,8 +158,8 @@ class EmulateInstruction : public PluginInterface {
|
||||
// Used when performing an absolute branch where the
|
||||
eContextAbsoluteBranchRegister,
|
||||
|
||||
// Used when performing a supervisor call to an operating system to
|
||||
// provide a service:
|
||||
// Used when performing a supervisor call to an operating system to provide
|
||||
// a service:
|
||||
eContextSupervisorCall,
|
||||
|
||||
// Used when performing a MemU operation to read the PC-relative offset
|
||||
@ -360,9 +359,8 @@ class EmulateInstruction : public PluginInterface {
|
||||
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.
|
||||
// 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;
|
||||
|
||||
|
@ -121,10 +121,8 @@ class EventDataReceipt : public EventData {
|
||||
|
||||
const ConstString &GetFlavor() const override { return GetFlavorString(); }
|
||||
|
||||
bool WaitForEventReceived(
|
||||
const std::chrono::microseconds &abstime = std::chrono::microseconds(0),
|
||||
bool *timed_out = nullptr) {
|
||||
return m_predicate.WaitForValueEqualTo(true, abstime, timed_out);
|
||||
bool WaitForEventReceived(const Timeout<std::micro> &timeout = llvm::None) {
|
||||
return m_predicate.WaitForValueEqualTo(true, timeout);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -28,9 +28,8 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class FileLineResolver FileLineResolver.h "lldb/Core/FileLineResolver.h"
|
||||
/// @brief This class finds address for source file and line. Optionally, it
|
||||
/// will look for inlined
|
||||
/// instances of the file and line specification.
|
||||
/// This class finds address for source file and line. Optionally, it will
|
||||
/// look for inlined instances of the file and line specification.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class FileLineResolver : public Searcher {
|
||||
|
@ -25,7 +25,7 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class FileSpecList FileSpecList.h "lldb/Core/FileSpecList.h"
|
||||
/// @brief A file collection class.
|
||||
/// A file collection class.
|
||||
///
|
||||
/// A class that contains a mutable list of FileSpec objects.
|
||||
//----------------------------------------------------------------------
|
||||
@ -56,8 +56,7 @@ class FileSpecList {
|
||||
//------------------------------------------------------------------
|
||||
/// Assignment operator.
|
||||
///
|
||||
/// Replace the file list in this object with the file list from
|
||||
/// \a rhs.
|
||||
/// Replace the file list in this object with the file list from \a rhs.
|
||||
///
|
||||
/// @param[in] rhs
|
||||
/// A file list object to copy.
|
||||
@ -80,8 +79,8 @@ class FileSpecList {
|
||||
//------------------------------------------------------------------
|
||||
/// Append a FileSpec object if unique.
|
||||
///
|
||||
/// Appends \a file to the end of the file list if it doesn't
|
||||
/// already exist in the file list.
|
||||
/// Appends \a file to the end of the file list if it doesn't already exist
|
||||
/// in the file list.
|
||||
///
|
||||
/// @param[in] file
|
||||
/// A new file to append to this file list.
|
||||
@ -107,8 +106,8 @@ class FileSpecList {
|
||||
//------------------------------------------------------------------
|
||||
/// Find a file index.
|
||||
///
|
||||
/// Find the index of the file in the file spec list that matches
|
||||
/// \a file starting \a idx entries into the file spec list.
|
||||
/// Find the index of the file in the file spec list that matches \a file
|
||||
/// starting \a idx entries into the file spec list.
|
||||
///
|
||||
/// @param[in] idx
|
||||
/// An index into the file list.
|
||||
@ -119,24 +118,18 @@ class FileSpecList {
|
||||
/// @param[in] full
|
||||
/// Should FileSpec::Equal be called with "full" true or false.
|
||||
///
|
||||
/// @param[in] remove_backup_dots
|
||||
/// Should FileSpec::Equal be called with "remove_backup_dots" true or
|
||||
/// false.
|
||||
///
|
||||
/// @return
|
||||
/// The index of the file that matches \a file if it is found,
|
||||
/// else UINT32_MAX is returned.
|
||||
//------------------------------------------------------------------
|
||||
size_t FindFileIndex(size_t idx, const FileSpec &file, bool full,
|
||||
bool remove_backup_dots = false) const;
|
||||
size_t FindFileIndex(size_t idx, const FileSpec &file, bool full) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get file at index.
|
||||
///
|
||||
/// Gets a file from the file list. If \a idx is not a valid index,
|
||||
/// an empty FileSpec object will be returned. The file objects
|
||||
/// that are returned can be tested using
|
||||
/// FileSpec::operator void*().
|
||||
/// Gets a file from the file list. If \a idx is not a valid index, an empty
|
||||
/// FileSpec object will be returned. The file objects that are returned can
|
||||
/// be tested using FileSpec::operator void*().
|
||||
///
|
||||
/// @param[in] idx
|
||||
/// An index into the file list.
|
||||
@ -151,8 +144,8 @@ class FileSpecList {
|
||||
//------------------------------------------------------------------
|
||||
/// Get file specification pointer at index.
|
||||
///
|
||||
/// Gets a file from the file list. The file objects that are
|
||||
/// returned can be tested using FileSpec::operator void*().
|
||||
/// Gets a file from the file list. The file objects that are returned can
|
||||
/// be tested using FileSpec::operator void*().
|
||||
///
|
||||
/// @param[in] idx
|
||||
/// An index into the file list.
|
||||
@ -166,9 +159,9 @@ class FileSpecList {
|
||||
//------------------------------------------------------------------
|
||||
/// Get the memory cost of this object.
|
||||
///
|
||||
/// Return the size in bytes that this object takes in memory. This
|
||||
/// returns the size in bytes of this object, not any shared string
|
||||
/// values it may refer to.
|
||||
/// Return the size in bytes that this object takes in memory. This returns
|
||||
/// the size in bytes of this object, not any shared string values it may
|
||||
/// refer to.
|
||||
///
|
||||
/// @return
|
||||
/// The number of bytes that this object occupies in memory.
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef liblldb_FormatEntity_h_
|
||||
#define liblldb_FormatEntity_h_
|
||||
|
||||
#include "lldb/Utility/CompletionRequest.h"
|
||||
#include "lldb/Utility/FileSpec.h" // for FileSpec
|
||||
#include "lldb/Utility/Status.h"
|
||||
#include "lldb/lldb-enumerations.h" // for Format::eFormatDefault, Format
|
||||
@ -211,17 +212,15 @@ class FormatEntity {
|
||||
llvm::StringRef &variable_name,
|
||||
llvm::StringRef &variable_format);
|
||||
|
||||
static size_t AutoComplete(llvm::StringRef s, int match_start_point,
|
||||
int max_return_elements, bool &word_complete,
|
||||
StringList &matches);
|
||||
static size_t AutoComplete(lldb_private::CompletionRequest &request);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Format the current elements into the stream \a s.
|
||||
//
|
||||
// The root element will be stripped off and the format str passed in
|
||||
// will be either an empty string (print a description of this object),
|
||||
// or contain a . separated series like a domain name that identifies
|
||||
// further sub elements to display.
|
||||
// The root element will be stripped off and the format str passed in will be
|
||||
// either an empty string (print a description of this object), or contain a
|
||||
// `.`-separated series like a domain name that identifies further
|
||||
// sub-elements to display.
|
||||
//----------------------------------------------------------------------
|
||||
static bool FormatFileSpec(const FileSpec &file, Stream &s,
|
||||
llvm::StringRef elements,
|
||||
|
@ -63,14 +63,13 @@ class IOHandler {
|
||||
|
||||
virtual ~IOHandler();
|
||||
|
||||
// Each IOHandler gets to run until it is done. It should read data
|
||||
// from the "in" and place output into "out" and "err and return
|
||||
// when done.
|
||||
// Each IOHandler gets to run until it is done. It should read data from the
|
||||
// "in" and place output into "out" and "err and return when done.
|
||||
virtual void Run() = 0;
|
||||
|
||||
// Called when an input reader should relinquish its control so another
|
||||
// can be pushed onto the IO handler stack, or so the current IO
|
||||
// handler can pop itself off the stack
|
||||
// Called when an input reader should relinquish its control so another can
|
||||
// be pushed onto the IO handler stack, or so the current IO handler can pop
|
||||
// itself off the stack
|
||||
|
||||
virtual void Cancel() = 0;
|
||||
|
||||
@ -273,8 +272,8 @@ class IOHandlerDelegate {
|
||||
//------------------------------------------------------------------
|
||||
virtual bool IOHandlerIsInputComplete(IOHandler &io_handler,
|
||||
StringList &lines) {
|
||||
// Impose no requirements for input to be considered
|
||||
// complete. subclasses should do something more intelligent.
|
||||
// Impose no requirements for input to be considered complete. subclasses
|
||||
// should do something more intelligent.
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -289,8 +288,8 @@ class IOHandlerDelegate {
|
||||
//------------------------------------------------------------------
|
||||
// Intercept the IOHandler::Interrupt() calls and do something.
|
||||
//
|
||||
// Return true if the interrupt was handled, false if the IOHandler
|
||||
// should continue to try handle the interrupt itself.
|
||||
// Return true if the interrupt was handled, false if the IOHandler should
|
||||
// continue to try handle the interrupt itself.
|
||||
//------------------------------------------------------------------
|
||||
virtual bool IOHandlerInterrupt(IOHandler &io_handler) { return false; }
|
||||
|
||||
@ -302,8 +301,7 @@ class IOHandlerDelegate {
|
||||
// IOHandlerDelegateMultiline
|
||||
//
|
||||
// A IOHandlerDelegate that handles terminating multi-line input when
|
||||
// the last line is equal to "end_line" which is specified in the
|
||||
// constructor.
|
||||
// the last line is equal to "end_line" which is specified in the constructor.
|
||||
//----------------------------------------------------------------------
|
||||
class IOHandlerDelegateMultiline : public IOHandlerDelegate {
|
||||
public:
|
||||
@ -325,9 +323,8 @@ class IOHandlerDelegateMultiline : public IOHandlerDelegate {
|
||||
// Determine whether the end of input signal has been entered
|
||||
const size_t num_lines = lines.GetSize();
|
||||
if (num_lines > 0 && lines[num_lines - 1] == m_end_line) {
|
||||
// Remove the terminal line from "lines" so it doesn't appear in
|
||||
// the resulting input and return true to indicate we are done
|
||||
// getting lines
|
||||
// Remove the terminal line from "lines" so it doesn't appear in the
|
||||
// resulting input and return true to indicate we are done getting lines
|
||||
lines.PopBack();
|
||||
return true;
|
||||
}
|
||||
@ -454,8 +451,7 @@ class IOHandlerEditline : public IOHandler {
|
||||
};
|
||||
|
||||
// The order of base classes is important. Look at the constructor of
|
||||
// IOHandlerConfirm
|
||||
// to see how.
|
||||
// IOHandlerConfirm to see how.
|
||||
class IOHandlerConfirm : public IOHandlerDelegate, public IOHandlerEditline {
|
||||
public:
|
||||
IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
|
||||
|
@ -13,10 +13,14 @@
|
||||
// C Includes
|
||||
|
||||
// C++ Includes
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/lldb-defines.h"
|
||||
#include "lldb/lldb-private-forward.h"
|
||||
#include "lldb/lldb-types.h"
|
||||
|
||||
namespace lldb_private {
|
||||
class LoadedModuleInfoList {
|
||||
|
@ -28,15 +28,15 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Mangled Mangled.h "lldb/Core/Mangled.h"
|
||||
/// @brief A class that handles mangled names.
|
||||
/// A class that handles mangled names.
|
||||
///
|
||||
/// Designed to handle mangled names. The demangled version of any names
|
||||
/// will be computed when the demangled name is accessed through the
|
||||
/// Demangled() acccessor. This class can also tokenize the demangled
|
||||
/// version of the name for powerful searches. Functions and symbols
|
||||
/// could make instances of this class for their mangled names. Uniqued
|
||||
/// string pools are used for the mangled, demangled, and token string
|
||||
/// values to allow for faster comparisons and for efficient memory use.
|
||||
/// Designed to handle mangled names. The demangled version of any names will
|
||||
/// be computed when the demangled name is accessed through the Demangled()
|
||||
/// acccessor. This class can also tokenize the demangled version of the name
|
||||
/// for powerful searches. Functions and symbols could make instances of this
|
||||
/// class for their mangled names. Uniqued string pools are used for the
|
||||
/// mangled, demangled, and token string values to allow for faster
|
||||
/// comparisons and for efficient memory use.
|
||||
//----------------------------------------------------------------------
|
||||
class Mangled {
|
||||
public:
|
||||
@ -91,16 +91,16 @@ class Mangled {
|
||||
//----------------------------------------------------------------------
|
||||
/// Destructor
|
||||
///
|
||||
/// Releases its ref counts on the mangled and demangled strings that
|
||||
/// live in the global string pool.
|
||||
/// Releases its ref counts on the mangled and demangled strings that live
|
||||
/// in the global string pool.
|
||||
//----------------------------------------------------------------------
|
||||
~Mangled();
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Convert to pointer operator.
|
||||
///
|
||||
/// This allows code to check a Mangled object to see if it contains
|
||||
/// a valid mangled name using code such as:
|
||||
/// This allows code to check a Mangled object to see if it contains a valid
|
||||
/// mangled name using code such as:
|
||||
///
|
||||
/// @code
|
||||
/// Mangled mangled(...);
|
||||
@ -117,8 +117,8 @@ class Mangled {
|
||||
//----------------------------------------------------------------------
|
||||
/// Logical NOT operator.
|
||||
///
|
||||
/// This allows code to check a Mangled object to see if it contains
|
||||
/// an empty mangled name using code such as:
|
||||
/// This allows code to check a Mangled object to see if it contains an
|
||||
/// empty mangled name using code such as:
|
||||
///
|
||||
/// @code
|
||||
/// Mangled mangled(...);
|
||||
@ -158,8 +158,8 @@ class Mangled {
|
||||
//----------------------------------------------------------------------
|
||||
/// Dump a description of this object to a Stream \a s.
|
||||
///
|
||||
/// Dump a Mangled object to stream \a s. We don't force our
|
||||
/// demangled name to be computed currently (we don't use the accessor).
|
||||
/// Dump a Mangled object to stream \a s. We don't force our demangled name
|
||||
/// to be computed currently (we don't use the accessor).
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to dump the object description.
|
||||
@ -245,9 +245,9 @@ class Mangled {
|
||||
//----------------------------------------------------------------------
|
||||
/// Get the memory cost of this object.
|
||||
///
|
||||
/// Return the size in bytes that this object takes in memory. This
|
||||
/// returns the size in bytes of this object, not any shared string
|
||||
/// values it may refer to.
|
||||
/// Return the size in bytes that this object takes in memory. This returns
|
||||
/// the size in bytes of this object, not any shared string values it may
|
||||
/// refer to.
|
||||
///
|
||||
/// @return
|
||||
/// The number of bytes that this object occupies in memory.
|
||||
@ -259,8 +259,8 @@ class Mangled {
|
||||
//----------------------------------------------------------------------
|
||||
/// Set the string value in this object.
|
||||
///
|
||||
/// If \a is_mangled is \b true, then the mangled named is set to \a
|
||||
/// name, else the demangled name is set to \a name.
|
||||
/// If \a is_mangled is \b true, then the mangled named is set to \a name,
|
||||
/// else the demangled name is set to \a name.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The already const version of the name for this object.
|
||||
@ -285,14 +285,14 @@ class Mangled {
|
||||
//----------------------------------------------------------------------
|
||||
/// Try to guess the language from the mangling.
|
||||
///
|
||||
/// For a mangled name to have a language it must have both a mangled
|
||||
/// and a demangled name and it can be guessed from the mangling what
|
||||
/// the language is. Note: this will return C++ for any language that
|
||||
/// uses Itanium ABI mangling.
|
||||
/// For a mangled name to have a language it must have both a mangled and a
|
||||
/// demangled name and it can be guessed from the mangling what the language
|
||||
/// is. Note: this will return C++ for any language that uses Itanium ABI
|
||||
/// mangling.
|
||||
///
|
||||
/// Standard C function names will return eLanguageTypeUnknown because
|
||||
/// they aren't mangled and it isn't clear what language the name
|
||||
/// represents (there will be no mangled name).
|
||||
/// Standard C function names will return eLanguageTypeUnknown because they
|
||||
/// aren't mangled and it isn't clear what language the name represents
|
||||
/// (there will be no mangled name).
|
||||
///
|
||||
/// @return
|
||||
/// The language for the mangled/demangled name, eLanguageTypeUnknown
|
||||
|
@ -24,6 +24,7 @@
|
||||
// Project includes
|
||||
#include "lldb/Utility/DataExtractor.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "llvm/Support/DJB.h"
|
||||
|
||||
class MappedHash {
|
||||
public:
|
||||
@ -32,22 +33,10 @@ class MappedHash {
|
||||
// by the ELF GNU_HASH sections
|
||||
};
|
||||
|
||||
static uint32_t HashStringUsingDJB(const char *s) {
|
||||
uint32_t h = 5381;
|
||||
|
||||
for (unsigned char c = *s; c; c = *++s)
|
||||
h = ((h << 5) + h) + c;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
static uint32_t HashString(uint32_t hash_function, const char *s) {
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
static uint32_t HashString(uint32_t hash_function, llvm::StringRef s) {
|
||||
switch (hash_function) {
|
||||
case MappedHash::eHashFunctionDJB:
|
||||
return HashStringUsingDJB(s);
|
||||
return llvm::djbHash(s);
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -152,164 +141,6 @@ class MappedHash {
|
||||
// Write (int fd);
|
||||
};
|
||||
|
||||
template <typename __KeyType, class __HeaderDataType, class __ValueType>
|
||||
class ExportTable {
|
||||
public:
|
||||
typedef __HeaderDataType HeaderDataType;
|
||||
typedef Header<HeaderDataType> HeaderType;
|
||||
typedef __KeyType KeyType;
|
||||
typedef __ValueType ValueType;
|
||||
|
||||
struct Entry {
|
||||
uint32_t hash;
|
||||
KeyType key;
|
||||
ValueType value;
|
||||
};
|
||||
|
||||
typedef std::vector<ValueType> ValueArrayType;
|
||||
|
||||
typedef std::map<KeyType, ValueArrayType> HashData;
|
||||
// Map a name hash to one or more name infos
|
||||
typedef std::map<uint32_t, HashData> HashToHashData;
|
||||
|
||||
virtual KeyType GetKeyForStringType(const char *cstr) const = 0;
|
||||
|
||||
virtual size_t GetByteSize(const HashData &key_to_key_values) = 0;
|
||||
|
||||
virtual bool WriteHashData(const HashData &hash_data,
|
||||
lldb_private::Stream &ostrm) = 0;
|
||||
//
|
||||
void AddEntry(const char *cstr, const ValueType &value) {
|
||||
Entry entry;
|
||||
entry.hash = MappedHash::HashString(eHashFunctionDJB, cstr);
|
||||
entry.key = GetKeyForStringType(cstr);
|
||||
entry.value = value;
|
||||
m_entries.push_back(entry);
|
||||
}
|
||||
|
||||
void Save(const HeaderDataType &header_data, lldb_private::Stream &ostrm) {
|
||||
if (m_entries.empty())
|
||||
return;
|
||||
|
||||
const uint32_t num_entries = m_entries.size();
|
||||
uint32_t i = 0;
|
||||
|
||||
HeaderType header;
|
||||
|
||||
header.magic = HASH_MAGIC;
|
||||
header.version = 1;
|
||||
header.hash_function = eHashFunctionDJB;
|
||||
header.bucket_count = 0;
|
||||
header.hashes_count = 0;
|
||||
header.prologue_length = header_data.GetByteSize();
|
||||
|
||||
// We need to figure out the number of unique hashes first before we can
|
||||
// calculate the number of buckets we want to use.
|
||||
typedef std::vector<uint32_t> hash_coll;
|
||||
hash_coll unique_hashes;
|
||||
unique_hashes.resize(num_entries);
|
||||
for (i = 0; i < num_entries; ++i)
|
||||
unique_hashes[i] = m_entries[i].hash;
|
||||
std::sort(unique_hashes.begin(), unique_hashes.end());
|
||||
hash_coll::iterator pos =
|
||||
std::unique(unique_hashes.begin(), unique_hashes.end());
|
||||
const size_t num_unique_hashes =
|
||||
std::distance(unique_hashes.begin(), pos);
|
||||
|
||||
if (num_unique_hashes > 1024)
|
||||
header.bucket_count = num_unique_hashes / 4;
|
||||
else if (num_unique_hashes > 16)
|
||||
header.bucket_count = num_unique_hashes / 2;
|
||||
else
|
||||
header.bucket_count = num_unique_hashes;
|
||||
if (header.bucket_count == 0)
|
||||
header.bucket_count = 1;
|
||||
|
||||
std::vector<HashToHashData> hash_buckets;
|
||||
std::vector<uint32_t> hash_indexes(header.bucket_count, 0);
|
||||
std::vector<uint32_t> hash_values;
|
||||
std::vector<uint32_t> hash_offsets;
|
||||
hash_buckets.resize(header.bucket_count);
|
||||
uint32_t bucket_entry_empties = 0;
|
||||
// StreamString hash_file_data(Stream::eBinary,
|
||||
// dwarf->GetObjectFile()->GetAddressByteSize(),
|
||||
// dwarf->GetObjectFile()->GetByteSize());
|
||||
|
||||
// Push all of the hashes into their buckets and create all bucket
|
||||
// entries all populated with data.
|
||||
for (i = 0; i < num_entries; ++i) {
|
||||
const uint32_t hash = m_entries[i].hash;
|
||||
const uint32_t bucket_idx = hash % header.bucket_count;
|
||||
const uint32_t strp_offset = m_entries[i].str_offset;
|
||||
const uint32_t die_offset = m_entries[i].die_offset;
|
||||
hash_buckets[bucket_idx][hash][strp_offset].push_back(die_offset);
|
||||
}
|
||||
|
||||
// Now for each bucket we write the bucket value which is the
|
||||
// number of hashes and the hash index encoded into a single
|
||||
// 32 bit unsigned integer.
|
||||
for (i = 0; i < header.bucket_count; ++i) {
|
||||
HashToHashData &bucket_entry = hash_buckets[i];
|
||||
|
||||
if (bucket_entry.empty()) {
|
||||
// Empty bucket
|
||||
++bucket_entry_empties;
|
||||
hash_indexes[i] = UINT32_MAX;
|
||||
} else {
|
||||
const uint32_t hash_value_index = hash_values.size();
|
||||
uint32_t hash_count = 0;
|
||||
typename HashToHashData::const_iterator pos, end = bucket_entry.end();
|
||||
for (pos = bucket_entry.begin(); pos != end; ++pos) {
|
||||
hash_values.push_back(pos->first);
|
||||
hash_offsets.push_back(GetByteSize(pos->second));
|
||||
++hash_count;
|
||||
}
|
||||
|
||||
hash_indexes[i] = hash_value_index;
|
||||
}
|
||||
}
|
||||
header.hashes_count = hash_values.size();
|
||||
|
||||
// Write the header out now that we have the hash_count
|
||||
header.Write(ostrm);
|
||||
|
||||
// Now for each bucket we write the start index of the hashes
|
||||
// for the current bucket, or UINT32_MAX if the bucket is empty
|
||||
for (i = 0; i < header.bucket_count; ++i) {
|
||||
ostrm.PutHex32(hash_indexes[i]);
|
||||
}
|
||||
|
||||
// Now we need to write out all of the hash values
|
||||
for (i = 0; i < header.hashes_count; ++i) {
|
||||
ostrm.PutHex32(hash_values[i]);
|
||||
}
|
||||
|
||||
// Now we need to write out all of the hash data offsets,
|
||||
// there is an offset for each hash in the hashes array
|
||||
// that was written out above
|
||||
for (i = 0; i < header.hashes_count; ++i) {
|
||||
ostrm.PutHex32(hash_offsets[i]);
|
||||
}
|
||||
|
||||
// Now we write the data for each hash and verify we got the offset
|
||||
// correct above...
|
||||
for (i = 0; i < header.bucket_count; ++i) {
|
||||
HashToHashData &bucket_entry = hash_buckets[i];
|
||||
|
||||
typename HashToHashData::const_iterator pos, end = bucket_entry.end();
|
||||
for (pos = bucket_entry.begin(); pos != end; ++pos) {
|
||||
if (!bucket_entry.empty()) {
|
||||
WriteHashData(pos->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::vector<Entry> collection;
|
||||
collection m_entries;
|
||||
};
|
||||
|
||||
// A class for reading and using a saved hash table from a block of data
|
||||
// in memory
|
||||
template <typename __KeyType, class __HeaderType, class __HashData>
|
||||
@ -377,8 +208,8 @@ class MappedHash {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Find(const char *name, Pair &pair) const {
|
||||
if (!name || !name[0])
|
||||
bool Find(llvm::StringRef name, Pair &pair) const {
|
||||
if (name.empty())
|
||||
return false;
|
||||
|
||||
if (IsValid()) {
|
||||
@ -425,13 +256,12 @@ class MappedHash {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This method must be implemented in any subclasses.
|
||||
// The KeyType is user specified and must somehow result in a string
|
||||
// value. For example, the KeyType might be a string offset in a string
|
||||
// table and subclasses can store their string table as a member of the
|
||||
// subclass and return a valie "const char *" given a "key". The value
|
||||
// could also be a C string pointer, in which case just returning "key"
|
||||
// will suffice.
|
||||
// This method must be implemented in any subclasses. The KeyType is user
|
||||
// specified and must somehow result in a string value. For example, the
|
||||
// KeyType might be a string offset in a string table and subclasses can
|
||||
// store their string table as a member of the subclass and return a valie
|
||||
// "const char *" given a "key". The value could also be a C string
|
||||
// pointer, in which case just returning "key" will suffice.
|
||||
virtual const char *GetStringForKeyType(KeyType key) const = 0;
|
||||
|
||||
virtual bool ReadHashData(uint32_t hash_data_offset,
|
||||
@ -439,20 +269,19 @@ class MappedHash {
|
||||
|
||||
// This method must be implemented in any subclasses and it must try to
|
||||
// read one "Pair" at the offset pointed to by the "hash_data_offset_ptr"
|
||||
// parameter. This offset should be updated as bytes are consumed and
|
||||
// a value "Result" enum should be returned. If the "name" matches the
|
||||
// full name for the "pair.key" (which must be filled in by this call),
|
||||
// then the HashData in the pair ("pair.value") should be extracted and
|
||||
// filled in and "eResultKeyMatch" should be returned. If "name" doesn't
|
||||
// match this string for the key, then "eResultKeyMismatch" should be
|
||||
// returned and all data for the current HashData must be consumed or
|
||||
// skipped and the "hash_data_offset_ptr" offset needs to be updated to
|
||||
// point to the next HashData. If the end of the HashData objects for
|
||||
// a given hash value have been reached, then "eResultEndOfHashData"
|
||||
// should be returned. If anything else goes wrong during parsing,
|
||||
// return "eResultError" and the corresponding "Find()" function will
|
||||
// be canceled and return false.
|
||||
virtual Result GetHashDataForName(const char *name,
|
||||
// parameter. This offset should be updated as bytes are consumed and a
|
||||
// value "Result" enum should be returned. If the "name" matches the full
|
||||
// name for the "pair.key" (which must be filled in by this call), then the
|
||||
// HashData in the pair ("pair.value") should be extracted and filled in
|
||||
// and "eResultKeyMatch" should be returned. If "name" doesn't match this
|
||||
// string for the key, then "eResultKeyMismatch" should be returned and all
|
||||
// data for the current HashData must be consumed or skipped and the
|
||||
// "hash_data_offset_ptr" offset needs to be updated to point to the next
|
||||
// HashData. If the end of the HashData objects for a given hash value have
|
||||
// been reached, then "eResultEndOfHashData" should be returned. If
|
||||
// anything else goes wrong during parsing, return "eResultError" and the
|
||||
// corresponding "Find()" function will be canceled and return false.
|
||||
virtual Result GetHashDataForName(llvm::StringRef name,
|
||||
lldb::offset_t *hash_data_offset_ptr,
|
||||
Pair &pair) const = 0;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "lldb/Core/Address.h" // for Address
|
||||
#include "lldb/Core/ModuleSpec.h" // for ModuleSpec
|
||||
#include "lldb/Symbol/ObjectFile.h" // for ObjectFile
|
||||
#include "lldb/Symbol/SymbolContextScope.h"
|
||||
#include "lldb/Symbol/TypeSystem.h"
|
||||
#include "lldb/Target/PathMappingList.h"
|
||||
@ -93,33 +94,30 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Module Module.h "lldb/Core/Module.h"
|
||||
/// @brief A class that describes an executable image and its associated
|
||||
/// A class that describes an executable image and its associated
|
||||
/// object and symbol files.
|
||||
///
|
||||
/// The module is designed to be able to select a single slice of an
|
||||
/// executable image as it would appear on disk and during program
|
||||
/// execution.
|
||||
/// executable image as it would appear on disk and during program execution.
|
||||
///
|
||||
/// Modules control when and if information is parsed according to which
|
||||
/// accessors are called. For example the object file (ObjectFile)
|
||||
/// representation will only be parsed if the object file is requested
|
||||
/// using the Module::GetObjectFile() is called. The debug symbols
|
||||
/// will only be parsed if the symbol vendor (SymbolVendor) is
|
||||
/// requested using the Module::GetSymbolVendor() is called.
|
||||
/// representation will only be parsed if the object file is requested using
|
||||
/// the Module::GetObjectFile() is called. The debug symbols will only be
|
||||
/// parsed if the symbol vendor (SymbolVendor) is requested using the
|
||||
/// Module::GetSymbolVendor() is called.
|
||||
///
|
||||
/// The module will parse more detailed information as more queries are
|
||||
/// made.
|
||||
/// The module will parse more detailed information as more queries are made.
|
||||
//----------------------------------------------------------------------
|
||||
class Module : public std::enable_shared_from_this<Module>,
|
||||
public SymbolContextScope {
|
||||
public:
|
||||
// Static functions that can track the lifetime of module objects.
|
||||
// This is handy because we might have Module objects that are in
|
||||
// shared pointers that aren't in the global module list (from
|
||||
// ModuleList). If this is the case we need to know about it.
|
||||
// The modules in the global list maintained by these functions
|
||||
// can be viewed using the "target modules list" command using the
|
||||
// "--global" (-g for short).
|
||||
// Static functions that can track the lifetime of module objects. This is
|
||||
// handy because we might have Module objects that are in shared pointers
|
||||
// that aren't in the global module list (from ModuleList). If this is the
|
||||
// case we need to know about it. The modules in the global list maintained
|
||||
// by these functions can be viewed using the "target modules list" command
|
||||
// using the "--global" (-g for short).
|
||||
static size_t GetNumberAllocatedModules();
|
||||
|
||||
static Module *GetAllocatedModuleAtIndex(size_t idx);
|
||||
@ -129,8 +127,8 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Construct with file specification and architecture.
|
||||
///
|
||||
/// Clients that wish to share modules with other targets should
|
||||
/// use ModuleList::GetSharedModule().
|
||||
/// Clients that wish to share modules with other targets should use
|
||||
/// ModuleList::GetSharedModule().
|
||||
///
|
||||
/// @param[in] file_spec
|
||||
/// The file specification for the on disk representation of
|
||||
@ -158,8 +156,23 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
|
||||
Module(const ModuleSpec &module_spec);
|
||||
|
||||
static lldb::ModuleSP
|
||||
CreateJITModule(const lldb::ObjectFileJITDelegateSP &delegate_sp);
|
||||
template <typename ObjFilePlugin, typename... Args>
|
||||
static lldb::ModuleSP CreateModuleFromObjectFile(Args &&... args) {
|
||||
// Must create a module and place it into a shared pointer before we can
|
||||
// create an object file since it has a std::weak_ptr back to the module,
|
||||
// so we need to control the creation carefully in this static function
|
||||
lldb::ModuleSP module_sp(new Module());
|
||||
module_sp->m_objfile_sp =
|
||||
std::make_shared<ObjFilePlugin>(module_sp, std::forward<Args>(args)...);
|
||||
|
||||
// Once we get the object file, update our module with the object file's
|
||||
// architecture since it might differ in vendor/os if some parts were
|
||||
// unknown.
|
||||
if (!module_sp->m_objfile_sp->GetArchitecture(module_sp->m_arch))
|
||||
return nullptr;
|
||||
|
||||
return module_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
@ -169,13 +182,13 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
bool MatchesModuleSpec(const ModuleSpec &module_ref);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the load address for all sections in a module to be the
|
||||
/// file address plus \a slide.
|
||||
/// Set the load address for all sections in a module to be the file address
|
||||
/// plus \a slide.
|
||||
///
|
||||
/// Many times a module will be loaded in a target with a constant
|
||||
/// offset applied to all top level sections. This function can
|
||||
/// set the load address for all top level sections to be the
|
||||
/// section file address + offset.
|
||||
/// Many times a module will be loaded in a target with a constant offset
|
||||
/// applied to all top level sections. This function can set the load
|
||||
/// address for all top level sections to be the section file address +
|
||||
/// offset.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// The target in which to apply the section load addresses.
|
||||
@ -225,19 +238,18 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Get the module path and object name.
|
||||
///
|
||||
/// Modules can refer to object files. In this case the specification
|
||||
/// is simple and would return the path to the file:
|
||||
/// Modules can refer to object files. In this case the specification is
|
||||
/// simple and would return the path to the file:
|
||||
///
|
||||
/// "/usr/lib/foo.dylib"
|
||||
///
|
||||
/// Modules can be .o files inside of a BSD archive (.a file). In
|
||||
/// this case, the object specification will look like:
|
||||
/// Modules can be .o files inside of a BSD archive (.a file). In this case,
|
||||
/// the object specification will look like:
|
||||
///
|
||||
/// "/usr/lib/foo.a(bar.o)"
|
||||
///
|
||||
/// There are many places where logging wants to log this fully
|
||||
/// qualified specification, so we centralize this functionality
|
||||
/// here.
|
||||
/// There are many places where logging wants to log this fully qualified
|
||||
/// specification, so we centralize this functionality here.
|
||||
///
|
||||
/// @return
|
||||
/// The object path + object name if there is one.
|
||||
@ -247,11 +259,10 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Dump a description of this object to a Stream.
|
||||
///
|
||||
/// Dump a description of the contents of this object to the
|
||||
/// supplied stream \a s. The dumped content will be only what has
|
||||
/// been loaded or parsed up to this point at which this function
|
||||
/// is called, so this is a good way to see what has been parsed
|
||||
/// in a module.
|
||||
/// Dump a description of the contents of this object to the supplied stream
|
||||
/// \a s. The dumped content will be only what has been loaded or parsed up
|
||||
/// to this point at which this function is called, so this is a good way to
|
||||
/// see what has been parsed in a module.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to dump the object description.
|
||||
@ -316,8 +327,8 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Find compile units by partial or full path.
|
||||
///
|
||||
/// Finds all compile units that match \a path in all of the modules
|
||||
/// and returns the results in \a sc_list.
|
||||
/// Finds all compile units that match \a path in all of the modules and
|
||||
/// returns the results in \a sc_list.
|
||||
///
|
||||
/// @param[in] path
|
||||
/// The name of the function we are looking for.
|
||||
@ -342,8 +353,7 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
///
|
||||
/// If the function is an inlined function, it will have a block,
|
||||
/// representing the inlined function, and the function will be the
|
||||
/// containing function. If it is not inlined, then the block will
|
||||
/// be NULL.
|
||||
/// containing function. If it is not inlined, then the block will be NULL.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The name of the compile unit we are looking for.
|
||||
@ -379,8 +389,7 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
///
|
||||
/// If the function is an inlined function, it will have a block,
|
||||
/// representing the inlined function, and the function will be the
|
||||
/// containing function. If it is not inlined, then the block will
|
||||
/// be NULL.
|
||||
/// containing function. If it is not inlined, then the block will be NULL.
|
||||
///
|
||||
/// @param[in] regex
|
||||
/// A regular expression to use when matching the name.
|
||||
@ -438,26 +447,19 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
/// @param[in] parent_decl_ctx
|
||||
/// If valid, a decl context that results must exist within
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If \b true, any matches will be appended to \a
|
||||
/// variable_list, else matches replace the contents of
|
||||
/// \a variable_list.
|
||||
///
|
||||
/// @param[in] max_matches
|
||||
/// Allow the number of matches to be limited to \a
|
||||
/// max_matches. Specify UINT32_MAX to get all possible matches.
|
||||
///
|
||||
/// @param[in] variable_list
|
||||
/// A list of variables that gets the matches appended to (if
|
||||
/// \a append it \b true), or replace (if \a append is \b false).
|
||||
/// A list of variables that gets the matches appended to.
|
||||
///
|
||||
/// @return
|
||||
/// The number of matches added to \a variable_list.
|
||||
//------------------------------------------------------------------
|
||||
size_t FindGlobalVariables(const ConstString &name,
|
||||
const CompilerDeclContext *parent_decl_ctx,
|
||||
bool append, size_t max_matches,
|
||||
VariableList &variable_list);
|
||||
size_t max_matches, VariableList &variable_list);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find global and static variables by regular expression.
|
||||
@ -465,44 +467,36 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
/// @param[in] regex
|
||||
/// A regular expression to use when matching the name.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If \b true, any matches will be appended to \a
|
||||
/// variable_list, else matches replace the contents of
|
||||
/// \a variable_list.
|
||||
///
|
||||
/// @param[in] max_matches
|
||||
/// Allow the number of matches to be limited to \a
|
||||
/// max_matches. Specify UINT32_MAX to get all possible matches.
|
||||
///
|
||||
/// @param[in] variable_list
|
||||
/// A list of variables that gets the matches appended to (if
|
||||
/// \a append it \b true), or replace (if \a append is \b false).
|
||||
/// A list of variables that gets the matches appended to.
|
||||
///
|
||||
/// @return
|
||||
/// The number of matches added to \a variable_list.
|
||||
//------------------------------------------------------------------
|
||||
size_t FindGlobalVariables(const RegularExpression ®ex, bool append,
|
||||
size_t max_matches, VariableList &variable_list);
|
||||
size_t FindGlobalVariables(const RegularExpression ®ex, size_t max_matches,
|
||||
VariableList &variable_list);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find types by name.
|
||||
///
|
||||
/// Type lookups in modules go through the SymbolVendor (which will
|
||||
/// use one or more SymbolFile subclasses). The SymbolFile needs to
|
||||
/// be able to lookup types by basename and not the fully qualified
|
||||
/// typename. This allows the type accelerator tables to stay small,
|
||||
/// even with heavily templatized C++. The type search will then
|
||||
/// narrow down the search results. If "exact_match" is true, then
|
||||
/// the type search will only match exact type name matches. If
|
||||
/// "exact_match" is false, the type will match as long as the base
|
||||
/// typename matches and as long as any immediate containing
|
||||
/// namespaces/class scopes that are specified match. So to search
|
||||
/// for a type "d" in "b::c", the name "b::c::d" can be specified
|
||||
/// and it will match any class/namespace "b" which contains a
|
||||
/// class/namespace "c" which contains type "d". We do this to
|
||||
/// allow users to not always have to specify complete scoping on
|
||||
/// all expressions, but it also allows for exact matching when
|
||||
/// required.
|
||||
/// Type lookups in modules go through the SymbolVendor (which will use one
|
||||
/// or more SymbolFile subclasses). The SymbolFile needs to be able to
|
||||
/// lookup types by basename and not the fully qualified typename. This
|
||||
/// allows the type accelerator tables to stay small, even with heavily
|
||||
/// templatized C++. The type search will then narrow down the search
|
||||
/// results. If "exact_match" is true, then the type search will only match
|
||||
/// exact type name matches. If "exact_match" is false, the type will match
|
||||
/// as long as the base typename matches and as long as any immediate
|
||||
/// containing namespaces/class scopes that are specified match. So to
|
||||
/// search for a type "d" in "b::c", the name "b::c::d" can be specified and
|
||||
/// it will match any class/namespace "b" which contains a class/namespace
|
||||
/// "c" which contains type "d". We do this to allow users to not always
|
||||
/// have to specify complete scoping on all expressions, but it also allows
|
||||
/// for exact matching when required.
|
||||
///
|
||||
/// @param[in] sc
|
||||
/// A symbol context that scopes where to extract a type list
|
||||
@ -535,9 +529,9 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
const ConstString &type_name, bool exact_match);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Find types by name that are in a namespace. This function is
|
||||
/// used by the expression parser when searches need to happen in
|
||||
/// an exact namespace scope.
|
||||
/// Find types by name that are in a namespace. This function is used by the
|
||||
/// expression parser when searches need to happen in an exact namespace
|
||||
/// scope.
|
||||
///
|
||||
/// @param[in] sc
|
||||
/// A symbol context that scopes where to extract a type list
|
||||
@ -572,9 +566,9 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Get const accessor for the module file specification.
|
||||
///
|
||||
/// This function returns the file for the module on the host system
|
||||
/// that is running LLDB. This can differ from the path on the
|
||||
/// platform since we might be doing remote debugging.
|
||||
/// This function returns the file for the module on the host system that is
|
||||
/// running LLDB. This can differ from the path on the platform since we
|
||||
/// might be doing remote debugging.
|
||||
///
|
||||
/// @return
|
||||
/// A const reference to the file specification object.
|
||||
@ -584,14 +578,13 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Get accessor for the module platform file specification.
|
||||
///
|
||||
/// Platform file refers to the path of the module as it is known on
|
||||
/// the remote system on which it is being debugged. For local
|
||||
/// debugging this is always the same as Module::GetFileSpec(). But
|
||||
/// remote debugging might mention a file "/usr/lib/liba.dylib"
|
||||
/// which might be locally downloaded and cached. In this case the
|
||||
/// platform file could be something like:
|
||||
/// "/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib"
|
||||
/// The file could also be cached in a local developer kit directory.
|
||||
/// Platform file refers to the path of the module as it is known on the
|
||||
/// remote system on which it is being debugged. For local debugging this is
|
||||
/// always the same as Module::GetFileSpec(). But remote debugging might
|
||||
/// mention a file "/usr/lib/liba.dylib" which might be locally downloaded
|
||||
/// and cached. In this case the platform file could be something like:
|
||||
/// "/tmp/lldb/platform-cache/remote.host.computer/usr/lib/liba.dylib" The
|
||||
/// file could also be cached in a local developer kit directory.
|
||||
///
|
||||
/// @return
|
||||
/// A const reference to the file specification object.
|
||||
@ -631,8 +624,8 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tells whether this module is capable of being the main executable
|
||||
/// for a process.
|
||||
/// Tells whether this module is capable of being the main executable for a
|
||||
/// process.
|
||||
///
|
||||
/// @return
|
||||
/// \b true if it is, \b false otherwise.
|
||||
@ -640,9 +633,9 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
bool IsExecutable();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tells whether this module has been loaded in the target passed in.
|
||||
/// This call doesn't distinguish between whether the module is loaded
|
||||
/// by the dynamic loader, or by a "target module add" type call.
|
||||
/// Tells whether this module has been loaded in the target passed in. This
|
||||
/// call doesn't distinguish between whether the module is loaded by the
|
||||
/// dynamic loader, or by a "target module add" type call.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// The target to check whether this is loaded in.
|
||||
@ -673,9 +666,8 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Get the object file representation for the current architecture.
|
||||
///
|
||||
/// If the object file has not been located or parsed yet, this
|
||||
/// function will find the best ObjectFile plug-in that can parse
|
||||
/// Module::m_file.
|
||||
/// If the object file has not been located or parsed yet, this function
|
||||
/// will find the best ObjectFile plug-in that can parse Module::m_file.
|
||||
///
|
||||
/// @return
|
||||
/// If Module::m_file does not exist, or no plug-in was found
|
||||
@ -688,12 +680,12 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
virtual ObjectFile *GetObjectFile();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the unified section list for the module. This is the section
|
||||
/// list created by the module's object file and any debug info and
|
||||
/// symbol files created by the symbol vendor.
|
||||
/// Get the unified section list for the module. This is the section list
|
||||
/// created by the module's object file and any debug info and symbol files
|
||||
/// created by the symbol vendor.
|
||||
///
|
||||
/// If the symbol vendor has not been loaded yet, this function
|
||||
/// will return the section list for the object file.
|
||||
/// If the symbol vendor has not been loaded yet, this function will return
|
||||
/// the section list for the object file.
|
||||
///
|
||||
/// @return
|
||||
/// Unified module section list.
|
||||
@ -701,27 +693,26 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
virtual SectionList *GetSectionList();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Notify the module that the file addresses for the Sections have
|
||||
/// been updated.
|
||||
/// Notify the module that the file addresses for the Sections have been
|
||||
/// updated.
|
||||
///
|
||||
/// If the Section file addresses for a module are updated, this
|
||||
/// method should be called. Any parts of the module, object file,
|
||||
/// or symbol file that has cached those file addresses must invalidate
|
||||
/// or update its cache.
|
||||
/// If the Section file addresses for a module are updated, this method
|
||||
/// should be called. Any parts of the module, object file, or symbol file
|
||||
/// that has cached those file addresses must invalidate or update its
|
||||
/// cache.
|
||||
//------------------------------------------------------------------
|
||||
virtual void SectionFileAddressesChanged();
|
||||
|
||||
uint32_t GetVersion(uint32_t *versions, uint32_t num_versions);
|
||||
llvm::VersionTuple GetVersion();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Load an object file from memory.
|
||||
///
|
||||
/// If available, the size of the object file in memory may be
|
||||
/// passed to avoid additional round trips to process memory.
|
||||
/// If the size is not provided, a default value is used. This
|
||||
/// value should be large enough to enable the ObjectFile plugins
|
||||
/// to read the header of the object file without going back to the
|
||||
/// process.
|
||||
/// If available, the size of the object file in memory may be passed to
|
||||
/// avoid additional round trips to process memory. If the size is not
|
||||
/// provided, a default value is used. This value should be large enough to
|
||||
/// enable the ObjectFile plugins to read the header of the object file
|
||||
/// without going back to the process.
|
||||
///
|
||||
/// @return
|
||||
/// The object file loaded from memory or nullptr, if the operation
|
||||
@ -733,9 +724,8 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Get the symbol vendor interface for the current architecture.
|
||||
///
|
||||
/// If the symbol vendor file has not been located yet, this
|
||||
/// function will find the best SymbolVendor plug-in that can
|
||||
/// use the current object file.
|
||||
/// If the symbol vendor file has not been located yet, this function will
|
||||
/// find the best SymbolVendor plug-in that can use the current object file.
|
||||
///
|
||||
/// @return
|
||||
/// If this module does not have a valid object file, or no
|
||||
@ -758,11 +748,11 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
TypeList *GetTypeList();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get a pointer to the UUID value contained in this object.
|
||||
/// Get a reference to the UUID value contained in this object.
|
||||
///
|
||||
/// If the executable image file doesn't not have a UUID value built
|
||||
/// into the file format, an MD5 checksum of the entire file, or
|
||||
/// slice of the file for the current architecture should be used.
|
||||
/// If the executable image file doesn't not have a UUID value built into
|
||||
/// the file format, an MD5 checksum of the entire file, or slice of the
|
||||
/// file for the current architecture should be used.
|
||||
///
|
||||
/// @return
|
||||
/// A const pointer to the internal copy of the UUID value in
|
||||
@ -775,14 +765,13 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
/// A debugging function that will cause everything in a module to
|
||||
/// be parsed.
|
||||
///
|
||||
/// All compile units will be parsed, along with all globals and
|
||||
/// static variables and all functions for those compile units.
|
||||
/// All types, scopes, local variables, static variables, global
|
||||
/// variables, and line tables will be parsed. This can be used
|
||||
/// prior to dumping a module to see a complete list of the
|
||||
/// resulting debug information that gets parsed, or as a debug
|
||||
/// function to ensure that the module can consume all of the
|
||||
/// debug data the symbol vendor provides.
|
||||
/// All compile units will be parsed, along with all globals and static
|
||||
/// variables and all functions for those compile units. All types, scopes,
|
||||
/// local variables, static variables, global variables, and line tables
|
||||
/// will be parsed. This can be used prior to dumping a module to see a
|
||||
/// complete list of the resulting debug information that gets parsed, or as
|
||||
/// a debug function to ensure that the module can consume all of the debug
|
||||
/// data the symbol vendor provides.
|
||||
//------------------------------------------------------------------
|
||||
void ParseAllDebugSymbols();
|
||||
|
||||
@ -791,17 +780,16 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve the symbol context for the given address.
|
||||
///
|
||||
/// Tries to resolve the matching symbol context based on a lookup
|
||||
/// from the current symbol vendor. If the lazy lookup fails,
|
||||
/// an attempt is made to parse the eh_frame section to handle
|
||||
/// stripped symbols. If this fails, an attempt is made to resolve
|
||||
/// the symbol to the previous address to handle the case of a
|
||||
/// function with a tail call.
|
||||
/// Tries to resolve the matching symbol context based on a lookup from the
|
||||
/// current symbol vendor. If the lazy lookup fails, an attempt is made to
|
||||
/// parse the eh_frame section to handle stripped symbols. If this fails,
|
||||
/// an attempt is made to resolve the symbol to the previous address to
|
||||
/// handle the case of a function with a tail call.
|
||||
///
|
||||
/// Use properties of the modified SymbolContext to inspect any
|
||||
/// resolved target, module, compilation unit, symbol, function,
|
||||
/// function block or line entry. Use the return value to determine
|
||||
/// which of these properties have been modified.
|
||||
/// Use properties of the modified SymbolContext to inspect any resolved
|
||||
/// target, module, compilation unit, symbol, function, function block or
|
||||
/// line entry. Use the return value to determine which of these properties
|
||||
/// have been modified.
|
||||
///
|
||||
/// @param[in] so_addr
|
||||
/// A load address to resolve.
|
||||
@ -836,15 +824,14 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve items in the symbol context for a given file and line.
|
||||
///
|
||||
/// Tries to resolve \a file_path and \a line to a list of matching
|
||||
/// symbol contexts.
|
||||
/// Tries to resolve \a file_path and \a line to a list of matching symbol
|
||||
/// contexts.
|
||||
///
|
||||
/// The line table entries contains addresses that can be used to
|
||||
/// further resolve the values in each match: the function, block,
|
||||
/// symbol. Care should be taken to minimize the amount of
|
||||
/// information that is requested to only what is needed --
|
||||
/// typically the module, compile unit, line table and line table
|
||||
/// entry are sufficient.
|
||||
/// The line table entries contains addresses that can be used to further
|
||||
/// resolve the values in each match: the function, block, symbol. Care
|
||||
/// should be taken to minimize the amount of information that is requested
|
||||
/// to only what is needed -- typically the module, compile unit, line table
|
||||
/// and line table entry are sufficient.
|
||||
///
|
||||
/// @param[in] file_path
|
||||
/// A path to a source file to match. If \a file_path does not
|
||||
@ -883,15 +870,14 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Resolve items in the symbol context for a given file and line.
|
||||
///
|
||||
/// Tries to resolve \a file_spec and \a line to a list of matching
|
||||
/// symbol contexts.
|
||||
/// Tries to resolve \a file_spec and \a line to a list of matching symbol
|
||||
/// contexts.
|
||||
///
|
||||
/// The line table entries contains addresses that can be used to
|
||||
/// further resolve the values in each match: the function, block,
|
||||
/// symbol. Care should be taken to minimize the amount of
|
||||
/// information that is requested to only what is needed --
|
||||
/// typically the module, compile unit, line table and line table
|
||||
/// entry are sufficient.
|
||||
/// The line table entries contains addresses that can be used to further
|
||||
/// resolve the values in each match: the function, block, symbol. Care
|
||||
/// should be taken to minimize the amount of information that is requested
|
||||
/// to only what is needed -- typically the module, compile unit, line table
|
||||
/// and line table entry are sufficient.
|
||||
///
|
||||
/// @param[in] file_spec
|
||||
/// A file spec to a source file to match. If \a file_path does
|
||||
@ -936,12 +922,10 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language);
|
||||
|
||||
// Special error functions that can do printf style formatting that will
|
||||
// prepend the message with
|
||||
// something appropriate for this module (like the architecture, path and
|
||||
// object name (if any)).
|
||||
// This centralizes code so that everyone doesn't need to format their error
|
||||
// and log messages on
|
||||
// their own and keeps the output a bit more consistent.
|
||||
// prepend the message with something appropriate for this module (like the
|
||||
// architecture, path and object name (if any)). This centralizes code so
|
||||
// that everyone doesn't need to format their error and log messages on their
|
||||
// own and keeps the output a bit more consistent.
|
||||
void LogMessage(Log *log, const char *format, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
|
||||
@ -960,15 +944,15 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Return true if the file backing this module has changed since the
|
||||
// module was originally created since we saved the initial file
|
||||
// modification time when the module first gets created.
|
||||
// Return true if the file backing this module has changed since the module
|
||||
// was originally created since we saved the initial file modification time
|
||||
// when the module first gets created.
|
||||
//------------------------------------------------------------------
|
||||
bool FileHasChanged() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// SymbolVendor, SymbolFile and ObjectFile member objects should
|
||||
// lock the module mutex to avoid deadlocks.
|
||||
// SymbolVendor, SymbolFile and ObjectFile member objects should lock the
|
||||
// module mutex to avoid deadlocks.
|
||||
//------------------------------------------------------------------
|
||||
std::recursive_mutex &GetMutex() const { return m_mutex; }
|
||||
|
||||
@ -979,14 +963,13 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Finds a source file given a file spec using the module source
|
||||
/// path remappings (if any).
|
||||
/// Finds a source file given a file spec using the module source path
|
||||
/// remappings (if any).
|
||||
///
|
||||
/// Tries to resolve \a orig_spec by checking the module source path
|
||||
/// remappings. It makes sure the file exists, so this call can be
|
||||
/// expensive if the remappings are on a network file system, so
|
||||
/// use this function sparingly (not in a tight debug info parsing
|
||||
/// loop).
|
||||
/// remappings. It makes sure the file exists, so this call can be expensive
|
||||
/// if the remappings are on a network file system, so use this function
|
||||
/// sparingly (not in a tight debug info parsing loop).
|
||||
///
|
||||
/// @param[in] orig_spec
|
||||
/// The original source file path to try and remap.
|
||||
@ -1004,9 +987,9 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
//------------------------------------------------------------------
|
||||
/// Remaps a source file given \a path into \a new_path.
|
||||
///
|
||||
/// Remaps \a path if any source remappings match. This function
|
||||
/// does NOT stat the file system so it can be used in tight loops
|
||||
/// where debug info is being parsed.
|
||||
/// Remaps \a path if any source remappings match. This function does NOT
|
||||
/// stat the file system so it can be used in tight loops where debug info
|
||||
/// is being parsed.
|
||||
///
|
||||
/// @param[in] path
|
||||
/// The original source file path to try and remap.
|
||||
@ -1021,43 +1004,28 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
bool RemapSourceFile(llvm::StringRef path, std::string &new_path) const;
|
||||
bool RemapSourceFile(const char *, std::string &) const = delete;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Loads this module to memory.
|
||||
///
|
||||
/// Loads the bits needed to create an executable image to the memory.
|
||||
/// It is useful with bare-metal targets where target does not have the
|
||||
/// ability to start a process itself.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// Target where to load the module.
|
||||
///
|
||||
/// @return
|
||||
//------------------------------------------------------------------
|
||||
Status LoadInMemory(Target &target, bool set_pc);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class LookupInfo Module.h "lldb/Core/Module.h"
|
||||
/// @brief A class that encapsulates name lookup information.
|
||||
/// A class that encapsulates name lookup information.
|
||||
///
|
||||
/// Users can type a wide variety of partial names when setting
|
||||
/// breakpoints by name or when looking for functions by name.
|
||||
/// SymbolVendor and SymbolFile objects are only required to implement
|
||||
/// name lookup for function basenames and for fully mangled names.
|
||||
/// This means if the user types in a partial name, we must reduce this
|
||||
/// to a name lookup that will work with all SymbolFile objects. So we
|
||||
/// might reduce a name lookup to look for a basename, and then prune
|
||||
/// out any results that don't match.
|
||||
/// Users can type a wide variety of partial names when setting breakpoints
|
||||
/// by name or when looking for functions by name. SymbolVendor and
|
||||
/// SymbolFile objects are only required to implement name lookup for
|
||||
/// function basenames and for fully mangled names. This means if the user
|
||||
/// types in a partial name, we must reduce this to a name lookup that will
|
||||
/// work with all SymbolFile objects. So we might reduce a name lookup to
|
||||
/// look for a basename, and then prune out any results that don't match.
|
||||
///
|
||||
/// The "m_name" member variable represents the name as it was typed
|
||||
/// by the user. "m_lookup_name" will be the name we actually search
|
||||
/// for through the symbol or objects files. Lanaguage is included in
|
||||
/// case we need to filter results by language at a later date. The
|
||||
/// "m_name_type_mask" member variable tells us what kinds of names we
|
||||
/// are looking for and can help us prune out unwanted results.
|
||||
/// The "m_name" member variable represents the name as it was typed by the
|
||||
/// user. "m_lookup_name" will be the name we actually search for through
|
||||
/// the symbol or objects files. Lanaguage is included in case we need to
|
||||
/// filter results by language at a later date. The "m_name_type_mask"
|
||||
/// member variable tells us what kinds of names we are looking for and can
|
||||
/// help us prune out unwanted results.
|
||||
///
|
||||
/// Function lookups are done in Module.cpp, ModuleList.cpp and in
|
||||
/// BreakpointResolverName.cpp and they all now use this class to do
|
||||
/// lookups correctly.
|
||||
/// BreakpointResolverName.cpp and they all now use this class to do lookups
|
||||
/// correctly.
|
||||
//----------------------------------------------------------------------
|
||||
class LookupInfo {
|
||||
public:
|
||||
@ -1146,7 +1114,7 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
|
||||
std::atomic<bool> m_did_load_objfile{false};
|
||||
std::atomic<bool> m_did_load_symbol_vendor{false};
|
||||
std::atomic<bool> m_did_parse_uuid{false};
|
||||
std::atomic<bool> m_did_set_uuid{false};
|
||||
mutable bool m_file_has_changed : 1,
|
||||
m_first_file_changed_log : 1; /// See if the module was modified after it
|
||||
/// was initially opened.
|
||||
@ -1156,9 +1124,9 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
///
|
||||
/// Tries to resolve \a vm_addr as a file address (if \a
|
||||
/// vm_addr_is_file_addr is true) or as a load address if \a
|
||||
/// vm_addr_is_file_addr is false) in the symbol vendor.
|
||||
/// \a resolve_scope indicates what clients wish to resolve
|
||||
/// and can be used to limit the scope of what is parsed.
|
||||
/// vm_addr_is_file_addr is false) in the symbol vendor. \a resolve_scope
|
||||
/// indicates what clients wish to resolve and can be used to limit the
|
||||
/// scope of what is parsed.
|
||||
///
|
||||
/// @param[in] vm_addr
|
||||
/// The load virtual address to resolve.
|
||||
@ -1196,6 +1164,8 @@ class Module : public std::enable_shared_from_this<Module>,
|
||||
|
||||
bool SetArchitecture(const ArchSpec &new_arch);
|
||||
|
||||
void SetUUID(const lldb_private::UUID &uuid);
|
||||
|
||||
SectionList *GetUnifiedSectionList();
|
||||
|
||||
friend class ModuleList;
|
||||
|
@ -16,7 +16,7 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class ModuleChild ModuleChild.h "lldb/Core/ModuleChild.h"
|
||||
/// @brief A mix in class that contains a pointer back to the module
|
||||
/// A mix in class that contains a pointer back to the module
|
||||
/// that owns the object which inherits from it.
|
||||
//----------------------------------------------------------------------
|
||||
class ModuleChild {
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "lldb/Core/Address.h" // for Address
|
||||
#include "lldb/Core/ModuleSpec.h" // for ModuleSpec
|
||||
#include "lldb/Core/UserSettingsController.h"
|
||||
#include "lldb/Utility/FileSpec.h" // for FileSpec
|
||||
#include "lldb/Utility/Iterable.h"
|
||||
#include "lldb/Utility/Status.h" // for Status
|
||||
@ -74,12 +75,21 @@ class VariableList;
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class ModuleListProperties : public Properties {
|
||||
public:
|
||||
ModuleListProperties();
|
||||
|
||||
FileSpec GetClangModulesCachePath() const;
|
||||
bool SetClangModulesCachePath(llvm::StringRef path);
|
||||
bool GetEnableExternalLookup() const;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class ModuleList ModuleList.h "lldb/Core/ModuleList.h"
|
||||
/// @brief A collection class for Module objects.
|
||||
/// A collection class for Module objects.
|
||||
///
|
||||
/// Modules in the module collection class are stored as reference
|
||||
/// counted shared pointers to Module objects.
|
||||
/// Modules in the module collection class are stored as reference counted
|
||||
/// shared pointers to Module objects.
|
||||
//----------------------------------------------------------------------
|
||||
class ModuleList {
|
||||
public:
|
||||
@ -107,8 +117,7 @@ class ModuleList {
|
||||
//------------------------------------------------------------------
|
||||
/// Copy Constructor.
|
||||
///
|
||||
/// Creates a new module list object with a copy of the modules from
|
||||
/// \a rhs.
|
||||
/// Creates a new module list object with a copy of the modules from \a rhs.
|
||||
///
|
||||
/// @param[in] rhs
|
||||
/// Another module list object.
|
||||
@ -146,9 +155,9 @@ class ModuleList {
|
||||
void Append(const lldb::ModuleSP &module_sp);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Append a module to the module list and remove any equivalent
|
||||
/// modules. Equivalent modules are ones whose file, platform file
|
||||
/// and architecture matches.
|
||||
/// Append a module to the module list and remove any equivalent modules.
|
||||
/// Equivalent modules are ones whose file, platform file and architecture
|
||||
/// matches.
|
||||
///
|
||||
/// Replaces the module to the collection.
|
||||
///
|
||||
@ -169,27 +178,27 @@ class ModuleList {
|
||||
//------------------------------------------------------------------
|
||||
/// Clear the object's state.
|
||||
///
|
||||
/// Clears the list of modules and releases a reference to each
|
||||
/// module object and if the reference count goes to zero, the
|
||||
/// module will be deleted.
|
||||
/// Clears the list of modules and releases a reference to each module
|
||||
/// object and if the reference count goes to zero, the module will be
|
||||
/// deleted.
|
||||
//------------------------------------------------------------------
|
||||
void Clear();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Clear the object's state.
|
||||
///
|
||||
/// Clears the list of modules and releases a reference to each
|
||||
/// module object and if the reference count goes to zero, the
|
||||
/// module will be deleted. Also release all memory that might be
|
||||
/// held by any collection classes (like std::vector)
|
||||
/// Clears the list of modules and releases a reference to each module
|
||||
/// object and if the reference count goes to zero, the module will be
|
||||
/// deleted. Also release all memory that might be held by any collection
|
||||
/// classes (like std::vector)
|
||||
//------------------------------------------------------------------
|
||||
void Destroy();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Dump the description of each module contained in this list.
|
||||
///
|
||||
/// Dump the description of each module contained in this list to
|
||||
/// the supplied stream \a s.
|
||||
/// Dump the description of each module contained in this list to the
|
||||
/// supplied stream \a s.
|
||||
///
|
||||
/// @param[in] s
|
||||
/// The stream to which to dump the object description.
|
||||
@ -220,8 +229,8 @@ class ModuleList {
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the module shared pointer for the module at index \a idx without
|
||||
/// acquiring the ModuleList mutex. This MUST already have been
|
||||
/// acquired with ModuleList::GetMutex and locked for this call to be safe.
|
||||
/// acquiring the ModuleList mutex. This MUST already have been acquired
|
||||
/// with ModuleList::GetMutex and locked for this call to be safe.
|
||||
///
|
||||
/// @param[in] idx
|
||||
/// An index into this module collection.
|
||||
@ -249,9 +258,9 @@ class ModuleList {
|
||||
Module *GetModulePointerAtIndex(size_t idx) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get the module pointer for the module at index \a idx without
|
||||
/// acquiring the ModuleList mutex. This MUST already have been
|
||||
/// acquired with ModuleList::GetMutex and locked for this call to be safe.
|
||||
/// Get the module pointer for the module at index \a idx without acquiring
|
||||
/// the ModuleList mutex. This MUST already have been acquired with
|
||||
/// ModuleList::GetMutex and locked for this call to be safe.
|
||||
///
|
||||
/// @param[in] idx
|
||||
/// An index into this module collection.
|
||||
@ -267,8 +276,8 @@ class ModuleList {
|
||||
//------------------------------------------------------------------
|
||||
/// Find compile units by partial or full path.
|
||||
///
|
||||
/// Finds all compile units that match \a path in all of the modules
|
||||
/// and returns the results in \a sc_list.
|
||||
/// Finds all compile units that match \a path in all of the modules and
|
||||
/// returns the results in \a sc_list.
|
||||
///
|
||||
/// @param[in] path
|
||||
/// The name of the compile unit we are looking for.
|
||||
@ -315,24 +324,17 @@ class ModuleList {
|
||||
/// The name of the global or static variable we are looking
|
||||
/// for.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If \b true, any matches will be appended to \a
|
||||
/// variable_list, else matches replace the contents of
|
||||
/// \a variable_list.
|
||||
///
|
||||
/// @param[in] max_matches
|
||||
/// Allow the number of matches to be limited to \a
|
||||
/// max_matches. Specify UINT32_MAX to get all possible matches.
|
||||
///
|
||||
/// @param[in] variable_list
|
||||
/// A list of variables that gets the matches appended to (if
|
||||
/// \a append it \b true), or replace (if \a append is \b false).
|
||||
/// A list of variables that gets the matches appended to.
|
||||
///
|
||||
/// @return
|
||||
/// The number of matches added to \a variable_list.
|
||||
//------------------------------------------------------------------
|
||||
size_t FindGlobalVariables(const ConstString &name, bool append,
|
||||
size_t max_matches,
|
||||
size_t FindGlobalVariables(const ConstString &name, size_t max_matches,
|
||||
VariableList &variable_list) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -341,29 +343,21 @@ class ModuleList {
|
||||
/// @param[in] regex
|
||||
/// A regular expression to use when matching the name.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If \b true, any matches will be appended to \a
|
||||
/// variable_list, else matches replace the contents of
|
||||
/// \a variable_list.
|
||||
///
|
||||
/// @param[in] max_matches
|
||||
/// Allow the number of matches to be limited to \a
|
||||
/// max_matches. Specify UINT32_MAX to get all possible matches.
|
||||
///
|
||||
/// @param[in] variable_list
|
||||
/// A list of variables that gets the matches appended to (if
|
||||
/// \a append it \b true), or replace (if \a append is \b false).
|
||||
/// A list of variables that gets the matches appended to.
|
||||
///
|
||||
/// @return
|
||||
/// The number of matches added to \a variable_list.
|
||||
//------------------------------------------------------------------
|
||||
size_t FindGlobalVariables(const RegularExpression ®ex, bool append,
|
||||
size_t max_matches,
|
||||
size_t FindGlobalVariables(const RegularExpression ®ex, size_t max_matches,
|
||||
VariableList &variable_list) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Finds the first module whose file specification matches \a
|
||||
/// file_spec.
|
||||
/// Finds the first module whose file specification matches \a file_spec.
|
||||
///
|
||||
/// @param[in] file_spec_ptr
|
||||
/// A file specification object to match against the Module's
|
||||
@ -400,9 +394,9 @@ class ModuleList {
|
||||
//------------------------------------------------------------------
|
||||
// Find a module by UUID
|
||||
//
|
||||
// The UUID value for a module is extracted from the ObjectFile and
|
||||
// is the MD5 checksum, or a smarter object file equivalent, so
|
||||
// finding modules by UUID values is very efficient and accurate.
|
||||
// The UUID value for a module is extracted from the ObjectFile and is the
|
||||
// MD5 checksum, or a smarter object file equivalent, so finding modules by
|
||||
// UUID values is very efficient and accurate.
|
||||
//------------------------------------------------------------------
|
||||
lldb::ModuleSP FindModule(const UUID &uuid) const;
|
||||
|
||||
@ -534,6 +528,8 @@ class ModuleList {
|
||||
Stream *feedback_stream = nullptr,
|
||||
bool continue_on_error = true);
|
||||
|
||||
static ModuleListProperties &GetGlobalModuleListProperties();
|
||||
|
||||
static bool ModuleIsInCache(const Module *module_ptr);
|
||||
|
||||
static Status GetSharedModule(const ModuleSpec &module_spec,
|
||||
@ -551,7 +547,7 @@ class ModuleList {
|
||||
static size_t RemoveOrphanSharedModules(bool mandatory);
|
||||
|
||||
static bool RemoveSharedModuleIfOrphaned(const Module *module_ptr);
|
||||
|
||||
|
||||
void ForEach(std::function<bool(const lldb::ModuleSP &module_sp)> const
|
||||
&callback) const;
|
||||
|
||||
|
@ -34,9 +34,9 @@ class ModuleSpec {
|
||||
m_object_name(), m_object_offset(0), m_object_size(0),
|
||||
m_source_mappings() {}
|
||||
|
||||
ModuleSpec(const FileSpec &file_spec)
|
||||
ModuleSpec(const FileSpec &file_spec, const UUID& uuid = UUID())
|
||||
: m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(),
|
||||
m_uuid(), m_object_name(), m_object_offset(0),
|
||||
m_uuid(uuid), m_object_name(), m_object_offset(0),
|
||||
m_object_size(file_spec.GetByteSize()), m_source_mappings() {}
|
||||
|
||||
ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch)
|
||||
@ -341,8 +341,8 @@ class ModuleSpecList {
|
||||
m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end());
|
||||
}
|
||||
|
||||
// The index "i" must be valid and this can't be used in
|
||||
// multi-threaded code as no mutex lock is taken.
|
||||
// The index "i" must be valid and this can't be used in multi-threaded code
|
||||
// as no mutex lock is taken.
|
||||
ModuleSpec &GetModuleSpecRefAtIndex(size_t i) { return m_specs[i]; }
|
||||
|
||||
bool GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const {
|
||||
|
@ -477,11 +477,11 @@ class PluginManager {
|
||||
const ConstString &name);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Some plug-ins might register a DebuggerInitializeCallback
|
||||
// callback when registering the plug-in. After a new Debugger
|
||||
// instance is created, this DebuggerInitialize function will get
|
||||
// called. This allows plug-ins to install Properties and do any
|
||||
// other initialization that requires a debugger instance.
|
||||
// Some plug-ins might register a DebuggerInitializeCallback callback when
|
||||
// registering the plug-in. After a new Debugger instance is created, this
|
||||
// DebuggerInitialize function will get called. This allows plug-ins to
|
||||
// install Properties and do any other initialization that requires a
|
||||
// debugger instance.
|
||||
//------------------------------------------------------------------
|
||||
static void DebuggerInitialize(Debugger &debugger);
|
||||
|
||||
|
@ -27,9 +27,8 @@
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Templatized classes for dealing with generic ranges and also
|
||||
// collections of ranges, or collections of ranges that have associated
|
||||
// data.
|
||||
// Templatized classes for dealing with generic ranges and also collections of
|
||||
// ranges, or collections of ranges that have associated data.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -214,8 +213,8 @@ template <typename B, typename S, unsigned N> class RangeArray {
|
||||
else
|
||||
minimal_ranges.push_back(*pos);
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// Use the swap technique in case our new vector is much smaller. We
|
||||
// must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap(minimal_ranges);
|
||||
}
|
||||
@ -228,8 +227,8 @@ template <typename B, typename S, unsigned N> class RangeArray {
|
||||
#endif
|
||||
if (m_entries.empty())
|
||||
return fail_value;
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the
|
||||
// first range's base
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the first
|
||||
// range's base
|
||||
return m_entries.front().GetRangeBase();
|
||||
}
|
||||
|
||||
@ -239,8 +238,8 @@ template <typename B, typename S, unsigned N> class RangeArray {
|
||||
#endif
|
||||
if (m_entries.empty())
|
||||
return fail_value;
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the
|
||||
// last range's end
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the last
|
||||
// range's end
|
||||
return m_entries.back().GetRangeEnd();
|
||||
}
|
||||
|
||||
@ -446,8 +445,8 @@ template <typename B, typename S> class RangeVector {
|
||||
else
|
||||
minimal_ranges.push_back(*pos);
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// Use the swap technique in case our new vector is much smaller. We
|
||||
// must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap(minimal_ranges);
|
||||
}
|
||||
@ -460,8 +459,8 @@ template <typename B, typename S> class RangeVector {
|
||||
#endif
|
||||
if (m_entries.empty())
|
||||
return fail_value;
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the
|
||||
// first range's base
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the first
|
||||
// range's base
|
||||
return m_entries.front().GetRangeBase();
|
||||
}
|
||||
|
||||
@ -471,8 +470,8 @@ template <typename B, typename S> class RangeVector {
|
||||
#endif
|
||||
if (m_entries.empty())
|
||||
return fail_value;
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the
|
||||
// last range's end
|
||||
// m_entries must be sorted, so if we aren't empty, we grab the last
|
||||
// range's end
|
||||
return m_entries.back().GetRangeEnd();
|
||||
}
|
||||
|
||||
@ -604,8 +603,8 @@ template <typename B, typename S> class RangeVector {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A simple range with data class where you get to define the type of
|
||||
// the range base "B", the type used for the range byte size "S", and
|
||||
// the type for the associated data "T".
|
||||
// the range base "B", the type used for the range byte size "S", and the type
|
||||
// for the associated data "T".
|
||||
//----------------------------------------------------------------------
|
||||
template <typename B, typename S, typename T>
|
||||
struct RangeData : public Range<B, S> {
|
||||
@ -688,8 +687,8 @@ template <typename B, typename S, typename T, unsigned N> class RangeDataArray {
|
||||
}
|
||||
}
|
||||
|
||||
// We we can combine at least one entry, then we make a new collection
|
||||
// and populate it accordingly, and then swap it into place.
|
||||
// We we can combine at least one entry, then we make a new collection and
|
||||
// populate it accordingly, and then swap it into place.
|
||||
if (can_combine) {
|
||||
Collection minimal_ranges;
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
|
||||
@ -699,9 +698,9 @@ template <typename B, typename S, typename T, unsigned N> class RangeDataArray {
|
||||
else
|
||||
minimal_ranges.push_back(*pos);
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
// Use the swap technique in case our new vector is much smaller. We must
|
||||
// swap when using the STL because std::vector objects never release or
|
||||
// reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap(minimal_ranges);
|
||||
}
|
||||
}
|
||||
@ -828,8 +827,8 @@ template <typename B, typename S, typename T, unsigned N> class RangeDataArray {
|
||||
Collection m_entries;
|
||||
};
|
||||
|
||||
// Same as RangeDataArray, but uses std::vector as to not
|
||||
// require static storage of N items in the class itself
|
||||
// Same as RangeDataArray, but uses std::vector as to not require static
|
||||
// storage of N items in the class itself
|
||||
template <typename B, typename S, typename T> class RangeDataVector {
|
||||
public:
|
||||
typedef RangeData<B, S, T> Entry;
|
||||
@ -878,8 +877,8 @@ template <typename B, typename S, typename T> class RangeDataVector {
|
||||
}
|
||||
}
|
||||
|
||||
// We we can combine at least one entry, then we make a new collection
|
||||
// and populate it accordingly, and then swap it into place.
|
||||
// We we can combine at least one entry, then we make a new collection and
|
||||
// populate it accordingly, and then swap it into place.
|
||||
if (can_combine) {
|
||||
Collection minimal_ranges;
|
||||
for (pos = m_entries.begin(), end = m_entries.end(), prev = end;
|
||||
@ -889,15 +888,15 @@ template <typename B, typename S, typename T> class RangeDataVector {
|
||||
else
|
||||
minimal_ranges.push_back(*pos);
|
||||
}
|
||||
// Use the swap technique in case our new vector is much smaller.
|
||||
// We must swap when using the STL because std::vector objects never
|
||||
// release or reduce the memory once it has been allocated/reserved.
|
||||
// Use the swap technique in case our new vector is much smaller. We must
|
||||
// swap when using the STL because std::vector objects never release or
|
||||
// reduce the memory once it has been allocated/reserved.
|
||||
m_entries.swap(minimal_ranges);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the byte size of ranges with zero byte sizes by finding
|
||||
// the next entry with a base address > the current base address
|
||||
// Calculate the byte size of ranges with zero byte sizes by finding the next
|
||||
// entry with a base address > the current base address
|
||||
void CalculateSizesOfZeroByteSizeRanges(S full_size = 0) {
|
||||
#ifdef ASSERT_RANGEMAP_ARE_SORTED
|
||||
assert(IsSorted());
|
||||
@ -907,9 +906,9 @@ template <typename B, typename S, typename T> class RangeDataVector {
|
||||
typename Collection::iterator next;
|
||||
for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos) {
|
||||
if (pos->GetByteSize() == 0) {
|
||||
// Watch out for multiple entries with same address and make sure
|
||||
// we find an entry that is greater than the current base address
|
||||
// before we use that for the size
|
||||
// Watch out for multiple entries with same address and make sure we
|
||||
// find an entry that is greater than the current base address before
|
||||
// we use that for the size
|
||||
auto curr_base = pos->GetRangeBase();
|
||||
for (next = pos + 1; next != end; ++next) {
|
||||
auto next_base = next->GetRangeBase();
|
||||
@ -1060,8 +1059,8 @@ template <typename B, typename S, typename T> class RangeDataVector {
|
||||
}
|
||||
|
||||
// This method will return the entry that contains the given address, or the
|
||||
// entry following that address. If you give it an address of 0 and the first
|
||||
// entry starts at address 0x100, you will get the entry at 0x100.
|
||||
// entry following that address. If you give it an address of 0 and the
|
||||
// first entry starts at address 0x100, you will get the entry at 0x100.
|
||||
//
|
||||
// For most uses, FindEntryThatContains is the correct one to use, this is a
|
||||
// less commonly needed behavior. It was added for core file memory regions,
|
||||
@ -1102,8 +1101,8 @@ template <typename B, typename S, typename T> class RangeDataVector {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A simple range with data class where you get to define the type of
|
||||
// the range base "B", the type used for the range byte size "S", and
|
||||
// the type for the associated data "T".
|
||||
// the range base "B", the type used for the range byte size "S", and the type
|
||||
// for the associated data "T".
|
||||
//----------------------------------------------------------------------
|
||||
template <typename B, typename T> struct AddressData {
|
||||
typedef B BaseType;
|
||||
|
@ -35,7 +35,7 @@ namespace lldb_private {
|
||||
|
||||
class RegisterValue {
|
||||
public:
|
||||
enum { kMaxRegisterByteSize = 32u };
|
||||
enum { kMaxRegisterByteSize = 64u };
|
||||
|
||||
enum Type {
|
||||
eTypeInvalid,
|
||||
@ -95,14 +95,13 @@ class RegisterValue {
|
||||
|
||||
bool GetData(DataExtractor &data) const;
|
||||
|
||||
// Copy the register value from this object into a buffer in "dst"
|
||||
// and obey the "dst_byte_order" when copying the data. Also watch out
|
||||
// in case "dst_len" is longer or shorter than the register value
|
||||
// described by "reg_info" and only copy the least significant bytes
|
||||
// of the register value, or pad the destination with zeroes if the
|
||||
// register byte size is shorter that "dst_len" (all while correctly
|
||||
// abiding the "dst_byte_order"). Returns the number of bytes copied
|
||||
// into "dst".
|
||||
// Copy the register value from this object into a buffer in "dst" and obey
|
||||
// the "dst_byte_order" when copying the data. Also watch out in case
|
||||
// "dst_len" is longer or shorter than the register value described by
|
||||
// "reg_info" and only copy the least significant bytes of the register
|
||||
// value, or pad the destination with zeroes if the register byte size is
|
||||
// shorter that "dst_len" (all while correctly abiding the "dst_byte_order").
|
||||
// Returns the number of bytes copied into "dst".
|
||||
uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
|
||||
uint32_t dst_len, lldb::ByteOrder dst_byte_order,
|
||||
Status &error) const;
|
||||
@ -249,12 +248,6 @@ class RegisterValue {
|
||||
Status SetValueFromData(const RegisterInfo *reg_info, DataExtractor &data,
|
||||
lldb::offset_t offset, bool partial_data_ok);
|
||||
|
||||
// The default value of 0 for reg_name_right_align_at means no alignment at
|
||||
// all.
|
||||
bool Dump(Stream *s, const RegisterInfo *reg_info, bool prefix_with_name,
|
||||
bool prefix_with_alt_name, lldb::Format format,
|
||||
uint32_t reg_name_right_align_at = 0) const;
|
||||
|
||||
const void *GetBytes() const;
|
||||
|
||||
lldb::ByteOrder GetByteOrder() const {
|
||||
|
@ -40,8 +40,8 @@ struct CStringEqualBinaryPredicate {
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Templated type for finding an entry in a std::map<F,S> whose value
|
||||
// is equal to something
|
||||
// Templated type for finding an entry in a std::map<F,S> whose value is equal
|
||||
// to something
|
||||
//----------------------------------------------------------------------
|
||||
template <class F, class S> class ValueEquals {
|
||||
public:
|
||||
|
@ -36,9 +36,9 @@ namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// A class designed to hold onto values and their corresponding types.
|
||||
// Operators are defined and Scalar objects will correctly promote
|
||||
// their types and values before performing these operations. Type
|
||||
// promotion currently follows the ANSI C type promotion rules.
|
||||
// Operators are defined and Scalar objects will correctly promote their types
|
||||
// and values before performing these operations. Type promotion currently
|
||||
// follows the ANSI C type promotion rules.
|
||||
//----------------------------------------------------------------------
|
||||
class Scalar {
|
||||
public:
|
||||
@ -50,13 +50,13 @@ class Scalar {
|
||||
e_ulong,
|
||||
e_slonglong,
|
||||
e_ulonglong,
|
||||
e_sint128,
|
||||
e_uint128,
|
||||
e_sint256,
|
||||
e_uint256,
|
||||
e_float,
|
||||
e_double,
|
||||
e_long_double,
|
||||
e_uint128,
|
||||
e_sint128,
|
||||
e_uint256,
|
||||
e_sint256
|
||||
e_long_double
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -165,8 +165,6 @@ class Scalar {
|
||||
|
||||
bool Promote(Scalar::Type type);
|
||||
|
||||
bool Cast(Scalar::Type type);
|
||||
|
||||
bool MakeSigned();
|
||||
|
||||
bool MakeUnsigned();
|
||||
@ -182,10 +180,10 @@ class Scalar {
|
||||
static Scalar::Type GetValueTypeForFloatWithByteSize(size_t byte_size);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// All operators can benefits from the implicit conversions that will
|
||||
// happen automagically by the compiler, so no temporary objects will
|
||||
// need to be created. As a result, we currently don't need a variety of
|
||||
// overloaded set value accessors.
|
||||
// All operators can benefits from the implicit conversions that will happen
|
||||
// automagically by the compiler, so no temporary objects will need to be
|
||||
// created. As a result, we currently don't need a variety of overloaded set
|
||||
// value accessors.
|
||||
//----------------------------------------------------------------------
|
||||
Scalar &operator=(const int i);
|
||||
Scalar &operator=(unsigned int v);
|
||||
@ -204,27 +202,27 @@ class Scalar {
|
||||
Scalar &operator&=(const Scalar &rhs);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Shifts the current value to the right without maintaining the current
|
||||
// sign of the value (if it is signed).
|
||||
// Shifts the current value to the right without maintaining the current sign
|
||||
// of the value (if it is signed).
|
||||
//----------------------------------------------------------------------
|
||||
bool ShiftRightLogical(const Scalar &rhs); // Returns true on success
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Takes the absolute value of the current value if it is signed, else
|
||||
// the value remains unchanged.
|
||||
// Returns false if the contained value has a void type.
|
||||
// Takes the absolute value of the current value if it is signed, else the
|
||||
// value remains unchanged. Returns false if the contained value has a void
|
||||
// type.
|
||||
//----------------------------------------------------------------------
|
||||
bool AbsoluteValue(); // Returns true on success
|
||||
//----------------------------------------------------------------------
|
||||
// Negates the current value (even for unsigned values).
|
||||
// Returns false if the contained value has a void type.
|
||||
// Negates the current value (even for unsigned values). Returns false if the
|
||||
// contained value has a void type.
|
||||
//----------------------------------------------------------------------
|
||||
bool UnaryNegate(); // Returns true on success
|
||||
//----------------------------------------------------------------------
|
||||
// Inverts all bits in the current value as long as it isn't void or
|
||||
// a float/double/long double type.
|
||||
// Returns false if the contained value has a void/float/double/long
|
||||
// double type, else the value is inverted and true is returned.
|
||||
// Inverts all bits in the current value as long as it isn't void or a
|
||||
// float/double/long double type. Returns false if the contained value has a
|
||||
// void/float/double/long double type, else the value is inverted and true is
|
||||
// returned.
|
||||
//----------------------------------------------------------------------
|
||||
bool OnesComplement(); // Returns true on success
|
||||
|
||||
@ -234,9 +232,9 @@ class Scalar {
|
||||
Scalar::Type GetType() const { return m_type; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Returns a casted value of the current contained data without
|
||||
// modifying the current value. FAIL_VALUE will be returned if the type
|
||||
// of the value is void or invalid.
|
||||
// Returns a casted value of the current contained data without modifying the
|
||||
// current value. FAIL_VALUE will be returned if the type of the value is
|
||||
// void or invalid.
|
||||
//----------------------------------------------------------------------
|
||||
int SInt(int fail_value = 0) const;
|
||||
|
||||
@ -344,8 +342,8 @@ class Scalar {
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Split out the operators into a format where the compiler will be able
|
||||
// to implicitly convert numbers into Scalar objects.
|
||||
// Split out the operators into a format where the compiler will be able to
|
||||
// implicitly convert numbers into Scalar objects.
|
||||
//
|
||||
// This allows code like:
|
||||
// Scalar two(2);
|
||||
|
@ -52,9 +52,9 @@ class Target;
|
||||
namespace lldb_private {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class Searcher SearchFilter.h "lldb/Core/SearchFilter.h"
|
||||
/// @brief Class that is driven by the SearchFilter to search the
|
||||
/// SymbolContext space of the target program.
|
||||
/// @class Searcher SearchFilter.h "lldb/Core/SearchFilter.h" Class that is
|
||||
/// driven by the SearchFilter to search the SymbolContext space of the target
|
||||
/// program.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -99,10 +99,10 @@ class Searcher {
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h"
|
||||
/// @brief Class descends through the SymbolContext space of the target,
|
||||
/// applying a filter at each stage till it reaches the depth specified by
|
||||
/// the GetDepth method of the searcher, and calls its callback at that point.
|
||||
/// @class SearchFilter SearchFilter.h "lldb/Core/SearchFilter.h" Class
|
||||
/// descends through the SymbolContext space of the target, applying a filter
|
||||
/// at each stage till it reaches the depth specified by the GetDepth method
|
||||
/// of the searcher, and calls its callback at that point.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -110,15 +110,12 @@ class Searcher {
|
||||
/// Provides the callback and search depth for the SearchFilter search.
|
||||
///
|
||||
/// The search is done by cooperation between the search filter and the
|
||||
/// searcher.
|
||||
/// The search filter does the heavy work of recursing through the SymbolContext
|
||||
/// space of the target program's symbol space. The Searcher specifies the
|
||||
/// depth
|
||||
/// at which it wants its callback to be invoked. Note that since the
|
||||
/// resolution
|
||||
/// of the Searcher may be greater than that of the SearchFilter, before the
|
||||
/// Searcher qualifies an address it should pass it to "AddressPasses."
|
||||
/// The default implementation is "Everything Passes."
|
||||
/// searcher. The search filter does the heavy work of recursing through the
|
||||
/// SymbolContext space of the target program's symbol space. The Searcher
|
||||
/// specifies the depth at which it wants its callback to be invoked. Note
|
||||
/// that since the resolution of the Searcher may be greater than that of the
|
||||
/// SearchFilter, before the Searcher qualifies an address it should pass it
|
||||
/// to "AddressPasses." The default implementation is "Everything Passes."
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class SearchFilter {
|
||||
@ -172,8 +169,8 @@ class SearchFilter {
|
||||
virtual bool AddressPasses(Address &addr);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Call this method with a FileSpec to see if \a file spec passes the filter
|
||||
/// as the name of a compilation unit.
|
||||
/// Call this method with a FileSpec to see if \a file spec passes the
|
||||
/// filter as the name of a compilation unit.
|
||||
///
|
||||
/// @param[in] fileSpec
|
||||
/// The file spec to check against the filter.
|
||||
@ -218,11 +215,10 @@ class SearchFilter {
|
||||
virtual void SearchInModuleList(Searcher &searcher, ModuleList &modules);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This determines which items are REQUIRED for the filter to pass.
|
||||
/// For instance, if you are filtering by Compilation Unit, obviously
|
||||
/// symbols that have no compilation unit can't pass So return
|
||||
/// eSymbolContextCU
|
||||
/// and search callbacks can then short cut the search to avoid looking at
|
||||
/// This determines which items are REQUIRED for the filter to pass. For
|
||||
/// instance, if you are filtering by Compilation Unit, obviously symbols
|
||||
/// that have no compilation unit can't pass So return eSymbolContextCU and
|
||||
/// search callbacks can then short cut the search to avoid looking at
|
||||
/// things that obviously won't pass.
|
||||
///
|
||||
/// @return
|
||||
@ -303,8 +299,7 @@ class SearchFilter {
|
||||
OptionNames name, FileSpecList &file_list);
|
||||
|
||||
// These are utility functions to assist with the search iteration. They are
|
||||
// used by the
|
||||
// default Search method.
|
||||
// used by the default Search method.
|
||||
|
||||
Searcher::CallbackReturn DoModuleIteration(const SymbolContext &context,
|
||||
Searcher &searcher);
|
||||
@ -333,9 +328,9 @@ class SearchFilter {
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class SearchFilterForUnconstrainedSearches SearchFilter.h
|
||||
/// "lldb/Core/SearchFilter.h"
|
||||
/// @brief This is a SearchFilter that searches through all modules. It also
|
||||
/// consults the Target::ModuleIsExcludedForUnconstrainedSearches.
|
||||
/// "lldb/Core/SearchFilter.h" This is a SearchFilter that searches through
|
||||
/// all modules. It also consults the
|
||||
/// Target::ModuleIsExcludedForUnconstrainedSearches.
|
||||
//----------------------------------------------------------------------
|
||||
class SearchFilterForUnconstrainedSearches : public SearchFilter {
|
||||
public:
|
||||
@ -360,8 +355,8 @@ class SearchFilterForUnconstrainedSearches : public SearchFilter {
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// @class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h"
|
||||
/// @brief This is a SearchFilter that restricts the search to a given module.
|
||||
/// @class SearchFilterByModule SearchFilter.h "lldb/Core/SearchFilter.h" This
|
||||
/// is a SearchFilter that restricts the search to a given module.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class SearchFilterByModule : public SearchFilter {
|
||||
|
@ -182,6 +182,8 @@ class Section : public std::enable_shared_from_this<Section>,
|
||||
|
||||
lldb::SectionType GetType() const { return m_type; }
|
||||
|
||||
const char *GetTypeAsCString() const;
|
||||
|
||||
lldb::SectionSP GetParent() const { return m_parent_wp.lock(); }
|
||||
|
||||
bool IsThreadSpecific() const { return m_thread_specific; }
|
||||
@ -270,10 +272,9 @@ class Section : public std::enable_shared_from_this<Section>,
|
||||
SectionList m_children; // Child sections
|
||||
bool m_fake : 1, // If true, then this section only can contain the address if
|
||||
// one of its
|
||||
// children contains an address. This allows for gaps between the children
|
||||
// that are contained in the address range for this section, but do not
|
||||
// produce
|
||||
// hits unless the children contain the address.
|
||||
// children contains an address. This allows for gaps between the
|
||||
// children that are contained in the address range for this section, but
|
||||
// do not produce hits unless the children contain the address.
|
||||
m_encrypted : 1, // Set to true if the contents are encrypted
|
||||
m_thread_specific : 1, // This section is thread specific
|
||||
m_readable : 1, // If this section has read permissions
|
||||
|
@ -106,9 +106,8 @@ class SourceManager {
|
||||
|
||||
#ifndef SWIG
|
||||
// The SourceFileCache class separates the source manager from the cache of
|
||||
// source files, so the
|
||||
// cache can be stored in the Debugger, but the source managers can be per
|
||||
// target.
|
||||
// source files, so the cache can be stored in the Debugger, but the source
|
||||
// managers can be per target.
|
||||
class SourceFileCache {
|
||||
public:
|
||||
SourceFileCache() = default;
|
||||
|
@ -39,9 +39,8 @@ template <unsigned N> class StreamBuffer : public Stream {
|
||||
void Clear() { m_packet.clear(); }
|
||||
|
||||
// Beware, this might not be NULL terminated as you can expect from
|
||||
// StringString as there may be random bits in the llvm::SmallVector. If
|
||||
// you are using this class to create a C string, be sure the call PutChar
|
||||
// ('\0')
|
||||
// StringString as there may be random bits in the llvm::SmallVector. If you
|
||||
// are using this class to create a C string, be sure the call PutChar ('\0')
|
||||
// after you have created your string, or use StreamString.
|
||||
const char *GetData() const { return m_packet.data(); }
|
||||
|
||||
|
@ -46,7 +46,7 @@ class ThreadSafeDenseSet {
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
stds::lock_guard<_MutexType> guard(m_mutex);
|
||||
std::lock_guard<_MutexType> guard(m_mutex);
|
||||
m_set.clear();
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-defines.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
|
@ -25,11 +25,10 @@ namespace lldb_private {
|
||||
//----------------------------------------------------------------------
|
||||
// Templatized uniqued string map.
|
||||
//
|
||||
// This map is useful for mapping unique C string names to values of
|
||||
// type T. Each "const char *" name added must be unique for a given
|
||||
// This map is useful for mapping unique C string names to values of type T.
|
||||
// Each "const char *" name added must be unique for a given
|
||||
// C string value. ConstString::GetCString() can provide such strings.
|
||||
// Any other string table that has guaranteed unique values can also
|
||||
// be used.
|
||||
// Any other string table that has guaranteed unique values can also be used.
|
||||
//----------------------------------------------------------------------
|
||||
template <typename T> class UniqueCStringMap {
|
||||
public:
|
||||
@ -51,9 +50,9 @@ template <typename T> class UniqueCStringMap {
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Call this function multiple times to add a bunch of entries to
|
||||
// this map, then later call UniqueCStringMap<T>::Sort() before doing
|
||||
// any searches by name.
|
||||
// Call this function multiple times to add a bunch of entries to this map,
|
||||
// then later call UniqueCStringMap<T>::Sort() before doing any searches by
|
||||
// name.
|
||||
//------------------------------------------------------------------
|
||||
void Append(ConstString unique_cstr, const T &value) {
|
||||
m_map.push_back(typename UniqueCStringMap<T>::Entry(unique_cstr, value));
|
||||
@ -64,8 +63,8 @@ template <typename T> class UniqueCStringMap {
|
||||
void Clear() { m_map.clear(); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Call this function to always keep the map sorted when putting
|
||||
// entries into the map.
|
||||
// Call this function to always keep the map sorted when putting entries into
|
||||
// the map.
|
||||
//------------------------------------------------------------------
|
||||
void Insert(ConstString unique_cstr, const T &value) {
|
||||
typename UniqueCStringMap<T>::Entry e(unique_cstr, value);
|
||||
@ -79,8 +78,8 @@ template <typename T> class UniqueCStringMap {
|
||||
//------------------------------------------------------------------
|
||||
// Get an entries by index in a variety of forms.
|
||||
//
|
||||
// The caller is responsible for ensuring that the collection does
|
||||
// not change during while using the returned values.
|
||||
// The caller is responsible for ensuring that the collection does not change
|
||||
// during while using the returned values.
|
||||
//------------------------------------------------------------------
|
||||
bool GetValueAtIndex(uint32_t idx, T &value) const {
|
||||
if (idx < m_map.size()) {
|
||||
@ -94,12 +93,12 @@ template <typename T> class UniqueCStringMap {
|
||||
return m_map[idx].cstring;
|
||||
}
|
||||
|
||||
// Use this function if you have simple types in your map that you
|
||||
// can easily copy when accessing values by index.
|
||||
// Use this function if you have simple types in your map that you can easily
|
||||
// copy when accessing values by index.
|
||||
T GetValueAtIndexUnchecked(uint32_t idx) const { return m_map[idx].value; }
|
||||
|
||||
// Use this function if you have complex types in your map that you
|
||||
// don't want to copy when accessing values by index.
|
||||
// Use this function if you have complex types in your map that you don't
|
||||
// want to copy when accessing values by index.
|
||||
const T &GetValueRefAtIndexUnchecked(uint32_t idx) const {
|
||||
return m_map[idx].value;
|
||||
}
|
||||
@ -111,8 +110,8 @@ template <typename T> class UniqueCStringMap {
|
||||
//------------------------------------------------------------------
|
||||
// Find the value for the unique string in the map.
|
||||
//
|
||||
// Return the value for \a unique_cstr if one is found, return
|
||||
// \a fail_value otherwise. This method works well for simple type
|
||||
// Return the value for \a unique_cstr if one is found, return \a fail_value
|
||||
// otherwise. This method works well for simple type
|
||||
// T values and only if there is a sensible failure value that can
|
||||
// be returned and that won't match any existing values.
|
||||
//------------------------------------------------------------------
|
||||
@ -128,11 +127,11 @@ template <typename T> class UniqueCStringMap {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Get a pointer to the first entry that matches "name". nullptr will
|
||||
// be returned if there is no entry that matches "name".
|
||||
// Get a pointer to the first entry that matches "name". nullptr will be
|
||||
// returned if there is no entry that matches "name".
|
||||
//
|
||||
// The caller is responsible for ensuring that the collection does
|
||||
// not change during while using the returned pointer.
|
||||
// The caller is responsible for ensuring that the collection does not change
|
||||
// during while using the returned pointer.
|
||||
//------------------------------------------------------------------
|
||||
const Entry *FindFirstValueForName(ConstString unique_cstr) const {
|
||||
Entry search_entry(unique_cstr);
|
||||
@ -144,12 +143,12 @@ template <typename T> class UniqueCStringMap {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Get a pointer to the next entry that matches "name" from a
|
||||
// previously returned Entry pointer. nullptr will be returned if there
|
||||
// is no subsequent entry that matches "name".
|
||||
// Get a pointer to the next entry that matches "name" from a previously
|
||||
// returned Entry pointer. nullptr will be returned if there is no subsequent
|
||||
// entry that matches "name".
|
||||
//
|
||||
// The caller is responsible for ensuring that the collection does
|
||||
// not change during while using the returned pointer.
|
||||
// The caller is responsible for ensuring that the collection does not change
|
||||
// during while using the returned pointer.
|
||||
//------------------------------------------------------------------
|
||||
const Entry *FindNextValueForName(const Entry *entry_ptr) const {
|
||||
if (!m_map.empty()) {
|
||||
@ -204,16 +203,15 @@ template <typename T> class UniqueCStringMap {
|
||||
bool IsEmpty() const { return m_map.empty(); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Reserve memory for at least "n" entries in the map. This is
|
||||
// useful to call when you know you will be adding a lot of entries
|
||||
// using UniqueCStringMap::Append() (which should be followed by a
|
||||
// call to UniqueCStringMap::Sort()) or to UniqueCStringMap::Insert().
|
||||
// Reserve memory for at least "n" entries in the map. This is useful to call
|
||||
// when you know you will be adding a lot of entries using
|
||||
// UniqueCStringMap::Append() (which should be followed by a call to
|
||||
// UniqueCStringMap::Sort()) or to UniqueCStringMap::Insert().
|
||||
//------------------------------------------------------------------
|
||||
void Reserve(size_t n) { m_map.reserve(n); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Sort the unsorted contents in this map. A typical code flow would
|
||||
// be:
|
||||
// Sort the unsorted contents in this map. A typical code flow would be:
|
||||
// size_t approximate_num_entries = ....
|
||||
// UniqueCStringMap<uint32_t> my_map;
|
||||
// my_map.Reserve (approximate_num_entries);
|
||||
@ -226,12 +224,11 @@ template <typename T> class UniqueCStringMap {
|
||||
void Sort() { std::sort(m_map.begin(), m_map.end()); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Since we are using a vector to contain our items it will always
|
||||
// double its memory consumption as things are added to the vector,
|
||||
// so if you intend to keep a UniqueCStringMap around and have
|
||||
// a lot of entries in the map, you will want to call this function
|
||||
// to create a new vector and copy _only_ the exact size needed as
|
||||
// part of the finalization of the string map.
|
||||
// Since we are using a vector to contain our items it will always double its
|
||||
// memory consumption as things are added to the vector, so if you intend to
|
||||
// keep a UniqueCStringMap around and have a lot of entries in the map, you
|
||||
// will want to call this function to create a new vector and copy _only_ the
|
||||
// exact size needed as part of the finalization of the string map.
|
||||
//------------------------------------------------------------------
|
||||
void SizeToFit() {
|
||||
if (m_map.size() < m_map.capacity()) {
|
||||
|
@ -49,8 +49,8 @@ class Properties {
|
||||
virtual ~Properties() {}
|
||||
|
||||
virtual lldb::OptionValuePropertiesSP GetValueProperties() const {
|
||||
// This function is virtual in case subclasses want to lazily
|
||||
// implement creating the properties.
|
||||
// This function is virtual in case subclasses want to lazily implement
|
||||
// creating the properties.
|
||||
return m_collection_sp;
|
||||
}
|
||||
|
||||
@ -82,16 +82,11 @@ class Properties {
|
||||
|
||||
// We sometimes need to introduce a setting to enable experimental features,
|
||||
// but then we don't want the setting for these to cause errors when the
|
||||
// setting
|
||||
// goes away. Add a sub-topic of the settings using this experimental name,
|
||||
// and
|
||||
// two things will happen. One is that settings that don't find the name will
|
||||
// not
|
||||
// be treated as errors. Also, if you decide to keep the settings just move
|
||||
// them into
|
||||
// the containing properties, and we will auto-forward the experimental
|
||||
// settings to the
|
||||
// real one.
|
||||
// setting goes away. Add a sub-topic of the settings using this
|
||||
// experimental name, and two things will happen. One is that settings that
|
||||
// don't find the name will not be treated as errors. Also, if you decide to
|
||||
// keep the settings just move them into the containing properties, and we
|
||||
// will auto-forward the experimental settings to the real one.
|
||||
static const char *GetExperimentalSettingsName();
|
||||
|
||||
static bool IsSettingExperimental(llvm::StringRef setting);
|
||||
|
@ -48,8 +48,8 @@ namespace lldb_private {
|
||||
|
||||
class Value {
|
||||
public:
|
||||
// Values Less than zero are an error, greater than or equal to zero
|
||||
// returns what the Scalar result is.
|
||||
// Values Less than zero are an error, greater than or equal to zero returns
|
||||
// what the Scalar result is.
|
||||
enum ValueType {
|
||||
// m_value contains...
|
||||
// ============================
|
||||
@ -107,8 +107,7 @@ class Value {
|
||||
byte_order != lldb::eByteOrderInvalid);
|
||||
}
|
||||
// Casts a vector, if valid, to an unsigned int of matching or largest
|
||||
// supported size.
|
||||
// Truncates to the beginning of the vector if required.
|
||||
// supported size. Truncates to the beginning of the vector if required.
|
||||
// Returns a default constructed Scalar if the Vector data is internally
|
||||
// inconsistent.
|
||||
llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
|
||||
@ -229,6 +228,9 @@ class Value {
|
||||
|
||||
static const char *GetContextTypeAsCString(ContextType context_type);
|
||||
|
||||
/// Convert this value's file address to a load address, if possible.
|
||||
void ConvertToLoadAddress(Module *module, Target *target);
|
||||
|
||||
bool GetData(DataExtractor &data);
|
||||
|
||||
void Clear();
|
||||
|
@ -11,7 +11,6 @@
|
||||
#define liblldb_ValueObject_h_
|
||||
|
||||
#include "lldb/Core/Value.h"
|
||||
#include "lldb/DataFormatters/DumpValueObjectOptions.h" // for DumpValueObj...
|
||||
#include "lldb/Symbol/CompilerType.h"
|
||||
#include "lldb/Symbol/Type.h" // for TypeImpl
|
||||
#include "lldb/Target/ExecutionContext.h"
|
||||
@ -45,6 +44,9 @@ namespace lldb_private {
|
||||
class Declaration;
|
||||
}
|
||||
namespace lldb_private {
|
||||
class DumpValueObjectOptions;
|
||||
}
|
||||
namespace lldb_private {
|
||||
class EvaluateExpressionOptions;
|
||||
}
|
||||
namespace lldb_private {
|
||||
@ -286,10 +288,10 @@ class ValueObject : public UserID {
|
||||
return m_exe_ctx_ref;
|
||||
}
|
||||
|
||||
// Set the EvaluationPoint to the values in exe_scope,
|
||||
// Return true if the Evaluation Point changed.
|
||||
// Since the ExecutionContextScope is always going to be valid currently,
|
||||
// the Updated Context will also always be valid.
|
||||
// Set the EvaluationPoint to the values in exe_scope, Return true if the
|
||||
// Evaluation Point changed. Since the ExecutionContextScope is always
|
||||
// going to be valid currently, the Updated Context will also always be
|
||||
// valid.
|
||||
|
||||
// bool
|
||||
// SetContext (ExecutionContextScope *exe_scope);
|
||||
@ -327,8 +329,7 @@ class ValueObject : public UserID {
|
||||
|
||||
void SetInvalid() {
|
||||
// Use the stop id to mark us as invalid, leave the thread id and the
|
||||
// stack id around for logging and
|
||||
// history purposes.
|
||||
// stack id around for logging and history purposes.
|
||||
m_mod_id.SetInvalid();
|
||||
|
||||
// Can't update an invalid state.
|
||||
@ -464,17 +465,16 @@ class ValueObject : public UserID {
|
||||
|
||||
virtual bool SetValueFromCString(const char *value_str, Status &error);
|
||||
|
||||
// Return the module associated with this value object in case the
|
||||
// value is from an executable file and might have its data in
|
||||
// sections of the file. This can be used for variables.
|
||||
// Return the module associated with this value object in case the value is
|
||||
// from an executable file and might have its data in sections of the file.
|
||||
// This can be used for variables.
|
||||
virtual lldb::ModuleSP GetModule();
|
||||
|
||||
ValueObject *GetRoot();
|
||||
|
||||
// Given a ValueObject, loop over itself and its parent, and its parent's
|
||||
// parent, ..
|
||||
// until either the given callback returns false, or you end up at a null
|
||||
// pointer
|
||||
// parent, .. until either the given callback returns false, or you end up at
|
||||
// a null pointer
|
||||
ValueObject *FollowParentChain(std::function<bool(ValueObject *)>);
|
||||
|
||||
virtual bool GetDeclaration(Declaration &decl);
|
||||
@ -517,9 +517,9 @@ class ValueObject : public UserID {
|
||||
|
||||
virtual bool ResolveValue(Scalar &scalar);
|
||||
|
||||
// return 'false' whenever you set the error, otherwise
|
||||
// callers may assume true means everything is OK - this will
|
||||
// break breakpoint conditions among potentially a few others
|
||||
// return 'false' whenever you set the error, otherwise callers may assume
|
||||
// true means everything is OK - this will break breakpoint conditions among
|
||||
// potentially a few others
|
||||
virtual bool IsLogicalTrue(Status &error);
|
||||
|
||||
virtual const char *GetLocationAsCString();
|
||||
@ -646,8 +646,8 @@ class ValueObject : public UserID {
|
||||
virtual lldb::ValueObjectSP CastPointerType(const char *name,
|
||||
lldb::TypeSP &type_sp);
|
||||
|
||||
// The backing bits of this value object were updated, clear any
|
||||
// descriptive string, so we know we have to refetch them
|
||||
// The backing bits of this value object were updated, clear any descriptive
|
||||
// string, so we know we have to refetch them
|
||||
virtual void ValueUpdated() {
|
||||
ClearUserVisibleData(eClearUserVisibleDataItemsValue |
|
||||
eClearUserVisibleDataItemsSummary |
|
||||
@ -694,9 +694,8 @@ class ValueObject : public UserID {
|
||||
|
||||
lldb::ValueObjectSP Persist();
|
||||
|
||||
// returns true if this is a char* or a char[]
|
||||
// if it is a char* and check_pointer is true,
|
||||
// it also checks that the pointer is valid
|
||||
// returns true if this is a char* or a char[] if it is a char* and
|
||||
// check_pointer is true, it also checks that the pointer is valid
|
||||
bool IsCStringContainer(bool check_pointer = false);
|
||||
|
||||
std::pair<size_t, bool>
|
||||
@ -776,11 +775,9 @@ class ValueObject : public UserID {
|
||||
}
|
||||
|
||||
// Use GetParent for display purposes, but if you want to tell the parent to
|
||||
// update itself
|
||||
// then use m_parent. The ValueObjectDynamicValue's parent is not the correct
|
||||
// parent for
|
||||
// displaying, they are really siblings, so for display it needs to route
|
||||
// through to its grandparent.
|
||||
// update itself then use m_parent. The ValueObjectDynamicValue's parent is
|
||||
// not the correct parent for displaying, they are really siblings, so for
|
||||
// display it needs to route through to its grandparent.
|
||||
virtual ValueObject *GetParent() { return m_parent; }
|
||||
|
||||
virtual const ValueObject *GetParent() const { return m_parent; }
|
||||
@ -904,9 +901,9 @@ class ValueObject : public UserID {
|
||||
ValueObjectManager *m_manager; // This object is managed by the root object
|
||||
// (any ValueObject that gets created
|
||||
// without a parent.) The manager gets passed through all the generations of
|
||||
// dependent objects, and will keep the whole cluster of objects alive as long
|
||||
// as a shared pointer to any of them has been handed out. Shared pointers to
|
||||
// value objects must always be made with the GetSP method.
|
||||
// dependent objects, and will keep the whole cluster of objects alive as
|
||||
// long as a shared pointer to any of them has been handed out. Shared
|
||||
// pointers to value objects must always be made with the GetSP method.
|
||||
|
||||
ChildrenManager m_children;
|
||||
std::map<ConstString, ValueObject *> m_synthetic_children;
|
||||
@ -954,21 +951,19 @@ class ValueObject : public UserID {
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Use the no-argument constructor to make a constant variable object (with no
|
||||
// ExecutionContextScope.)
|
||||
// Use the no-argument constructor to make a constant variable object (with
|
||||
// no ExecutionContextScope.)
|
||||
|
||||
ValueObject();
|
||||
|
||||
// Use this constructor to create a "root variable object". The ValueObject
|
||||
// will be locked to this context
|
||||
// through-out its lifespan.
|
||||
// will be locked to this context through-out its lifespan.
|
||||
|
||||
ValueObject(ExecutionContextScope *exe_scope,
|
||||
AddressType child_ptr_or_ref_addr_type = eAddressTypeLoad);
|
||||
|
||||
// Use this constructor to create a ValueObject owned by another ValueObject.
|
||||
// It will inherit the ExecutionContext
|
||||
// of its parent.
|
||||
// It will inherit the ExecutionContext of its parent.
|
||||
|
||||
ValueObject(ValueObject &parent);
|
||||
|
||||
@ -990,8 +985,8 @@ class ValueObject : public UserID {
|
||||
|
||||
virtual void CalculateSyntheticValue(bool use_synthetic = true);
|
||||
|
||||
// Should only be called by ValueObject::GetChildAtIndex()
|
||||
// Returns a ValueObject managed by this ValueObject's manager.
|
||||
// Should only be called by ValueObject::GetChildAtIndex() Returns a
|
||||
// ValueObject managed by this ValueObject's manager.
|
||||
virtual ValueObject *CreateChildAtIndex(size_t idx,
|
||||
bool synthetic_array_member,
|
||||
int32_t synthetic_index);
|
||||
@ -1043,8 +1038,9 @@ class ValueObject : public UserID {
|
||||
//------------------------------------------------------------------------------
|
||||
// A value object manager class that is seeded with the static variable value
|
||||
// and it vends the user facing value object. If the type is dynamic it can
|
||||
// vend the dynamic type. If this user type also has a synthetic type associated
|
||||
// with it, it will vend the synthetic type. The class watches the process' stop
|
||||
// vend the dynamic type. If this user type also has a synthetic type
|
||||
// associated with it, it will vend the synthetic type. The class watches the
|
||||
// process' stop
|
||||
// ID and will update the user type when needed.
|
||||
//------------------------------------------------------------------------------
|
||||
class ValueObjectManager {
|
||||
|
@ -39,9 +39,9 @@ namespace lldb_private {
|
||||
//----------------------------------------------------------------------
|
||||
// A ValueObject that obtains its children from some source other than
|
||||
// real information
|
||||
// This is currently used to implement Python-based children and filters
|
||||
// but you can bind it to any source of synthetic information and have
|
||||
// it behave accordingly
|
||||
// This is currently used to implement Python-based children and filters but
|
||||
// you can bind it to any source of synthetic information and have it behave
|
||||
// accordingly
|
||||
//----------------------------------------------------------------------
|
||||
class ValueObjectSynthetic : public ValueObject {
|
||||
public:
|
||||
|
@ -21,15 +21,14 @@
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
// this class is the high-level front-end of LLDB Data Visualization
|
||||
// code in FormatManager.h/cpp is the low-level implementation of this feature
|
||||
// clients should refer to this class as the entry-point into the data
|
||||
// formatters
|
||||
// this class is the high-level front-end of LLDB Data Visualization code in
|
||||
// FormatManager.h/cpp is the low-level implementation of this feature clients
|
||||
// should refer to this class as the entry-point into the data formatters
|
||||
// unless they have a good reason to bypass this and go to the backend
|
||||
class DataVisualization {
|
||||
public:
|
||||
// use this call to force the FM to consider itself updated even when there is
|
||||
// no apparent reason for that
|
||||
// use this call to force the FM to consider itself updated even when there
|
||||
// is no apparent reason for that
|
||||
static void ForceUpdate();
|
||||
|
||||
static uint32_t GetCurrentRevision();
|
||||
|
@ -160,8 +160,8 @@ class TypeNameSpecifierImpl {
|
||||
|
||||
private:
|
||||
bool m_is_regex;
|
||||
// this works better than TypeAndOrName because the latter only wraps a TypeSP
|
||||
// whereas TypePair can also be backed by a CompilerType
|
||||
// this works better than TypeAndOrName because the latter only wraps a
|
||||
// TypeSP whereas TypePair can also be backed by a CompilerType
|
||||
struct TypeOrName {
|
||||
std::string m_type_name;
|
||||
TypePair m_type_pair;
|
||||
|
@ -33,12 +33,10 @@
|
||||
namespace lldb_private {
|
||||
|
||||
// this file (and its. cpp) contain the low-level implementation of LLDB Data
|
||||
// Visualization
|
||||
// class DataVisualization is the high-level front-end of this feature
|
||||
// clients should refer to that class as the entry-point into the data
|
||||
// formatters
|
||||
// unless they have a good reason to bypass it and prefer to use this file's
|
||||
// objects directly
|
||||
// Visualization class DataVisualization is the high-level front-end of this
|
||||
// feature clients should refer to that class as the entry-point into the data
|
||||
// formatters unless they have a good reason to bypass it and prefer to use
|
||||
// this file's objects directly
|
||||
|
||||
class FormatManager : public IFormatChangeListener {
|
||||
typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap;
|
||||
@ -175,24 +173,22 @@ class FormatManager : public IFormatChangeListener {
|
||||
|
||||
static const char *GetFormatAsCString(lldb::Format format);
|
||||
|
||||
// if the user tries to add formatters for, say, "struct Foo"
|
||||
// those will not match any type because of the way we strip qualifiers from
|
||||
// typenames
|
||||
// this method looks for the case where the user is adding a
|
||||
// "class","struct","enum" or "union" Foo
|
||||
// and strips the unnecessary qualifier
|
||||
// if the user tries to add formatters for, say, "struct Foo" those will not
|
||||
// match any type because of the way we strip qualifiers from typenames this
|
||||
// method looks for the case where the user is adding a
|
||||
// "class","struct","enum" or "union" Foo and strips the unnecessary
|
||||
// qualifier
|
||||
static ConstString GetValidTypeName(const ConstString &type);
|
||||
|
||||
// when DataExtractor dumps a vectorOfT, it uses a predefined format for each
|
||||
// item
|
||||
// this method returns it, or eFormatInvalid if vector_format is not a
|
||||
// item this method returns it, or eFormatInvalid if vector_format is not a
|
||||
// vectorOf
|
||||
static lldb::Format GetSingleItemFormat(lldb::Format vector_format);
|
||||
|
||||
// this returns true if the ValueObjectPrinter is *highly encouraged*
|
||||
// to actually represent this ValueObject in one-liner format
|
||||
// If this object has a summary formatter, however, we should not
|
||||
// try and do one-lining, just let the summary do the right thing
|
||||
// this returns true if the ValueObjectPrinter is *highly encouraged* to
|
||||
// actually represent this ValueObject in one-liner format If this object has
|
||||
// a summary formatter, however, we should not try and do one-lining, just
|
||||
// let the summary do the right thing
|
||||
bool ShouldPrintAsOneLiner(ValueObject &valobj);
|
||||
|
||||
void Changed() override;
|
||||
@ -249,15 +245,12 @@ class FormatManager : public IFormatChangeListener {
|
||||
|
||||
TypeCategoryMap &GetCategories() { return m_categories_map; }
|
||||
|
||||
// These functions are meant to initialize formatters that are very
|
||||
// low-level/global in nature
|
||||
// and do not naturally belong in any language. The intent is that most
|
||||
// formatters go in
|
||||
// language-specific categories. Eventually, the runtimes should also be
|
||||
// allowed to vend their
|
||||
// own formatters, and then one could put formatters that depend on specific
|
||||
// library load events
|
||||
// in the language runtimes, on an as-needed basis
|
||||
// These functions are meant to initialize formatters that are very low-
|
||||
// level/global in nature and do not naturally belong in any language. The
|
||||
// intent is that most formatters go in language-specific categories.
|
||||
// Eventually, the runtimes should also be allowed to vend their own
|
||||
// formatters, and then one could put formatters that depend on specific
|
||||
// library load events in the language runtimes, on an as-needed basis
|
||||
void LoadSystemFormatters();
|
||||
|
||||
void LoadVectorFormatters();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user