llvm-toolchain/debian/patches/58-lldb-snapshot.diff
2013-03-03 08:47:03 +00:00

104093 lines
4.2 MiB

Index: aze/lldb/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/CMakeLists.txt 2013-03-03 09:35:50.043457357 +0100
@@ -0,0 +1,187 @@
+# If we are not building as a part of LLVM, build LLDB as an
+# standalone project, using LLVM as an external library:
+if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+ project(lldb)
+ cmake_minimum_required(VERSION 2.8)
+
+ set(LLDB_PATH_TO_LLVM_SOURCE "" CACHE PATH
+ "Path to LLVM source code. Not necessary if using an installed LLVM.")
+ set(LLDB_PATH_TO_LLVM_BUILD "" CACHE PATH
+ "Path to the directory where LLVM was built or installed.")
+
+ set(LLDB_PATH_TO_CLANG_SOURCE "" CACHE PATH
+ "Path to Clang source code. Not necessary if using an installed Clang.")
+ set(LLDB_PATH_TO_CLANG_BUILD "" CACHE PATH
+ "Path to the directory where Clang was built or installed.")
+
+ set(LLDB_DISABLE_PYTHON 1 BOOL "Disables the Python scripting integration.")
+
+ if (LLDB_PATH_TO_LLVM_SOURCE)
+ if (NOT EXISTS "${LLDB_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake")
+ message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_SOURCE to the root "
+ "directory of LLVM source code.")
+ else()
+ get_filename_component(LLVM_MAIN_SRC_DIR ${LLDB_PATH_TO_LLVM_SOURCE}
+ ABSOLUTE)
+ list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules")
+ endif()
+ endif()
+
+ if (LLDB_PATH_TO_CLANG_SOURCE)
+ get_filename_component(CLANG_MAIN_SRC_DIR ${LLDB_PATH_TO_CLANG_SOURCE}
+ ABSOLUTE)
+ endif()
+
+ list(APPEND CMAKE_MODULE_PATH "${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake")
+
+ get_filename_component(PATH_TO_LLVM_BUILD ${LLDB_PATH_TO_LLVM_BUILD}
+ ABSOLUTE)
+
+ get_filename_component(PATH_TO_CLANG_BUILD ${LLDB_PATH_TO_CLANG_BUILD}
+ ABSOLUTE)
+
+ include(AddLLVM)
+ include("${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake")
+ include(HandleLLVMOptions)
+
+ set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
+
+ set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include")
+ set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR})
+
+ set(CLANG_MAIN_INCLUDE_DIR "${CLANG_MAIN_SRC_DIR}/include")
+
+ set(CMAKE_INCLUDE_CURRENT_DIR ON)
+ include_directories("${PATH_TO_LLVM_BUILD}/include"
+ "${LLVM_MAIN_INCLUDE_DIR}"
+ "${PATH_TO_CLANG_BUILD}/include"
+ "${CLANG_MAIN_INCLUDE_DIR}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/source")
+ link_directories("${PATH_TO_LLVM_BUILD}/lib"
+ "${PATH_TO_CLANG_BUILD}/lib")
+
+ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+
+ set(LLDB_BUILT_STANDALONE 1)
+
+ if (LLDB_DISABLE_PYTHON)
+ add_definitions( -DLLDB_DISABLE_PYTHON )
+ endif()
+endif()
+
+macro(add_lldb_definitions)
+ # We don't want no semicolons on LLDB_DEFINITIONS:
+ foreach(arg ${ARGN})
+ set(LLDB_DEFINITIONS "${LLVM_DEFINITIONS} ${arg}")
+ endforeach(arg)
+ add_definitions( ${ARGN} )
+endmacro(add_lldb_definitions)
+
+include_directories(/usr/include/python2.7)
+include_directories(../clang/include)
+include_directories("${CMAKE_CURRENT_BINARY_DIR}/../clang/include")
+set(CMAKE_CXX_FLAGS "-std=c++11")
+
+# Disable MSVC warnings
+if( MSVC )
+ add_lldb_definitions(
+ -wd4018 # Suppress 'warning C4018: '>=' : signed/unsigned mismatch'
+ -wd4068 # Suppress 'warning C4068: unknown pragma'
+ -wd4150 # Suppress 'warning C4150: deletion of pointer to incomplete type'
+ -wd4521 # Suppress 'warning C4521: 'type' : multiple copy constructors specified'
+ )
+endif()
+
+set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+ message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite "
+"the makefiles distributed with LLDB. Please create a directory and run cmake "
+"from there, passing the path to this source directory as the last argument. "
+"This process created the file `CMakeCache.txt' and the directory "
+"`CMakeFiles'. Please delete them.")
+endif()
+
+macro(add_lldb_library name)
+ llvm_process_sources(srcs ${ARGN})
+ if (MSVC_IDE OR XCODE)
+ string(REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})
+ list(GET split_path -1 dir)
+ file(GLOB_RECURSE headers
+ ../../include/lldb${dir}/*.h)
+ set(srcs ${srcs} ${headers})
+ endif()
+ if (MODULE)
+ set(libkind MODULE)
+ elseif (SHARED_LIBRARY)
+ set(libkind SHARED)
+ else()
+ set(libkind STATIC)
+ endif()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
+ add_library(${name} ${libkind} ${srcs})
+ #if (LLVM_COMMON_DEPENDS)
+ ##add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
+ #endif()
+
+ if(LLDB_USED_LIBS)
+ target_link_libraries(${name} -Wl,--start-group ${LLDB_USED_LIBS} -Wl,--end-group)
+ endif()
+ target_link_libraries(${name} ${CLANG_USED_LIBS})
+ target_link_libraries(${name} ${LLVM_USED_LIBS})
+ llvm_config(${name} ${LLVM_LINK_COMPONENTS})
+ target_link_libraries(${name} ${LLVM_COMMON_LIBS})
+ link_system_libs(${name})
+ if (LLVM_COMMON_DEPENDS)
+ add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
+ endif()
+
+ # Hack: only some LLDB libraries depend on the clang autogenerated headers,
+ # but it is simple enough to make all of LLDB depend on some of those
+ # headers without negatively impacting much of anything.
+ set (LLDB_DEPENDENCIES
+ ClangDiagnosticCommon
+ #ClangDiagnosticFrontend
+ #libclang.so
+ )
+ add_dependencies(${name} ${LLDB_DEPENDENCIES})
+
+ install(TARGETS ${name}
+ LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+ ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX})
+ set_target_properties(${name} PROPERTIES FOLDER "lldb libraries")
+endmacro(add_lldb_library)
+
+macro(add_lldb_executable name)
+ #add_llvm_executable(${name} ${ARGN})
+ llvm_process_sources( ALL_FILES ${ARGN} )
+ add_executable(${name} ${ALL_FILES})
+ #target_link_libraries(${name} ${CLANG_USED_LIBS})
+ #llvm_config( ${name} ${LLVM_LINK_COMPONENTS} )
+ #link_system_libs( ${name} )
+ #if (LLVM_COMMON_DEPENDS)
+ #add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
+ #endif()
+ set_target_properties(${name} PROPERTIES FOLDER "lldb executables")
+endmacro(add_lldb_executable)
+
+include_directories(BEFORE
+ ${CMAKE_CURRENT_BINARY_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/include
+ )
+
+install(DIRECTORY include/
+ DESTINATION include
+ FILES_MATCHING
+ PATTERN "*.h"
+ PATTERN ".svn" EXCLUDE
+ )
+
+#add_subdirectory(include)
+add_subdirectory(scripts)
+add_subdirectory(source)
+add_subdirectory(test)
+add_subdirectory(tools)
Index: aze/lldb/docs/code-signing.txt
===================================================================
--- aze.orig/lldb/docs/code-signing.txt 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/docs/code-signing.txt 2013-03-03 09:35:50.043457357 +0100
@@ -61,7 +61,7 @@
"login", but the one in "System"), and select "Delete" to delete it from
the "System" keychain.
- Reboot
-- Clean by removing all previously creating code signed binarires and rebuild
+- Clean by removing all previously creating code signed binaries and rebuild
lldb and you should be able to debug.
That should do it.
Index: aze/lldb/docs/lldb-for-gdb-users.txt
===================================================================
--- aze.orig/lldb/docs/lldb-for-gdb-users.txt 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/docs/lldb-for-gdb-users.txt 2013-03-03 09:35:50.047457356 +0100
@@ -204,7 +204,7 @@
> DONE
The "-c" option specifies that the breakpoint command is a set of lldb
-commmand interpreter commands. Use "-s" if you want to implement your
+command interpreter commands. Use "-s" if you want to implement your
breakpoint command using the Python interface instead.
@@ -434,7 +434,7 @@
f) Customization:
-You can use the embedded Python interprter to add the following 'pwd' and 'cd' commands
+You can use the embedded Python interpreter to add the following 'pwd' and 'cd' commands
for your lldb session:
(lldb) script import os
Index: aze/lldb/docs/lldb-gdb-remote.txt
===================================================================
--- aze.orig/lldb/docs/lldb-gdb-remote.txt 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/docs/lldb-gdb-remote.txt 2013-03-03 09:35:50.047457356 +0100
@@ -27,7 +27,7 @@
// the performance of the connection.
//----------------------------------------------------------------------
Having to send an ACK/NACK after every packet slows things down a bit, so we
-have a way to disable ACK packets to mimize the traffic for reliable
+have a way to disable ACK packets to minimize the traffic for reliable
communication interfaces (like sockets). Below GDB or LLDB will send this
packet to try and disable ACKs. All lines that start with "send packet: " are
from GDB/LLDB, and all lines that start with "read packet: " are from the GDB
@@ -336,7 +336,7 @@
vector-float32
vector-uint128
-set The regiter set name as a string that this register belongs to.
+set The register set name as a string that this register belongs to.
gcc The GCC compiler registers number for this register (used for
EH frame and other compiler information that is encoded in the
@@ -370,6 +370,52 @@
arg1 - arg8 (specified for registers that contain function
arguments when the argument fits into a register)
+container-regs
+ The value for this key is a comma separated list of raw hex (no
+ leading "0x") register numbers.
+
+ This specifies that this register is contained in other concrete
+ register values. For example "eax" is in the lower 32 bits of the
+ "rax" register value for x86_64, so "eax" could specify that it is
+ contained in "rax" by specifying the register number for "rax" (whose
+ register number is 0x00)
+
+ "container-regs:00;"
+
+ If a register is comprised of one or more registers, like "d0" is ARM
+ which is a 64 bit register, it might be made up of "s0" and "s1". If
+ the register number for "s0" is 0x20, and the register number of "s1"
+ is "0x21", the "container-regs" key/value pair would be:
+
+ "container-regs:20,21;"
+
+ This is handy for defining what GDB used to call "pseudo" registers.
+ These registers are never requested by LLDB via the register read
+ or write packets, the container registers will be requested on behalf
+ of this register.
+
+invalidate-regs
+ The value for this key is a comma separated list of raw hex (no
+ leading "0x") register numbers.
+
+ This specifies which register values should be invalidated when this
+ register is modified. For example if modifying "eax" would cause "rax",
+ "eax", "ax", "ah", and "al" to be modified where rax is 0x0, eax is 0x15,
+ ax is 0x25, ah is 0x35, and al is 0x39, the "invalidate-regs" key/value
+ pair would be:
+
+ "invalidate-regs:0,15,25,35,39;"
+
+ If there is a single register that gets invalidated, then omit the comma
+ and just list a single register:
+
+ "invalidate-regs:0;"
+
+ This is handy when modifying a specific register can cause other
+ register values to change. For example, when debugging an ARM target,
+ modifying the CPSR register can cause the r8 - r14 and cpsr value to
+ change depending on if the mode has changed.
+
//----------------------------------------------------------------------
// "qHostInfo"
//
@@ -392,12 +438,56 @@
cputype: is a number that is the mach-o CPU type that is being debugged
cpusubtype: is a number that is the mach-o CPU subtype type that is being debugged
-ostype: is a string the represents the OS being debugged (darwin, lunix, freebsd)
+ostype: is a string the represents the OS being debugged (darwin, linux, freebsd)
vendor: is a string that represents the vendor (apple)
endian: is one of "little", "big", or "pdp"
ptrsize: is a number that represents how big pointers are in bytes on the debug target
//----------------------------------------------------------------------
+// "qProcessInfo"
+//
+// BRIEF
+// Get information about the process we are currently debugging.
+//
+// PRIORITY TO IMPLEMENT
+// Medium. On systems which can launch multiple different architecture processes,
+// the qHostInfo may not disambiguate sufficiently to know what kind of
+// process is being debugged.
+// e.g. on a 64-bit x86 Mac system both 32-bit and 64-bit user processes are possible,
+// and with Mach-O universal files, the executable file may contain both 32- and
+// 64-bit slices so it may be impossible to know until you're attached to a real
+// process to know what you're working with.
+//
+// All numeric fields return base-16 numbers without any "0x" prefix.
+//----------------------------------------------------------------------
+
+An i386 process:
+
+send packet: $qProcessInfo#00
+read packet: $pid:42a8;parent-pid:42bf;real-uid:ecf;real-gid:b;effective-uid:ecf;effective-gid:b;cputype:7;cpusubtype:3;ostype:macosx;vendor:apple;endian:little;ptrsize:4;#00
+
+An x86_64 process:
+
+send packet: $qProcessInfo#00
+read packet: $pid:d22c;parent-pid:d34d;real-uid:ecf;real-gid:b;effective-uid:ecf;effective-gid:b;cputype:1000007;cpusubtype:3;ostype:macosx;vendor:apple;endian:little;ptrsize:8;#00
+
+Key value pairs include:
+
+pid: the process id
+parent-pid: the process of the parent process (often debugserver will become the parent when attaching)
+real-uid: the real user id of the process
+real-gid: the real group id of the process
+effective-uid: the effective user id of the process
+effective-gid: the effective group id of the process
+cputype: the Mach-O CPU type of the process
+cpusubtype: the Mach-O CPU subtype of the process
+ostype: is a string the represents the OS being debugged (darwin, linux, freebsd)
+vendor: is a string that represents the vendor (apple)
+endian: is one of "little", "big", or "pdp"
+ptrsize: is a number that represents how big pointers are in bytes
+
+
+//----------------------------------------------------------------------
// "qShlibInfoAddr"
//
// BRIEF
@@ -417,8 +507,8 @@
LLDB and GDB both support the "qShlibInfoAddr" packet which is a hint to each
debugger as to where to find the dynamic loader information. For darwin
-binaires that run in user land this is the address of the "all_image_infos"
-stucture in the "/usr/lib/dyld" executable, or the result of a TASK_DYLD_INFO
+binaries that run in user land this is the address of the "all_image_infos"
+structure in the "/usr/lib/dyld" executable, or the result of a TASK_DYLD_INFO
call. The result is returned as big endian hex bytes that are the address
value:
@@ -469,7 +559,7 @@
//----------------------------------------------------------------------
When reading thread registers, you currently need to set the current
-thread,then read the registers. This is kind of cumbersome, so we added the
+thread, then read the registers. This is kind of cumbersome, so we added the
ability to query if the remote GDB server supports adding a "thread:<tid>;"
suffix to all packets that request information for a thread. To test if the
remote GDB server supports this feature:
@@ -630,7 +720,7 @@
// the hex value of the register in debuggee endian byte order.
// - If key == "thread", then the value is the big endian hex
// thread-id of the stopped thread.
-// - If key == "core", then value is a hex nujber of the core on
+// - If key == "core", then value is a hex number of the core on
// which the stop was detected.
// - If key == "watch" or key == "rwatch" or key == "awatch", then
// value is the data address in big endian hex
@@ -700,7 +790,7 @@
//
// BEST PRACTICES:
// Since register values can be supplied with this packet, it is often useful
-// to return the PC, SP, FP, LR (if any), and FLAGS regsiters so that separate
+// to return the PC, SP, FP, LR (if any), and FLAGS registers so that separate
// packets don't need to be sent to read each of these registers from each
// thread.
//
@@ -709,7 +799,7 @@
// "T" packet with "00" as the signal number and fill in as many key values
// and registers as possible.
//
-// LLDB likes to know why a thread stopped since many thread contol
+// LLDB likes to know why a thread stopped since many thread control
// operations like stepping over a source line, actually are implemented
// by running the process multiple times. If a breakpoint is hit while
// trying to step over a source line and LLDB finds out that a breakpoint
@@ -719,14 +809,14 @@
// at the current PC and do an instruction single step, knowing that
// we stopped due to a "trace" helps us know that we can continue
// running versus stopping due to a "breakpoint" (if we have two
-// breakpoint instruction on consucutive instructions). So the more info
+// breakpoint instruction on consecutive instructions). So the more info
// we can get about the reason a thread stops, the better job LLDB can
// do when controlling your process. A typical GDB server behavior is
// to send a SIGTRAP for breakpoints _and_ also when instruction single
// stepping, in this case the debugger doesn't really know why we
// stopped and it can make it hard for the debugger to control your
// program correctly. What if a real SIGTRAP was delivered to a thread
-// while we were trying to single step? We woudn't know the difference
+// while we were trying to single step? We wouldn't know the difference
// with a standard GDB remote server and we could do the wrong thing.
//
// PRIORITY TO IMPLEMENT
Index: aze/lldb/examples/darwin/heap_find/heap/heap_find.cpp
===================================================================
--- aze.orig/lldb/examples/darwin/heap_find/heap/heap_find.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/darwin/heap_find/heap/heap_find.cpp 2013-03-03 09:35:50.047457356 +0100
@@ -63,7 +63,7 @@
//
// This is a clue that the 0x104008000 is a "lldb_private::Process *".
//===----------------------------------------------------------------------===//
-
+// C includes
#include <assert.h>
#include <ctype.h>
#include <dlfcn.h>
@@ -73,6 +73,9 @@
#include <objc/objc-runtime.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
+
+// C++ includes
#include <vector>
//----------------------------------------------------------------------
@@ -362,7 +365,7 @@
{
const int k_page_size = getpagesize();
const mach_vm_size_t vm_size = ((n_bytes + k_page_size - 1)/k_page_size) * k_page_size;
- vm_address_t address = NULL;
+ vm_address_t address = 0;
kern_return_t kerr = vm_allocate (mach_task_self(), &address, vm_size, true);
if (kerr == KERN_SUCCESS)
return (void *)address;
Index: aze/lldb/examples/darwin/heap_find/heap.py
===================================================================
--- aze.orig/lldb/examples/darwin/heap_find/heap.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/darwin/heap_find/heap.py 2013-03-03 09:35:50.051457355 +0100
@@ -21,62 +21,158 @@
g_libheap_dylib_dir = None
g_libheap_dylib_dict = dict()
-g_verbose = False
-def load_dylib():
- if lldb.target:
- global g_libheap_dylib_dir
- global g_libheap_dylib_dict
- triple = lldb.target.triple
- if triple in g_libheap_dylib_dict:
- libheap_dylib_path = g_libheap_dylib_dict[triple]
- else:
- if not g_libheap_dylib_dir:
- g_libheap_dylib_dir = tempfile.gettempdir() + '/lldb-dylibs'
- triple_dir = g_libheap_dylib_dir + '/' + triple + '/' + __name__
- if not os.path.exists(triple_dir):
- os.makedirs(triple_dir)
- libheap_dylib_path = triple_dir + '/libheap.dylib'
- g_libheap_dylib_dict[triple] = libheap_dylib_path
- heap_code_directory = os.path.dirname(__file__) + '/heap'
- heap_source_file = heap_code_directory + '/heap_find.cpp'
- # Check if the dylib doesn't exist, or if "heap_find.cpp" is newer than the dylib
- if not os.path.exists(libheap_dylib_path) or os.stat(heap_source_file).st_mtime > os.stat(libheap_dylib_path).st_mtime:
- # Remake the dylib
- make_command = '(cd "%s" ; make EXE="%s" ARCH=%s)' % (heap_code_directory, libheap_dylib_path, string.split(triple, '-')[0])
- (make_exit_status, make_output) = commands.getstatusoutput(make_command)
- if make_exit_status != 0:
- return 'error: make failed: %s' % (make_output)
- if os.path.exists(libheap_dylib_path):
- libheap_dylib_spec = lldb.SBFileSpec(libheap_dylib_path)
- if lldb.target.FindModule(libheap_dylib_spec):
- return None # success, 'libheap.dylib' already loaded
- if lldb.process:
- state = lldb.process.state
- if state == lldb.eStateStopped:
- (libheap_dylib_path)
- error = lldb.SBError()
- image_idx = lldb.process.LoadImage(libheap_dylib_spec, error)
- if error.Success():
- return None
- else:
- if error:
- return 'error: %s' % error
- else:
- return 'error: "process load \'%s\'" failed' % libheap_dylib_spec
- else:
- return 'error: process is not stopped'
- else:
- return 'error: invalid process'
- else:
- return 'error: file does not exist "%s"' % libheap_dylib_path
+def get_iterate_memory_expr(options, process, user_init_code, user_return_code):
+ expr = '''
+typedef unsigned natural_t;
+typedef uintptr_t vm_size_t;
+typedef uintptr_t vm_address_t;
+typedef natural_t task_t;
+typedef int kern_return_t;
+#define KERN_SUCCESS 0
+typedef void (*range_callback_t)(task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size);
+''';
+ if options.search_vm_regions:
+ expr += '''
+typedef int vm_prot_t;
+typedef unsigned int vm_inherit_t;
+typedef unsigned long long memory_object_offset_t;
+typedef unsigned int boolean_t;
+typedef int vm_behavior_t;
+typedef uint32_t vm32_object_id_t;
+typedef natural_t mach_msg_type_number_t;
+typedef uint64_t mach_vm_address_t;
+typedef uint64_t mach_vm_offset_t;
+typedef uint64_t mach_vm_size_t;
+typedef uint64_t vm_map_offset_t;
+typedef uint64_t vm_map_address_t;
+typedef uint64_t vm_map_size_t;
+#define VM_PROT_NONE ((vm_prot_t) 0x00)
+#define VM_PROT_READ ((vm_prot_t) 0x01)
+#define VM_PROT_WRITE ((vm_prot_t) 0x02)
+#define VM_PROT_EXECUTE ((vm_prot_t) 0x04)
+typedef struct vm_region_submap_short_info_data_64_t {
+ vm_prot_t protection;
+ vm_prot_t max_protection;
+ vm_inherit_t inheritance;
+ memory_object_offset_t offset; // offset into object/map
+ unsigned int user_tag; // user tag on map entry
+ unsigned int ref_count; // obj/map mappers, etc
+ unsigned short shadow_depth; // only for obj
+ unsigned char external_pager; // only for obj
+ unsigned char share_mode; // see enumeration
+ boolean_t is_submap; // submap vs obj
+ vm_behavior_t behavior; // access behavior hint
+ vm32_object_id_t object_id; // obj/map name, not a handle
+ unsigned short user_wired_count;
+} vm_region_submap_short_info_data_64_t;
+#define VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 ((mach_msg_type_number_t)(sizeof(vm_region_submap_short_info_data_64_t)/sizeof(int)))''';
+ if user_init_code:
+ expr += user_init_code;
+ expr += '''
+task_t task = (task_t)mach_task_self();
+mach_vm_address_t vm_region_base_addr;
+mach_vm_size_t vm_region_size;
+natural_t vm_region_depth;
+vm_region_submap_short_info_data_64_t vm_region_info;
+kern_return_t err;
+for (vm_region_base_addr = 0, vm_region_size = 1; vm_region_size != 0; vm_region_base_addr += vm_region_size)
+{
+ mach_msg_type_number_t vm_region_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
+ err = (kern_return_t)mach_vm_region_recurse (task,
+ &vm_region_base_addr,
+ &vm_region_size,
+ &vm_region_depth,
+ &vm_region_info,
+ &vm_region_info_size);
+ if (err)
+ break;
+ // Check all read + write regions. This will cover the thread stacks
+ // and any regions of memory like __DATA segments, that might contain
+ // data we are looking for
+ if (vm_region_info.protection & VM_PROT_WRITE &&
+ vm_region_info.protection & VM_PROT_READ)
+ {
+ baton.callback (task,
+ &baton,
+ 64,
+ vm_region_base_addr,
+ vm_region_size);
+ }
+}'''
else:
- return 'error: invalid target'
-
- debugger.HandleCommand('process load "%s"' % libheap_dylib_path)
- if lldb.target.FindModule(libheap_dylib_spec):
- return None # success, 'libheap.dylib' already loaded
- return 'error: failed to load "%s"' % libheap_dylib_path
+ if options.search_stack:
+ expr += get_thread_stack_ranges_struct (process)
+ if options.search_segments:
+ expr += get_sections_ranges_struct (process)
+ if user_init_code:
+ expr += user_init_code
+ if options.search_heap:
+ expr += '''
+#define MALLOC_PTR_IN_USE_RANGE_TYPE 1
+typedef struct vm_range_t {
+ vm_address_t address;
+ vm_size_t size;
+} vm_range_t;
+typedef kern_return_t (*memory_reader_t)(task_t task, vm_address_t remote_address, vm_size_t size, void **local_memory);
+typedef void (*vm_range_recorder_t)(task_t task, void *baton, unsigned type, vm_range_t *range, unsigned size);
+typedef struct malloc_introspection_t {
+ kern_return_t (*enumerator)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */
+} malloc_introspection_t;
+typedef struct malloc_zone_t {
+ void *reserved1[12];
+ struct malloc_introspection_t *introspect;
+} malloc_zone_t;
+memory_reader_t task_peek = [](task_t task, vm_address_t remote_address, vm_size_t size, void **local_memory) -> kern_return_t {
+ *local_memory = (void*) remote_address;
+ return KERN_SUCCESS;
+};
+vm_address_t *zones = 0;
+unsigned int num_zones = 0;task_t task = 0;
+kern_return_t err = (kern_return_t)malloc_get_all_zones (task, task_peek, &zones, &num_zones);
+if (KERN_SUCCESS == err)
+{
+ for (unsigned int i=0; i<num_zones; ++i)
+ {
+ const malloc_zone_t *zone = (const malloc_zone_t *)zones[i];
+ if (zone && zone->introspect)
+ zone->introspect->enumerator (task,
+ &baton,
+ MALLOC_PTR_IN_USE_RANGE_TYPE,
+ (vm_address_t)zone,
+ task_peek,
+ [] (task_t task, void *baton, unsigned type, vm_range_t *ranges, unsigned size) -> void
+ {
+ range_callback_t callback = ((callback_baton_t *)baton)->callback;
+ for (unsigned i=0; i<size; ++i)
+ {
+ callback (task, baton, type, ranges[i].address, ranges[i].size);
+ }
+ });
+ }
+}'''
+
+ if options.search_stack:
+ expr += '''
+// Call the callback for the thread stack ranges
+for (uint32_t i=0; i<NUM_STACKS; ++i) {
+ range_callback(task, &baton, 8, stacks[i].base, stacks[i].size);
+ if (STACK_RED_ZONE_SIZE > 0) {
+ range_callback(task, &baton, 16, stacks[i].base - STACK_RED_ZONE_SIZE, STACK_RED_ZONE_SIZE);
+ }
+}
+ '''
+
+ if options.search_segments:
+ expr += '''
+// Call the callback for all segments
+for (uint32_t i=0; i<NUM_SEGMENTS; ++i)
+ range_callback(task, &baton, 32, segments[i].base, segments[i].size);'''
+
+ if user_return_code:
+ expr += "\n%s" % (user_return_code,)
+
+ return expr
def get_member_types_for_offset(value_type, offset, member_list):
member = value_type.GetFieldAtIndex(0)
@@ -131,28 +227,67 @@
parser.add_option('-I', '--omit-ivar-regex', type='string', action='callback', callback=append_regex_callback, dest='ivar_regex_blacklist', default=[], help='specify one or more regular expressions used to backlist any matches that are in ivars')
parser.add_option('-s', '--stack', action='store_true', dest='stack', help='gets the stack that allocated each malloc block if MallocStackLogging is enabled', default=False)
parser.add_option('-S', '--stack-history', action='store_true', dest='stack_history', help='gets the stack history for all allocations whose start address matches each malloc block if MallocStackLogging is enabled', default=False)
- parser.add_option('-M', '--max-matches', type='int', dest='max_matches', help='the maximum number of matches to print', default=256)
+ parser.add_option('-F', '--max-frames', type='int', dest='max_frames', help='the maximum number of stack frames to print when using the --stack or --stack-history options (default=128)', default=128)
+ parser.add_option('-H', '--max-history', type='int', dest='max_history', help='the maximum number of stack history backtraces to print for each allocation when using the --stack-history option (default=16)', default=16)
+ parser.add_option('-M', '--max-matches', type='int', dest='max_matches', help='the maximum number of matches to print', default=32)
parser.add_option('-O', '--offset', type='int', dest='offset', help='the matching data must be at this offset', default=-1)
- parser.add_option('-V', '--vm-regions', action='store_true', dest='check_vm_regions', help='Also check the VM regions', default=False)
+ parser.add_option('--ignore-stack', action='store_false', dest='search_stack', help="Don't search the stack when enumerating memory", default=True)
+ parser.add_option('--ignore-heap', action='store_false', dest='search_heap', help="Don't search the heap allocations when enumerating memory", default=True)
+ parser.add_option('--ignore-segments', action='store_false', dest='search_segments', help="Don't search readable executable segments enumerating memory", default=True)
+ parser.add_option('-V', '--vm-regions', action='store_true', dest='search_vm_regions', help='Check all VM regions instead of searching the heap, stack and segments', default=False)
+
+def type_flags_to_string(type_flags):
+ if type_flags == 0:
+ type_str = 'free'
+ elif type_flags & 2:
+ type_str = 'malloc'
+ elif type_flags & 4:
+ type_str = 'free'
+ elif type_flags & 1:
+ type_str = 'generic'
+ elif type_flags & 8:
+ type_str = 'stack'
+ elif type_flags & 16:
+ type_str = 'stack (red zone)'
+ elif type_flags & 32:
+ type_str = 'segment'
+ elif type_flags & 64:
+ type_str = 'vm_region'
+ else:
+ type_str = hex(type_flags)
+ return type_str
-def dump_stack_history_entry(result, stack_history_entry, idx):
+def type_flags_to_description(type_flags, ptr_addr, ptr_size, offset):
+ show_offset = False
+ if type_flags == 0 or type_flags & 4:
+ type_str = 'free(%#x)' % (ptr_addr,)
+ elif type_flags & 2 or type_flags & 1:
+ type_str = 'malloc(%6u) -> %#x' % (ptr_size, ptr_addr)
+ show_offset = True
+ elif type_flags & 8:
+ type_str = 'stack'
+ elif type_flags & 16:
+ type_str = 'stack (red zone)'
+ elif type_flags & 32:
+ sb_addr = lldb.debugger.GetSelectedTarget().ResolveLoadAddress(ptr_addr + offset)
+ type_str = 'segment [%#x - %#x), %s + %u, %s' % (ptr_addr, ptr_addr + ptr_size, sb_addr.section.name, sb_addr.offset, sb_addr)
+ elif type_flags & 64:
+ sb_addr = lldb.debugger.GetSelectedTarget().ResolveLoadAddress(ptr_addr + offset)
+ type_str = 'vm_region [%#x - %#x), %s + %u, %s' % (ptr_addr, ptr_addr + ptr_size, sb_addr.section.name, sb_addr.offset, sb_addr)
+ else:
+ type_str = '%#x' % (ptr_addr,)
+ show_offset = True
+ if show_offset and offset != 0:
+ type_str += ' + %-6u' % (offset,)
+ return type_str
+
+def dump_stack_history_entry(options, result, stack_history_entry, idx):
address = int(stack_history_entry.address)
if address:
type_flags = int(stack_history_entry.type_flags)
symbolicator = lldb.utils.symbolication.Symbolicator()
- symbolicator.target = lldb.target
- type_str = ''
- if type_flags == 0:
- type_str = 'free'
- else:
- if type_flags & 2:
- type_str = 'alloc'
- elif type_flags & 4:
- type_str = 'free'
- elif type_flags & 1:
- type_str = 'generic'
- else:
- type_str = hex(type_flags)
+ symbolicator.target = lldb.debugger.GetSelectedTarget()
+ type_str = type_flags_to_string(type_flags)
result.AppendMessage('stack[%u]: addr = 0x%x, type=%s, frames:' % (idx, address, type_str))
frame_idx = 0
idx = 0
@@ -171,28 +306,137 @@
pc = int(stack_history_entry.frames[idx])
else:
pc = 0
+ if idx >= options.max_frames:
+ result.AppendMessage('warning: the max number of stack frames (%u) was reached, use the "--max-frames=<COUNT>" option to see more frames' % (options.max_frames))
+
result.AppendMessage('')
-def dump_stack_history_entries(result, addr, history):
+def dump_stack_history_entries(options, result, addr, history):
# malloc_stack_entry *get_stack_history_for_address (const void * addr)
- expr = 'get_stack_history_for_address((void *)0x%x, %u)' % (addr, history)
- expr_sbvalue = lldb.frame.EvaluateExpression (expr)
+ single_expr = '''
+typedef int kern_return_t;
+#define MAX_FRAMES %u
+typedef struct $malloc_stack_entry {
+ uint64_t address;
+ uint64_t argument;
+ uint32_t type_flags;
+ uint32_t num_frames;
+ uint64_t frames[512];
+ kern_return_t err;
+} $malloc_stack_entry;
+typedef unsigned task_t;
+$malloc_stack_entry stack;
+stack.address = 0x%x;
+stack.type_flags = 2;
+stack.num_frames = 0;
+stack.frames[0] = 0;
+uint32_t max_stack_frames = MAX_FRAMES;
+stack.err = (kern_return_t)__mach_stack_logging_get_frames (
+ (task_t)mach_task_self(),
+ stack.address,
+ &stack.frames[0],
+ max_stack_frames,
+ &stack.num_frames);
+if (stack.num_frames < MAX_FRAMES)
+ stack.frames[stack.num_frames] = 0;
+else
+ stack.frames[MAX_FRAMES-1] = 0;
+stack''' % (options.max_frames, addr);
+
+ history_expr = '''
+typedef int kern_return_t;
+typedef unsigned task_t;
+#define MAX_FRAMES %u
+#define MAX_HISTORY %u
+typedef struct mach_stack_logging_record_t {
+ uint32_t type_flags;
+ uint64_t stack_identifier;
+ uint64_t argument;
+ uint64_t address;
+} mach_stack_logging_record_t;
+typedef void (*enumerate_callback_t)(mach_stack_logging_record_t, void *);
+typedef struct malloc_stack_entry {
+ uint64_t address;
+ uint64_t argument;
+ uint32_t type_flags;
+ uint32_t num_frames;
+ uint64_t frames[MAX_FRAMES];
+ kern_return_t frames_err;
+} malloc_stack_entry;
+typedef struct $malloc_stack_history {
+ task_t task;
+ unsigned idx;
+ malloc_stack_entry entries[MAX_HISTORY];
+} $malloc_stack_history;
+$malloc_stack_history info = { (task_t)mach_task_self(), 0 };
+uint32_t max_stack_frames = MAX_FRAMES;
+enumerate_callback_t callback = [] (mach_stack_logging_record_t stack_record, void *baton) -> void {
+ $malloc_stack_history *info = ($malloc_stack_history *)baton;
+ if (info->idx < MAX_HISTORY) {
+ malloc_stack_entry *stack_entry = &(info->entries[info->idx]);
+ stack_entry->address = stack_record.address;
+ stack_entry->type_flags = stack_record.type_flags;
+ stack_entry->argument = stack_record.argument;
+ stack_entry->num_frames = 0;
+ stack_entry->frames[0] = 0;
+ stack_entry->frames_err = (kern_return_t)__mach_stack_logging_frames_for_uniqued_stack (
+ info->task,
+ stack_record.stack_identifier,
+ stack_entry->frames,
+ (uint32_t)MAX_FRAMES,
+ &stack_entry->num_frames);
+ // Terminate the frames with zero if there is room
+ if (stack_entry->num_frames < MAX_FRAMES)
+ stack_entry->frames[stack_entry->num_frames] = 0;
+ }
+ ++info->idx;
+};
+(kern_return_t)__mach_stack_logging_enumerate_records (info.task, (uint64_t)0x%x, callback, &info);
+info''' % (options.max_frames, options.max_history, addr);
+
+ frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ if history:
+ expr = history_expr
+ else:
+ expr = single_expr
+ expr_sbvalue = frame.EvaluateExpression (expr)
+ if options.verbose:
+ print "expression:"
+ print expr
+ print "expression result:"
+ print expr_sbvalue
if expr_sbvalue.error.Success():
- if expr_sbvalue.unsigned:
- expr_value = lldb.value(expr_sbvalue)
- idx = 0;
- stack_history_entry = expr_value[idx]
- while int(stack_history_entry.address) != 0:
- dump_stack_history_entry(result, stack_history_entry, idx)
- idx = idx + 1
- stack_history_entry = expr_value[idx]
+ if history:
+ malloc_stack_history = lldb.value(expr_sbvalue)
+ num_stacks = int(malloc_stack_history.idx)
+ if num_stacks <= options.max_history:
+ i_max = num_stacks
+ else:
+ i_max = options.max_history
+ for i in range(i_max):
+ stack_history_entry = malloc_stack_history.entries[i]
+ dump_stack_history_entry(options, result, stack_history_entry, i)
+ if num_stacks > options.max_history:
+ result.AppendMessage('warning: the max number of stacks (%u) was reached, use the "--max-history=%u" option to see all of the stacks' % (options.max_history, num_stacks))
else:
- result.AppendMessage('"%s" returned zero' % (expr))
+ stack_history_entry = lldb.value(expr_sbvalue)
+ dump_stack_history_entry(options, result, stack_history_entry, 0)
+
else:
result.AppendMessage('error: expression failed "%s" => %s' % (expr, expr_sbvalue.error))
-
-def display_match_results (result, options, arg_str_description, expr_sbvalue, print_no_matches = True):
+
+def display_match_results (result, options, arg_str_description, expr, print_no_matches = True):
+ frame = lldb.debugger.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame()
+ if not frame:
+ result.AppendMessage('error: invalid frame')
+ return 0
+ expr_sbvalue = frame.EvaluateExpression (expr)
+ if options.verbose:
+ print "expression:"
+ print expr
+ print "expression result:"
+ print expr_sbvalue
if expr_sbvalue.error.Success():
if expr_sbvalue.unsigned:
match_value = lldb.value(expr_sbvalue)
@@ -201,8 +445,8 @@
while 1:
print_entry = True
match_entry = match_value[i]; i += 1
- if i >= options.max_matches:
- result.AppendMessage('error: the max number of matches (%u) was reached, use the --max-matches option to get more results' % (options.max_matches))
+ if i > options.max_matches:
+ result.AppendMessage('warning: the max number of matches (%u) was reached, use the --max-matches option to get more results' % (options.max_matches))
break
malloc_addr = match_entry.addr.sbvalue.unsigned
if malloc_addr == 0:
@@ -214,75 +458,90 @@
print_entry = False
else:
match_addr = malloc_addr + offset
- dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
- description = '%#x: ' % (match_addr)
- if options.show_size:
- description += '<%5u> ' % (malloc_size)
- if options.show_range:
- if offset > 0:
- description += '[%#x - %#x) + %-6u ' % (malloc_addr, malloc_addr + malloc_size, offset)
+ type_flags = int(match_entry.type)
+ #result.AppendMessage (hex(malloc_addr + offset))
+ if type_flags == 64:
+ search_stack_old = options.search_stack
+ search_segments_old = options.search_segments
+ search_heap_old = options.search_heap
+ search_vm_regions = options.search_vm_regions
+ options.search_stack = True
+ options.search_segments = True
+ options.search_heap = True
+ options.search_vm_regions = False
+ if malloc_info_impl (lldb.debugger, result, options, [hex(malloc_addr + offset)]):
+ print_entry = False
+ options.search_stack = search_stack_old
+ options.search_segments = search_segments_old
+ options.search_heap = search_heap_old
+ options.search_vm_regions = search_vm_regions
+ if print_entry:
+ description = '%#16.16x: %s' % (match_addr, type_flags_to_description(type_flags, malloc_addr, malloc_size, offset))
+ if options.show_size:
+ description += ' <%5u>' % (malloc_size)
+ if options.show_range:
+ description += ' [%#x - %#x)' % (malloc_addr, malloc_addr + malloc_size)
+ derefed_dynamic_value = None
+ dynamic_value = match_entry.addr.sbvalue.GetDynamicValue(lldb.eDynamicCanRunTarget)
+ if dynamic_value.type.name == 'void *':
+ if options.type == 'pointer' and malloc_size == 4096:
+ error = lldb.SBError()
+ process = expr_sbvalue.GetProcess()
+ target = expr_sbvalue.GetTarget()
+ data = bytearray(process.ReadMemory(malloc_addr, 16, error))
+ if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
+ ptr_size = target.addr_size
+ thread = process.ReadUnsignedFromMemory (malloc_addr + 16 + ptr_size, ptr_size, error)
+ # 4 bytes 0xa1a1a1a1
+ # 12 bytes 'AUTORELEASE!'
+ # ptr bytes autorelease insertion point
+ # ptr bytes pthread_t
+ # ptr bytes next colder page
+ # ptr bytes next hotter page
+ # 4 bytes this page's depth in the list
+ # 4 bytes high-water mark
+ description += ' AUTORELEASE! for pthread_t %#x' % (thread)
+ # else:
+ # description += 'malloc(%u)' % (malloc_size)
+ # else:
+ # description += 'malloc(%u)' % (malloc_size)
else:
- description += '[%#x - %#x)' % (malloc_addr, malloc_addr + malloc_size)
- else:
- if options.type != 'isa':
- description += '%#x + %-6u ' % (malloc_addr, offset)
- derefed_dynamic_value = None
- if dynamic_value.type.name == 'void *':
- if options.type == 'pointer' and malloc_size == 4096:
- error = lldb.SBError()
- data = bytearray(lldb.process.ReadMemory(malloc_addr, 16, error))
- if data == '\xa1\xa1\xa1\xa1AUTORELEASE!':
- ptr_size = lldb.target.addr_size
- thread = lldb.process.ReadUnsignedFromMemory (malloc_addr + 16 + ptr_size, ptr_size, error)
- # 4 bytes 0xa1a1a1a1
- # 12 bytes 'AUTORELEASE!'
- # ptr bytes autorelease insertion point
- # ptr bytes pthread_t
- # ptr bytes next colder page
- # ptr bytes next hotter page
- # 4 bytes this page's depth in the list
- # 4 bytes high-water mark
- description += 'AUTORELEASE! for pthread_t %#x' % (thread)
+ derefed_dynamic_value = dynamic_value.deref
+ if derefed_dynamic_value:
+ derefed_dynamic_type = derefed_dynamic_value.type
+ derefed_dynamic_type_size = derefed_dynamic_type.size
+ derefed_dynamic_type_name = derefed_dynamic_type.name
+ description += ' '
+ description += derefed_dynamic_type_name
+ if offset < derefed_dynamic_type_size:
+ member_list = list();
+ get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
+ if member_list:
+ member_path = ''
+ for member in member_list:
+ member_name = member.name
+ if member_name:
+ if member_path:
+ member_path += '.'
+ member_path += member_name
+ if member_path:
+ if options.ivar_regex_blacklist:
+ for ivar_regex in options.ivar_regex_blacklist:
+ if ivar_regex.match(member_path):
+ print_entry = False
+ description += '.%s' % (member_path)
+ else:
+ description += '%u bytes after %s' % (offset - derefed_dynamic_type_size, derefed_dynamic_type_name)
else:
- description += 'malloc(%u)' % (malloc_size)
- else:
- description += 'malloc(%u)' % (malloc_size)
- else:
- derefed_dynamic_value = dynamic_value.deref
- if derefed_dynamic_value:
- derefed_dynamic_type = derefed_dynamic_value.type
- derefed_dynamic_type_size = derefed_dynamic_type.size
- derefed_dynamic_type_name = derefed_dynamic_type.name
- description += derefed_dynamic_type_name
- if offset < derefed_dynamic_type_size:
- member_list = list();
- get_member_types_for_offset (derefed_dynamic_type, offset, member_list)
- if member_list:
- member_path = ''
- for member in member_list:
- member_name = member.name
- if member_name:
- if member_path:
- member_path += '.'
- member_path += member_name
- if member_path:
- if options.ivar_regex_blacklist:
- for ivar_regex in options.ivar_regex_blacklist:
- if ivar_regex.match(member_path):
- print_entry = False
- description += '.%s' % (member_path)
- else:
- description += '%u bytes after %s' % (offset - derefed_dynamic_type_size, derefed_dynamic_type_name)
- else:
- # strip the "*" from the end of the name since we were unable to dereference this
- description += dynamic_value.type.name[0:-1]
+ # strip the "*" from the end of the name since we were unable to dereference this
+ description += dynamic_value.type.name[0:-1]
if print_entry:
match_idx += 1
result_output = ''
if description:
result_output += description
if options.print_type and derefed_dynamic_value:
- result_output += '%s' % (derefed_dynamic_value)
+ result_output += ' %s' % (derefed_dynamic_value)
if options.print_object_description and dynamic_value:
desc = dynamic_value.GetObjectDescription()
if desc:
@@ -291,13 +550,18 @@
result.AppendMessage(result_output)
if options.memory:
cmd_result = lldb.SBCommandReturnObject()
- memory_command = "memory read -f %s 0x%x 0x%x" % (options.format, malloc_addr, malloc_addr + malloc_size)
+ if options.format == None:
+ memory_command = "memory read --force 0x%x 0x%x" % (malloc_addr, malloc_addr + malloc_size)
+ else:
+ memory_command = "memory read --force -f %s 0x%x 0x%x" % (options.format, malloc_addr, malloc_addr + malloc_size)
+ if options.verbose:
+ result.AppendMessage(memory_command)
lldb.debugger.GetCommandInterpreter().HandleCommand(memory_command, cmd_result)
result.AppendMessage(cmd_result.GetOutput())
if options.stack_history:
- dump_stack_history_entries(result, malloc_addr, 1)
+ dump_stack_history_entries(options, result, malloc_addr, 1)
elif options.stack:
- dump_stack_history_entries(result, malloc_addr, 0)
+ dump_stack_history_entries(options, result, malloc_addr, 0)
return i
elif print_no_matches:
result.AppendMessage('no matches found for %s' % (arg_str_description))
@@ -305,181 +569,332 @@
result.AppendMessage(str(expr_sbvalue.error))
return 0
-def heap_search(result, options, arg_str):
- dylid_load_err = load_dylib()
- if dylid_load_err:
- result.AppendMessage(dylid_load_err)
- return
- expr = None
- print_no_matches = True
- arg_str_description = arg_str
- if options.type == 'pointer':
- expr = 'find_pointer_in_heap((void *)%s, (int)%u)' % (arg_str, options.check_vm_regions)
- arg_str_description = 'malloc block containing pointer %s' % arg_str
- if options.format == None:
- options.format = "A" # 'A' is "address" format
- elif options.type == 'isa':
- expr = 'find_objc_objects_in_memory ((void *)%s, (int)%u)' % (arg_str, options.check_vm_regions)
- #result.AppendMessage ('expr -u0 -- %s' % expr) # REMOVE THIS LINE
- arg_str_description = 'objective C classes with isa %s' % arg_str
- options.offset = 0
- if options.format == None:
- options.format = "A" # 'A' is "address" format
- elif options.type == 'cstr':
- expr = 'find_cstring_in_heap("%s", (int)%u)' % (arg_str, options.check_vm_regions)
- arg_str_description = 'malloc block containing "%s"' % arg_str
- elif options.type == 'addr':
- expr = 'find_block_for_address((void *)%s, (int)%u)' % (arg_str, options.check_vm_regions)
- arg_str_description = 'malloc block for %s' % arg_str
- elif options.type == 'all':
- expr = 'get_heap_info(1)'
- arg_str_description = None
- print_no_matches = False
- else:
- result.AppendMessage('error: invalid type "%s"\nvalid values are "pointer", "cstr"' % options.type)
- return
- if options.format == None:
- options.format = "Y" # 'Y' is "bytes with ASCII" format
-
- display_match_results (result, options, arg_str_description, lldb.frame.EvaluateExpression (expr))
-
-def ptr_refs(debugger, command, result, dict):
- command_args = shlex.split(command)
+def get_ptr_refs_options ():
usage = "usage: %prog [options] <EXPR> [EXPR ...]"
- description='''Searches the heap for pointer references on darwin user space programs.
-
- Any matches that were found will dump the malloc blocks that contain the pointers
- and might be able to print what kind of objects the pointers are contained in using
- dynamic type information in the program.'''
+ description='''Searches all allocations on the heap for pointer values on
+darwin user space programs. Any matches that were found will dump the malloc
+blocks that contain the pointers and might be able to print what kind of
+objects the pointers are contained in using dynamic type information in the
+program.'''
parser = optparse.OptionParser(description=description, prog='ptr_refs',usage=usage)
add_common_options(parser)
+ return parser
+
+def ptr_refs(debugger, command, result, dict):
+ command_args = shlex.split(command)
+ parser = get_ptr_refs_options()
try:
(options, args) = parser.parse_args(command_args)
except:
return
+ process = lldb.debugger.GetSelectedTarget().GetProcess()
+ if not process:
+ result.AppendMessage('error: invalid process')
+ return
+ frame = process.GetSelectedThread().GetSelectedFrame()
+ if not frame:
+ result.AppendMessage('error: invalid frame')
+ return
+
options.type = 'pointer'
-
+ if options.format == None:
+ options.format = "A" # 'A' is "address" format
+
if args:
-
- for data in args:
- heap_search (result, options, data)
+ # When we initialize the expression, we must define any types that
+ # we will need when looking at every allocation. We must also define
+ # a type named callback_baton_t and make an instance named "baton"
+ # and initialize it how ever we want to. The address of "baton" will
+ # be passed into our range callback. callback_baton_t must contain
+ # a member named "callback" whose type is "range_callback_t". This
+ # will be used by our zone callbacks to call the range callback for
+ # each malloc range.
+ user_init_code_format = '''
+#define MAX_MATCHES %u
+struct $malloc_match {
+ void *addr;
+ uintptr_t size;
+ uintptr_t offset;
+ uintptr_t type;
+};
+typedef struct callback_baton_t {
+ range_callback_t callback;
+ unsigned num_matches;
+ $malloc_match matches[MAX_MATCHES];
+ void *ptr;
+} callback_baton_t;
+range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
+ callback_baton_t *info = (callback_baton_t *)baton;
+ typedef void* T;
+ const unsigned size = sizeof(T);
+ T *array = (T*)ptr_addr;
+ for (unsigned idx = 0; ((idx + 1) * sizeof(T)) <= ptr_size; ++idx) {
+ if (array[idx] == info->ptr) {
+ if (info->num_matches < MAX_MATCHES) {
+ info->matches[info->num_matches].addr = (void*)ptr_addr;
+ info->matches[info->num_matches].size = ptr_size;
+ info->matches[info->num_matches].offset = idx*sizeof(T);
+ info->matches[info->num_matches].type = type;
+ ++info->num_matches;
+ }
+ }
+ }
+};
+callback_baton_t baton = { range_callback, 0, {0}, (void *)%s };
+'''
+ # We must also define a snippet of code to be run that returns
+ # the result of the expression we run.
+ # Here we return NULL if our pointer was not found in any malloc blocks,
+ # and we return the address of the matches array so we can then access
+ # the matching results
+ user_return_code = '''if (baton.num_matches < MAX_MATCHES)
+ baton.matches[baton.num_matches].addr = 0; // Terminate the matches array
+baton.matches'''
+ # Iterate through all of our pointer expressions and display the results
+ for ptr_expr in args:
+ user_init_code = user_init_code_format % (options.max_matches, ptr_expr)
+ expr = get_iterate_memory_expr(options, process, user_init_code, user_return_code)
+ arg_str_description = 'malloc block containing pointer %s' % ptr_expr
+ display_match_results (result, options, arg_str_description, expr)
else:
- resultresult.AppendMessage('error: no pointer arguments were given')
+ result.AppendMessage('error: no pointer arguments were given')
-def cstr_refs(debugger, command, result, dict):
- command_args = shlex.split(command)
+def get_cstr_refs_options():
usage = "usage: %prog [options] <CSTR> [CSTR ...]"
- description='''Searches the heap for C string references on darwin user space programs.
-
- Any matches that were found will dump the malloc blocks that contain the C strings
- and might be able to print what kind of objects the pointers are contained in using
- dynamic type information in the program.'''
+ description='''Searches all allocations on the heap for C string values on
+darwin user space programs. Any matches that were found will dump the malloc
+blocks that contain the C strings and might be able to print what kind of
+objects the pointers are contained in using dynamic type information in the
+program.'''
parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
add_common_options(parser)
+ return parser
+
+def cstr_refs(debugger, command, result, dict):
+ command_args = shlex.split(command)
+ parser = get_cstr_refs_options();
try:
(options, args) = parser.parse_args(command_args)
except:
return
+ process = lldb.debugger.GetSelectedTarget().GetProcess()
+ if not process:
+ result.AppendMessage('error: invalid process')
+ return
+ frame = process.GetSelectedThread().GetSelectedFrame()
+ if not frame:
+ result.AppendMessage('error: invalid frame')
+ return
+
+
options.type = 'cstr'
+ if options.format == None:
+ options.format = "Y" # 'Y' is "bytes with ASCII" format
if args:
-
- for data in args:
- heap_search (result, options, data)
+ # When we initialize the expression, we must define any types that
+ # we will need when looking at every allocation. We must also define
+ # a type named callback_baton_t and make an instance named "baton"
+ # and initialize it how ever we want to. The address of "baton" will
+ # be passed into our range callback. callback_baton_t must contain
+ # a member named "callback" whose type is "range_callback_t". This
+ # will be used by our zone callbacks to call the range callback for
+ # each malloc range.
+ user_init_code_format = '''
+#define MAX_MATCHES %u
+struct $malloc_match {
+ void *addr;
+ uintptr_t size;
+ uintptr_t offset;
+ uintptr_t type;
+};
+typedef struct callback_baton_t {
+ range_callback_t callback;
+ unsigned num_matches;
+ $malloc_match matches[MAX_MATCHES];
+ const char *cstr;
+ unsigned cstr_len;
+} callback_baton_t;
+range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
+ callback_baton_t *info = (callback_baton_t *)baton;
+ if (info->cstr_len < ptr_size) {
+ const char *begin = (const char *)ptr_addr;
+ const char *end = begin + ptr_size - info->cstr_len;
+ for (const char *s = begin; s < end; ++s) {
+ if ((int)memcmp(s, info->cstr, info->cstr_len) == 0) {
+ if (info->num_matches < MAX_MATCHES) {
+ info->matches[info->num_matches].addr = (void*)ptr_addr;
+ info->matches[info->num_matches].size = ptr_size;
+ info->matches[info->num_matches].offset = s - begin;
+ info->matches[info->num_matches].type = type;
+ ++info->num_matches;
+ }
+ }
+ }
+ }
+};
+const char *cstr = "%s";
+callback_baton_t baton = { range_callback, 0, {0}, cstr, (unsigned)strlen(cstr) };'''
+ # We must also define a snippet of code to be run that returns
+ # the result of the expression we run.
+ # Here we return NULL if our pointer was not found in any malloc blocks,
+ # and we return the address of the matches array so we can then access
+ # the matching results
+ user_return_code = '''if (baton.num_matches < MAX_MATCHES)
+ baton.matches[baton.num_matches].addr = 0; // Terminate the matches array
+baton.matches'''
+ # Iterate through all of our pointer expressions and display the results
+ for cstr in args:
+ user_init_code = user_init_code_format % (options.max_matches, cstr)
+ expr = get_iterate_memory_expr(options, process, user_init_code, user_return_code)
+ arg_str_description = 'malloc block containing "%s"' % cstr
+ display_match_results (result, options, arg_str_description, expr)
else:
- result.AppendMessage('error: no c string arguments were given to search for');
+ result.AppendMessage('error: command takes one or more C string arguments')
-def malloc_info(debugger, command, result, dict):
- command_args = shlex.split(command)
- usage = "usage: %prog [options] <EXPR> [EXPR ...]"
- description='''Searches the heap a malloc block that contains the addresses specified as arguments.
- Any matches that were found will dump the malloc blocks that match or contain
- the specified address. The matching blocks might be able to show what kind
- of objects they are using dynamic type information in the program.'''
- parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
+def get_malloc_info_options():
+ usage = "usage: %prog [options] <EXPR> [EXPR ...]"
+ description='''Searches the heap a malloc block that contains the addresses
+specified as one or more address expressions. Any matches that were found will
+dump the malloc blocks that match or contain the specified address. The matching
+blocks might be able to show what kind of objects they are using dynamic type
+information in the program.'''
+ parser = optparse.OptionParser(description=description, prog='malloc_info',usage=usage)
add_common_options(parser)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
- options.type = 'addr'
- if args:
- for data in args:
- heap_search (result, options, data)
- else:
- result.AppendMessage('error: no c string arguments were given to search for')
+ return parser
-def heap(debugger, command, result, dict):
+def malloc_info(debugger, command, result, dict):
command_args = shlex.split(command)
- usage = "usage: %prog [options] <EXPR> [EXPR ...]"
- description='''Traverse all allocations on the heap and report statistics.
-
- If programs set the MallocStackLogging=1 in the environment, then stack
- history is available for any allocations. '''
- parser = optparse.OptionParser(description=description, prog='cstr_refs',usage=usage)
- add_common_options(parser)
+ parser = get_malloc_info_options()
try:
(options, args) = parser.parse_args(command_args)
except:
return
- options.type = 'all'
+ malloc_info_impl (debugger, result, options, args)
+
+def malloc_info_impl (debugger, result, options, args):
+ # We are specifically looking for something on the heap only
+ options.type = 'malloc_info'
+
+ process = lldb.debugger.GetSelectedTarget().GetProcess()
+ if not process:
+ result.AppendMessage('error: invalid process')
+ return
+ frame = process.GetSelectedThread().GetSelectedFrame()
+ if not frame:
+ result.AppendMessage('error: invalid frame')
+ return
+
+ user_init_code_format = '''
+struct $malloc_match {
+ void *addr;
+ uintptr_t size;
+ uintptr_t offset;
+ uintptr_t type;
+};
+typedef struct callback_baton_t {
+ range_callback_t callback;
+ unsigned num_matches;
+ $malloc_match matches[2]; // Two items so they can be NULL terminated
+ void *ptr;
+} callback_baton_t;
+range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
+ callback_baton_t *info = (callback_baton_t *)baton;
+ if (info->num_matches == 0) {
+ uint8_t *p = (uint8_t *)info->ptr;
+ uint8_t *lo = (uint8_t *)ptr_addr;
+ uint8_t *hi = lo + ptr_size;
+ if (lo <= p && p < hi) {
+ info->matches[info->num_matches].addr = (void*)ptr_addr;
+ info->matches[info->num_matches].size = ptr_size;
+ info->matches[info->num_matches].offset = p - lo;
+ info->matches[info->num_matches].type = type;
+ info->num_matches = 1;
+ }
+ }
+};
+callback_baton_t baton = { range_callback, 0, {0}, (void *)%s };
+baton.matches[0].addr = 0;
+baton.matches[1].addr = 0;'''
if args:
- result.AppendMessage('error: heap command takes no arguments, only options')
+ total_matches = 0
+ for ptr_expr in args:
+ user_init_code = user_init_code_format % (ptr_expr)
+ expr = get_iterate_memory_expr(options, process, user_init_code, 'baton.matches')
+ arg_str_description = 'malloc block that contains %s' % ptr_expr
+ total_matches += display_match_results (result, options, arg_str_description, expr)
+ return total_matches
else:
- heap_search (result, options, None)
+ result.AppendMessage('error: command takes one or more pointer expressions')
+ return 0
-def stack_ptr_refs(debugger, command, result, dict):
- command_args = shlex.split(command)
- usage = "usage: %prog [options] <EXPR> [EXPR ...]"
- description='''Searches thread stack contents for pointer values in darwin user space programs.'''
- parser = optparse.OptionParser(description=description, prog='section_ptr_refs',usage=usage)
- add_common_options(parser)
- try:
- (options, args) = parser.parse_args(command_args)
- except:
- return
+def get_thread_stack_ranges_struct (process):
+ '''Create code that defines a structure that represents threads stack bounds
+ for all threads. It returns a static sized array initialized with all of
+ the tid, base, size structs for all the threads.'''
+ stack_dicts = list()
+ if process:
+ i = 0;
+ for thread in process:
+ min_sp = thread.frame[0].sp
+ max_sp = min_sp
+ for frame in thread.frames:
+ sp = frame.sp
+ if sp < min_sp: min_sp = sp
+ if sp > max_sp: max_sp = sp
+ if min_sp < max_sp:
+ stack_dicts.append ({ 'tid' : thread.GetThreadID(), 'base' : min_sp , 'size' : max_sp-min_sp, 'index' : i })
+ i += 1
+ stack_dicts_len = len(stack_dicts)
+ if stack_dicts_len > 0:
+ result = '''
+#define NUM_STACKS %u
+#define STACK_RED_ZONE_SIZE %u
+typedef struct thread_stack_t { uint64_t tid, base, size; } thread_stack_t;
+thread_stack_t stacks[NUM_STACKS];''' % (stack_dicts_len, process.target.GetStackRedZoneSize())
+ for stack_dict in stack_dicts:
+ result += '''
+stacks[%(index)u].tid = 0x%(tid)x;
+stacks[%(index)u].base = 0x%(base)x;
+stacks[%(index)u].size = 0x%(size)x;''' % stack_dict
+ return result
+ else:
+ return None
- options.type = 'pointer'
-
- stack_threads = list()
- stack_bases = list()
- stack_sizes = list()
- for thread in lldb.process:
- min_sp = thread.frame[0].sp
- max_sp = min_sp
- for frame in thread.frames:
- sp = frame.sp
- if sp < min_sp: min_sp = sp
- if sp > max_sp: max_sp = sp
- result.AppendMessage ('%s stack [%#x - %#x)' % (thread, min_sp, max_sp))
- if min_sp < max_sp:
- stack_threads.append (thread)
- stack_bases.append (min_sp)
- stack_sizes.append (max_sp-min_sp)
-
- if stack_bases:
- dylid_load_err = load_dylib()
- if dylid_load_err:
- result.AppendMessage(dylid_load_err)
- return
- for expr_str in args:
- for (idx, stack_base) in enumerate(stack_bases):
- stack_size = stack_sizes[idx]
- expr = 'find_pointer_in_memory(0x%xllu, %ullu, (void *)%s)' % (stack_base, stack_size, expr_str)
- arg_str_description = 'thead %s stack containing "%s"' % (stack_threads[idx], expr_str)
- num_matches = display_match_results (result, options, arg_str_description, lldb.frame.EvaluateExpression (expr), False)
- if num_matches:
- if num_matches < options.max_matches:
- options.max_matches = options.max_matches - num_matches
- else:
- options.max_matches = 0
- if options.max_matches == 0:
- return
+def get_sections_ranges_struct (process):
+ '''Create code that defines a structure that represents all segments that
+ can contain data for all images in "target". It returns a static sized
+ array initialized with all of base, size structs for all the threads.'''
+ target = process.target
+ segment_dicts = list()
+ for (module_idx, module) in enumerate(target.modules):
+ for sect_idx in range(module.GetNumSections()):
+ section = module.GetSectionAtIndex(sect_idx)
+ if not section:
+ break
+ name = section.name
+ if name != '__TEXT' and name != '__LINKEDIT' and name != '__PAGEZERO':
+ base = section.GetLoadAddress(target)
+ size = section.GetByteSize()
+ if base != lldb.LLDB_INVALID_ADDRESS and size > 0:
+ segment_dicts.append ({ 'base' : base, 'size' : size })
+ segment_dicts_len = len(segment_dicts)
+ if segment_dicts_len > 0:
+ result = '''
+#define NUM_SEGMENTS %u
+typedef struct segment_range_t { uint64_t base; uint32_t size; } segment_range_t;
+segment_range_t segments[NUM_SEGMENTS];''' % (segment_dicts_len,)
+ for (idx, segment_dict) in enumerate(segment_dicts):
+ segment_dict['index'] = idx
+ result += '''
+segments[%(index)u].base = 0x%(base)x;
+segments[%(index)u].size = 0x%(size)x;''' % segment_dict
+ return result
else:
- result.AppendMessage('error: no thread stacks were found that match any of %s' % (', '.join(options.section_names)))
+ return None
def section_ptr_refs(debugger, command, result, dict):
command_args = shlex.split(command)
@@ -501,7 +916,8 @@
result.AppendMessage('error: at least one section must be specified with the --section option')
return
- for module in lldb.target.modules:
+ target = lldb.debugger.GetSelectedTarget()
+ for module in target.modules:
for section_name in options.section_names:
section = module.section[section_name]
if section:
@@ -512,11 +928,12 @@
if dylid_load_err:
result.AppendMessage(dylid_load_err)
return
+ frame = target.GetProcess().GetSelectedThread().GetSelectedFrame()
for expr_str in args:
for (idx, section) in enumerate(sections):
expr = 'find_pointer_in_memory(0x%xllu, %ullu, (void *)%s)' % (section.addr.load_addr, section.size, expr_str)
arg_str_description = 'section %s.%s containing "%s"' % (section_modules[idx].file.fullpath, section.name, expr_str)
- num_matches = display_match_results (result, options, arg_str_description, lldb.frame.EvaluateExpression (expr), False)
+ num_matches = display_match_results (result, options, arg_str_description, expr, False)
if num_matches:
if num_matches < options.max_matches:
options.max_matches = options.max_matches - num_matches
@@ -527,53 +944,172 @@
else:
result.AppendMessage('error: no sections were found that match any of %s' % (', '.join(options.section_names)))
+def get_objc_refs_options():
+ usage = "usage: %prog [options] <CLASS> [CLASS ...]"
+ description='''Searches all allocations on the heap for instances of
+objective C classes, or any classes that inherit from the specified classes
+in darwin user space programs. Any matches that were found will dump the malloc
+blocks that contain the C strings and might be able to print what kind of
+objects the pointers are contained in using dynamic type information in the
+program.'''
+ parser = optparse.OptionParser(description=description, prog='objc_refs',usage=usage)
+ add_common_options(parser)
+ return parser
+
def objc_refs(debugger, command, result, dict):
command_args = shlex.split(command)
- usage = "usage: %prog [options] <EXPR> [EXPR ...]"
- description='''Find all heap allocations given one or more objective C class names.'''
- parser = optparse.OptionParser(description=description, prog='object_refs',usage=usage)
- add_common_options(parser)
+ parser = get_objc_refs_options()
try:
(options, args) = parser.parse_args(command_args)
except:
return
- dylid_load_err = load_dylib()
- if dylid_load_err:
- result.AppendMessage(dylid_load_err)
- else:
- if args:
- for class_name in args:
- addr_expr_str = "(void *)[%s class]" % class_name
- expr_sbvalue = lldb.frame.EvaluateExpression (addr_expr_str)
- if expr_sbvalue.error.Success():
- isa = expr_sbvalue.unsigned
- if isa:
- options.type = 'isa'
- result.AppendMessage('Searching for all instances of classes or subclasses of %s (isa=0x%x)' % (class_name, isa))
- heap_search (result, options, '0x%x' % isa)
- else:
- result.AppendMessage('error: Can\'t find isa for an ObjC class named "%s"' % (class_name))
+ process = lldb.debugger.GetSelectedTarget().GetProcess()
+ if not process:
+ result.AppendMessage('error: invalid process')
+ return
+ frame = process.GetSelectedThread().GetSelectedFrame()
+ if not frame:
+ result.AppendMessage('error: invalid frame')
+ return
+
+ options.type = 'isa'
+ if options.format == None:
+ options.format = "A" # 'A' is "address" format
+
+ num_objc_classes_value = frame.EvaluateExpression("(int)objc_getClassList((void *)0, (int)0)")
+ if not num_objc_classes_value.error.Success():
+ result.AppendMessage('error: %s' % num_objc_classes_value.error.GetCString())
+ return
+
+ num_objc_classes = num_objc_classes_value.GetValueAsUnsigned()
+ if num_objc_classes == 0:
+ result.AppendMessage('error: no objective C classes in program')
+ return
+
+ if args:
+ # When we initialize the expression, we must define any types that
+ # we will need when looking at every allocation. We must also define
+ # a type named callback_baton_t and make an instance named "baton"
+ # and initialize it how ever we want to. The address of "baton" will
+ # be passed into our range callback. callback_baton_t must contain
+ # a member named "callback" whose type is "range_callback_t". This
+ # will be used by our zone callbacks to call the range callback for
+ # each malloc range.
+ user_init_code_format = '''
+#define MAX_MATCHES %u
+struct $malloc_match {
+ void *addr;
+ uintptr_t size;
+ uintptr_t offset;
+ uintptr_t type;
+};
+typedef int (*compare_callback_t)(const void *a, const void *b);
+typedef struct callback_baton_t {
+ range_callback_t callback;
+ compare_callback_t compare_callback;
+ unsigned num_matches;
+ $malloc_match matches[MAX_MATCHES];
+ void *isa;
+ Class classes[%u];
+} callback_baton_t;
+compare_callback_t compare_callback = [](const void *a, const void *b) -> int {
+ Class a_ptr = *(Class *)a;
+ Class b_ptr = *(Class *)b;
+ if (a_ptr < b_ptr) return -1;
+ if (a_ptr > b_ptr) return +1;
+ return 0;
+};
+range_callback_t range_callback = [](task_t task, void *baton, unsigned type, uintptr_t ptr_addr, uintptr_t ptr_size) -> void {
+ callback_baton_t *info = (callback_baton_t *)baton;
+ if (sizeof(Class) <= ptr_size) {
+ Class *curr_class_ptr = (Class *)ptr_addr;
+ Class *matching_class_ptr = (Class *)bsearch (curr_class_ptr,
+ (const void *)info->classes,
+ sizeof(info->classes)/sizeof(Class),
+ sizeof(Class),
+ info->compare_callback);
+ if (matching_class_ptr) {
+ bool match = false;
+ if (info->isa) {
+ Class isa = *curr_class_ptr;
+ if (info->isa == isa)
+ match = true;
+ else { // if (info->objc.match_superclasses) {
+ Class super = (Class)class_getSuperclass(isa);
+ while (super) {
+ if (super == info->isa) {
+ match = true;
+ break;
+ }
+ super = (Class)class_getSuperclass(super);
+ }
+ }
+ }
+ else
+ match = true;
+ if (match) {
+ if (info->num_matches < MAX_MATCHES) {
+ info->matches[info->num_matches].addr = (void*)ptr_addr;
+ info->matches[info->num_matches].size = ptr_size;
+ info->matches[info->num_matches].offset = 0;
+ info->matches[info->num_matches].type = type;
+ ++info->num_matches;
+ }
+ }
+ }
+ }
+};
+callback_baton_t baton = { range_callback, compare_callback, 0, {0}, (void *)0x%x, {0} };
+int nc = (int)objc_getClassList(baton.classes, sizeof(baton.classes)/sizeof(Class));
+(void)qsort (baton.classes, sizeof(baton.classes)/sizeof(Class), sizeof(Class), compare_callback);'''
+ # We must also define a snippet of code to be run that returns
+ # the result of the expression we run.
+ # Here we return NULL if our pointer was not found in any malloc blocks,
+ # and we return the address of the matches array so we can then access
+ # the matching results
+ user_return_code = '''if (baton.num_matches < MAX_MATCHES)
+ baton.matches[baton.num_matches].addr = 0; // Terminate the matches array
+ baton.matches'''
+ # Iterate through all of our ObjC class name arguments
+ for class_name in args:
+ addr_expr_str = "(void *)[%s class]" % class_name
+ expr_sbvalue = frame.EvaluateExpression (addr_expr_str)
+ if expr_sbvalue.error.Success():
+ isa = expr_sbvalue.unsigned
+ if isa:
+ options.type = 'isa'
+ result.AppendMessage('Searching for all instances of classes or subclasses of "%s" (isa=0x%x)' % (class_name, isa))
+ user_init_code = user_init_code_format % (options.max_matches, num_objc_classes, isa)
+ expr = get_iterate_memory_expr(options, process, user_init_code, user_return_code)
+ arg_str_description = 'objective C classes with isa 0x%x' % isa
+ display_match_results (result, options, arg_str_description, expr)
else:
- result.AppendMessage('error: expression error for "%s": %s' % (addr_expr_str, expr_sbvalue.error))
- else:
- # Find all objective C objects by not specifying an isa
- options.type = 'isa'
- heap_search (result, options, '0x0')
+ result.AppendMessage('error: Can\'t find isa for an ObjC class named "%s"' % (class_name))
+ else:
+ result.AppendMessage('error: expression error for "%s": %s' % (addr_expr_str, expr_sbvalue.error))
+ else:
+ result.AppendMessage('error: command takes one or more C string arguments');
if __name__ == '__main__':
lldb.debugger = lldb.SBDebugger.Create()
-# This initializer is being run from LLDB in the embedded command interpreter
-# Add any commands contained in this module to LLDB
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.ptr_refs ptr_refs')
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.cstr_refs cstr_refs')
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.malloc_info malloc_info')
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.heap heap')
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.section_ptr_refs section_ptr_refs')
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.stack_ptr_refs stack_ptr_refs')
-lldb.debugger.HandleCommand('command script add -f lldb.macosx.heap.objc_refs objc_refs')
-print '"ptr_refs", "cstr_refs", "malloc_info", "heap", "section_ptr_refs" and "stack_ptr_refs" commands have been installed, use the "--help" options on these commands for detailed help.'
+# Make the options so we can generate the help text for the new LLDB
+# command line command prior to registering it with LLDB below. This way
+# if clients in LLDB type "help malloc_info", they will see the exact same
+# output as typing "malloc_info --help".
+ptr_refs.__doc__ = get_ptr_refs_options().format_help()
+cstr_refs.__doc__ = get_cstr_refs_options().format_help()
+malloc_info.__doc__ = get_malloc_info_options().format_help()
+objc_refs.__doc__ = get_objc_refs_options().format_help()
+lldb.debugger.HandleCommand('command script add -f %s.ptr_refs ptr_refs' % __name__)
+lldb.debugger.HandleCommand('command script add -f %s.cstr_refs cstr_refs' % __name__)
+lldb.debugger.HandleCommand('command script add -f %s.malloc_info malloc_info' % __name__)
+# lldb.debugger.HandleCommand('command script add -f %s.heap heap' % package_name)
+# lldb.debugger.HandleCommand('command script add -f %s.section_ptr_refs section_ptr_refs' % package_name)
+# lldb.debugger.HandleCommand('command script add -f %s.stack_ptr_refs stack_ptr_refs' % package_name)
+lldb.debugger.HandleCommand('command script add -f %s.objc_refs objc_refs' % __name__)
+print '"malloc_info", "ptr_refs", "cstr_refs", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.'
Index: aze/lldb/examples/python/cmdtemplate.py
===================================================================
--- aze.orig/lldb/examples/python/cmdtemplate.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/python/cmdtemplate.py 2013-03-03 09:35:50.051457355 +0100
@@ -38,6 +38,9 @@
try:
(options, args) = 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)
+ result.SetStatus (lldb.eReturnStatusFailed)
return
for arg in args:
Index: aze/lldb/examples/python/crashlog.py
===================================================================
--- aze.orig/lldb/examples/python/crashlog.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/python/crashlog.py 2013-03-03 09:35:50.051457355 +0100
@@ -83,6 +83,7 @@
class CrashLog(symbolication.Symbolicator):
"""Class that does parses darwin crash logs"""
+ parent_process_regex = re.compile('^Parent Process:\s*(.*)\[(\d+)\]');
thread_state_regex = re.compile('^Thread ([0-9]+) crashed with')
thread_regex = re.compile('^Thread ([0-9]+)([^:]*):(.*)')
frame_regex = re.compile('^([0-9]+) +([^ ]+) *\t?(0x[0-9a-fA-F]+) +(.*)')
@@ -265,9 +266,10 @@
else:
self.process = version_string
self.process_compatability_version = version_string
- elif line.startswith ('Parent Process:'):
- (self.parent_process_name, pid_with_brackets) = line[15:].strip().split()
- self.parent_process_id = pid_with_brackets.strip('[]')
+ elif self.parent_process_regex.search(line):
+ parent_process_match = self.parent_process_regex.search(line)
+ self.parent_process_name = parent_process_match.group(1)
+ self.parent_process_id = parent_process_match.group(2)
elif line.startswith ('Exception Type:'):
self.thread_exception = line[15:].strip()
continue
Index: aze/lldb/examples/python/operating_system.py
===================================================================
--- aze.orig/lldb/examples/python/operating_system.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/python/operating_system.py 2013-03-03 09:35:50.055457354 +0100
@@ -23,6 +23,14 @@
# tracks the current target in the LLDB command interpreter which isn't the
# correct thing to use for this plug-in.
return self.process.target
+
+ def create_thread(self, tid, context):
+ print 'tid type is: ' + str(type(tid))
+ if tid == 0x444444444:
+ thread_info = { 'tid' : tid, 'name' : 'four' , 'queue' : 'queue4', 'state' : 'stopped', 'stop_reason' : 'none' }
+ self.threads.append(thread_info)
+ return thread_info
+ return None
def get_thread_info(self):
if not self.threads:
@@ -37,6 +45,11 @@
# 'none' thread is just stopped because the process is stopped
# 'trace' the thread just single stepped
# The usual value for this while threads are in memory is 'none'
+ # register_data_addr => the address of the register data in memory (optional key/value pair)
+ # Specifying this key/value pair for a thread will avoid a call to get_register_data()
+ # and can be used when your registers are in a thread context structure that is contiguous
+ # in memory. Don't specify this if your register layout in memory doesn't match the layout
+ # described by the dictionary returned from a call to the get_register_info() method.
self.threads = [
{ 'tid' : 0x111111111, 'name' : 'one' , 'queue' : 'queue1', 'state' : 'stopped', 'stop_reason' : 'breakpoint'},
{ 'tid' : 0x222222222, 'name' : 'two' , 'queue' : 'queue2', 'state' : 'stopped', 'stop_reason' : 'none' },
@@ -84,4 +97,9 @@
return struct.pack('21Q',11,12,13,14,15,16,17,18,19,110,111,112,113,114,115,116,117,118,119,120,121);
elif tid == 0x333333333:
return struct.pack('21Q',21,22,23,24,25,26,27,28,29,210,211,212,213,214,215,216,217,218,219,220,221);
+ elif tid == 0x444444444:
+ return struct.pack('21Q',31,32,33,34,35,36,37,38,39,310,311,312,313,314,315,316,317,318,319,320,321);
+ else:
+ return struct.pack('21Q',41,42,43,44,45,46,47,48,49,410,411,412,413,414,415,416,417,418,419,420,421);
+ return None
Index: aze/lldb/examples/python/symbolication.py
===================================================================
--- aze.orig/lldb/examples/python/symbolication.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/python/symbolication.py 2013-03-03 09:35:50.055457354 +0100
@@ -419,9 +419,19 @@
if not self.target:
self.create_target()
if self.target:
- image = self.find_image_containing_load_addr (load_addr)
- if image:
- image.add_module (self.target)
+ live_process = False
+ process = self.target.process
+ if process:
+ state = process.state
+ if state > lldb.eStateUnloaded and state < lldb.eStateDetached:
+ live_process = True
+ # If we don't have a live process, we can attempt to find the image
+ # that a load address belongs to and lazily load its module in the
+ # target, but we shouldn't do any of this if we have a live process
+ if not live_process:
+ image = self.find_image_containing_load_addr (load_addr)
+ if image:
+ image.add_module (self.target)
symbolicated_address = Address(self.target, load_addr)
if symbolicated_address.symbolicate (verbose):
if symbolicated_address.so_addr:
Index: aze/lldb/examples/summaries/cocoa/Logger.py
===================================================================
--- aze.orig/lldb/examples/summaries/cocoa/Logger.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/summaries/cocoa/Logger.py 2013-03-03 09:35:50.055457354 +0100
@@ -58,10 +58,10 @@
self.file = None
# to enable logging:
-# define Logger._lldb_formatters_debug_level to any number greater than 0
+# define lldb.formatters.Logger._lldb_formatters_debug_level to any number greater than 0
# if you define it to any value greater than 1, the log will be automatically flushed after each write (slower but should make sure most of the stuff makes it to the log even if we crash)
# if you define it to any value greater than 2, the calling function's details will automatically be logged (even slower, but provides additional details)
-# if you need the log to go to a file instead of on screen, define Logger._lldb_formatters_debug_filename to a valid filename
+# if you need the log to go to a file instead of on screen, define lldb.formatters.Logger._lldb_formatters_debug_filename to a valid filename
class Logger:
def __init__(self,autoflush=False,logcaller=False):
global _lldb_formatters_debug_level
Index: aze/lldb/examples/summaries/cocoa/NSNumber.py
===================================================================
--- aze.orig/lldb/examples/summaries/cocoa/NSNumber.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/summaries/cocoa/NSNumber.py 2013-03-03 09:35:50.055457354 +0100
@@ -54,7 +54,7 @@
if self.info_bits == 12:
return '(long)' + str(ctypes.c_long(self.data).value)
else:
- return 'absurd value:(info=' + str(self.info_bits) + ", value = " + str(self.data) + ')'
+ return 'unexpected value:(info=' + str(self.info_bits) + ", value = " + str(self.data) + ')'
class NSUntaggedNumber_SummaryProvider:
@@ -158,7 +158,7 @@
statistics.metric_hit('code_notrun',self.valobj)
return '(double)' + str(data_double)
statistics.metric_hit('unknown_class',str(valobj.GetName()) + " had unknown data_type " + str(data_type))
- return 'absurd: dt = ' + str(data_type)
+ return 'unexpected: dt = ' + str(data_type)
class NSUnknownNumber_SummaryProvider:
Index: aze/lldb/examples/summaries/cocoa/NSURL.py
===================================================================
--- aze.orig/lldb/examples/summaries/cocoa/NSURL.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/summaries/cocoa/NSURL.py 2013-03-03 09:35:50.055457354 +0100
@@ -43,7 +43,10 @@
# one pointer is the ISA
# then there is one more pointer and 8 bytes of plain data
# (which are also present on a 32-bit system)
- # plus another pointer, and then the real data
+ # then there is a pointer to an NSString which is the url text
+ # optionally, the next pointer is another NSURL which is the "base"
+ # of this one when doing NSURLs composition (incidentally, NSURLs can
+ # recurse the base+text mechanism to any desired depth)
def offset_text(self):
logger = lldb.formatters.Logger.Logger()
return 24 if self.sys_params.is_64_bit else 16
Index: aze/lldb/examples/summaries/cocoa/objc_runtime.py
===================================================================
--- aze.orig/lldb/examples/summaries/cocoa/objc_runtime.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/summaries/cocoa/objc_runtime.py 2013-03-03 09:35:50.055457354 +0100
@@ -242,17 +242,6 @@
logger >> "Marking as invalid - cachePointer is not allowed"
self.valid = 0
return
-
- self.vtablePointer = Utilities.read_child_of(self.valobj,3*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
- if not(Utilities.is_valid_pointer(self.vtablePointer,self.sys_params.pointer_size,allow_tagged=0)):
- logger >> "Marking as invalid - vtablePointer is invalid"
- self.valid = 0
- return
- if not(Utilities.is_allowed_pointer(self.vtablePointer)):
- logger >> "Marking as invalid - vtablePointer is not allowed"
- self.valid = 0
- return
-
self.dataPointer = Utilities.read_child_of(self.valobj,4*self.sys_params.pointer_size,self.sys_params.types_cache.addr_ptr_type)
if not(Utilities.is_valid_pointer(self.dataPointer,self.sys_params.pointer_size,allow_tagged=0)):
logger >> "Marking as invalid - dataPointer is invalid"
@@ -321,7 +310,6 @@
return 'isaPointer = ' + hex(self.isaPointer) + "\n" + \
"superclassIsaPointer = " + hex(self.superclassIsaPointer) + "\n" + \
"cachePointer = " + hex(self.cachePointer) + "\n" + \
- "vtablePointer = " + hex(self.vtablePointer) + "\n" + \
"data = " + hex(self.dataPointer)
def is_tagged(self):
@@ -594,7 +582,7 @@
global isa_caches
process = valobj.GetTarget().GetProcess()
- self.pid = process.GetProcessID()
+ self.pid = process.GetUniqueID() # using the unique ID for added guarantees (see svn revision 172628 for further details)
if runtime_version.look_for_key(self.pid):
self.runtime_version = runtime_version.get_value(self.pid)
Index: aze/lldb/examples/synthetic/gnu_libstdcpp.py
===================================================================
--- aze.orig/lldb/examples/synthetic/gnu_libstdcpp.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/synthetic/gnu_libstdcpp.py 2013-03-03 09:35:50.055457354 +0100
@@ -133,24 +133,6 @@
pass
def has_children(self):
- logger = lldb.formatters.Logger.Logger()
- if self.count == None:
- self.update ()
- try:
- next_val = self.next.GetValueAsUnsigned(0)
- prev_val = self.prev.GetValueAsUnsigned(0)
- if next_val == 0 or prev_val == 0:
- return False
- if next_val == self.node_address:
- return False
- # skip all the advanced logic to detect the exact count of children
- # in the interest of speed from this point on, we MIGHT have children
- # our loop detection logic will still make nothing show up :)
- return True
- except:
- return False
- if self.count == 0:
- return False
return True
class StdVectorSynthProvider:
@@ -249,7 +231,7 @@
def has_children(self):
- return self.num_children() > 0
+ return True
class StdMapSynthProvider:
@@ -434,7 +416,7 @@
return x;
def has_children(self):
- return self.num_children() > 0
+ return True
_map_capping_size = 255
_list_capping_size = 255
Index: aze/lldb/examples/synthetic/libcxx.py
===================================================================
--- aze.orig/lldb/examples/synthetic/libcxx.py 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/examples/synthetic/libcxx.py 2013-03-03 09:35:50.059457354 +0100
@@ -6,6 +6,9 @@
# ships with current releases of OS X - They will not work for other implementations
# of the standard C++ library - and they are bound to use the libc++-specific namespace
+# the std::string summary is just an example for your convenience
+# the actual summary that LLDB uses is C++ code inside the debugger's own core
+
# this could probably be made more efficient but since it only reads a handful of bytes at a time
# we probably don't need to worry too much about this for the time being
def make_string(F,L):
@@ -125,8 +128,7 @@
pass
def has_children(self):
- # retrieving the count is quick enough on a std::vector
- return self.num_children() > 0
+ return True
# Just an example: the actual summary is produced by a summary string: size=${svar%#}
def stdvector_SummaryProvider(valobj,dict):
@@ -322,24 +324,6 @@
pass
def has_children(self):
- logger = lldb.formatters.Logger.Logger()
- if self.count == None:
- self.update()
- try:
- next_val = self.head.GetValueAsUnsigned(0)
- prev_val = self.tail.GetValueAsUnsigned(0)
- if next_val == 0 or prev_val == 0:
- return False
- if next_val == self.node_address:
- return False
- # skip all the advanced logic to detect the exact count of children
- # in the interest of speed from this point on, we MIGHT have children
- # our loop detection logic will still make nothing show up :)
- return True
- except:
- return 0;
- if self.count == 0:
- return False
return True
@@ -504,7 +488,7 @@
return 0;
def has_children(self):
- return self.num_children_impl() > 0
+ return True
def get_data_type(self):
logger = lldb.formatters.Logger.Logger()
@@ -577,8 +561,12 @@
else:
# FIXME we need to have accessed item 0 before accessing any other item!
if self.skip_size == None:
- logger >> "You asked for item > 0 before asking for item == 0, too bad - I have no clue"
- return None
+ logger >> "You asked for item > 0 before asking for item == 0, I will fetch 0 now then retry"
+ if self.get_child_at_index(0):
+ return self.get_child_at_index(index)
+ else:
+ logger >> "item == 0 could not be found. sorry, nothing can be done here."
+ return None
return current.CreateChildAtOffset('[' + str(index) + ']',self.skip_size,self.data_type)
else:
logger >> "Unable to infer data-type - returning None (should mark tree as garbage here?)"
@@ -629,9 +617,7 @@
return min(self.count, _deque_capping_size)
def has_children(self):
- if self.cont is None:
- self.update()
- return self.count > 0
+ return True
def get_child_index(self,name):
logger = lldb.formatters.Logger.Logger()
Index: aze/lldb/include/lldb/API/SBCommandInterpreter.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBCommandInterpreter.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBCommandInterpreter.h 2013-03-03 09:35:50.059457354 +0100
@@ -85,8 +85,18 @@
lldb::ReturnStatus
HandleCommand (const char *command_line, lldb::SBCommandReturnObject &result, bool add_to_history = false);
- // This 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...
+ // 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...
+
+ // 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,
+ // 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
+ // type further to disambiguate.
+
int
HandleCompletion (const char *current_line,
const char *cursor,
Index: aze/lldb/include/lldb/API/SBData.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBData.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBData.h 2013-03-03 09:35:50.059457354 +0100
@@ -49,47 +49,47 @@
SetByteOrder (lldb::ByteOrder endian);
float
- GetFloat (lldb::SBError& error, uint32_t offset);
+ GetFloat (lldb::SBError& error, lldb::offset_t offset);
double
- GetDouble (lldb::SBError& error, uint32_t offset);
+ GetDouble (lldb::SBError& error, lldb::offset_t offset);
long double
- GetLongDouble (lldb::SBError& error, uint32_t offset);
+ GetLongDouble (lldb::SBError& error, lldb::offset_t offset);
lldb::addr_t
- GetAddress (lldb::SBError& error, uint32_t offset);
+ GetAddress (lldb::SBError& error, lldb::offset_t offset);
uint8_t
- GetUnsignedInt8 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset);
uint16_t
- GetUnsignedInt16 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset);
uint32_t
- GetUnsignedInt32 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset);
uint64_t
- GetUnsignedInt64 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset);
int8_t
- GetSignedInt8 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset);
int16_t
- GetSignedInt16 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset);
int32_t
- GetSignedInt32 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset);
int64_t
- GetSignedInt64 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset);
const char*
- GetString (lldb::SBError& error, uint32_t offset);
+ GetString (lldb::SBError& error, lldb::offset_t offset);
size_t
ReadRawData (lldb::SBError& error,
- uint32_t offset,
+ lldb::offset_t offset,
void *buf,
size_t size);
Index: aze/lldb/include/lldb/API/SBDebugger.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBDebugger.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBDebugger.h 2013-03-03 09:35:50.059457354 +0100
@@ -78,7 +78,7 @@
void
SetErrorFileHandle (FILE *f, bool transfer_ownership);
-
+
FILE *
GetInputFileHandle ();
@@ -88,6 +88,12 @@
FILE *
GetErrorFileHandle ();
+ void
+ SaveInputTerminalState();
+
+ void
+ RestoreInputTerminalState();
+
lldb::SBCommandInterpreter
GetCommandInterpreter ();
Index: aze/lldb/include/lldb/API/SBEvent.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBEvent.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBEvent.h 2013-03-03 09:35:50.059457354 +0100
@@ -75,6 +75,7 @@
friend class SBDebugger;
friend class SBProcess;
friend class SBThread;
+ friend class SBWatchpoint;
SBEvent (lldb::EventSP &event_sp);
Index: aze/lldb/include/lldb/API/SBExpressionOptions.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBExpressionOptions.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBExpressionOptions.h 2013-03-03 09:35:50.059457354 +0100
@@ -20,9 +20,6 @@
class SBExpressionOptions
{
-friend class SBFrame;
-friend class SBValue;
-
public:
SBExpressionOptions();
@@ -43,7 +40,13 @@
GetUnwindOnError () const;
void
- SetUnwindOnError (bool unwind = false);
+ SetUnwindOnError (bool unwind = true);
+
+ bool
+ GetIgnoreBreakpoints () const;
+
+ void
+ SetIgnoreBreakpoints (bool ignore = true);
lldb::DynamicValueType
GetFetchDynamicValue () const;
@@ -73,6 +76,10 @@
lldb_private::EvaluateExpressionOptions &
ref () const;
+ friend class SBFrame;
+ friend class SBValue;
+ friend class SBTarget;
+
private:
// This auto_pointer is made in the constructor and is always valid.
mutable std::auto_ptr<lldb_private::EvaluateExpressionOptions> m_opaque_ap;
Index: aze/lldb/include/lldb/API/SBFrame.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBFrame.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBFrame.h 2013-03-03 09:35:50.059457354 +0100
@@ -12,7 +12,6 @@
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBValueList.h"
-#include "lldb/API/SBWatchpoint.h"
namespace lldb {
Index: aze/lldb/include/lldb/API/SBFunction.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBFunction.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBFunction.h 2013-03-03 09:35:50.059457354 +0100
@@ -41,6 +41,9 @@
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor);
+
lldb::SBAddress
GetStartAddress ();
Index: aze/lldb/include/lldb/API/SBHostOS.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBHostOS.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBHostOS.h 2013-03-03 09:35:50.063457355 +0100
@@ -21,6 +21,9 @@
static lldb::SBFileSpec
GetProgramFileSpec ();
+
+ static lldb::SBFileSpec
+ GetLLDBPythonPath ();
static void
ThreadCreated (const char *name);
Index: aze/lldb/include/lldb/API/SBModule.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBModule.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBModule.h 2013-03-03 09:35:50.063457355 +0100
@@ -120,6 +120,14 @@
lldb::SBSymbol
GetSymbolAtIndex (size_t idx);
+ lldb::SBSymbol
+ FindSymbol (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
+ lldb::SBSymbolContextList
+ FindSymbols (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
size_t
GetNumSections ();
@@ -167,12 +175,30 @@
const char *name,
uint32_t max_matches);
+ //------------------------------------------------------------------
+ /// Find the first global (or static) variable by name.
+ ///
+ /// @param[in] target
+ /// A valid SBTarget instance representing the debuggee.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @return
+ /// An SBValue that gets filled in with the found variable (if any).
+ //------------------------------------------------------------------
+ lldb::SBValue
+ FindFirstGlobalVariable (lldb::SBTarget &target, const char *name);
+
lldb::SBType
FindFirstType (const char* name);
lldb::SBTypeList
FindTypes (const char* type);
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
//------------------------------------------------------------------
/// Get the module version numbers.
Index: aze/lldb/include/lldb/API/SBProcess.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBProcess.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBProcess.h 2013-03-03 09:35:50.063457355 +0100
@@ -30,7 +30,8 @@
eBroadcastBitStateChanged = (1 << 0),
eBroadcastBitInterrupt = (1 << 1),
eBroadcastBitSTDOUT = (1 << 2),
- eBroadcastBitSTDERR = (1 << 3)
+ eBroadcastBitSTDERR = (1 << 3),
+ eBroadcastBitProfileData = (1 << 4)
};
SBProcess ();
@@ -74,6 +75,9 @@
size_t
GetSTDERR (char *dst, size_t dst_len) const;
+ size_t
+ GetAsyncProfileData(char *dst, size_t dst_len) const;
+
void
ReportEventState (const lldb::SBEvent &event, FILE *out) const;
@@ -118,6 +122,15 @@
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.
+ //------------------------------------------------------------------
+ lldb::SBThread
+ CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
+
bool
SetSelectedThread (const lldb::SBThread &thread);
@@ -140,9 +153,39 @@
const char *
GetExitDescription ();
+ //------------------------------------------------------------------
+ /// Gets the process ID
+ ///
+ /// Returns the process identifier for the process as it is known
+ /// on the system on which the process is running. For unix systems
+ /// this is typically the same as if you called "getpid()" in the
+ /// process.
+ ///
+ /// @return
+ /// Returns LLDB_INVALID_PROCESS_ID if this object does not
+ /// contain a valid process object, or if the process has not
+ /// been launched. Returns a valid process ID if the process is
+ /// valid.
+ //------------------------------------------------------------------
lldb::pid_t
GetProcessID ();
+ //------------------------------------------------------------------
+ /// Gets the unique ID associated with this process object
+ ///
+ /// Unique IDs start at 1 and increment up with each new process
+ /// instance. Since starting a process on a system might always
+ /// create a process with the same process ID, there needs to be a
+ /// way to tell two process instances apart.
+ ///
+ /// @return
+ /// Returns a non-zero integer ID if this object contains a
+ /// valid process object, zero if this object does not contain
+ /// a valid process object.
+ //------------------------------------------------------------------
+ uint32_t
+ GetUniqueID();
+
uint32_t
GetAddressByteSize() const;
@@ -167,6 +210,9 @@
void
SendAsyncInterrupt();
+ uint32_t
+ GetStopID(bool include_expression_stops = false);
+
size_t
ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
@@ -188,6 +234,12 @@
static bool
GetRestartedFromEvent (const lldb::SBEvent &event);
+
+ static size_t
+ GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event);
+
+ static const char *
+ GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx);
static lldb::SBProcess
GetProcessFromEvent (const lldb::SBEvent &event);
Index: aze/lldb/include/lldb/API/SBSymbol.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBSymbol.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBSymbol.h 2013-03-03 09:35:50.063457355 +0100
@@ -43,6 +43,9 @@
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor_string);
+
SBAddress
GetStartAddress ();
Index: aze/lldb/include/lldb/API/SBTarget.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBTarget.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBTarget.h 2013-03-03 09:35:50.063457355 +0100
@@ -17,6 +17,7 @@
#include "lldb/API/SBFileSpecList.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/API/SBType.h"
+#include "lldb/API/SBValue.h"
#include "lldb/API/SBWatchpoint.h"
namespace lldb {
@@ -235,7 +236,8 @@
{
eBroadcastBitBreakpointChanged = (1 << 0),
eBroadcastBitModulesLoaded = (1 << 1),
- eBroadcastBitModulesUnloaded = (1 << 2)
+ eBroadcastBitModulesUnloaded = (1 << 2),
+ eBroadcastBitWatchpointChanged = (1 << 3)
};
//------------------------------------------------------------------
@@ -601,6 +603,19 @@
FindGlobalVariables (const char *name,
uint32_t max_matches);
+ //------------------------------------------------------------------
+ /// Find the first global (or static) variable by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @return
+ /// An SBValue that gets filled in with the found variable (if any).
+ //------------------------------------------------------------------
+ lldb::SBValue
+ FindFirstGlobalVariable (const char* name);
+
void
Clear ();
@@ -719,6 +734,9 @@
lldb::SBTypeList
FindTypes (const char* type);
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
+
SBSourceManager
GetSourceManager();
@@ -726,11 +744,27 @@
ReadInstructions (lldb::SBAddress base_addr, uint32_t count);
lldb::SBInstructionList
+ ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string);
+
+ lldb::SBInstructionList
GetInstructions (lldb::SBAddress base_addr, 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.
+
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);
+
lldb::SBInstructionList
GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size);
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size);
+
+ lldb::SBSymbolContextList
+ FindSymbols (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
bool
operator == (const lldb::SBTarget &rhs) const;
@@ -740,6 +774,12 @@
bool
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+ lldb::SBValue
+ EvaluateExpression (const char *expr, const SBExpressionOptions &options);
+
+ lldb::addr_t
+ GetStackRedZoneSize();
+
protected:
friend class SBAddress;
friend class SBBlock;
Index: aze/lldb/include/lldb/API/SBThread.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBThread.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBThread.h 2013-03-03 09:35:50.063457355 +0100
@@ -26,7 +26,8 @@
eBroadcastBitStackChanged = (1 << 0),
eBroadcastBitThreadSuspended = (1 << 1),
eBroadcastBitThreadResumed = (1 << 2),
- eBroadcastBitSelectedFrameChanged = (1 << 3)
+ eBroadcastBitSelectedFrameChanged = (1 << 3),
+ eBroadcastBitThreadSelected = (1 << 4)
};
static const char *
@@ -67,6 +68,7 @@
/// eStopReasonWatchpoint 1 watchpoint id
/// eStopReasonSignal 1 unix signal number
/// eStopReasonException N exception data
+ /// eStopReasonExec 0
/// eStopReasonPlanComplete 0
//--------------------------------------------------------------------------
uint64_t
@@ -97,6 +99,9 @@
StepInto (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
void
+ StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
+ void
StepOut ();
void
Index: aze/lldb/include/lldb/API/SBType.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBType.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBType.h 2013-03-03 09:35:50.063457355 +0100
@@ -108,6 +108,8 @@
lldb::SBType
GetUnqualifiedType();
+ lldb::SBType
+ GetCanonicalType();
// Get the "lldb::BasicType" enumeration for a type. If a type is not a basic
// type eBasicTypeInvalid will be returned
lldb::BasicType
Index: aze/lldb/include/lldb/API/SBTypeSynthetic.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBTypeSynthetic.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBTypeSynthetic.h 2013-03-03 09:35:50.063457355 +0100
@@ -79,15 +79,15 @@
friend class SBTypeCategory;
friend class SBValue;
- lldb::TypeSyntheticImplSP
+ lldb::ScriptedSyntheticChildrenSP
GetSP ();
void
- SetSP (const lldb::TypeSyntheticImplSP &typefilter_impl_sp);
+ SetSP (const lldb::ScriptedSyntheticChildrenSP &typefilter_impl_sp);
- lldb::TypeSyntheticImplSP m_opaque_sp;
+ lldb::ScriptedSyntheticChildrenSP m_opaque_sp;
- SBTypeSynthetic (const lldb::TypeSyntheticImplSP &);
+ SBTypeSynthetic (const lldb::ScriptedSyntheticChildrenSP &);
bool
CopyOnWrite_Impl();
Index: aze/lldb/include/lldb/API/SBValue.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBValue.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBValue.h 2013-03-03 09:35:50.067457356 +0100
@@ -419,6 +419,7 @@
protected:
friend class SBBlock;
friend class SBFrame;
+ friend class SBTarget;
friend class SBThread;
friend class SBValueList;
Index: aze/lldb/include/lldb/API/SBValueList.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBValueList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBValueList.h 2013-03-03 09:35:50.067457356 +0100
@@ -12,6 +12,10 @@
#include "lldb/API/SBDefines.h"
+namespace {
+ class ValueListImpl;
+}
+
namespace lldb {
class SBValueList
@@ -48,28 +52,17 @@
const lldb::SBValueList &
operator = (const lldb::SBValueList &rhs);
- lldb_private::ValueObjectList *
- operator -> ();
-
- lldb_private::ValueObjectList &
- operator* ();
-
- const lldb_private::ValueObjectList *
- operator -> () const;
-
- const lldb_private::ValueObjectList &
- operator* () const;
+protected:
- lldb_private::ValueObjectList *
- get ();
-
- lldb_private::ValueObjectList &
- ref ();
+ // 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:
friend class SBFrame;
-
- SBValueList (const lldb_private::ValueObjectList *lldb_object_ptr);
+
+ SBValueList (const ValueListImpl *lldb_object_ptr);
void
Append (lldb::ValueObjectSP& val_obj_sp);
@@ -77,7 +70,23 @@
void
CreateIfNeeded ();
- std::auto_ptr<lldb_private::ValueObjectList> m_opaque_ap;
+ ValueListImpl *
+ operator -> ();
+
+ ValueListImpl &
+ operator* ();
+
+ const ValueListImpl *
+ operator -> () const;
+
+ const ValueListImpl &
+ operator* () const;
+
+
+ ValueListImpl &
+ ref ();
+
+ std::auto_ptr<ValueListImpl> m_opaque_ap;
};
Index: aze/lldb/include/lldb/API/SBWatchpoint.h
===================================================================
--- aze.orig/lldb/include/lldb/API/SBWatchpoint.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/API/SBWatchpoint.h 2013-03-03 09:35:50.067457356 +0100
@@ -81,6 +81,15 @@
void
SetSP (const lldb::WatchpointSP &sp);
+ static bool
+ EventIsWatchpointEvent (const lldb::SBEvent &event);
+
+ static lldb::WatchpointEventType
+ GetWatchpointEventTypeFromEvent (const lldb::SBEvent& event);
+
+ static lldb::SBWatchpoint
+ GetWatchpointFromEvent (const lldb::SBEvent& event);
+
private:
friend class SBTarget;
friend class SBValue;
Index: aze/lldb/include/lldb/Breakpoint/Breakpoint.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/Breakpoint.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/Breakpoint.h 2013-03-03 09:35:50.067457356 +0100
@@ -136,7 +136,7 @@
static lldb::BreakpointLocationSP
GetBreakpointLocationAtIndexFromEvent (const lldb::EventSP &event_sp, uint32_t loc_idx);
- static uint32_t
+ static size_t
GetNumBreakpointLocationsFromEvent (const lldb::EventSP &event_sp);
static const BreakpointEventData *
@@ -310,7 +310,7 @@
/// greater than then number of actual locations.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
- GetLocationAtIndex (uint32_t index);
+ GetLocationAtIndex (size_t index);
//------------------------------------------------------------------
// The next section deals with various breakpoint options.
@@ -489,6 +489,32 @@
GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations = false);
//------------------------------------------------------------------
+ /// 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.
+ ///
+ /// @param[in] kind
+ /// New "kind" description.
+ //------------------------------------------------------------------
+ void
+ SetBreakpointKind (const char *kind)
+ {
+ m_kind_description.assign (kind);
+ }
+
+ //------------------------------------------------------------------
+ /// Return the "kind" description for a breakpoint.
+ ///
+ /// @return
+ /// The breakpoint kind, or NULL if none is set.
+ //------------------------------------------------------------------
+ const char *GetBreakpointKind () const
+ {
+ return m_kind_description.c_str();
+ }
+
+ //------------------------------------------------------------------
/// Accessor for the breakpoint Target.
/// @return
/// This breakpoint's Target.
@@ -588,6 +614,7 @@
lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines this breakpoint.
BreakpointOptions m_options; // Settable breakpoint options
BreakpointLocationList m_locations; // The list of locations currently found for this breakpoint.
+ std::string m_kind_description;
void
SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind);
Index: aze/lldb/include/lldb/Breakpoint/BreakpointIDList.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/BreakpointIDList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/BreakpointIDList.h 2013-03-03 09:35:50.067457356 +0100
@@ -41,10 +41,10 @@
GetSize();
BreakpointID &
- GetBreakpointIDAtIndex (uint32_t index);
+ GetBreakpointIDAtIndex (size_t index);
bool
- RemoveBreakpointIDAtIndex (uint32_t index);
+ RemoveBreakpointIDAtIndex (size_t index);
void
Clear();
@@ -56,16 +56,16 @@
AddBreakpointID (const char *bp_id);
bool
- FindBreakpointID (BreakpointID &bp_id, uint32_t *position);
+ FindBreakpointID (BreakpointID &bp_id, size_t *position);
bool
- FindBreakpointID (const char *bp_id, uint32_t *position);
+ FindBreakpointID (const char *bp_id, size_t *position);
void
- InsertStringArray (const char **string_array, uint32_t array_size, CommandReturnObject &result);
+ InsertStringArray (const char **string_array, size_t array_size, CommandReturnObject &result);
static bool
- StringContainsIDRangeExpression (const char *in_string, uint32_t *range_start_len, uint32_t *range_end_pos);
+ StringContainsIDRangeExpression (const char *in_string, size_t *range_start_len, size_t *range_end_pos);
static void
FindAndReplaceIDRanges (Args &old_args, Target *target, CommandReturnObject &result, Args &new_args);
Index: aze/lldb/include/lldb/Breakpoint/BreakpointList.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/BreakpointList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/BreakpointList.h 2013-03-03 09:35:50.067457356 +0100
@@ -92,7 +92,7 @@
/// breakpoint doesn't exist.
//------------------------------------------------------------------
lldb::BreakpointSP
- GetBreakpointAtIndex (uint32_t i);
+ GetBreakpointAtIndex (size_t i);
//------------------------------------------------------------------
/// Returns a shared pointer to the breakpoint with index \a i, const version
@@ -105,7 +105,7 @@
/// breakpoint doesn't exist.
//------------------------------------------------------------------
const lldb::BreakpointSP
- GetBreakpointAtIndex (uint32_t i) const;
+ GetBreakpointAtIndex (size_t i) const;
//------------------------------------------------------------------
/// Returns the number of elements in this breakpoint list.
Index: aze/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h 2013-03-03 09:35:50.067457356 +0100
@@ -101,7 +101,7 @@
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
- GetByIndex (uint32_t i);
+ GetByIndex (size_t i);
//------------------------------------------------------------------
/// Returns a shared pointer to the breakpoint location with index
@@ -115,7 +115,7 @@
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
const lldb::BreakpointLocationSP
- GetByIndex (uint32_t i) const;
+ GetByIndex (size_t i) const;
//------------------------------------------------------------------
/// Returns the number of elements in this breakpoint location list.
@@ -171,6 +171,14 @@
//------------------------------------------------------------------
bool ValidForThisThread (Thread *thread);
+ //------------------------------------------------------------------
+ /// Tell whether ALL the breakpoints in the location collection are internal.
+ ///
+ /// @result
+ /// \b true if all breakpoint locations are owned by internal breakpoints,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool IsInternal() const;
protected:
Index: aze/lldb/include/lldb/Breakpoint/BreakpointLocationList.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/BreakpointLocationList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/BreakpointLocationList.h 2013-03-03 09:35:50.067457356 +0100
@@ -119,7 +119,7 @@
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
- GetByIndex (uint32_t i);
+ GetByIndex (size_t i);
//------------------------------------------------------------------
/// Returns a shared pointer to the breakpoint location with index
@@ -133,7 +133,7 @@
/// pointer if the breakpoint doesn't exist.
//------------------------------------------------------------------
const lldb::BreakpointLocationSP
- GetByIndex (uint32_t i) const;
+ GetByIndex (size_t i) const;
//------------------------------------------------------------------
/// Removes all the locations in this list from their breakpoint site
Index: aze/lldb/include/lldb/Breakpoint/BreakpointSite.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/BreakpointSite.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/BreakpointSite.h 2013-03-03 09:35:50.067457356 +0100
@@ -83,7 +83,7 @@
//------------------------------------------------------------------
bool
SetTrapOpcode (const uint8_t *trap_opcode,
- size_t trap_opcode_size);
+ uint32_t trap_opcode_size);
//------------------------------------------------------------------
/// Gets the original instruction bytes that were overwritten by the trap
@@ -168,7 +168,7 @@
/// @return
/// The number of owners.
//------------------------------------------------------------------
- uint32_t
+ size_t
GetNumberOfOwners ();
//------------------------------------------------------------------
@@ -183,7 +183,7 @@
/// A shared pointer to the breakpoint location at that index.
//------------------------------------------------------------------
lldb::BreakpointLocationSP
- GetOwnerAtIndex (uint32_t index);
+ GetOwnerAtIndex (size_t idx);
//------------------------------------------------------------------
/// Check whether the owners of this breakpoint site have any
@@ -220,9 +220,29 @@
GetDescription (Stream *s,
lldb::DescriptionLevel level);
+ //------------------------------------------------------------------
+ /// Tell whether a breakpoint has a location at this site.
+ ///
+ /// @param[in] bp_id
+ /// The breakpoint id to query.
+ ///
+ /// @result
+ /// \b true if bp_id has a location that is at this site,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
bool
IsBreakpointAtThisSite (lldb::break_id_t bp_id);
+ //------------------------------------------------------------------
+ /// Tell whether ALL the breakpoints in the location collection are internal.
+ ///
+ /// @result
+ /// \b true if all breakpoint locations are owned by internal breakpoints,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ IsInternal () const;
+
BreakpointSite::Type
GetType () const
{
@@ -244,7 +264,7 @@
/// @param[in] context
/// \a break_loc_id is the Breakpoint Location to remove.
//------------------------------------------------------------------
- uint32_t
+ size_t
RemoveOwner (lldb::break_id_t break_id,
lldb::break_id_t break_loc_id);
@@ -265,7 +285,6 @@
BreakpointSite (BreakpointSiteList *list,
const lldb::BreakpointLocationSP& owner,
lldb::addr_t m_addr,
- lldb::tid_t tid,
bool use_hardware);
DISALLOW_COPY_AND_ASSIGN(BreakpointSite);
Index: aze/lldb/include/lldb/Breakpoint/Watchpoint.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/Watchpoint.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/Watchpoint.h 2013-03-03 09:35:50.067457356 +0100
@@ -28,11 +28,55 @@
namespace lldb_private {
class Watchpoint :
+ public STD_ENABLE_SHARED_FROM_THIS(Watchpoint),
public StoppointLocation
{
public:
- Watchpoint (Target& target, lldb::addr_t addr, size_t size, const ClangASTType *type, bool hardware = true);
+ class WatchpointEventData :
+ public EventData
+ {
+ public:
+
+ static const ConstString &
+ GetFlavorString ();
+
+ virtual const ConstString &
+ GetFlavor () const;
+
+ WatchpointEventData (lldb::WatchpointEventType sub_type,
+ const lldb::WatchpointSP &new_watchpoint_sp);
+
+ virtual
+ ~WatchpointEventData();
+
+ lldb::WatchpointEventType
+ GetWatchpointEventType () const;
+
+ lldb::WatchpointSP &
+ GetWatchpoint ();
+
+ virtual void
+ Dump (Stream *s) const;
+
+ static lldb::WatchpointEventType
+ GetWatchpointEventTypeFromEvent (const lldb::EventSP &event_sp);
+
+ static lldb::WatchpointSP
+ GetWatchpointFromEvent (const lldb::EventSP &event_sp);
+
+ static const WatchpointEventData *
+ GetEventDataFromEvent (const Event *event_sp);
+
+ private:
+
+ lldb::WatchpointEventType m_watchpoint_event;
+ lldb::WatchpointSP m_new_watchpoint_sp;
+
+ DISALLOW_COPY_AND_ASSIGN (WatchpointEventData);
+ };
+
+ Watchpoint (Target& target, lldb::addr_t addr, uint32_t size, const ClangASTType *type, bool hardware = true);
~Watchpoint ();
void
@@ -42,7 +86,7 @@
IsEnabled () const;
void
- SetEnabled (bool enabled);
+ SetEnabled (bool enabled, bool notify = true);
virtual bool
IsHardware () const;
@@ -54,7 +98,7 @@
bool WatchpointWrite () const;
uint32_t GetIgnoreCount () const;
void SetIgnoreCount (uint32_t n);
- void SetWatchpointType (uint32_t type);
+ void SetWatchpointType (uint32_t type, bool notify = true);
void SetDeclInfo (const std::string &str);
std::string GetWatchSpec();
void SetWatchSpec (const std::string &str);
@@ -188,10 +232,17 @@
Error m_error; // An error object describing errors associated with this watchpoint.
WatchpointOptions m_options; // Settable watchpoint options, which is a delegate to handle
// the callback machinery.
+ bool m_being_created;
std::auto_ptr<ClangUserExpression> m_condition_ap; // The condition to test.
void SetID(lldb::watch_id_t id) { m_loc_id = id; }
+
+ void
+ SendWatchpointChangedEvent (lldb::WatchpointEventType eventKind);
+
+ void
+ SendWatchpointChangedEvent (WatchpointEventData *data);
DISALLOW_COPY_AND_ASSIGN (Watchpoint);
};
Index: aze/lldb/include/lldb/Breakpoint/WatchpointList.h
===================================================================
--- aze.orig/lldb/include/lldb/Breakpoint/WatchpointList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Breakpoint/WatchpointList.h 2013-03-03 09:35:50.067457356 +0100
@@ -58,7 +58,7 @@
/// The ID of the Watchpoint in the list.
//------------------------------------------------------------------
lldb::watch_id_t
- Add (const lldb::WatchpointSP& wp_sp);
+ Add (const lldb::WatchpointSP& wp_sp, bool notify);
//------------------------------------------------------------------
/// Standard "Dump" method.
@@ -180,7 +180,7 @@
/// \b true if the watchpoint \a watchID was in the list.
//------------------------------------------------------------------
bool
- Remove (lldb::watch_id_t watchID);
+ Remove (lldb::watch_id_t watchID, bool notify);
//------------------------------------------------------------------
/// Returns the number hit count of all watchpoints in this list.
@@ -241,7 +241,7 @@
SetEnabledAll (bool enabled);
void
- RemoveAll ();
+ RemoveAll (bool notify);
//------------------------------------------------------------------
/// Sets the passed in Locker to hold the Watchpoint List mutex.
Index: aze/lldb/include/lldb/Core/Address.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Address.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Address.h 2013-03-03 09:35:50.067457356 +0100
@@ -302,7 +302,7 @@
/// the address is currently not loaded.
//------------------------------------------------------------------
lldb::addr_t
- GetCallableLoadAddress (Target *target) const;
+ GetCallableLoadAddress (Target *target, bool is_indirect = false) const;
//------------------------------------------------------------------
/// Get the load address as an opcode load address.
Index: aze/lldb/include/lldb/Core/ArchSpec.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ArchSpec.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ArchSpec.h 2013-03-03 09:35:50.067457356 +0100
@@ -159,7 +159,7 @@
const ArchSpec&
operator= (const ArchSpec& rhs);
- static uint32_t
+ static size_t
AutoComplete (const char *name,
StringList &matches);
@@ -389,7 +389,7 @@
protected:
bool
- Compare (const ArchSpec& rhs, bool exact_match) const;
+ IsEqualTo (const ArchSpec& rhs, bool exact_match) const;
llvm::Triple m_triple;
Core m_core;
@@ -401,35 +401,6 @@
CoreUpdated (bool update_triple);
};
-
-//------------------------------------------------------------------
-/// @fn bool operator== (const ArchSpec& lhs, const ArchSpec& rhs)
-/// @brief Equal to operator.
-///
-/// Tests two ArchSpec objects to see if they are equal.
-///
-/// @param[in] lhs The Left Hand Side ArchSpec object to compare.
-/// @param[in] rhs The Left Hand Side ArchSpec object to compare.
-///
-/// Uses the IsExactMatch() method for comparing the cpu types.
-///
-/// @return true if \a lhs is equal to \a rhs
-//------------------------------------------------------------------
-bool operator==(const ArchSpec& lhs, const ArchSpec& rhs);
-
-//------------------------------------------------------------------
-/// @fn bool operator!= (const ArchSpec& lhs, const ArchSpec& rhs)
-/// @brief Not equal to operator.
-///
-/// Tests two ArchSpec objects to see if they are not equal.
-///
-/// @param[in] lhs The Left Hand Side ArchSpec object to compare.
-/// @param[in] rhs The Left Hand Side ArchSpec object to compare.
-///
-/// @return true if \a lhs is not equal to \a rhs
-//------------------------------------------------------------------
-bool operator!=(const ArchSpec& lhs, const ArchSpec& rhs);
-
//------------------------------------------------------------------
/// @fn bool operator< (const ArchSpec& lhs, const ArchSpec& rhs)
/// @brief Less than operator.
Index: aze/lldb/include/lldb/Core/Broadcaster.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Broadcaster.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/Broadcaster.h 2013-03-03 09:35:50.067457356 +0100
@@ -233,7 +233,8 @@
/// eBroadcastBitStateChanged = (1 << 0),
/// eBroadcastBitInterrupt = (1 << 1),
/// eBroadcastBitSTDOUT = (1 << 2),
-/// eBroadcastBitSTDERR = (1 << 3)
+/// eBroadcastBitSTDERR = (1 << 3),
+/// eBroadcastBitProfileData = (1 << 4)
/// };
/// \endcode
//----------------------------------------------------------------------
Index: aze/lldb/include/lldb/Core/CXXFormatterFunctions.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/CXXFormatterFunctions.h 2013-03-03 09:35:47.779457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,332 +0,0 @@
-//===-- CXXFormatterFunctions.h------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_CXXFormatterFunctions_h_
-#define liblldb_CXXFormatterFunctions_h_
-
-#include <stdint.h>
-#include "lldb/lldb-forward.h"
-
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/FormatClasses.h"
-
-#include "clang/AST/ASTContext.h"
-
-namespace lldb_private {
- namespace formatters
- {
-
- bool
- ExtractValueFromObjCExpression (ValueObject &valobj,
- const char* target_type,
- const char* selector,
- uint64_t &value);
-
- lldb::ValueObjectSP
- CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- uint64_t index);
-
- lldb::ValueObjectSP
- CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- const char* key);
-
- template<bool name_entries>
- bool
- NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream);
-
- bool
- NSArraySummaryProvider (ValueObject& valobj, Stream& stream);
-
- template<bool needs_at>
- bool
- NSDataSummaryProvider (ValueObject& valobj, Stream& stream);
-
- bool
- NSNumberSummaryProvider (ValueObject& valobj, Stream& stream);
-
- bool
- NSStringSummaryProvider (ValueObject& valobj, Stream& stream);
-
- bool
- ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream);
-
- template <bool is_sel_ptr>
- bool
- ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream);
-
- bool
- RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream);
-
- extern template bool
- NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
-
- extern template bool
- NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
-
- extern template bool
- NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
-
- extern template bool
- NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
-
- extern template bool
- ObjCSELSummaryProvider<true> (ValueObject&, Stream&);
-
- extern template bool
- ObjCSELSummaryProvider<false> (ValueObject&, Stream&);
-
- class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- private:
- struct DataDescriptor_32
- {
- uint32_t _used;
- uint32_t _priv1 : 2 ;
- uint32_t _size : 30;
- uint32_t _priv2 : 2;
- uint32_t offset : 30;
- uint32_t _priv3;
- uint32_t _data;
- };
- struct DataDescriptor_64
- {
- uint64_t _used;
- uint64_t _priv1 : 2 ;
- uint64_t _size : 62;
- uint64_t _priv2 : 2;
- uint64_t offset : 62;
- uint32_t _priv3;
- uint64_t _data;
- };
- public:
- NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- virtual uint32_t
- CalculateNumChildren ();
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update();
-
- virtual bool
- MightHaveChildren ();
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name);
-
- virtual
- ~NSArrayMSyntheticFrontEnd ();
- private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- ClangASTType m_id_type;
- std::vector<lldb::ValueObjectSP> m_children;
- };
-
- class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- virtual uint32_t
- CalculateNumChildren ();
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update();
-
- virtual bool
- MightHaveChildren ();
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name);
-
- virtual
- ~NSArrayISyntheticFrontEnd ();
- private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- uint64_t m_items;
- lldb::addr_t m_data_ptr;
- ClangASTType m_id_type;
- std::vector<lldb::ValueObjectSP> m_children;
- };
-
- class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- virtual uint32_t
- CalculateNumChildren ();
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update();
-
- virtual bool
- MightHaveChildren ();
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name);
-
- virtual
- ~NSArrayCodeRunningSyntheticFrontEnd ();
- };
-
- SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- private:
- struct DataDescriptor_32
- {
- uint32_t _used : 26;
- uint32_t _szidx : 6;
- };
- struct DataDescriptor_64
- {
- uint64_t _used : 58;
- uint32_t _szidx : 6;
- };
-
- struct DictionaryItemDescriptor
- {
- lldb::addr_t key_ptr;
- lldb::addr_t val_ptr;
- lldb::ValueObjectSP valobj_sp;
- };
-
- public:
- NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- virtual uint32_t
- CalculateNumChildren ();
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update();
-
- virtual bool
- MightHaveChildren ();
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name);
-
- virtual
- ~NSDictionaryISyntheticFrontEnd ();
- private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- lldb::addr_t m_data_ptr;
- std::vector<DictionaryItemDescriptor> m_children;
- };
-
- class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- private:
- struct DataDescriptor_32
- {
- uint32_t _used : 26;
- uint32_t _kvo : 1;
- uint32_t _size;
- uint32_t _mutations;
- uint32_t _objs_addr;
- uint32_t _keys_addr;
- };
- struct DataDescriptor_64
- {
- uint64_t _used : 58;
- uint32_t _kvo : 1;
- uint64_t _size;
- uint64_t _mutations;
- uint64_t _objs_addr;
- uint64_t _keys_addr;
- };
- struct DictionaryItemDescriptor
- {
- lldb::addr_t key_ptr;
- lldb::addr_t val_ptr;
- lldb::ValueObjectSP valobj_sp;
- };
- public:
- NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- virtual uint32_t
- CalculateNumChildren ();
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update();
-
- virtual bool
- MightHaveChildren ();
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name);
-
- virtual
- ~NSDictionaryMSyntheticFrontEnd ();
- private:
- ExecutionContextRef m_exe_ctx_ref;
- uint8_t m_ptr_size;
- uint64_t m_items;
- DataDescriptor_32 *m_data_32;
- DataDescriptor_64 *m_data_64;
- std::vector<DictionaryItemDescriptor> m_children;
- };
-
- class NSDictionaryCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
- {
- public:
- NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
-
- virtual uint32_t
- CalculateNumChildren ();
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update();
-
- virtual bool
- MightHaveChildren ();
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name);
-
- virtual
- ~NSDictionaryCodeRunningSyntheticFrontEnd ();
- };
-
- SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
-
- }
-}
-
-#endif
Index: aze/lldb/include/lldb/Core/DataExtractor.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/DataExtractor.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/DataExtractor.h 2013-03-03 09:35:50.071457356 +0100
@@ -86,7 +86,7 @@
/// @param[in] addr_size
/// A new address byte size value.
//------------------------------------------------------------------
- DataExtractor (const void* data, uint32_t data_length, lldb::ByteOrder byte_order, uint8_t addr_size);
+ DataExtractor (const void* data, lldb::offset_t data_length, lldb::ByteOrder byte_order, uint32_t addr_size);
//------------------------------------------------------------------
/// Construct with shared data.
@@ -105,7 +105,7 @@
/// @param[in] addr_size
/// A new address byte size value.
//------------------------------------------------------------------
- DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint8_t addr_size);
+ DataExtractor (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint32_t addr_size);
//------------------------------------------------------------------
/// Construct with a subset of \a data.
@@ -130,7 +130,7 @@
/// @param[in] length
/// The length in bytes of the subset of data.
//------------------------------------------------------------------
- DataExtractor (const DataExtractor& data, uint32_t offset, uint32_t length);
+ DataExtractor (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length);
DataExtractor (const DataExtractor& rhs);
//------------------------------------------------------------------
@@ -204,10 +204,10 @@
/// @return
/// The offset at which dumping ended.
//------------------------------------------------------------------
- uint32_t
+ lldb::offset_t
PutToLog (Log *log,
- uint32_t offset,
- uint32_t length,
+ lldb::offset_t offset,
+ lldb::offset_t length,
uint64_t base_addr,
uint32_t num_per_line,
Type type,
@@ -273,13 +273,13 @@
/// @return
/// The offset at which dumping ended.
//------------------------------------------------------------------
- uint32_t
+ lldb::offset_t
Dump (Stream *s,
- uint32_t offset,
+ lldb::offset_t offset,
lldb::Format item_format,
- uint32_t item_byte_size,
- uint32_t item_count,
- uint32_t num_per_line,
+ size_t item_byte_size,
+ size_t item_count,
+ size_t num_per_line,
uint64_t base_addr,
uint32_t item_bit_size,
uint32_t item_bit_offset,
@@ -300,7 +300,7 @@
/// UUID value.
//------------------------------------------------------------------
void
- DumpUUID (Stream *s, uint32_t offset) const;
+ DumpUUID (Stream *s, lldb::offset_t offset) const;
//------------------------------------------------------------------
/// Extract an arbitrary number of bytes in the specified byte
@@ -332,7 +332,7 @@
/// if there aren't enough bytes at the specified offset.
//------------------------------------------------------------------
size_t
- ExtractBytes (uint32_t offset, uint32_t length, lldb::ByteOrder dst_byte_order, void *dst) const;
+ ExtractBytes (lldb::offset_t offset, lldb::offset_t length, lldb::ByteOrder dst_byte_order, void *dst) const;
//------------------------------------------------------------------
/// Extract an address from \a *offset_ptr.
@@ -353,10 +353,10 @@
/// The extracted address value.
//------------------------------------------------------------------
uint64_t
- GetAddress (uint32_t *offset_ptr) const;
+ GetAddress (lldb::offset_t *offset_ptr) const;
uint64_t
- GetAddress_unchecked (uint32_t *offset_ptr) const;
+ GetAddress_unchecked (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Get the current address size.
@@ -367,7 +367,7 @@
/// @return
/// The size in bytes of address values that will be extracted.
//------------------------------------------------------------------
- uint8_t
+ uint32_t
GetAddressByteSize () const
{
return m_addr_size;
@@ -379,7 +379,7 @@
/// @return
/// The total number of bytes of data this object refers to.
//------------------------------------------------------------------
- size_t
+ uint64_t
GetByteSize () const
{
return m_end - m_start;
@@ -408,7 +408,7 @@
/// NULL will be returned.
//------------------------------------------------------------------
const char *
- GetCStr (uint32_t *offset_ptr) const;
+ GetCStr (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract \a length bytes from \a *offset_ptr.
@@ -434,7 +434,13 @@
/// and length are valid, or NULL otherwise.
//------------------------------------------------------------------
const void*
- GetData (uint32_t *offset_ptr, uint32_t length) const;
+ GetData (lldb::offset_t *offset_ptr, lldb::offset_t length) const
+ {
+ const uint8_t *ptr = PeekData (*offset_ptr, length);
+ if (ptr)
+ *offset_ptr += length;
+ return ptr;
+ }
//------------------------------------------------------------------
/// Copy \a dst_len bytes from \a *offset_ptr and ensure the copied
@@ -475,11 +481,11 @@
/// Returns the number of bytes that were copied, or zero if
/// anything goes wrong.
//------------------------------------------------------------------
- uint32_t
- CopyByteOrderedData (uint32_t src_offset,
- uint32_t src_len,
+ lldb::offset_t
+ CopyByteOrderedData (lldb::offset_t src_offset,
+ lldb::offset_t src_len,
void *dst,
- uint32_t dst_len,
+ lldb::offset_t dst_len,
lldb::ByteOrder dst_byte_order) const;
//------------------------------------------------------------------
@@ -538,13 +544,13 @@
/// The floating value that was extracted, or zero on failure.
//------------------------------------------------------------------
float
- GetFloat (uint32_t *offset_ptr) const;
+ GetFloat (lldb::offset_t *offset_ptr) const;
double
- GetDouble (uint32_t *offset_ptr) const;
+ GetDouble (lldb::offset_t *offset_ptr) const;
long double
- GetLongDouble (uint32_t *offset_ptr) const;
+ GetLongDouble (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract a GNU encoded pointer value from \a *offset_ptr.
@@ -575,7 +581,11 @@
/// The extracted GNU encoded pointer value.
//------------------------------------------------------------------
uint64_t
- GetGNUEHPointer (uint32_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr, lldb::addr_t text_addr, lldb::addr_t data_addr);
+ GetGNUEHPointer (lldb::offset_t *offset_ptr,
+ uint32_t eh_ptr_enc,
+ lldb::addr_t pc_rel_addr,
+ lldb::addr_t text_addr,
+ lldb::addr_t data_addr);
//------------------------------------------------------------------
/// Extract an integer of size \a byte_size from \a *offset_ptr.
@@ -601,7 +611,7 @@
/// The integer value that was extracted, or zero on failure.
//------------------------------------------------------------------
uint32_t
- GetMaxU32 (uint32_t *offset_ptr, uint32_t byte_size) const;
+ GetMaxU32 (lldb::offset_t *offset_ptr, size_t byte_size) const;
//------------------------------------------------------------------
/// Extract an unsigned integer of size \a byte_size from \a
@@ -630,10 +640,10 @@
/// failure.
//------------------------------------------------------------------
uint64_t
- GetMaxU64 (uint32_t *offset_ptr, uint32_t byte_size) const;
+ GetMaxU64 (lldb::offset_t *offset_ptr, size_t byte_size) const;
uint64_t
- GetMaxU64_unchecked (uint32_t *offset_ptr, uint32_t byte_size) const;
+ GetMaxU64_unchecked (lldb::offset_t *offset_ptr, size_t byte_size) const;
//------------------------------------------------------------------
/// Extract an signed integer of size \a byte_size from \a *offset_ptr.
@@ -661,7 +671,7 @@
/// or zero on failure.
//------------------------------------------------------------------
int64_t
- GetMaxS64 (uint32_t *offset_ptr, uint32_t size) const;
+ GetMaxS64 (lldb::offset_t *offset_ptr, size_t size) const;
//------------------------------------------------------------------
/// Extract an unsigned integer of size \a byte_size from \a
@@ -700,7 +710,10 @@
/// zero on failure.
//------------------------------------------------------------------
uint64_t
- GetMaxU64Bitfield (uint32_t *offset_ptr, uint32_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const;
+ GetMaxU64Bitfield (lldb::offset_t *offset_ptr,
+ size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const;
//------------------------------------------------------------------
/// Extract an signed integer of size \a byte_size from \a
@@ -739,7 +752,10 @@
/// zero on failure.
//------------------------------------------------------------------
int64_t
- GetMaxS64Bitfield (uint32_t *offset_ptr, uint32_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const;
+ GetMaxS64Bitfield (lldb::offset_t *offset_ptr,
+ size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const;
//------------------------------------------------------------------
/// Extract an pointer from \a *offset_ptr.
@@ -760,7 +776,7 @@
/// The extracted pointer value as a 64 integer.
//------------------------------------------------------------------
uint64_t
- GetPointer (uint32_t *offset_ptr) const;
+ GetPointer (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Get the current byte order value.
@@ -792,10 +808,10 @@
/// The extracted uint8_t value.
//------------------------------------------------------------------
uint8_t
- GetU8 ( uint32_t *offset_ptr) const;
+ GetU8 ( lldb::offset_t *offset_ptr) const;
uint8_t
- GetU8_unchecked (uint32_t *offset_ptr) const
+ GetU8_unchecked (lldb::offset_t *offset_ptr) const
{
uint8_t val = m_start[*offset_ptr];
*offset_ptr += 1;
@@ -803,13 +819,13 @@
}
uint16_t
- GetU16_unchecked (uint32_t *offset_ptr) const;
+ GetU16_unchecked (lldb::offset_t *offset_ptr) const;
uint32_t
- GetU32_unchecked (uint32_t *offset_ptr) const;
+ GetU32_unchecked (lldb::offset_t *offset_ptr) const;
uint64_t
- GetU64_unchecked (uint32_t *offset_ptr) const;
+ GetU64_unchecked (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract \a count uint8_t values from \a *offset_ptr.
///
@@ -836,7 +852,7 @@
/// NULL otherise.
//------------------------------------------------------------------
void *
- GetU8 ( uint32_t *offset_ptr, void *dst, uint32_t count) const;
+ GetU8 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
//------------------------------------------------------------------
/// Extract a uint16_t value from \a *offset_ptr.
@@ -855,7 +871,7 @@
/// The extracted uint16_t value.
//------------------------------------------------------------------
uint16_t
- GetU16 (uint32_t *offset_ptr) const;
+ GetU16 (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract \a count uint16_t values from \a *offset_ptr.
@@ -883,7 +899,7 @@
/// NULL otherise.
//------------------------------------------------------------------
void *
- GetU16 (uint32_t *offset_ptr, void *dst, uint32_t count) const;
+ GetU16 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
//------------------------------------------------------------------
/// Extract a uint32_t value from \a *offset_ptr.
@@ -902,7 +918,7 @@
/// The extracted uint32_t value.
//------------------------------------------------------------------
uint32_t
- GetU32 (uint32_t *offset_ptr) const;
+ GetU32 (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract \a count uint32_t values from \a *offset_ptr.
@@ -930,7 +946,7 @@
/// NULL otherise.
//------------------------------------------------------------------
void *
- GetU32 (uint32_t *offset_ptr, void *dst, uint32_t count) const;
+ GetU32 (lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
//------------------------------------------------------------------
/// Extract a uint64_t value from \a *offset_ptr.
@@ -949,7 +965,7 @@
/// The extracted uint64_t value.
//------------------------------------------------------------------
uint64_t
- GetU64 (uint32_t *offset_ptr) const;
+ GetU64 (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract \a count uint64_t values from \a *offset_ptr.
@@ -977,7 +993,7 @@
/// NULL otherise.
//------------------------------------------------------------------
void *
- GetU64 ( uint32_t *offset_ptr, void *dst, uint32_t count) const;
+ GetU64 ( lldb::offset_t *offset_ptr, void *dst, uint32_t count) const;
//------------------------------------------------------------------
/// Extract a signed LEB128 value from \a *offset_ptr.
@@ -998,7 +1014,7 @@
/// The extracted signed integer value.
//------------------------------------------------------------------
int64_t
- GetSLEB128 (uint32_t *offset_ptr) const;
+ GetSLEB128 (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Extract a unsigned LEB128 value from \a *offset_ptr.
@@ -1019,7 +1035,7 @@
/// The extracted unsigned integer value.
//------------------------------------------------------------------
uint64_t
- GetULEB128 (uint32_t *offset_ptr) const;
+ GetULEB128 (lldb::offset_t *offset_ptr) const;
lldb::DataBufferSP &
GetSharedDataBuffer ()
@@ -1042,7 +1058,7 @@
/// NULL otherwise.
//------------------------------------------------------------------
const char *
- PeekCStr (uint32_t offset) const;
+ PeekCStr (lldb::offset_t offset) const;
//------------------------------------------------------------------
/// Peek at a bytes at \a offset.
@@ -1056,7 +1072,12 @@
/// otherwise.
//------------------------------------------------------------------
const uint8_t*
- PeekData (uint32_t offset, uint32_t length) const;
+ PeekData (lldb::offset_t offset, lldb::offset_t length) const
+ {
+ if (length > 0 && ValidOffsetForDataOfSize(offset, length))
+ return m_start + offset;
+ return NULL;
+ }
//------------------------------------------------------------------
/// Set the address byte size.
@@ -1068,7 +1089,7 @@
/// The size in bytes to use when extracting addresses.
//------------------------------------------------------------------
void
- SetAddressByteSize (uint8_t addr_size)
+ SetAddressByteSize (uint32_t addr_size)
{
m_addr_size = addr_size;
}
@@ -1094,8 +1115,8 @@
/// @return
/// The number of bytes that this object now contains.
//------------------------------------------------------------------
- uint32_t
- SetData (const void *bytes, uint32_t length, lldb::ByteOrder byte_order);
+ lldb::offset_t
+ SetData (const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order);
//------------------------------------------------------------------
/// Adopt a subset of \a data.
@@ -1123,8 +1144,8 @@
/// @return
/// The number of bytes that this object now contains.
//------------------------------------------------------------------
- uint32_t
- SetData (const DataExtractor& data, uint32_t offset, uint32_t length);
+ lldb::offset_t
+ SetData (const DataExtractor& data, lldb::offset_t offset, lldb::offset_t length);
//------------------------------------------------------------------
/// Adopt a subset of shared data in \a data_sp.
@@ -1151,8 +1172,8 @@
/// @return
/// The number of bytes that this object now contains.
//------------------------------------------------------------------
- uint32_t
- SetData (const lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT32_MAX);
+ lldb::offset_t
+ SetData (const lldb::DataBufferSP& data_sp, lldb::offset_t offset = 0, lldb::offset_t length = LLDB_INVALID_OFFSET);
//------------------------------------------------------------------
/// Set the byte_order value.
@@ -1188,7 +1209,7 @@
// The number of bytes consumed during the extraction.
//------------------------------------------------------------------
uint32_t
- Skip_LEB128 (uint32_t *offset_ptr) const;
+ Skip_LEB128 (lldb::offset_t *offset_ptr) const;
//------------------------------------------------------------------
/// Test the validity of \a offset.
@@ -1198,7 +1219,7 @@
/// object, \b false otherwise.
//------------------------------------------------------------------
bool
- ValidOffset (uint32_t offset) const
+ ValidOffset (lldb::offset_t offset) const
{
return offset < GetByteSize();
}
@@ -1211,7 +1232,11 @@
/// length bytes available at that offset, \b false otherwise.
//------------------------------------------------------------------
bool
- ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const;
+ ValidOffsetForDataOfSize (lldb::offset_t offset, lldb::offset_t length) const
+ {
+ lldb::offset_t bytes_left = BytesLeft (offset);
+ return length <= bytes_left;
+ }
size_t
Copy (DataExtractor& dest_data) const;
@@ -1220,16 +1245,26 @@
Append (DataExtractor& rhs);
bool
- Append (void* bytes, uint32_t length);
+ Append (void* bytes, lldb::offset_t length);
protected:
+
+ lldb::offset_t
+ BytesLeft (lldb::offset_t offset) const
+ {
+ const lldb::offset_t size = GetByteSize();
+ if (offset >= size)
+ return 0;
+ return offset - size;
+ }
+
//------------------------------------------------------------------
// Member variables
//------------------------------------------------------------------
const uint8_t * m_start; ///< A pointer to the first byte of data.
const uint8_t * m_end; ///< A pointer to the byte that is past the end of the data.
lldb::ByteOrder m_byte_order; ///< The byte order of the data we are extracting from.
- uint8_t m_addr_size; ///< The address size to use when extracting pointers or addresses
+ uint32_t m_addr_size; ///< The address size to use when extracting pointers or addresses
mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multilple instances
};
Index: aze/lldb/include/lldb/Core/DataVisualization.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/DataVisualization.h 2013-03-03 09:35:47.779457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,174 +0,0 @@
-//===-- DataVisualization.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_DataVisualization_h_
-#define lldb_DataVisualization_h_
-
-// C Includes
-// C++ Includes
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/FormatClasses.h"
-#include "lldb/Core/FormatManager.h"
-
-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
-// 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
- static void
- ForceUpdate();
-
- static uint32_t
- GetCurrentRevision ();
-
- class ValueFormats
- {
- public:
- static lldb::TypeFormatImplSP
- GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic);
-
- static lldb::TypeFormatImplSP
- GetFormat (const ConstString &type);
-
- static void
- Add (const ConstString &type, const lldb::TypeFormatImplSP &entry);
-
- static bool
- Delete (const ConstString &type);
-
- static void
- Clear ();
-
- static void
- LoopThrough (TypeFormatImpl::ValueCallback callback, void* callback_baton);
-
- static uint32_t
- GetCount ();
-
- static lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierForFormatAtIndex (uint32_t);
-
- static lldb::TypeFormatImplSP
- GetFormatAtIndex (uint32_t);
- };
-
- static lldb::TypeSummaryImplSP
- GetSummaryFormat(ValueObject& valobj,
- lldb::DynamicValueType use_dynamic);
-
- static lldb::TypeSummaryImplSP
- GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
-
-#ifndef LLDB_DISABLE_PYTHON
- static lldb::SyntheticChildrenSP
- GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
-#endif
-
- static lldb::TypeFilterImplSP
- GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
-
-#ifndef LLDB_DISABLE_PYTHON
- static lldb::TypeSyntheticImplSP
- GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
- static lldb::SyntheticChildrenSP
- GetSyntheticChildren(ValueObject& valobj,
- lldb::DynamicValueType use_dynamic);
-#endif
-
- static bool
- AnyMatches(ConstString type_name,
- TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
- bool only_enabled = true,
- const char** matching_category = NULL,
- TypeCategoryImpl::FormatCategoryItems* matching_type = NULL);
-
- class NamedSummaryFormats
- {
- public:
- static bool
- GetSummaryFormat (const ConstString &type, lldb::TypeSummaryImplSP &entry);
-
- static void
- Add (const ConstString &type, const lldb::TypeSummaryImplSP &entry);
-
- static bool
- Delete (const ConstString &type);
-
- static void
- Clear ();
-
- static void
- LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton);
-
- static uint32_t
- GetCount ();
- };
-
- class Categories
- {
- public:
-
- static bool
- GetCategory (const ConstString &category,
- lldb::TypeCategoryImplSP &entry,
- bool allow_create = true);
-
- static void
- Add (const ConstString &category);
-
- static bool
- Delete (const ConstString &category);
-
- static void
- Clear ();
-
- static void
- Clear (const ConstString &category);
-
- static void
- Enable (const ConstString& category,
- CategoryMap::Position = CategoryMap::Default);
-
- static void
- Disable (const ConstString& category);
-
- static void
- Enable (const lldb::TypeCategoryImplSP& category,
- CategoryMap::Position = CategoryMap::Default);
-
- static void
- Disable (const lldb::TypeCategoryImplSP& category);
-
- static void
- LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton);
-
- static uint32_t
- GetCount ();
-
- static lldb::TypeCategoryImplSP
- GetCategoryAtIndex (uint32_t);
- };
-};
-
-
-} // namespace lldb_private
-
-#endif // lldb_DataVisualization_h_
Index: aze/lldb/include/lldb/Core/Debugger.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Debugger.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/Debugger.h 2013-03-03 09:35:50.071457356 +0100
@@ -23,13 +23,14 @@
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/InputReaderStack.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Core/UserID.h"
#include "lldb/Core/UserSettingsController.h"
+#include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/Terminal.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Platform.h"
@@ -116,6 +117,12 @@
void
SetErrorFileHandle (FILE *fh, bool tranfer_ownership);
+
+ void
+ SaveInputTerminalState();
+
+ void
+ RestoreInputTerminalState();
Stream&
GetOutputStream ()
@@ -220,11 +227,11 @@
static lldb::DebuggerSP
FindDebuggerWithInstanceName (const ConstString &instance_name);
- static uint32_t
+ static size_t
GetNumDebuggers();
static lldb::DebuggerSP
- GetDebuggerAtIndex (uint32_t);
+ GetDebuggerAtIndex (size_t index);
static bool
FormatPrompt (const char *format,
@@ -351,6 +358,7 @@
StreamFile m_input_file;
StreamFile m_output_file;
StreamFile m_error_file;
+ TerminalState m_terminal_state;
TargetList m_target_list;
PlatformList m_platform_list;
Listener m_listener;
@@ -361,7 +369,7 @@
InputReaderStack m_input_reader_stack;
std::string m_input_reader_data;
- typedef std::map<std::string, lldb::StreamSP> LogStreamMap;
+ typedef std::map<std::string, lldb::StreamWP> LogStreamMap;
LogStreamMap m_log_streams;
lldb::StreamSP m_log_callback_stream_sp;
ConstString m_instance_name;
Index: aze/lldb/include/lldb/Core/Disassembler.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Disassembler.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Disassembler.h 2013-03-03 09:35:50.071457356 +0100
@@ -13,6 +13,7 @@
// C Includes
// C++ Includes
#include <vector>
+#include <string>
// Other libraries and framework includes
// Project includes
@@ -51,7 +52,7 @@
GetOperands (const ExecutionContext* exe_ctx)
{
CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
- return m_mnemocics.c_str();
+ return m_mnemonics.c_str();
}
const char *
@@ -88,8 +89,8 @@
virtual size_t
Decode (const Disassembler &disassembler,
- const DataExtractor& data,
- uint32_t data_offset) = 0;
+ const DataExtractor& data,
+ lldb::offset_t data_offset) = 0;
virtual void
SetDescription (const char *) {} // May be overridden in sub-classes that have descriptions.
@@ -137,7 +138,7 @@
protected:
Opcode m_opcode; // The opcode for this instruction
std::string m_opcode_name;
- std::string m_mnemocics;
+ std::string m_mnemonics;
std::string m_comment;
bool m_calculated_strings;
@@ -166,7 +167,7 @@
GetMaxOpcocdeByteSize () const;
lldb::InstructionSP
- GetInstructionAtIndex (uint32_t idx) const;
+ GetInstructionAtIndex (size_t idx) const;
uint32_t
GetIndexOfNextBranchInstruction(uint32_t start) const;
@@ -218,7 +219,7 @@
virtual size_t
Decode (const Disassembler &disassembler,
const DataExtractor &data,
- uint32_t data_offset);
+ lldb::offset_t data_offset);
void
SetOpcode (size_t opcode_size, void *opcode_data);
@@ -247,18 +248,28 @@
eOptionMarkPCAddress = (1u << 3) // Mark the disassembly line the contains the PC
};
+ // 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
+ // don't understand, use the default. Folks who care to check can use the FlavorValidForArchSpec method on the
+ // disassembler they got back.
static lldb::DisassemblerSP
- FindPlugin (const ArchSpec &arch, const char *plugin_name);
+ FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name);
+
+ // This version will use the value in the Target settings if flavor is NULL;
+ static lldb::DisassemblerSP
+ FindPluginForTarget(const lldb::TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name);
static lldb::DisassemblerSP
DisassembleRange (const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range);
static lldb::DisassemblerSP
DisassembleBytes (const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const Address &start,
const void *bytes,
size_t length,
@@ -268,6 +279,7 @@
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &range,
uint32_t num_instructions,
@@ -279,6 +291,7 @@
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const Address &start,
uint32_t num_instructions,
@@ -290,6 +303,7 @@
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_instructions,
@@ -301,6 +315,7 @@
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
@@ -313,16 +328,17 @@
Disassemble (Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
uint32_t num_instructions,
uint32_t num_mixed_context_lines,
uint32_t options,
Stream &strm);
-
+
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- Disassembler(const ArchSpec &arch);
+ Disassembler(const ArchSpec &arch, const char *flavor);
virtual ~Disassembler();
typedef const char * (*SummaryCallback)(const Instruction& inst, ExecutionContext *exe_context, void *user_data);
@@ -350,8 +366,8 @@
virtual size_t
DecodeInstructions (const Address &base_addr,
const DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
+ lldb::offset_t data_offset,
+ size_t num_instructions,
bool append) = 0;
InstructionList &
@@ -365,6 +381,15 @@
{
return m_arch;
}
+
+ const char *
+ GetFlavor () const
+ {
+ return m_flavor.c_str();
+ }
+
+ virtual bool
+ FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor) = 0;
protected:
//------------------------------------------------------------------
@@ -373,6 +398,7 @@
const ArchSpec m_arch;
InstructionList m_instruction_list;
lldb::addr_t m_base_addr;
+ std::string m_flavor;
private:
//------------------------------------------------------------------
Index: aze/lldb/include/lldb/Core/dwarf.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/dwarf.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/dwarf.h 2013-03-03 09:35:50.071457356 +0100
@@ -34,7 +34,6 @@
#endif
/* Constants */
-#define DW_INVALID_ADDRESS (~(dw_addr_t)0)
#define DW_INVALID_OFFSET (~(dw_offset_t)0)
#define DW_INVALID_INDEX 0xFFFFFFFFul
Index: aze/lldb/include/lldb/Core/FileSpecList.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/FileSpecList.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/FileSpecList.h 2013-03-03 09:35:50.071457356 +0100
@@ -123,8 +123,8 @@
/// The index of the file that matches \a file if it is found,
/// else UINT32_MAX is returned.
//------------------------------------------------------------------
- uint32_t
- FindFileIndex (uint32_t idx, const FileSpec &file, bool full) const;
+ size_t
+ FindFileIndex (size_t idx, const FileSpec &file, bool full) const;
//------------------------------------------------------------------
/// Get file at index.
@@ -143,7 +143,7 @@
/// returned.
//------------------------------------------------------------------
const FileSpec &
- GetFileSpecAtIndex (uint32_t idx) const;
+ GetFileSpecAtIndex (size_t idx) const;
//------------------------------------------------------------------
/// Get file specification pointer at index.
@@ -159,7 +159,7 @@
/// If \a idx is out of range, then an NULL is returned.
//------------------------------------------------------------------
const FileSpec *
- GetFileSpecPointerAtIndex (uint32_t idx) const;
+ GetFileSpecPointerAtIndex (size_t idx) const;
//------------------------------------------------------------------
/// Get the memory cost of this object.
@@ -176,17 +176,23 @@
size_t
MemorySize () const;
+ bool
+ IsEmpty() const
+ {
+ return m_files.empty();
+ }
+
//------------------------------------------------------------------
/// Get the number of files in the file list.
///
/// @return
/// The number of files in the file spec list.
//------------------------------------------------------------------
- uint32_t
+ size_t
GetSize () const;
bool
- Insert (uint32_t idx, const FileSpec &file)
+ Insert (size_t idx, const FileSpec &file)
{
if (idx < m_files.size())
{
@@ -202,7 +208,7 @@
}
bool
- Replace (uint32_t idx, const FileSpec &file)
+ Replace (size_t idx, const FileSpec &file)
{
if (idx < m_files.size())
{
@@ -213,7 +219,7 @@
}
bool
- Remove (uint32_t idx)
+ Remove (size_t idx)
{
if (idx < m_files.size())
{
Index: aze/lldb/include/lldb/Core/FormatClasses.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/FormatClasses.h 2013-03-03 09:35:47.779457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,1598 +0,0 @@
-//===-- FormatClasses.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_FormatClasses_h_
-#define lldb_FormatClasses_h_
-
-// C Includes
-#include <stdint.h>
-#include <unistd.h>
-
-// C++ Includes
-#include <string>
-#include <vector>
-
-// Other libraries and framework includes
-
-// Project includes
-#include "lldb/lldb-public.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Interpreter/ScriptInterpreterPython.h"
-#include "lldb/Symbol/Type.h"
-
-namespace lldb_private {
-
-class TypeFormatImpl
-{
-public:
- class Flags
- {
- public:
-
- Flags () :
- m_flags (lldb::eTypeOptionCascade)
- {}
-
- Flags (const Flags& other) :
- m_flags (other.m_flags)
- {}
-
- Flags (uint32_t value) :
- m_flags (value)
- {}
-
- Flags&
- operator = (const Flags& rhs)
- {
- if (&rhs != this)
- m_flags = rhs.m_flags;
-
- return *this;
- }
-
- Flags&
- operator = (const uint32_t& rhs)
- {
- m_flags = rhs;
- return *this;
- }
-
- Flags&
- Clear()
- {
- m_flags = 0;
- return *this;
- }
-
- bool
- GetCascades () const
- {
- return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
- }
-
- Flags&
- SetCascades (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionCascade;
- else
- m_flags &= ~lldb::eTypeOptionCascade;
- return *this;
- }
-
- bool
- GetSkipPointers () const
- {
- return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
- }
-
- Flags&
- SetSkipPointers (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionSkipPointers;
- else
- m_flags &= ~lldb::eTypeOptionSkipPointers;
- return *this;
- }
-
- bool
- GetSkipReferences () const
- {
- return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
- }
-
- Flags&
- SetSkipReferences (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionSkipReferences;
- else
- m_flags &= ~lldb::eTypeOptionSkipReferences;
- return *this;
- }
-
- uint32_t
- GetValue ()
- {
- return m_flags;
- }
-
- void
- SetValue (uint32_t value)
- {
- m_flags = value;
- }
-
- private:
- uint32_t m_flags;
- };
-
- TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid,
- const Flags& flags = Flags());
-
- typedef STD_SHARED_PTR(TypeFormatImpl) SharedPointer;
- typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&);
-
- ~TypeFormatImpl ()
- {
- }
-
- bool
- Cascades () const
- {
- return m_flags.GetCascades();
- }
- bool
- SkipsPointers () const
- {
- return m_flags.GetSkipPointers();
- }
- bool
- SkipsReferences () const
- {
- return m_flags.GetSkipReferences();
- }
-
- void
- SetCascades (bool value)
- {
- m_flags.SetCascades(value);
- }
-
- void
- SetSkipsPointers (bool value)
- {
- m_flags.SetSkipPointers(value);
- }
-
- void
- SetSkipsReferences (bool value)
- {
- m_flags.SetSkipReferences(value);
- }
-
- lldb::Format
- GetFormat () const
- {
- return m_format;
- }
-
- void
- SetFormat (lldb::Format fmt)
- {
- m_format = fmt;
- }
-
- uint32_t
- GetOptions ()
- {
- return m_flags.GetValue();
- }
-
- void
- SetOptions (uint32_t value)
- {
- m_flags.SetValue(value);
- }
-
- uint32_t&
- GetRevision ()
- {
- return m_my_revision;
- }
-
- std::string
- GetDescription();
-
-protected:
- Flags m_flags;
- lldb::Format m_format;
- uint32_t m_my_revision;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
-};
-
-class SyntheticChildrenFrontEnd
-{
-protected:
- ValueObject &m_backend;
-public:
-
- SyntheticChildrenFrontEnd (ValueObject &backend) :
- m_backend(backend)
- {}
-
- virtual
- ~SyntheticChildrenFrontEnd ()
- {
- }
-
- virtual uint32_t
- CalculateNumChildren () = 0;
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx) = 0;
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name) = 0;
-
- // this function is assumed to always succeed and it if fails, the front-end should know to deal
- // with it in the correct way (most probably, by refusing to return any children)
- // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
- // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
- // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
- virtual bool
- Update () = 0;
-
- // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
- // might validly decide not to inquire for children given a false return value from this call
- // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
- // it should if at all possible be more efficient than CalculateNumChildren()
- virtual bool
- MightHaveChildren () = 0;
-
- typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
- typedef std::auto_ptr<SyntheticChildrenFrontEnd> AutoPointer;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
-};
-
-class SyntheticChildren
-{
-public:
-
- class Flags
- {
- public:
-
- Flags () :
- m_flags (lldb::eTypeOptionCascade)
- {}
-
- Flags (const Flags& other) :
- m_flags (other.m_flags)
- {}
-
- Flags (uint32_t value) :
- m_flags (value)
- {}
-
- Flags&
- operator = (const Flags& rhs)
- {
- if (&rhs != this)
- m_flags = rhs.m_flags;
-
- return *this;
- }
-
- Flags&
- operator = (const uint32_t& rhs)
- {
- m_flags = rhs;
- return *this;
- }
-
- Flags&
- Clear()
- {
- m_flags = 0;
- return *this;
- }
-
- bool
- GetCascades () const
- {
- return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
- }
-
- Flags&
- SetCascades (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionCascade;
- else
- m_flags &= ~lldb::eTypeOptionCascade;
- return *this;
- }
-
- bool
- GetSkipPointers () const
- {
- return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
- }
-
- Flags&
- SetSkipPointers (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionSkipPointers;
- else
- m_flags &= ~lldb::eTypeOptionSkipPointers;
- return *this;
- }
-
- bool
- GetSkipReferences () const
- {
- return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
- }
-
- Flags&
- SetSkipReferences (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionSkipReferences;
- else
- m_flags &= ~lldb::eTypeOptionSkipReferences;
- return *this;
- }
-
- uint32_t
- GetValue ()
- {
- return m_flags;
- }
-
- void
- SetValue (uint32_t value)
- {
- m_flags = value;
- }
-
- private:
- uint32_t m_flags;
- };
-
- SyntheticChildren (const Flags& flags) :
- m_flags(flags)
- {
- }
-
- virtual
- ~SyntheticChildren ()
- {
- }
-
- bool
- Cascades () const
- {
- return m_flags.GetCascades();
- }
- bool
- SkipsPointers () const
- {
- return m_flags.GetSkipPointers();
- }
- bool
- SkipsReferences () const
- {
- return m_flags.GetSkipReferences();
- }
-
- void
- SetCascades (bool value)
- {
- m_flags.SetCascades(value);
- }
-
- void
- SetSkipsPointers (bool value)
- {
- m_flags.SetSkipPointers(value);
- }
-
- void
- SetSkipsReferences (bool value)
- {
- m_flags.SetSkipReferences(value);
- }
-
- uint32_t
- GetOptions ()
- {
- return m_flags.GetValue();
- }
-
- void
- SetOptions (uint32_t value)
- {
- m_flags.SetValue(value);
- }
-
- virtual bool
- IsScripted () = 0;
-
- virtual std::string
- GetDescription () = 0;
-
- virtual SyntheticChildrenFrontEnd::AutoPointer
- GetFrontEnd (ValueObject &backend) = 0;
-
- typedef STD_SHARED_PTR(SyntheticChildren) SharedPointer;
- typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
-
- uint32_t&
- GetRevision ()
- {
- return m_my_revision;
- }
-
-protected:
- uint32_t m_my_revision;
- Flags m_flags;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
-};
-
-class TypeFilterImpl : public SyntheticChildren
-{
- std::vector<std::string> m_expression_paths;
-public:
- TypeFilterImpl(const SyntheticChildren::Flags& flags) :
- SyntheticChildren(flags),
- m_expression_paths()
- {
- }
-
- void
- AddExpressionPath (const char* path)
- {
- AddExpressionPath(std::string(path));
- }
-
- void
- Clear()
- {
- m_expression_paths.clear();
- }
-
- int
- GetCount() const
- {
- return m_expression_paths.size();
- }
-
- const char*
- GetExpressionPathAtIndex(int i) const
- {
- return m_expression_paths[i].c_str();
- }
-
- bool
- SetExpressionPathAtIndex (int i, const char* path)
- {
- return SetExpressionPathAtIndex(i, std::string(path));
- }
-
- void
- AddExpressionPath (std::string path)
- {
- bool need_add_dot = true;
- if (path[0] == '.' ||
- (path[0] == '-' && path[1] == '>') ||
- path[0] == '[')
- need_add_dot = false;
- // add a '.' symbol to help forgetful users
- if(!need_add_dot)
- m_expression_paths.push_back(path);
- else
- m_expression_paths.push_back(std::string(".") + path);
- }
-
- bool
- SetExpressionPathAtIndex (int i, std::string path)
- {
- if (i >= GetCount())
- return false;
- bool need_add_dot = true;
- if (path[0] == '.' ||
- (path[0] == '-' && path[1] == '>') ||
- path[0] == '[')
- need_add_dot = false;
- // add a '.' symbol to help forgetful users
- if(!need_add_dot)
- m_expression_paths[i] = path;
- else
- m_expression_paths[i] = std::string(".") + path;
- return true;
- }
-
- bool
- IsScripted()
- {
- return false;
- }
-
- std::string
- GetDescription();
-
- class FrontEnd : public SyntheticChildrenFrontEnd
- {
- private:
- TypeFilterImpl* filter;
- public:
-
- FrontEnd(TypeFilterImpl* flt,
- ValueObject &backend) :
- SyntheticChildrenFrontEnd(backend),
- filter(flt)
- {}
-
- virtual
- ~FrontEnd()
- {
- }
-
- virtual uint32_t
- CalculateNumChildren()
- {
- return filter->GetCount();
- }
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx)
- {
- if (idx >= filter->GetCount())
- return lldb::ValueObjectSP();
- return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
- }
-
- virtual bool
- Update() { return false; }
-
- virtual bool
- MightHaveChildren ()
- {
- return filter->GetCount() > 0;
- }
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name)
- {
- const char* name_cstr = name.GetCString();
- for (int i = 0; i < filter->GetCount(); i++)
- {
- const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
- if (expr_cstr)
- {
- if (*expr_cstr == '.')
- expr_cstr++;
- else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
- expr_cstr += 2;
- }
- if (!::strcmp(name_cstr, expr_cstr))
- return i;
- }
- return UINT32_MAX;
- }
-
- typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FrontEnd);
- };
-
- virtual SyntheticChildrenFrontEnd::AutoPointer
- GetFrontEnd(ValueObject &backend)
- {
- return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
- }
-
-private:
- DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
-};
-
- class CXXSyntheticChildren : public SyntheticChildren
- {
- public:
- typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
- protected:
- CreateFrontEndCallback m_create_callback;
- std::string m_description;
- public:
- CXXSyntheticChildren(const SyntheticChildren::Flags& flags,
- const char* description,
- CreateFrontEndCallback callback) :
- SyntheticChildren(flags),
- m_create_callback(callback),
- m_description(description ? description : "")
- {
- }
-
- bool
- IsScripted()
- {
- return false;
- }
-
- std::string
- GetDescription();
-
- virtual SyntheticChildrenFrontEnd::AutoPointer
- GetFrontEnd(ValueObject &backend)
- {
- return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
- };
-
-#ifndef LLDB_DISABLE_PYTHON
-
-class TypeSyntheticImpl : public SyntheticChildren
-{
- std::string m_python_class;
- std::string m_python_code;
-public:
-
- TypeSyntheticImpl(const SyntheticChildren::Flags& flags,
- const char* pclass,
- const char* pcode = NULL) :
- SyntheticChildren(flags),
- m_python_class(),
- m_python_code()
- {
- if (pclass)
- m_python_class = pclass;
- if (pcode)
- m_python_code = pcode;
- }
-
- const char*
- GetPythonClassName()
- {
- return m_python_class.c_str();
- }
-
- const char*
- GetPythonCode()
- {
- return m_python_code.c_str();
- }
-
- void
- SetPythonClassName (const char* fname)
- {
- m_python_class.assign(fname);
- m_python_code.clear();
- }
-
- void
- SetPythonCode (const char* script)
- {
- m_python_code.assign(script);
- }
-
- std::string
- GetDescription();
-
- bool
- IsScripted()
- {
- return true;
- }
-
- class FrontEnd : public SyntheticChildrenFrontEnd
- {
- private:
- std::string m_python_class;
- lldb::ScriptInterpreterObjectSP m_wrapper_sp;
- ScriptInterpreter *m_interpreter;
- public:
-
- FrontEnd(std::string pclass,
- ValueObject &backend);
-
- virtual
- ~FrontEnd();
-
- virtual uint32_t
- CalculateNumChildren()
- {
- if (!m_wrapper_sp || m_interpreter == NULL)
- return 0;
- return m_interpreter->CalculateNumChildren(m_wrapper_sp);
- }
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx);
-
- virtual bool
- Update()
- {
- if (!m_wrapper_sp || m_interpreter == NULL)
- return false;
-
- return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
- }
-
- virtual bool
- MightHaveChildren()
- {
- if (!m_wrapper_sp || m_interpreter == NULL)
- return false;
-
- return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
- }
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name)
- {
- if (!m_wrapper_sp || m_interpreter == NULL)
- return UINT32_MAX;
- return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
- }
-
- typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FrontEnd);
- };
-
- virtual SyntheticChildrenFrontEnd::AutoPointer
- GetFrontEnd(ValueObject &backend)
- {
- return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
- }
-
-private:
- DISALLOW_COPY_AND_ASSIGN(TypeSyntheticImpl);
-};
-
-#endif // #ifndef LLDB_DISABLE_PYTHON
-class SyntheticArrayView : public SyntheticChildren
-{
-public:
-
- struct SyntheticArrayRange
- {
- private:
- int m_low;
- int m_high;
- SyntheticArrayRange* m_next;
-
- public:
-
- SyntheticArrayRange () :
- m_low(-1),
- m_high(-2),
- m_next(NULL)
- {}
-
- SyntheticArrayRange (int L) :
- m_low(L),
- m_high(L),
- m_next(NULL)
- {}
-
- SyntheticArrayRange (int L, int H) :
- m_low(L),
- m_high(H),
- m_next(NULL)
- {}
-
- SyntheticArrayRange (int L, int H, SyntheticArrayRange* N) :
- m_low(L),
- m_high(H),
- m_next(N)
- {}
-
- inline int
- GetLow ()
- {
- return m_low;
- }
-
- inline int
- GetHigh ()
- {
- return m_high;
- }
-
- inline void
- SetLow (int L)
- {
- m_low = L;
- }
-
- inline void
- SetHigh (int H)
- {
- m_high = H;
- }
-
- inline int
- GetSelfCount()
- {
- return GetHigh() - GetLow() + 1;
- }
-
- int
- GetCount()
- {
- int count = GetSelfCount();
- if (m_next)
- count += m_next->GetCount();
- return count;
- }
-
- inline SyntheticArrayRange*
- GetNext()
- {
- return m_next;
- }
-
- void
- SetNext(SyntheticArrayRange* N)
- {
- if (m_next)
- delete m_next;
- m_next = N;
- }
-
- void
- SetNext(int L, int H)
- {
- if (m_next)
- delete m_next;
- m_next = new SyntheticArrayRange(L, H);
- }
-
- void
- SetNext(int L)
- {
- if (m_next)
- delete m_next;
- m_next = new SyntheticArrayRange(L);
- }
-
- ~SyntheticArrayRange()
- {
- delete m_next;
- m_next = NULL;
- }
-
- };
-
- SyntheticArrayView(const SyntheticChildren::Flags& flags) :
- SyntheticChildren(flags),
- m_head(),
- m_tail(&m_head)
- {
- }
-
- void
- AddRange(int L, int H)
- {
- m_tail->SetLow(L);
- m_tail->SetHigh(H);
- m_tail->SetNext(new SyntheticArrayRange());
- m_tail = m_tail->GetNext();
- }
-
- int
- GetCount()
- {
- return m_head.GetCount();
- }
-
- int
- GetRealIndexForIndex(int i);
-
- bool
- IsScripted()
- {
- return false;
- }
-
- std::string
- GetDescription();
-
- class FrontEnd : public SyntheticChildrenFrontEnd
- {
- private:
- SyntheticArrayView* filter;
- public:
-
- FrontEnd(SyntheticArrayView* flt,
- ValueObject &backend) :
- SyntheticChildrenFrontEnd(backend),
- filter(flt)
- {}
-
- virtual
- ~FrontEnd()
- {
- }
-
- virtual uint32_t
- CalculateNumChildren()
- {
- return filter->GetCount();
- }
-
- virtual bool
- MightHaveChildren ()
- {
- return filter->GetCount() > 0;
- }
-
- virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx)
- {
- if (idx >= filter->GetCount())
- return lldb::ValueObjectSP();
- return m_backend.GetSyntheticArrayMember(filter->GetRealIndexForIndex(idx), true);
- }
-
- virtual bool
- Update() { return false; }
-
- virtual uint32_t
- GetIndexOfChildWithName (const ConstString &name_cs);
-
- typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FrontEnd);
- };
-
- virtual SyntheticChildrenFrontEnd::AutoPointer
- GetFrontEnd(ValueObject &backend)
- {
- return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
- }
-private:
- SyntheticArrayRange m_head;
- SyntheticArrayRange *m_tail;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(SyntheticArrayView);
-};
-
-
-class TypeSummaryImpl
-{
-public:
- class Flags
- {
- public:
-
- Flags () :
- m_flags (lldb::eTypeOptionCascade)
- {}
-
- Flags (const Flags& other) :
- m_flags (other.m_flags)
- {}
-
- Flags (uint32_t value) :
- m_flags (value)
- {}
-
- Flags&
- operator = (const Flags& rhs)
- {
- if (&rhs != this)
- m_flags = rhs.m_flags;
-
- return *this;
- }
-
- Flags&
- operator = (const uint32_t& rhs)
- {
- m_flags = rhs;
- return *this;
- }
-
- Flags&
- Clear()
- {
- m_flags = 0;
- return *this;
- }
-
- bool
- GetCascades () const
- {
- return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
- }
-
- Flags&
- SetCascades (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionCascade;
- else
- m_flags &= ~lldb::eTypeOptionCascade;
- return *this;
- }
-
- bool
- GetSkipPointers () const
- {
- return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
- }
-
- Flags&
- SetSkipPointers (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionSkipPointers;
- else
- m_flags &= ~lldb::eTypeOptionSkipPointers;
- return *this;
- }
-
- bool
- GetSkipReferences () const
- {
- return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
- }
-
- Flags&
- SetSkipReferences (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionSkipReferences;
- else
- m_flags &= ~lldb::eTypeOptionSkipReferences;
- return *this;
- }
-
- bool
- GetDontShowChildren () const
- {
- return (m_flags & lldb::eTypeOptionHideChildren) == lldb::eTypeOptionHideChildren;
- }
-
- Flags&
- SetDontShowChildren (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionHideChildren;
- else
- m_flags &= ~lldb::eTypeOptionHideChildren;
- return *this;
- }
-
- bool
- GetDontShowValue () const
- {
- return (m_flags & lldb::eTypeOptionHideValue) == lldb::eTypeOptionHideValue;
- }
-
- Flags&
- SetDontShowValue (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionHideValue;
- else
- m_flags &= ~lldb::eTypeOptionHideValue;
- return *this;
- }
-
- bool
- GetShowMembersOneLiner () const
- {
- return (m_flags & lldb::eTypeOptionShowOneLiner) == lldb::eTypeOptionShowOneLiner;
- }
-
- Flags&
- SetShowMembersOneLiner (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionShowOneLiner;
- else
- m_flags &= ~lldb::eTypeOptionShowOneLiner;
- return *this;
- }
-
- bool
- GetHideItemNames () const
- {
- return (m_flags & lldb::eTypeOptionHideNames) == lldb::eTypeOptionHideNames;
- }
-
- Flags&
- SetHideItemNames (bool value = true)
- {
- if (value)
- m_flags |= lldb::eTypeOptionHideNames;
- else
- m_flags &= ~lldb::eTypeOptionHideNames;
- return *this;
- }
-
- uint32_t
- GetValue ()
- {
- return m_flags;
- }
-
- void
- SetValue (uint32_t value)
- {
- m_flags = value;
- }
-
- private:
- uint32_t m_flags;
- };
-
- typedef enum Type
- {
- eTypeUnknown,
- eTypeString,
- eTypeScript,
- eTypeCallback
- } Type;
-
- TypeSummaryImpl (const TypeSummaryImpl::Flags& flags);
-
- bool
- Cascades () const
- {
- return m_flags.GetCascades();
- }
- bool
- SkipsPointers () const
- {
- return m_flags.GetSkipPointers();
- }
- bool
- SkipsReferences () const
- {
- return m_flags.GetSkipReferences();
- }
-
- bool
- DoesPrintChildren () const
- {
- return !m_flags.GetDontShowChildren();
- }
-
- bool
- DoesPrintValue () const
- {
- return !m_flags.GetDontShowValue();
- }
-
- bool
- IsOneliner () const
- {
- return m_flags.GetShowMembersOneLiner();
- }
-
- bool
- HideNames () const
- {
- return m_flags.GetHideItemNames();
- }
-
- void
- SetCascades (bool value)
- {
- m_flags.SetCascades(value);
- }
-
- void
- SetSkipsPointers (bool value)
- {
- m_flags.SetSkipPointers(value);
- }
-
- void
- SetSkipsReferences (bool value)
- {
- m_flags.SetSkipReferences(value);
- }
-
- void
- SetDoesPrintChildren (bool value)
- {
- m_flags.SetDontShowChildren(!value);
- }
-
- void
- SetDoesPrintValue (bool value)
- {
- m_flags.SetDontShowValue(!value);
- }
-
- void
- SetIsOneliner (bool value)
- {
- m_flags.SetShowMembersOneLiner(value);
- }
-
- void
- SetHideNames (bool value)
- {
- m_flags.SetHideItemNames(value);
- }
-
- uint32_t
- GetOptions ()
- {
- return m_flags.GetValue();
- }
-
- void
- SetOptions (uint32_t value)
- {
- m_flags.SetValue(value);
- }
-
- virtual
- ~TypeSummaryImpl ()
- {
- }
-
- // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
- // extended periods of time and we trust the ValueObject to stay around for as long as it is required
- // for us to generate its summary
- virtual bool
- FormatObject (ValueObject *valobj,
- std::string& dest) = 0;
-
- virtual std::string
- GetDescription () = 0;
-
- virtual bool
- IsScripted() = 0;
-
- virtual Type
- GetType () = 0;
-
- uint32_t&
- GetRevision ()
- {
- return m_my_revision;
- }
-
- typedef STD_SHARED_PTR(TypeSummaryImpl) SharedPointer;
- typedef bool(*SummaryCallback)(void*, ConstString, const lldb::TypeSummaryImplSP&);
- typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const lldb::TypeSummaryImplSP&);
-
-protected:
- uint32_t m_my_revision;
- Flags m_flags;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
-};
-
-// simple string-based summaries, using ${var to show data
-struct StringSummaryFormat : public TypeSummaryImpl
-{
- std::string m_format;
-
- StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
- const char* f);
-
- const char*
- GetSummaryString () const
- {
- return m_format.c_str();
- }
-
- void
- SetSummaryString (const char* data)
- {
- if (data)
- m_format.assign(data);
- else
- m_format.clear();
- }
-
- virtual
- ~StringSummaryFormat()
- {
- }
-
- virtual bool
- FormatObject(ValueObject *valobj,
- std::string& dest);
-
- virtual std::string
- GetDescription();
-
- virtual bool
- IsScripted()
- {
- return false;
- }
-
-
- virtual Type
- GetType ()
- {
- return TypeSummaryImpl::eTypeString;
- }
-
-private:
- DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
-};
-
-// summaries implemented via a C++ function
-struct CXXFunctionSummaryFormat : public TypeSummaryImpl
-{
-
- // we should convert these to SBValue and SBStream if we ever cross
- // the boundary towards the external world
- typedef bool (*Callback)(ValueObject& valobj,
- Stream& dest);
-
-
- Callback m_impl;
- std::string m_description;
-
- CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags& flags,
- Callback impl,
- const char* description);
-
- Callback
- GetBackendFunction () const
- {
- return m_impl;
- }
-
- const char*
- GetTextualInfo () const
- {
- return m_description.c_str();
- }
-
- void
- SetBackendFunction (Callback cb_func)
- {
- m_impl = cb_func;
- }
-
- void
- SetTextualInfo (const char* descr)
- {
- if (descr)
- m_description.assign(descr);
- else
- m_description.clear();
- }
-
- virtual
- ~CXXFunctionSummaryFormat()
- {
- }
-
- virtual bool
- FormatObject(ValueObject *valobj,
- std::string& dest);
-
- virtual std::string
- GetDescription();
-
- virtual bool
- IsScripted()
- {
- return false;
- }
-
- virtual Type
- GetType ()
- {
- return TypeSummaryImpl::eTypeCallback;
- }
-
- typedef STD_SHARED_PTR(CXXFunctionSummaryFormat) SharedPointer;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
-};
-
-#ifndef LLDB_DISABLE_PYTHON
-
-// Python-based summaries, running script code to show data
-struct ScriptSummaryFormat : public TypeSummaryImpl
-{
- std::string m_function_name;
- std::string m_python_script;
- lldb::ScriptInterpreterObjectSP m_script_function_sp;
-
- ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
- const char *function_name,
- const char* python_script = NULL);
-
- const char*
- GetFunctionName () const
- {
- return m_function_name.c_str();
- }
-
- const char*
- GetPythonScript () const
- {
- return m_python_script.c_str();
- }
-
- void
- SetFunctionName (const char* function_name)
- {
- if (function_name)
- m_function_name.assign(function_name);
- else
- m_function_name.clear();
- m_python_script.clear();
- }
-
- void
- SetPythonScript (const char* script)
- {
- if (script)
- m_python_script.assign(script);
- else
- m_python_script.clear();
- }
-
- virtual
- ~ScriptSummaryFormat()
- {
- }
-
- virtual bool
- FormatObject(ValueObject *valobj,
- std::string& dest);
-
- virtual std::string
- GetDescription();
-
- virtual bool
- IsScripted()
- {
- return true;
- }
-
- virtual Type
- GetType ()
- {
- return TypeSummaryImpl::eTypeScript;
- }
-
- typedef STD_SHARED_PTR(ScriptSummaryFormat) SharedPointer;
-
-
-private:
- DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
-};
-
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
-// TODO: at the moment, this class is only used as a backing store for SBTypeNameSpecifier in the public API
-// In the future, this might be used as the basic unit for typename-to-formatter matching, replacing
-// the current plain/regexp distinction in FormatNavigator<>
-class TypeNameSpecifierImpl
-{
-public:
-
- TypeNameSpecifierImpl() :
- m_is_regex(false),
- m_type()
- {
- }
-
- TypeNameSpecifierImpl (const char* name, bool is_regex) :
- m_is_regex(is_regex),
- m_type()
- {
- if (name)
- m_type.m_type_name.assign(name);
- }
-
- // if constructing with a given type, is_regex cannot be true since we are
- // giving an exact type to match
- TypeNameSpecifierImpl (lldb::TypeSP type) :
- m_is_regex(false),
- m_type()
- {
- if (type)
- {
- m_type.m_type_name.assign(type->GetName().GetCString());
- m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
- }
- }
-
- TypeNameSpecifierImpl (ClangASTType type) :
- m_is_regex(false),
- m_type()
- {
- if (type.IsValid())
- {
- m_type.m_type_name.assign(type.GetConstTypeName().GetCString());
- m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
- }
- }
-
- const char*
- GetName()
- {
- if (m_type.m_type_name.size())
- return m_type.m_type_name.c_str();
- return NULL;
- }
-
- lldb::TypeSP
- GetTypeSP ()
- {
- if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
- return m_type.m_typeimpl_sp->GetTypeSP();
- return lldb::TypeSP();
- }
-
- ClangASTType
- GetClangASTType ()
- {
- if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
- return m_type.m_typeimpl_sp->GetClangASTType();
- return ClangASTType();
- }
-
- bool
- IsRegex()
- {
- return m_is_regex;
- }
-
-private:
- bool m_is_regex;
- // this works better than TypeAndOrName because the latter only wraps a TypeSP
- // whereas TypeImplSP can also be backed by a ClangASTType which is more commonly
- // used in LLDB. moreover, TypeImplSP is also what is currently backing SBType
- struct TypeOrName
- {
- std::string m_type_name;
- lldb::TypeImplSP m_typeimpl_sp;
- };
- TypeOrName m_type;
-
-
-private:
- DISALLOW_COPY_AND_ASSIGN(TypeNameSpecifierImpl);
-};
-
-} // namespace lldb_private
-
-#endif // lldb_FormatClasses_h_
Index: aze/lldb/include/lldb/Core/FormatManager.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/FormatManager.h 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,776 +0,0 @@
-//===-- FormatManager.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_FormatManager_h_
-#define lldb_FormatManager_h_
-
-// C Includes
-// C++ Includes
-
-// Other libraries and framework includes
-// Project includes
-#include "lldb/lldb-public.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "lldb/Core/FormatNavigator.h"
-#include "lldb/Interpreter/ScriptInterpreterPython.h"
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Platform.h"
-
-using lldb::LogSP;
-
-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
-
-class CategoryMap;
-
-class TypeCategoryImpl
-{
-private:
-
- typedef FormatNavigator<ConstString, TypeSummaryImpl> SummaryNavigator;
- typedef FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl> RegexSummaryNavigator;
-
- typedef FormatNavigator<ConstString, TypeFilterImpl> FilterNavigator;
- typedef FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl> RegexFilterNavigator;
-
-#ifndef LLDB_DISABLE_PYTHON
- typedef FormatNavigator<ConstString, TypeSyntheticImpl> SynthNavigator;
- typedef FormatNavigator<lldb::RegularExpressionSP, TypeSyntheticImpl> RegexSynthNavigator;
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
- typedef SummaryNavigator::MapType SummaryMap;
- typedef RegexSummaryNavigator::MapType RegexSummaryMap;
- typedef FilterNavigator::MapType FilterMap;
- typedef RegexFilterNavigator::MapType RegexFilterMap;
-#ifndef LLDB_DISABLE_PYTHON
- typedef SynthNavigator::MapType SynthMap;
- typedef RegexSynthNavigator::MapType RegexSynthMap;
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
-public:
-
- typedef uint16_t FormatCategoryItems;
- static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
-
- typedef SummaryNavigator::SharedPointer SummaryNavigatorSP;
- typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
- typedef FilterNavigator::SharedPointer FilterNavigatorSP;
- typedef RegexFilterNavigator::SharedPointer RegexFilterNavigatorSP;
-#ifndef LLDB_DISABLE_PYTHON
- typedef SynthNavigator::SharedPointer SynthNavigatorSP;
- typedef RegexSynthNavigator::SharedPointer RegexSynthNavigatorSP;
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
- TypeCategoryImpl (IFormatChangeListener* clist,
- ConstString name);
-
- SummaryNavigatorSP
- GetSummaryNavigator ()
- {
- return SummaryNavigatorSP(m_summary_nav);
- }
-
- RegexSummaryNavigatorSP
- GetRegexSummaryNavigator ()
- {
- return RegexSummaryNavigatorSP(m_regex_summary_nav);
- }
-
- FilterNavigatorSP
- GetFilterNavigator ()
- {
- return FilterNavigatorSP(m_filter_nav);
- }
-
- RegexFilterNavigatorSP
- GetRegexFilterNavigator ()
- {
- return RegexFilterNavigatorSP(m_regex_filter_nav);
- }
-
- SummaryNavigator::MapValueType
- GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
- {
- SummaryNavigator::MapValueType retval;
-
- if (type_sp)
- {
- if (type_sp->IsRegex())
- m_regex_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
- else
- m_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
- }
-
- return retval;
- }
-
- FilterNavigator::MapValueType
- GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
- {
- FilterNavigator::MapValueType retval;
-
- if (type_sp)
- {
- if (type_sp->IsRegex())
- m_regex_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
- else
- m_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
- }
-
- return retval;
- }
-
-#ifndef LLDB_DISABLE_PYTHON
- SynthNavigator::MapValueType
- GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
- {
- SynthNavigator::MapValueType retval;
-
- if (type_sp)
- {
- if (type_sp->IsRegex())
- m_regex_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
- else
- m_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
- }
-
- return retval;
- }
-#endif
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierForSummaryAtIndex (uint32_t index)
- {
- if (index < m_summary_nav->GetCount())
- return m_summary_nav->GetTypeNameSpecifierAtIndex(index);
- else
- return m_regex_summary_nav->GetTypeNameSpecifierAtIndex(index-m_summary_nav->GetCount());
- }
-
- SummaryNavigator::MapValueType
- GetSummaryAtIndex (uint32_t index)
- {
- if (index < m_summary_nav->GetCount())
- return m_summary_nav->GetAtIndex(index);
- else
- return m_regex_summary_nav->GetAtIndex(index-m_summary_nav->GetCount());
- }
-
- FilterNavigator::MapValueType
- GetFilterAtIndex (uint32_t index)
- {
- if (index < m_filter_nav->GetCount())
- return m_filter_nav->GetAtIndex(index);
- else
- return m_regex_filter_nav->GetAtIndex(index-m_filter_nav->GetCount());
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierForFilterAtIndex (uint32_t index)
- {
- if (index < m_filter_nav->GetCount())
- return m_filter_nav->GetTypeNameSpecifierAtIndex(index);
- else
- return m_regex_filter_nav->GetTypeNameSpecifierAtIndex(index-m_filter_nav->GetCount());
- }
-
-#ifndef LLDB_DISABLE_PYTHON
- SynthNavigatorSP
- GetSyntheticNavigator ()
- {
- return SynthNavigatorSP(m_synth_nav);
- }
-
- RegexSynthNavigatorSP
- GetRegexSyntheticNavigator ()
- {
- return RegexSynthNavigatorSP(m_regex_synth_nav);
- }
-
- SynthNavigator::MapValueType
- GetSyntheticAtIndex (uint32_t index)
- {
- if (index < m_synth_nav->GetCount())
- return m_synth_nav->GetAtIndex(index);
- else
- return m_regex_synth_nav->GetAtIndex(index-m_synth_nav->GetCount());
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierForSyntheticAtIndex (uint32_t index)
- {
- if (index < m_synth_nav->GetCount())
- return m_synth_nav->GetTypeNameSpecifierAtIndex(index);
- else
- return m_regex_synth_nav->GetTypeNameSpecifierAtIndex(index - m_synth_nav->GetCount());
- }
-
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
- bool
- IsEnabled () const
- {
- return m_enabled;
- }
-
- uint32_t
- GetEnabledPosition()
- {
- if (m_enabled == false)
- return UINT32_MAX;
- else
- return m_enabled_position;
- }
-
- bool
- Get (ValueObject& valobj,
- lldb::TypeSummaryImplSP& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t* reason = NULL);
-
- bool
- Get (ValueObject& valobj,
- lldb::SyntheticChildrenSP& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t* reason = NULL);
-
- void
- Clear (FormatCategoryItems items = ALL_ITEM_TYPES);
-
- bool
- Delete (ConstString name,
- FormatCategoryItems items = ALL_ITEM_TYPES);
-
- uint32_t
- GetCount (FormatCategoryItems items = ALL_ITEM_TYPES);
-
- const char*
- GetName ()
- {
- return m_name.GetCString();
- }
-
- bool
- AnyMatches (ConstString type_name,
- FormatCategoryItems items = ALL_ITEM_TYPES,
- bool only_enabled = true,
- const char** matching_category = NULL,
- FormatCategoryItems* matching_type = NULL);
-
- typedef STD_SHARED_PTR(TypeCategoryImpl) SharedPointer;
-
-private:
- SummaryNavigator::SharedPointer m_summary_nav;
- RegexSummaryNavigator::SharedPointer m_regex_summary_nav;
- FilterNavigator::SharedPointer m_filter_nav;
- RegexFilterNavigator::SharedPointer m_regex_filter_nav;
-#ifndef LLDB_DISABLE_PYTHON
- SynthNavigator::SharedPointer m_synth_nav;
- RegexSynthNavigator::SharedPointer m_regex_synth_nav;
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
- bool m_enabled;
-
- IFormatChangeListener* m_change_listener;
-
- Mutex m_mutex;
-
- ConstString m_name;
-
- uint32_t m_enabled_position;
-
- void
- Enable (bool value,
- uint32_t position)
- {
- Mutex::Locker locker(m_mutex);
- m_enabled = value;
- m_enabled_position = position;
- if (m_change_listener)
- m_change_listener->Changed();
- }
-
- void
- Disable ()
- {
- Enable(false, UINT32_MAX);
- }
-
- friend class CategoryMap;
-
- friend class FormatNavigator<ConstString, TypeSummaryImpl>;
- friend class FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl>;
-
- friend class FormatNavigator<ConstString, TypeFilterImpl>;
- friend class FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl>;
-
-#ifndef LLDB_DISABLE_PYTHON
- friend class FormatNavigator<ConstString, TypeSyntheticImpl>;
- friend class FormatNavigator<lldb::RegularExpressionSP, TypeSyntheticImpl>;
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
-
-};
-
-class CategoryMap
-{
-private:
- typedef ConstString KeyType;
- typedef TypeCategoryImpl ValueType;
- typedef ValueType::SharedPointer ValueSP;
- typedef std::list<lldb::TypeCategoryImplSP> ActiveCategoriesList;
- typedef ActiveCategoriesList::iterator ActiveCategoriesIterator;
-
-public:
- typedef std::map<KeyType, ValueSP> MapType;
- typedef MapType::iterator MapIterator;
- typedef bool(*CallbackType)(void*, const ValueSP&);
- typedef uint32_t Position;
-
- static const Position First = 0;
- static const Position Default = 1;
- static const Position Last = UINT32_MAX;
-
- CategoryMap (IFormatChangeListener* lst) :
- m_map_mutex(Mutex::eMutexTypeRecursive),
- listener(lst),
- m_map(),
- m_active_categories()
- {
- ConstString default_cs("default");
- lldb::TypeCategoryImplSP default_sp = lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
- Add(default_cs,default_sp);
- Enable(default_cs,First);
- }
-
- void
- Add (KeyType name,
- const ValueSP& entry)
- {
- Mutex::Locker locker(m_map_mutex);
- m_map[name] = entry;
- if (listener)
- listener->Changed();
- }
-
- bool
- Delete (KeyType name)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- m_map.erase(name);
- Disable(name);
- if (listener)
- listener->Changed();
- return true;
- }
-
- bool
- Enable (KeyType category_name,
- Position pos = Default)
- {
- Mutex::Locker locker(m_map_mutex);
- ValueSP category;
- if (!Get(category_name,category))
- return false;
- return Enable(category, pos);
- }
-
- bool
- Disable (KeyType category_name)
- {
- Mutex::Locker locker(m_map_mutex);
- ValueSP category;
- if (!Get(category_name,category))
- return false;
- return Disable(category);
- }
-
- bool
- Enable (ValueSP category,
- Position pos = Default)
- {
- Mutex::Locker locker(m_map_mutex);
- if (category.get())
- {
- Position pos_w = pos;
- if (pos == First || m_active_categories.size() == 0)
- m_active_categories.push_front(category);
- else if (pos == Last || pos == m_active_categories.size())
- m_active_categories.push_back(category);
- else if (pos < m_active_categories.size())
- {
- ActiveCategoriesList::iterator iter = m_active_categories.begin();
- while (pos_w)
- {
- pos_w--,iter++;
- }
- m_active_categories.insert(iter,category);
- }
- else
- return false;
- category->Enable(true,
- pos);
- return true;
- }
- return false;
- }
-
- bool
- Disable (ValueSP category)
- {
- Mutex::Locker locker(m_map_mutex);
- if (category.get())
- {
- m_active_categories.remove_if(delete_matching_categories(category));
- category->Disable();
- return true;
- }
- return false;
- }
-
- void
- Clear ()
- {
- Mutex::Locker locker(m_map_mutex);
- m_map.clear();
- m_active_categories.clear();
- if (listener)
- listener->Changed();
- }
-
- bool
- Get (KeyType name,
- ValueSP& entry)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- entry = iter->second;
- return true;
- }
-
- bool
- Get (uint32_t pos,
- ValueSP& entry)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.begin();
- MapIterator end = m_map.end();
- while (pos > 0)
- {
- iter++;
- pos--;
- if (iter == end)
- return false;
- }
- entry = iter->second;
- return false;
- }
-
- void
- LoopThrough (CallbackType callback, void* param);
-
- lldb::TypeCategoryImplSP
- GetAtIndex (uint32_t);
-
- bool
- AnyMatches (ConstString type_name,
- TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
- bool only_enabled = true,
- const char** matching_category = NULL,
- TypeCategoryImpl::FormatCategoryItems* matching_type = NULL);
-
- uint32_t
- GetCount ()
- {
- return m_map.size();
- }
-
- lldb::TypeSummaryImplSP
- GetSummaryFormat (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic);
-
-#ifndef LLDB_DISABLE_PYTHON
- lldb::SyntheticChildrenSP
- GetSyntheticChildren (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic);
-#endif
-
-private:
-
- class delete_matching_categories
- {
- lldb::TypeCategoryImplSP ptr;
- public:
- delete_matching_categories(lldb::TypeCategoryImplSP p) : ptr(p)
- {}
-
- bool operator()(const lldb::TypeCategoryImplSP& other)
- {
- return ptr.get() == other.get();
- }
- };
-
- Mutex m_map_mutex;
- IFormatChangeListener* listener;
-
- MapType m_map;
- ActiveCategoriesList m_active_categories;
-
- MapType& map ()
- {
- return m_map;
- }
-
- ActiveCategoriesList& active_list ()
- {
- return m_active_categories;
- }
-
- Mutex& mutex ()
- {
- return m_map_mutex;
- }
-
- friend class FormatNavigator<KeyType, ValueType>;
- friend class FormatManager;
-};
-
-class FormatManager : public IFormatChangeListener
-{
- typedef FormatNavigator<ConstString, TypeFormatImpl> ValueNavigator;
- typedef ValueNavigator::MapType ValueMap;
- typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap;
- typedef CategoryMap::MapType::iterator CategoryMapIterator;
-public:
-
- typedef CategoryMap::CallbackType CategoryCallback;
-
- FormatManager ();
-
- ValueNavigator&
- GetValueNavigator ()
- {
- return m_value_nav;
- }
-
- NamedSummariesMap&
- GetNamedSummaryNavigator ()
- {
- return m_named_summaries_map;
- }
-
- void
- EnableCategory (const ConstString& category_name,
- CategoryMap::Position pos = CategoryMap::Default)
- {
- m_categories_map.Enable(category_name,
- pos);
- }
-
- void
- DisableCategory (const ConstString& category_name)
- {
- m_categories_map.Disable(category_name);
- }
-
- void
- EnableCategory (const lldb::TypeCategoryImplSP& category,
- CategoryMap::Position pos = CategoryMap::Default)
- {
- m_categories_map.Enable(category,
- pos);
- }
-
- void
- DisableCategory (const lldb::TypeCategoryImplSP& category)
- {
- m_categories_map.Disable(category);
- }
-
- bool
- DeleteCategory (const ConstString& category_name)
- {
- return m_categories_map.Delete(category_name);
- }
-
- void
- ClearCategories ()
- {
- return m_categories_map.Clear();
- }
-
- uint32_t
- GetCategoriesCount ()
- {
- return m_categories_map.GetCount();
- }
-
- lldb::TypeCategoryImplSP
- GetCategoryAtIndex (uint32_t index)
- {
- return m_categories_map.GetAtIndex(index);
- }
-
- void
- LoopThroughCategories (CategoryCallback callback, void* param)
- {
- m_categories_map.LoopThrough(callback, param);
- }
-
- lldb::TypeCategoryImplSP
- GetCategory (const char* category_name = NULL,
- bool can_create = true)
- {
- if (!category_name)
- return GetCategory(m_default_category_name);
- return GetCategory(ConstString(category_name));
- }
-
- lldb::TypeCategoryImplSP
- GetCategory (const ConstString& category_name,
- bool can_create = true);
-
- lldb::TypeSummaryImplSP
- GetSummaryFormat (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic)
- {
- return m_categories_map.GetSummaryFormat(valobj, use_dynamic);
- }
-
- lldb::TypeSummaryImplSP
- GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
-
- lldb::TypeFilterImplSP
- GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
-
-#ifndef LLDB_DISABLE_PYTHON
- lldb::TypeSyntheticImplSP
- GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
- lldb::SyntheticChildrenSP
- GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
- lldb::SyntheticChildrenSP
- GetSyntheticChildren (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic)
- {
- return m_categories_map.GetSyntheticChildren(valobj, use_dynamic);
- }
-#endif
-
- bool
- AnyMatches (ConstString type_name,
- TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
- bool only_enabled = true,
- const char** matching_category = NULL,
- TypeCategoryImpl::FormatCategoryItems* matching_type = NULL)
- {
- return m_categories_map.AnyMatches(type_name,
- items,
- only_enabled,
- matching_category,
- matching_type);
- }
-
- static bool
- GetFormatFromCString (const char *format_cstr,
- bool partial_match_ok,
- lldb::Format &format);
-
- static char
- GetFormatAsFormatChar (lldb::Format format);
-
- 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
- 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 vectorOf
- static lldb::Format
- GetSingleItemFormat (lldb::Format vector_format);
-
- void
- Changed ()
- {
- __sync_add_and_fetch(&m_last_revision, +1);
- }
-
- uint32_t
- GetCurrentRevision ()
- {
- return m_last_revision;
- }
-
- ~FormatManager ()
- {
- }
-
-private:
- ValueNavigator m_value_nav;
- NamedSummariesMap m_named_summaries_map;
- uint32_t m_last_revision;
- CategoryMap m_categories_map;
-
- ConstString m_default_category_name;
- ConstString m_system_category_name;
- ConstString m_gnu_cpp_category_name;
- ConstString m_libcxx_category_name;
- ConstString m_objc_category_name;
- ConstString m_corefoundation_category_name;
- ConstString m_coregraphics_category_name;
- ConstString m_coreservices_category_name;
- ConstString m_vectortypes_category_name;
- ConstString m_appkit_category_name;
-
- CategoryMap&
- GetCategories ()
- {
- return m_categories_map;
- }
-
- // WARNING: these are temporary functions that setup formatters
- // while a few of these actually should be globally available and setup by LLDB itself
- // most would actually belong to the users' lldbinit file or to some other form of configurable
- // storage
- void
- LoadSTLFormatters();
-
- void
- LoadLibcxxFormatters();
-
- void
- LoadSystemFormatters();
-
- void
- LoadObjCFormatters();
-};
-
-} // namespace lldb_private
-
-#endif // lldb_FormatManager_h_
Index: aze/lldb/include/lldb/Core/FormatNavigator.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/FormatNavigator.h 2013-03-03 09:35:47.779457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,642 +0,0 @@
-//===-- FormatNavigator.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_FormatNavigator_h_
-#define lldb_FormatNavigator_h_
-
-// C Includes
-// C++ Includes
-
-// Other libraries and framework includes
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/DeclObjC.h"
-
-// Project includes
-#include "lldb/lldb-public.h"
-
-#include "lldb/Core/FormatClasses.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/RegularExpression.h"
-#include "lldb/Core/ValueObject.h"
-
-#include "lldb/Symbol/ClangASTContext.h"
-
-#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/TargetList.h"
-
-using lldb::LogSP;
-
-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
-class IFormatChangeListener
-{
-public:
- virtual void
- Changed () = 0;
-
- virtual
- ~IFormatChangeListener () {}
-
- virtual uint32_t
- GetCurrentRevision () = 0;
-
-};
-
-static inline bool
-IsWhitespace (char c)
-{
- return ( (c == ' ') || (c == '\t') || (c == '\v') || (c == '\f') );
-}
-
-static inline bool
-HasPrefix (const char* str1, const char* str2)
-{
- return ( ::strstr(str1, str2) == str1 );
-}
-
-// 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_Impl (const ConstString& type)
-{
- int strip_len = 0;
-
- if (type == false)
- return type;
-
- const char* type_cstr = type.AsCString();
-
- if ( HasPrefix(type_cstr, "class ") )
- strip_len = 6;
- else if ( HasPrefix(type_cstr, "enum ") )
- strip_len = 5;
- else if ( HasPrefix(type_cstr, "struct ") )
- strip_len = 7;
- else if ( HasPrefix(type_cstr, "union ") )
- strip_len = 6;
-
- if (strip_len == 0)
- return type;
-
- type_cstr += strip_len;
- while (IsWhitespace(*type_cstr) && ++type_cstr)
- ;
-
- return ConstString(type_cstr);
-}
-
-template<typename KeyType, typename ValueType>
-class FormatNavigator;
-
-template<typename KeyType, typename ValueType>
-class FormatMap
-{
-public:
-
- typedef typename ValueType::SharedPointer ValueSP;
- typedef std::map<KeyType, ValueSP> MapType;
- typedef typename MapType::iterator MapIterator;
- typedef bool(*CallbackType)(void*, KeyType, const ValueSP&);
-
- FormatMap(IFormatChangeListener* lst) :
- m_map(),
- m_map_mutex(Mutex::eMutexTypeRecursive),
- listener(lst)
- {
- }
-
- void
- Add(KeyType name,
- const ValueSP& entry)
- {
- if (listener)
- entry->GetRevision() = listener->GetCurrentRevision();
- else
- entry->GetRevision() = 0;
-
- Mutex::Locker locker(m_map_mutex);
- m_map[name] = entry;
- if (listener)
- listener->Changed();
- }
-
- bool
- Delete (KeyType name)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- m_map.erase(name);
- if (listener)
- listener->Changed();
- return true;
- }
-
- void
- Clear ()
- {
- Mutex::Locker locker(m_map_mutex);
- m_map.clear();
- if (listener)
- listener->Changed();
- }
-
- bool
- Get(KeyType name,
- ValueSP& entry)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- entry = iter->second;
- return true;
- }
-
- void
- LoopThrough (CallbackType callback, void* param)
- {
- if (callback)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator pos, end = m_map.end();
- for (pos = m_map.begin(); pos != end; pos++)
- {
- KeyType type = pos->first;
- if (!callback(param, type, pos->second))
- break;
- }
- }
- }
-
- uint32_t
- GetCount ()
- {
- return m_map.size();
- }
-
- ValueSP
- GetValueAtIndex (uint32_t index)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.begin();
- MapIterator end = m_map.end();
- while (index > 0)
- {
- iter++;
- index--;
- if (end == iter)
- return ValueSP();
- }
- return iter->second;
- }
-
- KeyType
- GetKeyAtIndex (uint32_t index)
- {
- Mutex::Locker locker(m_map_mutex);
- MapIterator iter = m_map.begin();
- MapIterator end = m_map.end();
- while (index > 0)
- {
- iter++;
- index--;
- if (end == iter)
- return KeyType();
- }
- return iter->first;
- }
-
-protected:
- MapType m_map;
- Mutex m_map_mutex;
- IFormatChangeListener* listener;
-
- MapType&
- map ()
- {
- return m_map;
- }
-
- Mutex&
- mutex ()
- {
- return m_map_mutex;
- }
-
- friend class FormatNavigator<KeyType, ValueType>;
- friend class FormatManager;
-
-};
-
-template<typename KeyType, typename ValueType>
-class FormatNavigator
-{
-protected:
- typedef FormatMap<KeyType,ValueType> BackEndType;
-
-public:
- typedef typename BackEndType::MapType MapType;
- typedef typename MapType::iterator MapIterator;
- typedef typename MapType::key_type MapKeyType;
- typedef typename MapType::mapped_type MapValueType;
- typedef typename BackEndType::CallbackType CallbackType;
-#ifdef _LIBCPP_VERSION
- typedef typename std::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
-#else
- typedef typename std::tr1::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
-#endif
-
- friend class TypeCategoryImpl;
-
- FormatNavigator(std::string name,
- IFormatChangeListener* lst) :
- m_format_map(lst),
- m_name(name),
- m_id_cs(ConstString("id"))
- {
- }
-
- void
- Add (const MapKeyType &type, const MapValueType& entry)
- {
- Add_Impl(type, entry, (KeyType*)NULL);
- }
-
- bool
- Delete (ConstString type)
- {
- return Delete_Impl(type, (KeyType*)NULL);
- }
-
- bool
- Get(ValueObject& valobj,
- MapValueType& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t* why = NULL)
- {
- uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
- clang::QualType type = clang::QualType::getFromOpaquePtr(valobj.GetClangType());
- bool ret = Get(valobj, type, entry, use_dynamic, value);
- if (ret)
- entry = MapValueType(entry);
- else
- entry = MapValueType();
- if (why)
- *why = value;
- return ret;
- }
-
- bool
- Get (ConstString type, MapValueType& entry)
- {
- return Get_Impl(type, entry, (KeyType*)NULL);
- }
-
- bool
- GetExact (ConstString type, MapValueType& entry)
- {
- return GetExact_Impl(type, entry, (KeyType*)NULL);
- }
-
- MapValueType
- GetAtIndex (uint32_t index)
- {
- return m_format_map.GetValueAtIndex(index);
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierAtIndex (uint32_t index)
- {
- return GetTypeNameSpecifierAtIndex_Impl(index, (KeyType*)NULL);
- }
-
- void
- Clear ()
- {
- m_format_map.Clear();
- }
-
- void
- LoopThrough (CallbackType callback, void* param)
- {
- m_format_map.LoopThrough(callback,param);
- }
-
- uint32_t
- GetCount ()
- {
- return m_format_map.GetCount();
- }
-
-protected:
-
- BackEndType m_format_map;
-
- std::string m_name;
-
- DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
-
- ConstString m_id_cs;
-
- void
- Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
- {
- m_format_map.Add(type,entry);
- }
-
- void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
- {
- m_format_map.Add(GetValidTypeName_Impl(type), entry);
- }
-
- bool
- Delete_Impl (ConstString type, ConstString *dummy)
- {
- return m_format_map.Delete(type);
- }
-
- bool
- Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
- {
- Mutex& x_mutex = m_format_map.mutex();
- lldb_private::Mutex::Locker locker(x_mutex);
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++)
- {
- lldb::RegularExpressionSP regex = pos->first;
- if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
- {
- m_format_map.map().erase(pos);
- if (m_format_map.listener)
- m_format_map.listener->Changed();
- return true;
- }
- }
- return false;
- }
-
- bool
- Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
- {
- return m_format_map.Get(type, entry);
- }
-
- bool
- GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
- {
- return Get_Impl(type,entry, (KeyType*)0);
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierAtIndex_Impl (uint32_t index, ConstString *dummy)
- {
- ConstString key = m_format_map.GetKeyAtIndex(index);
- if (key)
- return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
- false));
- else
- return lldb::TypeNameSpecifierImplSP();
- }
-
- lldb::TypeNameSpecifierImplSP
- GetTypeNameSpecifierAtIndex_Impl (uint32_t index, lldb::RegularExpressionSP *dummy)
- {
- lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
- if (regex.get() == NULL)
- return lldb::TypeNameSpecifierImplSP();
- return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(regex->GetText(),
- true));
- }
-
- bool
- Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
- {
- const char* key_cstr = key.AsCString();
- if (!key_cstr)
- return false;
- Mutex& x_mutex = m_format_map.mutex();
- lldb_private::Mutex::Locker locker(x_mutex);
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++)
- {
- lldb::RegularExpressionSP regex = pos->first;
- if (regex->Execute(key_cstr))
- {
- value = pos->second;
- return true;
- }
- }
- return false;
- }
-
- bool
- GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
- {
- Mutex& x_mutex = m_format_map.mutex();
- lldb_private::Mutex::Locker locker(x_mutex);
- MapIterator pos, end = m_format_map.map().end();
- for (pos = m_format_map.map().begin(); pos != end; pos++)
- {
- lldb::RegularExpressionSP regex = pos->first;
- if (strcmp(regex->GetText(),key.AsCString()) == 0)
- {
- value = pos->second;
- return true;
- }
- }
- return false;
- }
-
- bool
- Get_BitfieldMatch (ValueObject& valobj,
- ConstString typeName,
- MapValueType& entry,
- uint32_t& reason)
- {
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- // for bitfields, append size to the typename so one can custom format them
- StreamString sstring;
- sstring.Printf("%s:%d",typeName.AsCString(),valobj.GetBitfieldBitSize());
- ConstString bitfieldname = ConstString(sstring.GetData());
- if (log)
- log->Printf("[Get_BitfieldMatch] appended bitfield info, final result is %s", bitfieldname.GetCString());
- if (Get(bitfieldname, entry))
- {
- if (log)
- log->Printf("[Get_BitfieldMatch] bitfield direct match found, returning");
- return true;
- }
- else
- {
- reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
- if (log)
- log->Printf("[Get_BitfieldMatch] no bitfield direct match");
- return false;
- }
- }
-
- bool Get_ObjC (ValueObject& valobj,
- MapValueType& entry)
- {
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- lldb::ProcessSP process_sp = valobj.GetProcessSP();
- ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
- if (runtime == NULL)
- {
- if (log)
- log->Printf("[Get_ObjC] no valid ObjC runtime, skipping dynamic");
- return false;
- }
- ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
- if (!objc_class_sp)
- {
- if (log)
- log->Printf("[Get_ObjC] invalid ISA, skipping dynamic");
- return false;
- }
- ConstString name (objc_class_sp->GetClassName());
- if (log)
- log->Printf("[Get_ObjC] dynamic type inferred is %s - looking for direct dynamic match", name.GetCString());
- if (Get(name, entry))
- {
- if (log)
- log->Printf("[Get_ObjC] direct dynamic match found, returning");
- return true;
- }
- if (log)
- log->Printf("[Get_ObjC] no dynamic match");
- return false;
- }
-
- bool Get (ValueObject& valobj,
- clang::QualType type, // TODO: find out why "type" is passed in the type when it belongs to valobj? Can it ever differ?
- MapValueType& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t& reason)
- {
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
- if (type.isNull())
- {
- if (log)
- log->Printf("[Get] type is NULL, returning");
- return false;
- }
-
- type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
- const clang::Type* typePtr = type.getTypePtrOrNull();
- if (!typePtr)
- {
- if (log)
- log->Printf("[Get] type is NULL, returning");
- return false;
- }
- ConstString typeName(ClangASTType::GetTypeNameForQualType(valobj.GetClangAST(), type).c_str());
-
- if (valobj.GetBitfieldBitSize() > 0)
- {
- if (Get_BitfieldMatch(valobj, typeName, entry, reason))
- return true;
- }
-
- if (log)
- log->Printf("[Get] trying to get %s for VO name %s of type %s",
- m_name.c_str(),
- valobj.GetName().AsCString(),
- typeName.AsCString());
-
- if (Get(typeName, entry))
- {
- if (log)
- log->Printf("[Get] direct match found, returning");
- return true;
- }
- if (log)
- log->Printf("[Get] no direct match");
-
- // strip pointers and references and see if that helps
- if (typePtr->isReferenceType())
- {
- if (log)
- log->Printf("[Get] stripping reference");
- if (Get(valobj,type.getNonReferenceType(),entry, use_dynamic, reason) && !entry->SkipsReferences())
- {
- reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
- return true;
- }
- }
- else if (typePtr->isPointerType())
- {
- if (log)
- log->Printf("[Get] stripping pointer");
- clang::QualType pointee = typePtr->getPointeeType();
- if (Get(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
- {
- reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
- return true;
- }
- }
-
- bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(),
- type.getAsOpaquePtr(),
- NULL,
- false, // no C++
- true); // yes ObjC
-
- if (canBeObjCDynamic)
- {
- if (use_dynamic != lldb::eNoDynamicValues)
- {
- if (log)
- log->Printf("[Get] allowed to figure out dynamic ObjC type");
- if (Get_ObjC(valobj,entry))
- {
- reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCDiscovery;
- return true;
- }
- }
- if (log)
- log->Printf("[Get] dynamic disabled or failed - stripping ObjC pointer");
- clang::QualType pointee = typePtr->getPointeeType();
- if (Get(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
- {
- reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
- return true;
- }
- }
-
- // try to strip typedef chains
- const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
- if (type_tdef)
- {
- if (log)
- log->Printf("[Get] stripping typedef");
- if ((Get(valobj, type_tdef->getDecl()->getUnderlyingType(), entry, use_dynamic, reason)) && entry->Cascades())
- {
- reason |= lldb_private::eFormatterChoiceCriterionNavigatedTypedefs;
- return true;
- }
- }
- return false;
- }
-};
-
-} // namespace lldb_private
-
-#endif // lldb_FormatNavigator_h_
Index: aze/lldb/include/lldb/Core/Listener.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Listener.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Listener.h 2013-03-03 09:35:50.071457356 +0100
@@ -117,7 +117,7 @@
size_t
HandleBroadcastEvent (lldb::EventSP &event_sp);
-protected:
+private:
//------------------------------------------------------------------
// Classes that inherit from Listener can see and modify these
@@ -177,7 +177,6 @@
void
BroadcasterManagerWillDestruct (BroadcasterManager *manager);
-private:
// broadcaster_collection::iterator
// FindBroadcasterWithMask (Broadcaster *broadcaster,
Index: aze/lldb/include/lldb/Core/MappedHash.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/MappedHash.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/MappedHash.h 2013-03-03 09:35:50.075457356 +0100
@@ -36,7 +36,7 @@
}
static uint32_t
- HashString (const uint8_t hash_function, const char *s)
+ HashString (uint32_t hash_function, const char *s)
{
switch (hash_function)
{
@@ -115,8 +115,8 @@
s.Printf ("header.header_data_len = 0x%8.8x %u\n", header_data_len, header_data_len);
}
- virtual uint32_t
- Read (lldb_private::DataExtractor &data, uint32_t offset)
+ virtual lldb::offset_t
+ Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
{
if (data.ValidOffsetForDataOfSize (offset,
sizeof (magic) +
@@ -140,14 +140,14 @@
data.SetByteOrder(lldb::eByteOrderBig);
break;
default:
- return UINT32_MAX;
+ return LLDB_INVALID_OFFSET;
}
}
else
{
// Magic bytes didn't match
version = 0;
- return UINT32_MAX;
+ return LLDB_INVALID_OFFSET;
}
}
@@ -155,7 +155,7 @@
if (version != 1)
{
// Unsupported version
- return UINT32_MAX;
+ return LLDB_INVALID_OFFSET;
}
hash_function = data.GetU16 (&offset);
if (hash_function == 4)
@@ -165,7 +165,7 @@
header_data_len = data.GetU32 (&offset);
return offset;
}
- return UINT32_MAX;
+ return LLDB_INVALID_OFFSET;
}
//
// // Returns a buffer that contains a serialized version of this table
@@ -271,7 +271,7 @@
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 dw_offset_t die_offset = m_entries[i].die_offset;
+ const uint32_t die_offset = m_entries[i].die_offset;
hash_buckets[bucket_idx][hash][strp_offset].push_back(die_offset);
}
@@ -379,8 +379,8 @@
m_hash_values (NULL),
m_hash_offsets (NULL)
{
- uint32_t offset = m_header.Read (data, 0);
- if (offset != UINT32_MAX && IsValid ())
+ lldb::offset_t offset = m_header.Read (data, 0);
+ if (offset != LLDB_INVALID_OFFSET && IsValid ())
{
m_hash_indexes = (uint32_t *)data.GetData (&offset, m_header.bucket_count * sizeof(uint32_t));
m_hash_values = (uint32_t *)data.GetData (&offset, m_header.hashes_count * sizeof(uint32_t));
@@ -443,10 +443,10 @@
const uint32_t curr_hash_value = GetHashValue (hash_idx);
if (curr_hash_value == hash_value)
{
- uint32_t hash_data_offset = GetHashDataOffset (hash_idx);
+ lldb::offset_t hash_data_offset = GetHashDataOffset (hash_idx);
while (hash_data_offset != UINT32_MAX)
{
- const uint32_t prev_hash_data_offset = hash_data_offset;
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
Result hash_result = GetHashDataForName (name, &hash_data_offset, pair);
// Check the result of getting our hash data
switch (hash_result)
@@ -505,7 +505,7 @@
virtual Result
GetHashDataForName (const char *name,
- uint32_t* hash_data_offset_ptr,
+ lldb::offset_t* hash_data_offset_ptr,
Pair &pair) const = 0;
const HeaderType &
Index: aze/lldb/include/lldb/Core/Module.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Module.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/Module.h 2013-03-03 09:35:50.075457356 +0100
@@ -173,8 +173,9 @@
virtual void
DumpSymbolContext (Stream *s);
+
//------------------------------------------------------------------
- /// Find a symbol in the object files symbol table.
+ /// Find a symbol in the object file's symbol table.
///
/// @param[in] name
/// The name of the symbol that we are looking for.
@@ -204,6 +205,28 @@
SymbolContextList &sc_list);
//------------------------------------------------------------------
+ /// Find a funciton symbols in the object file's symbol table.
+ ///
+ /// @param[in] name
+ /// The name of the symbol that we are looking for.
+ ///
+ /// @param[in] name_type_mask
+ /// A mask that has one or more bitwise OR'ed values from the
+ /// lldb::FunctionNameType enumeration type that indicate what
+ /// kind of names we are looking for.
+ ///
+ /// @param[out] sc_list
+ /// A list to append any matching symbol contexts to.
+ ///
+ /// @return
+ /// The number of symbol contexts that were added to \a sc_list
+ //------------------------------------------------------------------
+ size_t
+ FindFunctionSymbols (const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList& sc_list);
+
+ //------------------------------------------------------------------
/// Find compile units by partial or full path.
///
/// Finds all compile units that match \a path in all of the modules
@@ -224,7 +247,7 @@
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list);
@@ -261,7 +284,7 @@
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindFunctions (const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
uint32_t name_type_mask,
@@ -292,7 +315,7 @@
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindFunctions (const RegularExpression& regex,
bool symbols_ok,
bool inlines_ok,
@@ -325,11 +348,11 @@
/// @return
/// The number of matches added to \a variable_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindGlobalVariables (const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variable_list);
//------------------------------------------------------------------
@@ -354,10 +377,10 @@
/// @return
/// The number of matches added to \a variable_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindGlobalVariables (const RegularExpression& regex,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variable_list);
//------------------------------------------------------------------
@@ -401,13 +424,18 @@
/// @return
/// The number of matches added to \a type_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindTypes (const SymbolContext& sc,
const ConstString &type_name,
bool exact_match,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& types);
+ lldb::TypeSP
+ FindFirstType (const SymbolContext& sc,
+ 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
@@ -430,11 +458,11 @@
/// @return
/// The number of matches added to \a type_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindTypesInNamespace (const SymbolContext& sc,
const ConstString &type_name,
const ClangNamespaceDecl *namespace_decl,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& type_list);
//------------------------------------------------------------------
@@ -542,11 +570,11 @@
/// The number of compile units that the symbol vendor plug-in
/// finds.
//------------------------------------------------------------------
- uint32_t
+ size_t
GetNumCompileUnits();
lldb::CompUnitSP
- GetCompileUnitAtIndex (uint32_t);
+ GetCompileUnitAtIndex (size_t idx);
const ConstString &
GetObjectName() const;
@@ -598,7 +626,8 @@
/// object and remains valid as long as the object is around.
//------------------------------------------------------------------
virtual SymbolVendor*
- GetSymbolVendor(bool can_create = true);
+ GetSymbolVendor(bool can_create = true,
+ lldb_private::Stream *feedback_strm = NULL);
//------------------------------------------------------------------
/// Get accessor the type list for this module.
@@ -934,12 +963,12 @@
private:
- uint32_t
+ size_t
FindTypes_Impl (const SymbolContext& sc,
const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& types);
Index: aze/lldb/include/lldb/Core/ModuleList.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ModuleList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ModuleList.h 2013-03-03 09:35:50.075457356 +0100
@@ -165,7 +165,7 @@
return m_modules_mutex;
}
- uint32_t
+ size_t
GetIndexForModule (const Module *module) const;
//------------------------------------------------------------------
@@ -181,7 +181,7 @@
/// @see ModuleList::GetSize()
//------------------------------------------------------------------
lldb::ModuleSP
- GetModuleAtIndex (uint32_t idx) const;
+ GetModuleAtIndex (size_t idx) const;
//------------------------------------------------------------------
/// Get the module shared pointer for the module at index \a idx without
@@ -198,7 +198,7 @@
/// @see ModuleList::GetSize()
//------------------------------------------------------------------
lldb::ModuleSP
- GetModuleAtIndexUnlocked (uint32_t idx) const;
+ GetModuleAtIndexUnlocked (size_t idx) const;
//------------------------------------------------------------------
/// Get the module pointer for the module at index \a idx.
@@ -213,7 +213,7 @@
/// @see ModuleList::GetSize()
//------------------------------------------------------------------
Module*
- GetModulePointerAtIndex (uint32_t idx) const;
+ GetModulePointerAtIndex (size_t idx) const;
//------------------------------------------------------------------
/// Get the module pointer for the module at index \a idx without
@@ -230,7 +230,7 @@
/// @see ModuleList::GetSize()
//------------------------------------------------------------------
Module*
- GetModulePointerAtIndexUnlocked (uint32_t idx) const;
+ GetModulePointerAtIndexUnlocked (size_t idx) const;
//------------------------------------------------------------------
/// Find compile units by partial or full path.
@@ -253,7 +253,7 @@
/// @return
/// The number of matches added to \a sc_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list) const;
@@ -261,7 +261,7 @@
//------------------------------------------------------------------
/// @see Module::FindFunctions ()
//------------------------------------------------------------------
- uint32_t
+ size_t
FindFunctions (const ConstString &name,
uint32_t name_type_mask,
bool include_symbols,
@@ -292,10 +292,10 @@
/// @return
/// The number of matches added to \a variable_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindGlobalVariables (const ConstString &name,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variable_list) const;
//------------------------------------------------------------------
@@ -320,10 +320,10 @@
/// @return
/// The number of matches added to \a variable_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindGlobalVariables (const RegularExpression& regex,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variable_list) const;
//------------------------------------------------------------------
@@ -422,11 +422,11 @@
/// @return
/// The number of matches added to \a type_list.
//------------------------------------------------------------------
- uint32_t
+ size_t
FindTypes (const SymbolContext& sc,
const ConstString &name,
bool name_is_fully_qualified,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& types) const;
bool
@@ -503,7 +503,7 @@
FindSharedModules (const ModuleSpec &module_spec,
ModuleList &matching_module_list);
- static uint32_t
+ static size_t
RemoveOrphanSharedModules (bool mandatory);
static bool
Index: aze/lldb/include/lldb/Core/PluginManager.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/PluginManager.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/PluginManager.h 2013-03-03 09:35:50.075457356 +0100
@@ -216,7 +216,7 @@
static const char *
GetPlatformPluginDescriptionAtIndex (uint32_t idx);
- static uint32_t
+ static size_t
AutoCompletePlatformName (const char *partial_name,
StringList &matches);
//------------------------------------------------------------------
Index: aze/lldb/include/lldb/Core/RegisterValue.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/RegisterValue.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/RegisterValue.h 2013-03-03 09:35:50.075457356 +0100
@@ -345,7 +345,7 @@
Error
SetValueFromData (const RegisterInfo *reg_info,
DataExtractor &data,
- uint32_t offset,
+ lldb::offset_t offset,
bool partial_data_ok);
// The default value of 0 for reg_name_right_align_at means no alignment at all.
Index: aze/lldb/include/lldb/Core/RegularExpression.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/RegularExpression.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/RegularExpression.h 2013-03-03 09:35:50.075457356 +0100
@@ -17,6 +17,11 @@
#include <string>
#include <vector>
+namespace llvm
+{
+ class StringRef;
+}
+
namespace lldb_private {
//----------------------------------------------------------------------
@@ -123,11 +128,22 @@
bool
Execute (const char* string, size_t match_count = 0, int execute_flags = 0) const;
+ bool
+ ExecuteThreadSafe (const char* s,
+ llvm::StringRef *matches,
+ size_t num_matches,
+ int execute_flags = 0) const;
size_t
GetErrorAsCString (char *err_str, size_t err_str_max_len) const;
bool
GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const;
+
+ bool
+ GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const;
+
+ bool
+ GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const;
//------------------------------------------------------------------
/// Free the compiled regular expression.
///
Index: aze/lldb/include/lldb/Core/Scalar.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Scalar.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Scalar.h 2013-03-03 09:35:50.075457356 +0100
@@ -73,9 +73,9 @@
bool
GetData (DataExtractor &data, size_t limit_byte_size = UINT32_MAX) const;
- uint32_t
+ size_t
GetAsMemoryData (void *dst,
- uint32_t dst_len,
+ size_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const;
@@ -219,7 +219,7 @@
GetRawBits64 (uint64_t fail_value) const;
Error
- SetValueFromCString (const char *s, lldb::Encoding encoding, uint32_t byte_size);
+ SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size);
static bool
UIntValueIsValidForSize (uint64_t uval64, size_t total_byte_size)
@@ -249,6 +249,16 @@
}
protected:
+ typedef int sint_t;
+ typedef unsigned int uint_t;
+ typedef long slong_t;
+ typedef unsigned long ulong_t;
+ typedef long long slonglong_t;
+ typedef unsigned long long ulonglong_t;
+ typedef float float_t;
+ typedef double double_t;
+ typedef long double long_double_t;
+
union ValueData
{
int sint;
@@ -277,6 +287,8 @@
friend const Scalar operator| (const Scalar& lhs, const Scalar& rhs);
friend const Scalar operator% (const Scalar& lhs, const Scalar& rhs);
friend const Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator<< (const Scalar& lhs, const Scalar& rhs);
+ friend const Scalar operator>> (const Scalar& lhs, const Scalar& rhs);
friend bool operator== (const Scalar& lhs, const Scalar& rhs);
friend bool operator!= (const Scalar& lhs, const Scalar& rhs);
friend bool operator< (const Scalar& lhs, const Scalar& rhs);
@@ -309,6 +321,8 @@
const Scalar operator| (const Scalar& lhs, const Scalar& rhs);
const Scalar operator% (const Scalar& lhs, const Scalar& rhs);
const Scalar operator^ (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator<< (const Scalar& lhs, const Scalar& rhs);
+const Scalar operator>> (const Scalar& lhs, const Scalar& rhs);
bool operator== (const Scalar& lhs, const Scalar& rhs);
bool operator!= (const Scalar& lhs, const Scalar& rhs);
bool operator< (const Scalar& lhs, const Scalar& rhs);
Index: aze/lldb/include/lldb/Core/Section.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Section.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Section.h 2013-03-03 09:35:50.075457356 +0100
@@ -34,13 +34,13 @@
virtual
~SectionList();
- uint32_t
+ size_t
AddSection (const lldb::SectionSP& section_sp);
- uint32_t
+ size_t
AddUniqueSection (const lldb::SectionSP& section_sp);
- uint32_t
+ size_t
FindSectionIndex (const Section* sect);
bool
@@ -56,7 +56,7 @@
FindSectionByID (lldb::user_id_t sect_id) const;
lldb::SectionSP
- FindSectionByType (lldb::SectionType sect_type, bool check_children, uint32_t start_idx = 0) const;
+ FindSectionByType (lldb::SectionType sect_type, bool check_children, size_t start_idx = 0) const;
lldb::SectionSP
FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT32_MAX) const;
@@ -82,7 +82,7 @@
ReplaceSection (lldb::user_id_t sect_id, const lldb::SectionSP& section_sp, uint32_t depth = UINT32_MAX);
lldb::SectionSP
- GetSectionAtIndex (uint32_t idx) const;
+ GetSectionAtIndex (size_t idx) const;
size_t
Slide (lldb::addr_t slide_amount, bool slide_children);
Index: aze/lldb/include/lldb/Core/SourceManager.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/SourceManager.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/SourceManager.h 2013-03-03 09:35:50.075457356 +0100
@@ -119,13 +119,6 @@
}
size_t
- DisplaySourceLines (const FileSpec &file,
- uint32_t line,
- uint32_t context_before,
- uint32_t context_after,
- Stream *s);
-
- size_t
DisplaySourceLinesWithLineNumbers (const FileSpec &file,
uint32_t line,
uint32_t context_before,
@@ -145,7 +138,8 @@
size_t
DisplayMoreWithLineNumbers (Stream *s,
- const SymbolContextList *bp_locs = NULL);
+ const SymbolContextList *bp_locs = NULL,
+ bool reverse = false);
bool
SetDefaultFileAndLine (const FileSpec &file_spec, uint32_t line);
@@ -179,6 +173,7 @@
uint32_t m_last_file_context_before;
uint32_t m_last_file_context_after;
bool m_default_set;
+ bool m_first_reverse;
Target *m_target;
Debugger *m_debugger;
Index: aze/lldb/include/lldb/Core/StreamAsynchronousIO.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StreamAsynchronousIO.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/StreamAsynchronousIO.h 2013-03-03 09:35:50.075457356 +0100
@@ -28,7 +28,7 @@
virtual void
Flush ();
- virtual int
+ virtual size_t
Write (const void *src, size_t src_len);
Index: aze/lldb/include/lldb/Core/StreamBuffer.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StreamBuffer.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/StreamBuffer.h 2013-03-03 09:35:50.075457356 +0100
@@ -47,7 +47,7 @@
// Nothing to do when flushing a buffer based stream...
}
- virtual int
+ virtual size_t
Write (const void *s, size_t length)
{
if (s && length)
Index: aze/lldb/include/lldb/Core/StreamCallback.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StreamCallback.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/StreamCallback.h 2013-03-03 09:35:50.075457356 +0100
@@ -29,7 +29,7 @@
virtual void
Flush ();
- virtual int
+ virtual size_t
Write (const void *src, size_t src_len);
Index: aze/lldb/include/lldb/Core/StreamFile.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StreamFile.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/StreamFile.h 2013-03-03 09:35:50.075457356 +0100
@@ -57,7 +57,7 @@
virtual void
Flush ();
- virtual int
+ virtual size_t
Write (const void *s, size_t length);
protected:
Index: aze/lldb/include/lldb/Core/Stream.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Stream.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Stream.h 2013-03-03 09:35:50.075457356 +0100
@@ -87,13 +87,13 @@
/// @return
/// The number of bytes that were appended to the stream.
//------------------------------------------------------------------
- virtual int
+ virtual size_t
Write (const void *src, size_t src_len) = 0;
//------------------------------------------------------------------
// Member functions
//------------------------------------------------------------------
- int
+ size_t
PutChar (char ch);
//------------------------------------------------------------------
@@ -125,7 +125,7 @@
/// @return
/// The number of bytes that were appended to the stream.
//------------------------------------------------------------------
- int
+ size_t
PrintfAsRawHex8 (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
//------------------------------------------------------------------
@@ -142,59 +142,59 @@
/// @return
/// The number of bytes that were appended to the stream.
//------------------------------------------------------------------
- int
+ size_t
PutHex8 (uint8_t uvalue);
- int
+ size_t
PutNHex8 (size_t n, uint8_t uvalue);
- int
+ size_t
PutHex16 (uint16_t uvalue,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutHex32 (uint32_t uvalue,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutHex64 (uint64_t uvalue,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutMaxHex64 (uint64_t uvalue,
size_t byte_size,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutFloat (float f,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutDouble (double d,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutLongDouble (long double ld,
lldb::ByteOrder byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutPointer (void *ptr);
// Append \a src_len bytes from \a src to the stream as hex characters
// (two ascii characters per byte of input data)
- int
+ size_t
PutBytesAsRawHex8 (const void *src,
size_t src_len,
lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
// Append \a src_len bytes from \a s to the stream as binary data.
- int
+ size_t
PutRawBytes (const void *s,
size_t src_len,
lldb::ByteOrder src_byte_order = lldb::eByteOrderInvalid,
lldb::ByteOrder dst_byte_order = lldb::eByteOrderInvalid);
- int
+ size_t
PutCStringAsRawHex8 (const char *s);
//------------------------------------------------------------------
@@ -359,7 +359,7 @@
/// A suffix C string. If NULL, no suffix will be output.
//------------------------------------------------------------------
void
- Address (uint64_t addr, int addr_size, const char *prefix = NULL, const char *suffix = NULL);
+ Address (uint64_t addr, uint32_t addr_size, const char *prefix = NULL, const char *suffix = NULL);
//------------------------------------------------------------------
/// Output an address range to this stream.
@@ -383,7 +383,7 @@
/// A suffix C string. If NULL, no suffix will be output.
//------------------------------------------------------------------
void
- AddressRange(uint64_t lo_addr, uint64_t hi_addr, int addr_size, const char *prefix = NULL, const char *suffix = NULL);
+ AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix = NULL, const char *suffix = NULL);
//------------------------------------------------------------------
/// Output a C string to the stream.
@@ -393,13 +393,13 @@
/// @param[in] cstr
/// The string to be output to the stream.
//------------------------------------------------------------------
- int
+ size_t
PutCString (const char *cstr);
//------------------------------------------------------------------
/// Output and End of Line character to the stream.
//------------------------------------------------------------------
- int
+ size_t
EOL();
//------------------------------------------------------------------
@@ -409,7 +409,7 @@
/// The size of an address in bytes that is used when outputting
/// address and pointer values to the stream.
//------------------------------------------------------------------
- uint8_t
+ uint32_t
GetAddressByteSize () const;
//------------------------------------------------------------------
@@ -478,7 +478,7 @@
/// A C string to print following the indentation. If NULL, just
/// output the indentation characters.
//------------------------------------------------------------------
- int
+ size_t
Indent(const char *s = NULL);
//------------------------------------------------------------------
@@ -520,10 +520,10 @@
/// Variable arguments that are needed for the printf style
/// format string \a format.
//------------------------------------------------------------------
- int
+ size_t
Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
- int
+ size_t
PrintfVarArg(const char *format, va_list args);
//------------------------------------------------------------------
@@ -549,7 +549,7 @@
/// address and pointer values.
//------------------------------------------------------------------
void
- SetAddressByteSize (uint8_t addr_size);
+ SetAddressByteSize (uint32_t addr_size);
//------------------------------------------------------------------
/// Set the current indentation level.
@@ -572,7 +572,7 @@
/// @param[in] format
/// The optional printf format that can be overridden.
//------------------------------------------------------------------
- int
+ size_t
PutSLEB128 (int64_t uval);
//------------------------------------------------------------------
@@ -587,7 +587,7 @@
/// @param[in] format
/// The optional printf format that can be overridden.
//------------------------------------------------------------------
- int
+ size_t
PutULEB128 (uint64_t uval);
static void
@@ -597,12 +597,12 @@
//------------------------------------------------------------------
// Member variables
//------------------------------------------------------------------
- Flags m_flags; ///< Dump flags.
- uint8_t m_addr_size; ///< Size of an address in bytes.
- lldb::ByteOrder m_byte_order;///< Byte order to use when encoding scalar types.
- int m_indent_level; ///< Indention level.
+ Flags m_flags; ///< Dump flags.
+ uint32_t m_addr_size; ///< Size of an address in bytes.
+ lldb::ByteOrder m_byte_order; ///< Byte order to use when encoding scalar types.
+ int m_indent_level; ///< Indention level.
- int _PutHex8 (uint8_t uvalue, bool add_prefix);
+ size_t _PutHex8 (uint8_t uvalue, bool add_prefix);
};
} // namespace lldb_private
Index: aze/lldb/include/lldb/Core/StreamString.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StreamString.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/StreamString.h 2013-03-03 09:35:50.075457356 +0100
@@ -31,7 +31,7 @@
virtual void
Flush ();
- virtual int
+ virtual size_t
Write (const void *s, size_t length);
void
Index: aze/lldb/include/lldb/Core/StreamTee.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StreamTee.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/StreamTee.h 2013-03-03 09:35:50.075457356 +0100
@@ -93,14 +93,14 @@
}
}
- virtual int
+ virtual size_t
Write (const void *s, size_t length)
{
Mutex::Locker locker (m_streams_mutex);
if (m_streams.empty())
return 0;
- int min_bytes_written = INT_MAX;
+ size_t min_bytes_written = SIZE_MAX;
collection::iterator pos, end;
for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos)
{
@@ -111,11 +111,13 @@
Stream *strm = pos->get();
if (strm)
{
- int bytes_written = strm->Write (s, length);
+ const size_t bytes_written = strm->Write (s, length);
if (min_bytes_written > bytes_written)
min_bytes_written = bytes_written;
}
}
+ if (min_bytes_written == SIZE_MAX)
+ return 0;
return min_bytes_written;
}
Index: aze/lldb/include/lldb/Core/StringList.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/StringList.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/StringList.h 2013-03-03 09:35:50.075457356 +0100
@@ -48,7 +48,7 @@
bool
ReadFileLines (FileSpec &input_file);
- uint32_t
+ size_t
GetSize () const;
const char *
Index: aze/lldb/include/lldb/Core/Timer.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Timer.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/Timer.h 2013-03-03 09:35:50.075457356 +0100
@@ -11,8 +11,10 @@
#define liblldb_Timer_h_
#if defined(__cplusplus)
-#include <memory>
+#include <stdarg.h>
#include <stdio.h>
+#include <memory>
+#include <string>
#include "lldb/lldb-private.h"
#include "lldb/Host/TimeValue.h"
@@ -90,6 +92,68 @@
Timer();
DISALLOW_COPY_AND_ASSIGN (Timer);
};
+
+class IntervalTimer
+{
+public:
+ IntervalTimer() :
+ m_start (TimeValue::Now())
+ {
+ }
+
+ ~IntervalTimer()
+ {
+ }
+
+ uint64_t
+ GetElapsedNanoSeconds() const
+ {
+ return TimeValue::Now() - m_start;
+ }
+
+ void
+ Reset ()
+ {
+ m_start = TimeValue::Now();
+ }
+
+ int
+ PrintfElapsed (const char *format, ...) __attribute__ ((format (printf, 2, 3)))
+ {
+ TimeValue now (TimeValue::Now());
+ const uint64_t elapsed_nsec = now - m_start;
+ const char *unit = NULL;
+ float elapsed_value;
+ if (elapsed_nsec < 1000)
+ {
+ unit = "ns";
+ elapsed_value = (float)elapsed_nsec;
+ }
+ else if (elapsed_nsec < 1000000)
+ {
+ unit = "us";
+ elapsed_value = (float)elapsed_nsec/1000.0f;
+ }
+ else if (elapsed_nsec < 1000000000)
+ {
+ unit = "ms";
+ elapsed_value = (float)elapsed_nsec/1000000.0f;
+ }
+ else
+ {
+ unit = "sec";
+ elapsed_value = (float)elapsed_nsec/1000000000.0f;
+ }
+ int result = printf ("%3.2f %s: ", elapsed_value, unit);
+ va_list args;
+ va_start (args, format);
+ result += vprintf (format, args);
+ va_end (args);
+ return result;
+ }
+protected:
+ TimeValue m_start;
+};
} // namespace lldb_private
Index: aze/lldb/include/lldb/Core/UniqueCStringMap.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/UniqueCStringMap.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/UniqueCStringMap.h 2013-03-03 09:35:50.075457356 +0100
@@ -313,6 +313,33 @@
}
}
+ size_t
+ Erase (const char *unique_cstr)
+ {
+ size_t num_removed = 0;
+ Entry search_entry (unique_cstr);
+ iterator end = m_map.end();
+ iterator begin = m_map.begin();
+ iterator lower_pos = std::lower_bound (begin, end, search_entry);
+ if (lower_pos != end)
+ {
+ if (lower_pos->cstring == unique_cstr)
+ {
+ iterator upper_pos = std::upper_bound (lower_pos, end, search_entry);
+ if (lower_pos == upper_pos)
+ {
+ m_map.erase (lower_pos);
+ num_removed = 1;
+ }
+ else
+ {
+ num_removed = std::distance (lower_pos, upper_pos);
+ m_map.erase (lower_pos, upper_pos);
+ }
+ }
+ }
+ return num_removed;
+ }
protected:
typedef std::vector<Entry> collection;
typedef typename collection::iterator iterator;
Index: aze/lldb/include/lldb/Core/Value.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/Value.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/Value.h 2013-03-03 09:35:50.079457355 +0100
@@ -213,7 +213,7 @@
}
void
- ResizeData(int len);
+ ResizeData(size_t len);
bool
ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context);
Index: aze/lldb/include/lldb/Core/ValueObjectCast.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectCast.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectCast.h 2013-03-03 09:35:50.079457355 +0100
@@ -35,7 +35,7 @@
virtual size_t
GetByteSize();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual lldb::ValueType
Index: aze/lldb/include/lldb/Core/ValueObjectChild.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectChild.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectChild.h 2013-03-03 09:35:50.079457355 +0100
@@ -53,7 +53,7 @@
virtual lldb::ValueType
GetValueType() const;
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual ConstString
Index: aze/lldb/include/lldb/Core/ValueObjectConstResultChild.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectConstResultChild.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectConstResultChild.h 2013-03-03 09:35:50.079457355 +0100
@@ -43,7 +43,7 @@
Dereference (Error &error);
virtual ValueObject *
- CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
virtual lldb::clang_type_t
GetClangType ()
Index: aze/lldb/include/lldb/Core/ValueObjectConstResult.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectConstResult.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectConstResult.h 2013-03-03 09:35:50.079457355 +0100
@@ -47,7 +47,7 @@
const ConstString &name,
const lldb::DataBufferSP &result_data_sp,
lldb::ByteOrder byte_order,
- uint8_t addr_size,
+ uint32_t addr_size,
lldb::addr_t address = LLDB_INVALID_ADDRESS);
static lldb::ValueObjectSP
@@ -57,7 +57,7 @@
const ConstString &name,
lldb::addr_t address,
AddressType address_type,
- uint8_t addr_byte_size);
+ uint32_t addr_byte_size);
static lldb::ValueObjectSP
Create (ExecutionContextScope *exe_scope,
@@ -78,7 +78,7 @@
virtual lldb::ValueType
GetValueType() const;
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual ConstString
@@ -101,7 +101,7 @@
Dereference (Error &error);
virtual ValueObject *
- CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
virtual lldb::ValueObjectSP
GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create);
@@ -147,7 +147,7 @@
clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from
ConstString m_type_name;
- uint32_t m_byte_size;
+ size_t m_byte_size;
ValueObjectConstResultImpl m_impl;
@@ -171,7 +171,7 @@
const ConstString &name,
const lldb::DataBufferSP &result_data_sp,
lldb::ByteOrder byte_order,
- uint8_t addr_size,
+ uint32_t addr_size,
lldb::addr_t address);
ValueObjectConstResult (ExecutionContextScope *exe_scope,
@@ -180,7 +180,7 @@
const ConstString &name,
lldb::addr_t address,
AddressType address_type,
- uint8_t addr_byte_size);
+ uint32_t addr_byte_size);
ValueObjectConstResult (ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
Index: aze/lldb/include/lldb/Core/ValueObjectConstResultImpl.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectConstResultImpl.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectConstResultImpl.h 2013-03-03 09:35:50.079457355 +0100
@@ -39,7 +39,7 @@
Dereference (Error &error);
ValueObject *
- CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
lldb::ValueObjectSP
GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create);
Index: aze/lldb/include/lldb/Core/ValueObjectDynamicValue.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectDynamicValue.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectDynamicValue.h 2013-03-03 09:35:50.079457355 +0100
@@ -15,6 +15,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/Type.h"
namespace lldb_private {
@@ -34,7 +35,10 @@
virtual ConstString
GetTypeName();
- virtual uint32_t
+ virtual ConstString
+ GetQualifiedTypeName();
+
+ virtual size_t
CalculateNumChildren();
virtual lldb::ValueType
@@ -86,6 +90,12 @@
virtual bool
SetValueFromCString (const char *value_str, Error& error);
+ virtual lldb::DynamicValueType
+ GetDynamicValueType ()
+ {
+ return m_use_dynamic;
+ }
+
protected:
virtual bool
UpdateValue ();
@@ -97,7 +107,7 @@
GetClangTypeImpl ();
Address m_address; ///< The variable that this value object is based upon
- lldb::TypeSP m_type_sp;
+ TypeAndOrName m_dynamic_type_info; // We can have a type_sp or just a name
lldb::ValueObjectSP m_owning_valobj_sp;
lldb::DynamicValueType m_use_dynamic;
Index: aze/lldb/include/lldb/Core/ValueObject.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObject.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObject.h 2013-03-03 09:35:50.079457355 +0100
@@ -232,6 +232,8 @@
lldb::TypeSummaryImplSP m_summary_sp;
std::string m_root_valobj_name;
bool m_hide_root_type;
+ bool m_hide_name;
+ bool m_hide_value;
DumpValueObjectOptions() :
m_max_ptr_depth(0),
@@ -248,7 +250,9 @@
m_format (lldb::eFormatDefault),
m_summary_sp(),
m_root_valobj_name(),
- m_hide_root_type(false) // <rdar://problem/11505459> provide a special compact display for "po",
+ m_hide_root_type(false), // provide a special compact display for "po"
+ m_hide_name(false), // provide a special compact display for "po"
+ m_hide_value(false) // provide a special compact display for "po"
{}
static const DumpValueObjectOptions
@@ -274,7 +278,9 @@
m_format(rhs.m_format),
m_summary_sp(rhs.m_summary_sp),
m_root_valobj_name(rhs.m_root_valobj_name),
- m_hide_root_type(rhs.m_hide_root_type)
+ m_hide_root_type(rhs.m_hide_root_type),
+ m_hide_name(rhs.m_hide_name),
+ m_hide_value(rhs.m_hide_value)
{}
DumpValueObjectOptions&
@@ -372,12 +378,16 @@
SetUseSyntheticValue(false);
SetOmitSummaryDepth(UINT32_MAX);
SetIgnoreCap(true);
+ SetHideName(false);
+ SetHideValue(false);
}
else
{
SetUseSyntheticValue(true);
SetOmitSummaryDepth(0);
SetIgnoreCap(false);
+ SetHideName(false);
+ SetHideValue(false);
}
return *this;
}
@@ -412,7 +422,20 @@
m_hide_root_type = hide_root_type;
return *this;
}
+
+ DumpValueObjectOptions&
+ SetHideName (bool hide_name = false)
+ {
+ m_hide_name = hide_name;
+ return *this;
+ }
+ DumpValueObjectOptions&
+ SetHideValue (bool hide_value = false)
+ {
+ m_hide_value = hide_value;
+ return *this;
+ }
};
class EvaluationPoint
@@ -597,6 +620,9 @@
virtual lldb::LanguageType
GetObjectRuntimeLanguage();
+ virtual uint32_t
+ GetTypeInfo (lldb::clang_type_t *pointee_or_element_clang_type = NULL);
+
virtual bool
IsPointerType ();
@@ -613,6 +639,9 @@
IsPossibleDynamicType ();
virtual bool
+ IsObjCNil ();
+
+ virtual bool
IsBaseClass ()
{
return false;
@@ -729,15 +758,32 @@
GetName() const;
virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx, bool can_create);
+ GetChildAtIndex (size_t idx, bool can_create);
+
+ // this will always create the children if necessary
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::initializer_list<size_t> &idxs,
+ size_t* index_of_error = NULL);
+
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::vector<size_t> &idxs,
+ size_t* index_of_error = NULL);
+
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> > &idxs,
+ size_t* index_of_error = NULL);
+ lldb::ValueObjectSP
+ GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs,
+ size_t* index_of_error = NULL);
+
virtual lldb::ValueObjectSP
GetChildMemberWithName (const ConstString &name, bool can_create);
- virtual uint32_t
+ virtual size_t
GetIndexOfChildWithName (const ConstString &name);
- uint32_t
+ size_t
GetNumChildren ();
const Value &
@@ -788,10 +834,7 @@
UpdateValueIfNeeded (bool update_format = true);
bool
- UpdateValueIfNeeded (lldb::DynamicValueType use_dynamic, bool update_format = true);
-
- bool
- UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic = lldb::eNoDynamicValues);
+ UpdateFormatsIfNeeded();
lldb::ValueObjectSP
GetSP ()
@@ -813,20 +856,17 @@
GetSyntheticChild (const ConstString &key) const;
lldb::ValueObjectSP
- GetSyntheticArrayMember (int32_t index, bool can_create);
+ GetSyntheticArrayMember (size_t index, bool can_create);
lldb::ValueObjectSP
- GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create);
+ GetSyntheticArrayMemberFromPointer (size_t index, bool can_create);
lldb::ValueObjectSP
- GetSyntheticArrayMemberFromArray (int32_t index, bool can_create);
+ GetSyntheticArrayMemberFromArray (size_t index, bool can_create);
lldb::ValueObjectSP
GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create);
-
- lldb::ValueObjectSP
- GetSyntheticArrayRangeChild (uint32_t from, uint32_t to, bool can_create);
-
+
lldb::ValueObjectSP
GetSyntheticExpressionPathChild(const char* expression, bool can_create);
@@ -836,6 +876,15 @@
virtual lldb::ValueObjectSP
GetDynamicValue (lldb::DynamicValueType valueType);
+ virtual lldb::DynamicValueType
+ GetDynamicValueType ()
+ {
+ if (m_parent)
+ return m_parent->GetDynamicValueType ();
+ else
+ return lldb::eNoDynamicValues;
+ }
+
virtual lldb::ValueObjectSP
GetStaticValue ();
@@ -943,7 +992,7 @@
bool
IsCStringContainer (bool check_pointer = false);
- void
+ size_t
ReadPointedString (Stream& s,
Error& error,
uint32_t max_length = 0,
@@ -989,7 +1038,7 @@
lldb::TypeSummaryImplSP
GetSummaryFormat()
{
- UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
+ UpdateFormatsIfNeeded();
return m_type_summary_sp;
}
@@ -1010,7 +1059,7 @@
lldb::TypeFormatImplSP
GetValueFormat()
{
- UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
+ UpdateFormatsIfNeeded();
return m_type_format_sp;
}
@@ -1026,7 +1075,7 @@
lldb::SyntheticChildrenSP
GetSyntheticChildren()
{
- UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
+ UpdateFormatsIfNeeded();
return m_synthetic_children_sp;
}
@@ -1097,13 +1146,13 @@
{
public:
ChildrenManager() :
- m_mutex(Mutex::eMutexTypeRecursive),
- m_children(),
- m_children_count(0)
+ m_mutex(Mutex::eMutexTypeRecursive),
+ m_children(),
+ m_children_count(0)
{}
bool
- HasChildAtIndex (uint32_t idx)
+ HasChildAtIndex (size_t idx)
{
Mutex::Locker locker(m_mutex);
ChildrenIterator iter = m_children.find(idx);
@@ -1112,7 +1161,7 @@
}
ValueObject*
- GetChildAtIndex (uint32_t idx)
+ GetChildAtIndex (size_t idx)
{
Mutex::Locker locker(m_mutex);
ChildrenIterator iter = m_children.find(idx);
@@ -1124,7 +1173,7 @@
}
void
- SetChildAtIndex (uint32_t idx, ValueObject* valobj)
+ SetChildAtIndex (size_t idx, ValueObject* valobj)
{
ChildrenPair pair(idx,valobj); // we do not need to be mutex-protected to make a pair
Mutex::Locker locker(m_mutex);
@@ -1132,12 +1181,12 @@
}
void
- SetChildrenCount (uint32_t count)
+ SetChildrenCount (size_t count)
{
m_children_count = count;
}
- uint32_t
+ size_t
GetChildrenCount ()
{
return m_children_count;
@@ -1152,12 +1201,12 @@
}
private:
- typedef std::map<uint32_t, ValueObject*> ChildrenMap;
+ typedef std::map<size_t, ValueObject*> ChildrenMap;
typedef ChildrenMap::iterator ChildrenIterator;
typedef ChildrenMap::value_type ChildrenPair;
Mutex m_mutex;
ChildrenMap m_children;
- uint32_t m_children_count;
+ size_t m_children_count;
};
//------------------------------------------------------------------
@@ -1198,7 +1247,6 @@
lldb::Format m_format;
uint32_t m_last_format_mgr_revision;
- lldb::DynamicValueType m_last_format_mgr_dynamic;
lldb::TypeSummaryImplSP m_type_summary_sp;
lldb::TypeFormatImplSP m_type_format_sp;
lldb::SyntheticChildrenSP m_synthetic_children_sp;
@@ -1212,7 +1260,6 @@
m_is_deref_of_parent:1,
m_is_array_item_for_pointer:1,
m_is_bitfield_for_scalar:1,
- m_is_expression_path_child:1,
m_is_child_at_offset:1,
m_is_getting_summary:1,
m_did_calculate_complete_objc_class_type:1;
@@ -1259,14 +1306,14 @@
// Should only be called by ValueObject::GetChildAtIndex()
// Returns a ValueObject managed by this ValueObject's manager.
virtual ValueObject *
- CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
// Should only be called by ValueObject::GetNumChildren()
- virtual uint32_t
+ virtual size_t
CalculateNumChildren() = 0;
void
- SetNumChildren (uint32_t num_children);
+ SetNumChildren (size_t num_children);
void
SetValueDidChange (bool value_changed);
Index: aze/lldb/include/lldb/Core/ValueObjectList.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectList.h 2013-03-03 09:35:50.079457355 +0100
@@ -50,20 +50,20 @@
lldb::ValueObjectSP
FindValueObjectByPointer (ValueObject *valobj);
- uint32_t
+ size_t
GetSize () const;
void
- Resize (uint32_t size);
+ Resize (size_t size);
lldb::ValueObjectSP
- GetValueObjectAtIndex (uint32_t idx);
+ GetValueObjectAtIndex (size_t idx);
lldb::ValueObjectSP
- RemoveValueObjectAtIndex (uint32_t idx);
+ RemoveValueObjectAtIndex (size_t idx);
void
- SetValueObjectAtIndex (uint32_t idx,
+ SetValueObjectAtIndex (size_t idx,
const lldb::ValueObjectSP &valobj_sp);
lldb::ValueObjectSP
Index: aze/lldb/include/lldb/Core/ValueObjectMemory.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectMemory.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectMemory.h 2013-03-03 09:35:50.079457355 +0100
@@ -47,7 +47,7 @@
virtual ConstString
GetTypeName();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual lldb::ValueType
Index: aze/lldb/include/lldb/Core/ValueObjectRegister.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectRegister.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectRegister.h 2013-03-03 09:35:50.079457355 +0100
@@ -46,11 +46,11 @@
virtual ConstString
GetQualifiedTypeName();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual ValueObject *
- CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
protected:
virtual bool
@@ -96,16 +96,16 @@
virtual ConstString
GetQualifiedTypeName();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual ValueObject *
- CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
+ CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index);
virtual lldb::ValueObjectSP
GetChildMemberWithName (const ConstString &name, bool can_create);
- virtual uint32_t
+ virtual size_t
GetIndexOfChildWithName (const ConstString &name);
@@ -154,7 +154,7 @@
virtual ConstString
GetTypeName();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual bool
Index: aze/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h 2013-03-03 09:35:50.079457355 +0100
@@ -38,25 +38,31 @@
virtual ConstString
GetTypeName();
+
+ virtual ConstString
+ GetQualifiedTypeName();
virtual bool
MightHaveChildren();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual lldb::ValueType
GetValueType() const;
virtual lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx, bool can_create);
+ GetChildAtIndex (size_t idx, bool can_create);
virtual lldb::ValueObjectSP
GetChildMemberWithName (const ConstString &name, bool can_create);
- virtual uint32_t
+ virtual size_t
GetIndexOfChildWithName (const ConstString &name);
+ virtual lldb::ValueObjectSP
+ GetDynamicValue (lldb::DynamicValueType valueType);
+
virtual bool
IsInScope ();
@@ -83,6 +89,24 @@
return false;
}
+ virtual lldb::ValueObjectSP
+ GetStaticValue ()
+ {
+ if (m_parent)
+ return m_parent->GetStaticValue();
+ else
+ return GetSP();
+ }
+
+ virtual lldb::DynamicValueType
+ GetDynamicValueType ()
+ {
+ if (m_parent)
+ return m_parent->GetDynamicValueType();
+ else
+ return lldb::eNoDynamicValues;
+ }
+
virtual ValueObject *
GetParent()
{
Index: aze/lldb/include/lldb/Core/ValueObjectVariable.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/ValueObjectVariable.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Core/ValueObjectVariable.h 2013-03-03 09:35:50.079457355 +0100
@@ -40,7 +40,7 @@
virtual ConstString
GetQualifiedTypeName();
- virtual uint32_t
+ virtual size_t
CalculateNumChildren();
virtual lldb::ValueType
Index: aze/lldb/include/lldb/Core/VMRange.h
===================================================================
--- aze.orig/lldb/include/lldb/Core/VMRange.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Core/VMRange.h 2013-03-03 09:35:50.079457355 +0100
@@ -161,7 +161,7 @@
// Returns a valid index into coll when a match is found, else UINT32_MAX
// is returned
- static uint32_t
+ static size_t
FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value);
protected:
Index: aze/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h 2013-03-03 09:35:50.079457355 +0100
@@ -0,0 +1,657 @@
+//===-- CXXFormatterFunctions.h------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_CXXFormatterFunctions_h_
+#define liblldb_CXXFormatterFunctions_h_
+
+#include <stdint.h>
+#include "lldb/lldb-forward.h"
+
+#include "lldb/Core/ConstString.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+#include "lldb/Target/Target.h"
+
+#include "clang/AST/ASTContext.h"
+
+namespace lldb_private {
+ namespace formatters
+ {
+ bool
+ ExtractValueFromObjCExpression (ValueObject &valobj,
+ const char* target_type,
+ const char* selector,
+ uint64_t &value);
+
+ bool
+ ExtractSummaryFromObjCExpression (ValueObject &valobj,
+ const char* target_type,
+ const char* selector,
+ Stream &stream);
+
+ lldb::ValueObjectSP
+ CallSelectorOnObject (ValueObject &valobj,
+ const char* return_type,
+ const char* selector,
+ uint64_t index);
+
+ lldb::ValueObjectSP
+ CallSelectorOnObject (ValueObject &valobj,
+ const char* return_type,
+ const char* selector,
+ const char* key);
+
+ size_t
+ ExtractIndexFromString (const char* item_name);
+
+ bool
+ Char16StringSummaryProvider (ValueObject& valobj, Stream& stream); // char16_t* and unichar*
+
+ bool
+ Char32StringSummaryProvider (ValueObject& valobj, Stream& stream); // char32_t*
+
+ bool
+ WCharStringSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t*
+
+ bool
+ Char16SummaryProvider (ValueObject& valobj, Stream& stream); // char16_t and unichar
+
+ bool
+ Char32SummaryProvider (ValueObject& valobj, Stream& stream); // char32_t
+
+ bool
+ WCharSummaryProvider (ValueObject& valobj, Stream& stream); // wchar_t
+
+ bool
+ LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::string
+
+ bool
+ LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream); // libc++ std::wstring
+
+ template<bool name_entries>
+ bool
+ NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSArraySummaryProvider (ValueObject& valobj, Stream& stream);
+
+ template<bool cf_style>
+ bool
+ NSSetSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ template<bool needs_at>
+ bool
+ NSDataSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSNumberSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSStringSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ NSURLSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ template <bool is_sel_ptr>
+ bool
+ ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ extern template bool
+ NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
+
+ extern template bool
+ NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
+
+ extern template bool
+ NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
+
+ extern template bool
+ NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
+
+ extern template bool
+ ObjCSELSummaryProvider<true> (ValueObject&, Stream&);
+
+ extern template bool
+ ObjCSELSummaryProvider<false> (ValueObject&, Stream&);
+
+ class NSArrayMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used;
+ uint32_t _priv1 : 2 ;
+ uint32_t _size : 30;
+ uint32_t _priv2 : 2;
+ uint32_t offset : 30;
+ uint32_t _priv3;
+ uint32_t _data;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used;
+ uint64_t _priv1 : 2 ;
+ uint64_t _size : 62;
+ uint64_t _priv2 : 2;
+ uint64_t offset : 62;
+ uint32_t _priv3;
+ uint64_t _data;
+ };
+ public:
+ NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSArrayMSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ ClangASTType m_id_type;
+ std::vector<lldb::ValueObjectSP> m_children;
+ };
+
+ class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSArrayISyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ uint64_t m_items;
+ lldb::addr_t m_data_ptr;
+ ClangASTType m_id_type;
+ std::vector<lldb::ValueObjectSP> m_children;
+ };
+
+ class NSArrayCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSArrayCodeRunningSyntheticFrontEnd ();
+ };
+
+ SyntheticChildrenFrontEnd* NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class NSDictionaryISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint32_t _szidx : 6;
+ };
+
+ struct DictionaryItemDescriptor
+ {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ public:
+ NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSDictionaryISyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ lldb::addr_t m_data_ptr;
+ std::vector<DictionaryItemDescriptor> m_children;
+ };
+
+ class NSDictionaryMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _kvo : 1;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ uint32_t _keys_addr;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint32_t _kvo : 1;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ uint64_t _keys_addr;
+ };
+ struct DictionaryItemDescriptor
+ {
+ lldb::addr_t key_ptr;
+ lldb::addr_t val_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+ public:
+ NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSDictionaryMSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ std::vector<DictionaryItemDescriptor> m_children;
+ };
+
+ class NSDictionaryCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSDictionaryCodeRunningSyntheticFrontEnd ();
+ };
+
+ SyntheticChildrenFrontEnd* NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class NSSetISyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _szidx : 6;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint32_t _szidx : 6;
+ };
+
+ struct SetItemDescriptor
+ {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+
+ public:
+ NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSSetISyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ lldb::addr_t m_data_ptr;
+ std::vector<SetItemDescriptor> m_children;
+ };
+
+ class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ struct DataDescriptor_32
+ {
+ uint32_t _used : 26;
+ uint32_t _size;
+ uint32_t _mutations;
+ uint32_t _objs_addr;
+ };
+ struct DataDescriptor_64
+ {
+ uint64_t _used : 58;
+ uint64_t _size;
+ uint64_t _mutations;
+ uint64_t _objs_addr;
+ };
+ struct SetItemDescriptor
+ {
+ lldb::addr_t item_ptr;
+ lldb::ValueObjectSP valobj_sp;
+ };
+ public:
+ NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSSetMSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint8_t m_ptr_size;
+ DataDescriptor_32 *m_data_32;
+ DataDescriptor_64 *m_data_64;
+ std::vector<SetItemDescriptor> m_children;
+ };
+
+ class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ NSSetCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~NSSetCodeRunningSyntheticFrontEnd ();
+ };
+
+ SyntheticChildrenFrontEnd* NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibcxxVectorBoolSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint64_t m_count;
+ lldb::addr_t m_base_data_address;
+ EvaluateExpressionOptions m_options;
+ };
+
+ SyntheticChildrenFrontEnd* LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibstdcppVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibstdcppVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibstdcppVectorBoolSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ uint64_t m_count;
+ lldb::addr_t m_base_data_address;
+ EvaluateExpressionOptions m_options;
+ };
+
+ SyntheticChildrenFrontEnd* LibstdcppVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibstdcppMapIteratorSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ lldb::addr_t m_pair_address;
+ ClangASTType m_pair_type;
+ EvaluateExpressionOptions m_options;
+ lldb::ValueObjectSP m_pair_sp;
+ };
+
+ SyntheticChildrenFrontEnd* LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class LibCxxMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~LibCxxMapIteratorSyntheticFrontEnd ();
+ private:
+ ValueObject *m_pair_ptr;
+ };
+
+ SyntheticChildrenFrontEnd* LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ class VectorIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd
+ {
+ public:
+ VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp,
+ ConstString item_name);
+
+ virtual size_t
+ CalculateNumChildren ();
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update();
+
+ virtual bool
+ MightHaveChildren ();
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name);
+
+ virtual
+ ~VectorIteratorSyntheticFrontEnd ();
+ private:
+ ExecutionContextRef m_exe_ctx_ref;
+ ConstString m_item_name;
+ lldb::ValueObjectSP m_item_sp;
+ };
+
+ SyntheticChildrenFrontEnd* LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ SyntheticChildrenFrontEnd* LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP);
+
+ } // namespace formatters
+} // namespace lldb_private
+
+#endif // liblldb_CXXFormatterFunctions_h_
Index: aze/lldb/include/lldb/DataFormatters/DataVisualization.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/DataVisualization.h 2013-03-03 09:35:50.079457355 +0100
@@ -0,0 +1,174 @@
+//===-- DataVisualization.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_DataVisualization_h_
+#define lldb_DataVisualization_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ConstString.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+#include "lldb/DataFormatters/FormatManager.h"
+
+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
+// 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
+ static void
+ ForceUpdate();
+
+ static uint32_t
+ GetCurrentRevision ();
+
+ class ValueFormats
+ {
+ public:
+ static lldb::TypeFormatImplSP
+ GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic);
+
+ static lldb::TypeFormatImplSP
+ GetFormat (const ConstString &type);
+
+ static void
+ Add (const ConstString &type, const lldb::TypeFormatImplSP &entry);
+
+ static bool
+ Delete (const ConstString &type);
+
+ static void
+ Clear ();
+
+ static void
+ LoopThrough (TypeFormatImpl::ValueCallback callback, void* callback_baton);
+
+ static size_t
+ GetCount ();
+
+ static lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForFormatAtIndex (size_t);
+
+ static lldb::TypeFormatImplSP
+ GetFormatAtIndex (size_t);
+ };
+
+ static lldb::TypeSummaryImplSP
+ GetSummaryFormat(ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+
+ static lldb::TypeSummaryImplSP
+ GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ static lldb::SyntheticChildrenSP
+ GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+ static lldb::TypeFilterImplSP
+ GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ static lldb::ScriptedSyntheticChildrenSP
+ GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ static lldb::SyntheticChildrenSP
+ GetSyntheticChildren(ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+#endif
+
+ static bool
+ AnyMatches(ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ TypeCategoryImpl::FormatCategoryItems* matching_type = NULL);
+
+ class NamedSummaryFormats
+ {
+ public:
+ static bool
+ GetSummaryFormat (const ConstString &type, lldb::TypeSummaryImplSP &entry);
+
+ static void
+ Add (const ConstString &type, const lldb::TypeSummaryImplSP &entry);
+
+ static bool
+ Delete (const ConstString &type);
+
+ static void
+ Clear ();
+
+ static void
+ LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCount ();
+ };
+
+ class Categories
+ {
+ public:
+
+ static bool
+ GetCategory (const ConstString &category,
+ lldb::TypeCategoryImplSP &entry,
+ bool allow_create = true);
+
+ static void
+ Add (const ConstString &category);
+
+ static bool
+ Delete (const ConstString &category);
+
+ static void
+ Clear ();
+
+ static void
+ Clear (const ConstString &category);
+
+ static void
+ Enable (const ConstString& category,
+ TypeCategoryMap::Position = TypeCategoryMap::Default);
+
+ static void
+ Disable (const ConstString& category);
+
+ static void
+ Enable (const lldb::TypeCategoryImplSP& category,
+ TypeCategoryMap::Position = TypeCategoryMap::Default);
+
+ static void
+ Disable (const lldb::TypeCategoryImplSP& category);
+
+ static void
+ LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton);
+
+ static uint32_t
+ GetCount ();
+
+ static lldb::TypeCategoryImplSP
+ GetCategoryAtIndex (size_t);
+ };
+};
+
+
+} // namespace lldb_private
+
+#endif // lldb_DataVisualization_h_
Index: aze/lldb/include/lldb/DataFormatters/FormatCache.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/FormatCache.h 2013-03-03 09:35:50.079457355 +0100
@@ -0,0 +1,105 @@
+//===-- FormatCache.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_FormatCache_h_
+#define lldb_FormatCache_h_
+
+// C Includes
+// C++ Includes
+#include <map>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+
+namespace lldb_private {
+class FormatCache
+{
+private:
+ struct Entry
+ {
+ private:
+ bool m_summary_cached : 1;
+ bool m_synthetic_cached : 1;
+
+ lldb::TypeSummaryImplSP m_summary_sp;
+ lldb::SyntheticChildrenSP m_synthetic_sp;
+ public:
+ Entry ();
+ Entry (lldb::TypeSummaryImplSP);
+ Entry (lldb::SyntheticChildrenSP);
+ Entry (lldb::TypeSummaryImplSP,lldb::SyntheticChildrenSP);
+
+ bool
+ IsSummaryCached ();
+
+ bool
+ IsSyntheticCached ();
+
+ lldb::TypeSummaryImplSP
+ GetSummary ();
+
+ lldb::SyntheticChildrenSP
+ GetSynthetic ();
+
+ void
+ SetSummary (lldb::TypeSummaryImplSP);
+
+ void
+ SetSynthetic (lldb::SyntheticChildrenSP);
+ };
+ typedef std::map<ConstString,Entry> CacheMap;
+ CacheMap m_map;
+ Mutex m_mutex;
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ uint64_t m_cache_hits;
+ uint64_t m_cache_misses;
+#endif
+
+ Entry&
+ GetEntry (const ConstString& type);
+
+public:
+ FormatCache ();
+
+ bool
+ GetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp);
+
+ bool
+ GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp);
+
+ void
+ SetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp);
+
+ void
+ SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp);
+
+ void
+ Clear ();
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ uint64_t
+ GetCacheHits ()
+ {
+ return m_cache_hits;
+ }
+
+ uint64_t
+ GetCacheMisses ()
+ {
+ return m_cache_misses;
+ }
+#endif
+};
+} // namespace lldb_private
+
+#endif // lldb_FormatCache_h_
Index: aze/lldb/include/lldb/DataFormatters/FormatClasses.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/FormatClasses.h 2013-03-03 09:35:50.079457355 +0100
@@ -0,0 +1,128 @@
+//===-- FormatClasses.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_FormatClasses_h_
+#define lldb_FormatClasses_h_
+
+// C Includes
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/Type.h"
+
+#include "lldb/DataFormatters/TypeFormat.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+
+namespace lldb_private {
+
+class TypeNameSpecifierImpl
+{
+public:
+ TypeNameSpecifierImpl() :
+ m_is_regex(false),
+ m_type()
+ {
+ }
+
+ TypeNameSpecifierImpl (const char* name, bool is_regex) :
+ m_is_regex(is_regex),
+ m_type()
+ {
+ if (name)
+ m_type.m_type_name.assign(name);
+ }
+
+ // if constructing with a given type, is_regex cannot be true since we are
+ // giving an exact type to match
+ TypeNameSpecifierImpl (lldb::TypeSP type) :
+ m_is_regex(false),
+ m_type()
+ {
+ if (type)
+ {
+ m_type.m_type_name.assign(type->GetName().GetCString());
+ m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
+ }
+ }
+
+ TypeNameSpecifierImpl (ClangASTType type) :
+ m_is_regex(false),
+ m_type()
+ {
+ if (type.IsValid())
+ {
+ m_type.m_type_name.assign(type.GetConstTypeName().GetCString());
+ m_type.m_typeimpl_sp = lldb::TypeImplSP(new TypeImpl(type));
+ }
+ }
+
+ const char*
+ GetName()
+ {
+ if (m_type.m_type_name.size())
+ return m_type.m_type_name.c_str();
+ return NULL;
+ }
+
+ lldb::TypeSP
+ GetTypeSP ()
+ {
+ if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
+ return m_type.m_typeimpl_sp->GetTypeSP();
+ return lldb::TypeSP();
+ }
+
+ ClangASTType
+ GetClangASTType ()
+ {
+ if (m_type.m_typeimpl_sp && m_type.m_typeimpl_sp->IsValid())
+ return m_type.m_typeimpl_sp->GetClangASTType();
+ return ClangASTType();
+ }
+
+ bool
+ IsRegex()
+ {
+ return m_is_regex;
+ }
+
+private:
+ bool m_is_regex;
+ // this works better than TypeAndOrName because the latter only wraps a TypeSP
+ // whereas TypeImplSP can also be backed by a ClangASTType which is more commonly
+ // used in LLDB. moreover, TypeImplSP is also what is currently backing SBType
+ struct TypeOrName
+ {
+ std::string m_type_name;
+ lldb::TypeImplSP m_typeimpl_sp;
+ };
+ TypeOrName m_type;
+
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(TypeNameSpecifierImpl);
+};
+
+} // namespace lldb_private
+
+#endif // lldb_FormatClasses_h_
Index: aze/lldb/include/lldb/DataFormatters/FormatManager.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/FormatManager.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,251 @@
+//===-- FormatManager.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_FormatManager_h_
+#define lldb_FormatManager_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/DataFormatters/FormatCache.h"
+#include "lldb/DataFormatters/FormatNavigator.h"
+#include "lldb/DataFormatters/TypeCategory.h"
+#include "lldb/DataFormatters/TypeCategoryMap.h"
+
+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
+
+class FormatManager : public IFormatChangeListener
+{
+ typedef FormatNavigator<ConstString, TypeFormatImpl> ValueNavigator;
+ typedef ValueNavigator::MapType ValueMap;
+ typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap;
+ typedef TypeCategoryMap::MapType::iterator CategoryMapIterator;
+public:
+
+ typedef TypeCategoryMap::CallbackType CategoryCallback;
+
+ FormatManager ();
+
+ ValueNavigator&
+ GetValueNavigator ()
+ {
+ return m_value_nav;
+ }
+
+ NamedSummariesMap&
+ GetNamedSummaryNavigator ()
+ {
+ return m_named_summaries_map;
+ }
+
+ void
+ EnableCategory (const ConstString& category_name,
+ TypeCategoryMap::Position pos = TypeCategoryMap::Default)
+ {
+ m_categories_map.Enable(category_name,
+ pos);
+ }
+
+ void
+ DisableCategory (const ConstString& category_name)
+ {
+ m_categories_map.Disable(category_name);
+ }
+
+ void
+ EnableCategory (const lldb::TypeCategoryImplSP& category,
+ TypeCategoryMap::Position pos = TypeCategoryMap::Default)
+ {
+ m_categories_map.Enable(category,
+ pos);
+ }
+
+ void
+ DisableCategory (const lldb::TypeCategoryImplSP& category)
+ {
+ m_categories_map.Disable(category);
+ }
+
+ bool
+ DeleteCategory (const ConstString& category_name)
+ {
+ return m_categories_map.Delete(category_name);
+ }
+
+ void
+ ClearCategories ()
+ {
+ return m_categories_map.Clear();
+ }
+
+ uint32_t
+ GetCategoriesCount ()
+ {
+ return m_categories_map.GetCount();
+ }
+
+ lldb::TypeCategoryImplSP
+ GetCategoryAtIndex (size_t index)
+ {
+ return m_categories_map.GetAtIndex(index);
+ }
+
+ void
+ LoopThroughCategories (CategoryCallback callback, void* param)
+ {
+ m_categories_map.LoopThrough(callback, param);
+ }
+
+ lldb::TypeCategoryImplSP
+ GetCategory (const char* category_name = NULL,
+ bool can_create = true)
+ {
+ if (!category_name)
+ return GetCategory(m_default_category_name);
+ return GetCategory(ConstString(category_name));
+ }
+
+ lldb::TypeCategoryImplSP
+ GetCategory (const ConstString& category_name,
+ bool can_create = true);
+
+ lldb::TypeSummaryImplSP
+ GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+ lldb::TypeFilterImplSP
+ GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::ScriptedSyntheticChildrenSP
+ GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+ lldb::TypeSummaryImplSP
+ GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+#endif
+
+ bool
+ AnyMatches (ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ TypeCategoryImpl::FormatCategoryItems* matching_type = NULL)
+ {
+ return m_categories_map.AnyMatches(type_name,
+ items,
+ only_enabled,
+ matching_category,
+ matching_type);
+ }
+
+ static bool
+ GetFormatFromCString (const char *format_cstr,
+ bool partial_match_ok,
+ lldb::Format &format);
+
+ static char
+ GetFormatAsFormatChar (lldb::Format format);
+
+ 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
+ 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 vectorOf
+ static lldb::Format
+ GetSingleItemFormat (lldb::Format vector_format);
+
+ void
+ Changed ()
+ {
+ __sync_add_and_fetch(&m_last_revision, +1);
+ m_format_cache.Clear ();
+ }
+
+ uint32_t
+ GetCurrentRevision ()
+ {
+ return m_last_revision;
+ }
+
+ ~FormatManager ()
+ {
+ }
+
+private:
+ FormatCache m_format_cache;
+ ValueNavigator m_value_nav;
+ NamedSummariesMap m_named_summaries_map;
+ uint32_t m_last_revision;
+ TypeCategoryMap m_categories_map;
+
+ ConstString m_default_category_name;
+ ConstString m_system_category_name;
+ ConstString m_gnu_cpp_category_name;
+ ConstString m_libcxx_category_name;
+ ConstString m_objc_category_name;
+ ConstString m_corefoundation_category_name;
+ ConstString m_coregraphics_category_name;
+ ConstString m_coreservices_category_name;
+ ConstString m_vectortypes_category_name;
+ ConstString m_appkit_category_name;
+
+ TypeCategoryMap&
+ GetCategories ()
+ {
+ return m_categories_map;
+ }
+
+ // WARNING: these are temporary functions that setup formatters
+ // while a few of these actually should be globally available and setup by LLDB itself
+ // most would actually belong to the users' lldbinit file or to some other form of configurable
+ // storage
+ void
+ LoadLibStdcppFormatters ();
+
+ void
+ LoadLibcxxFormatters ();
+
+ void
+ LoadSystemFormatters ();
+
+ void
+ LoadObjCFormatters ();
+};
+
+} // namespace lldb_private
+
+#endif // lldb_FormatManager_h_
Index: aze/lldb/include/lldb/DataFormatters/FormatNavigator.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/FormatNavigator.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,681 @@
+//===-- FormatNavigator.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_FormatNavigator_h_
+#define lldb_FormatNavigator_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/DeclObjC.h"
+
+// Project includes
+#include "lldb/lldb-public.h"
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/ValueObject.h"
+
+#include "lldb/DataFormatters/FormatClasses.h"
+
+#include "lldb/Symbol/ClangASTContext.h"
+
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/TargetList.h"
+
+using lldb::LogSP;
+
+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
+class IFormatChangeListener
+{
+public:
+ virtual void
+ Changed () = 0;
+
+ virtual
+ ~IFormatChangeListener () {}
+
+ virtual uint32_t
+ GetCurrentRevision () = 0;
+
+};
+
+static inline bool
+IsWhitespace (char c)
+{
+ return ( (c == ' ') || (c == '\t') || (c == '\v') || (c == '\f') );
+}
+
+static inline bool
+HasPrefix (const char* str1, const char* str2)
+{
+ return ( ::strstr(str1, str2) == str1 );
+}
+
+// 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_Impl (const ConstString& type)
+{
+ int strip_len = 0;
+
+ if (type == false)
+ return type;
+
+ const char* type_cstr = type.AsCString();
+
+ if ( HasPrefix(type_cstr, "class ") )
+ strip_len = 6;
+ else if ( HasPrefix(type_cstr, "enum ") )
+ strip_len = 5;
+ else if ( HasPrefix(type_cstr, "struct ") )
+ strip_len = 7;
+ else if ( HasPrefix(type_cstr, "union ") )
+ strip_len = 6;
+
+ if (strip_len == 0)
+ return type;
+
+ type_cstr += strip_len;
+ while (IsWhitespace(*type_cstr) && ++type_cstr)
+ ;
+
+ return ConstString(type_cstr);
+}
+
+template<typename KeyType, typename ValueType>
+class FormatNavigator;
+
+template<typename KeyType, typename ValueType>
+class FormatMap
+{
+public:
+
+ typedef typename ValueType::SharedPointer ValueSP;
+ typedef std::map<KeyType, ValueSP> MapType;
+ typedef typename MapType::iterator MapIterator;
+ typedef bool(*CallbackType)(void*, KeyType, const ValueSP&);
+
+ FormatMap(IFormatChangeListener* lst) :
+ m_map(),
+ m_map_mutex(Mutex::eMutexTypeRecursive),
+ listener(lst)
+ {
+ }
+
+ void
+ Add(KeyType name,
+ const ValueSP& entry)
+ {
+ if (listener)
+ entry->GetRevision() = listener->GetCurrentRevision();
+ else
+ entry->GetRevision() = 0;
+
+ Mutex::Locker locker(m_map_mutex);
+ m_map[name] = entry;
+ if (listener)
+ listener->Changed();
+ }
+
+ bool
+ Delete (KeyType name)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ m_map.erase(name);
+ if (listener)
+ listener->Changed();
+ return true;
+ }
+
+ void
+ Clear ()
+ {
+ Mutex::Locker locker(m_map_mutex);
+ m_map.clear();
+ if (listener)
+ listener->Changed();
+ }
+
+ bool
+ Get(KeyType name,
+ ValueSP& entry)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ entry = iter->second;
+ return true;
+ }
+
+ void
+ LoopThrough (CallbackType callback, void* param)
+ {
+ if (callback)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; pos++)
+ {
+ KeyType type = pos->first;
+ if (!callback(param, type, pos->second))
+ break;
+ }
+ }
+ }
+
+ uint32_t
+ GetCount ()
+ {
+ return m_map.size();
+ }
+
+ ValueSP
+ GetValueAtIndex (size_t index)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.begin();
+ MapIterator end = m_map.end();
+ while (index > 0)
+ {
+ iter++;
+ index--;
+ if (end == iter)
+ return ValueSP();
+ }
+ return iter->second;
+ }
+
+ KeyType
+ GetKeyAtIndex (size_t index)
+ {
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.begin();
+ MapIterator end = m_map.end();
+ while (index > 0)
+ {
+ iter++;
+ index--;
+ if (end == iter)
+ return KeyType();
+ }
+ return iter->first;
+ }
+
+protected:
+ MapType m_map;
+ Mutex m_map_mutex;
+ IFormatChangeListener* listener;
+
+ MapType&
+ map ()
+ {
+ return m_map;
+ }
+
+ Mutex&
+ mutex ()
+ {
+ return m_map_mutex;
+ }
+
+ friend class FormatNavigator<KeyType, ValueType>;
+ friend class FormatManager;
+
+};
+
+template<typename KeyType, typename ValueType>
+class FormatNavigator
+{
+protected:
+ typedef FormatMap<KeyType,ValueType> BackEndType;
+
+public:
+ typedef typename BackEndType::MapType MapType;
+ typedef typename MapType::iterator MapIterator;
+ typedef typename MapType::key_type MapKeyType;
+ typedef typename MapType::mapped_type MapValueType;
+ typedef typename BackEndType::CallbackType CallbackType;
+#ifdef _LIBCPP_VERSION
+ typedef typename std::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
+#else
+ typedef typename std::tr1::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
+#endif
+
+ friend class TypeCategoryImpl;
+
+ FormatNavigator(std::string name,
+ IFormatChangeListener* lst) :
+ m_format_map(lst),
+ m_name(name),
+ m_id_cs(ConstString("id"))
+ {
+ }
+
+ void
+ Add (const MapKeyType &type, const MapValueType& entry)
+ {
+ Add_Impl(type, entry, (KeyType*)NULL);
+ }
+
+ bool
+ Delete (ConstString type)
+ {
+ return Delete_Impl(type, (KeyType*)NULL);
+ }
+
+ bool
+ Get(ValueObject& valobj,
+ MapValueType& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* why = NULL)
+ {
+ uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
+ clang::QualType type = clang::QualType::getFromOpaquePtr(valobj.GetClangType());
+ bool ret = Get(valobj, type, entry, use_dynamic, value);
+ if (ret)
+ entry = MapValueType(entry);
+ else
+ entry = MapValueType();
+ if (why)
+ *why = value;
+ return ret;
+ }
+
+ bool
+ Get (ConstString type, MapValueType& entry)
+ {
+ return Get_Impl(type, entry, (KeyType*)NULL);
+ }
+
+ bool
+ GetExact (ConstString type, MapValueType& entry)
+ {
+ return GetExact_Impl(type, entry, (KeyType*)NULL);
+ }
+
+ MapValueType
+ GetAtIndex (size_t index)
+ {
+ return m_format_map.GetValueAtIndex(index);
+ }
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierAtIndex (size_t index)
+ {
+ return GetTypeNameSpecifierAtIndex_Impl(index, (KeyType*)NULL);
+ }
+
+ void
+ Clear ()
+ {
+ m_format_map.Clear();
+ }
+
+ void
+ LoopThrough (CallbackType callback, void* param)
+ {
+ m_format_map.LoopThrough(callback,param);
+ }
+
+ uint32_t
+ GetCount ()
+ {
+ return m_format_map.GetCount();
+ }
+
+protected:
+
+ BackEndType m_format_map;
+
+ std::string m_name;
+
+ DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
+
+ ConstString m_id_cs;
+
+ void
+ Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
+ {
+ m_format_map.Add(type,entry);
+ }
+
+ void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
+ {
+ m_format_map.Add(GetValidTypeName_Impl(type), entry);
+ }
+
+ bool
+ Delete_Impl (ConstString type, ConstString *dummy)
+ {
+ return m_format_map.Delete(type);
+ }
+
+ bool
+ Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
+ {
+ Mutex& x_mutex = m_format_map.mutex();
+ lldb_private::Mutex::Locker locker(x_mutex);
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
+ {
+ m_format_map.map().erase(pos);
+ if (m_format_map.listener)
+ m_format_map.listener->Changed();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
+ {
+ return m_format_map.Get(type, entry);
+ }
+
+ bool
+ GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
+ {
+ return Get_Impl(type,entry, (KeyType*)0);
+ }
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierAtIndex_Impl (size_t index, ConstString *dummy)
+ {
+ ConstString key = m_format_map.GetKeyAtIndex(index);
+ if (key)
+ return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
+ false));
+ else
+ return lldb::TypeNameSpecifierImplSP();
+ }
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierAtIndex_Impl (size_t index, lldb::RegularExpressionSP *dummy)
+ {
+ lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
+ if (regex.get() == NULL)
+ return lldb::TypeNameSpecifierImplSP();
+ return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(regex->GetText(),
+ true));
+ }
+
+ bool
+ Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
+ {
+ const char* key_cstr = key.AsCString();
+ if (!key_cstr)
+ return false;
+ Mutex& x_mutex = m_format_map.mutex();
+ lldb_private::Mutex::Locker locker(x_mutex);
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if (regex->Execute(key_cstr))
+ {
+ value = pos->second;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
+ {
+ Mutex& x_mutex = m_format_map.mutex();
+ lldb_private::Mutex::Locker locker(x_mutex);
+ MapIterator pos, end = m_format_map.map().end();
+ for (pos = m_format_map.map().begin(); pos != end; pos++)
+ {
+ lldb::RegularExpressionSP regex = pos->first;
+ if (strcmp(regex->GetText(),key.AsCString()) == 0)
+ {
+ value = pos->second;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool
+ Get_BitfieldMatch (ValueObject& valobj,
+ ConstString typeName,
+ MapValueType& entry,
+ uint32_t& reason)
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ // for bitfields, append size to the typename so one can custom format them
+ StreamString sstring;
+ sstring.Printf("%s:%d",typeName.AsCString(),valobj.GetBitfieldBitSize());
+ ConstString bitfieldname = ConstString(sstring.GetData());
+ if (log)
+ log->Printf("[Get_BitfieldMatch] appended bitfield info, final result is %s", bitfieldname.GetCString());
+ if (Get(bitfieldname, entry))
+ {
+ if (log)
+ log->Printf("[Get_BitfieldMatch] bitfield direct match found, returning");
+ return true;
+ }
+ else
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
+ if (log)
+ log->Printf("[Get_BitfieldMatch] no bitfield direct match");
+ return false;
+ }
+ }
+
+ bool Get_ObjC (ValueObject& valobj,
+ MapValueType& entry)
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ lldb::ProcessSP process_sp = valobj.GetProcessSP();
+ ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
+ if (runtime == NULL)
+ {
+ if (log)
+ log->Printf("[Get_ObjC] no valid ObjC runtime, skipping dynamic");
+ return false;
+ }
+ ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
+ if (!objc_class_sp)
+ {
+ if (log)
+ log->Printf("[Get_ObjC] invalid ISA, skipping dynamic");
+ return false;
+ }
+ ConstString name (objc_class_sp->GetClassName());
+ if (log)
+ log->Printf("[Get_ObjC] dynamic type inferred is %s - looking for direct dynamic match", name.GetCString());
+ if (Get(name, entry))
+ {
+ if (log)
+ log->Printf("[Get_ObjC] direct dynamic match found, returning");
+ return true;
+ }
+ if (log)
+ log->Printf("[Get_ObjC] no dynamic match");
+ return false;
+ }
+
+ bool
+ Get_Impl (ValueObject& valobj,
+ clang::QualType type,
+ MapValueType& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t& reason)
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+
+ if (type.isNull())
+ {
+ if (log)
+ log->Printf("[Get_Impl] type is NULL, returning");
+ return false;
+ }
+
+ type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
+ const clang::Type* typePtr = type.getTypePtrOrNull();
+ if (!typePtr)
+ {
+ if (log)
+ log->Printf("[Get_Impl] type is NULL, returning");
+ return false;
+ }
+ ConstString typeName(ClangASTType::GetTypeNameForQualType(valobj.GetClangAST(), type).c_str());
+
+ if (valobj.GetBitfieldBitSize() > 0)
+ {
+ if (Get_BitfieldMatch(valobj, typeName, entry, reason))
+ return true;
+ }
+
+ if (log)
+ log->Printf("[Get_Impl] trying to get %s for VO name %s of type %s",
+ m_name.c_str(),
+ valobj.GetName().AsCString(),
+ typeName.AsCString());
+
+ if (Get(typeName, entry))
+ {
+ if (log)
+ log->Printf("[Get] direct match found, returning");
+ return true;
+ }
+ if (log)
+ log->Printf("[Get_Impl] no direct match");
+
+ // strip pointers and references and see if that helps
+ if (typePtr->isReferenceType())
+ {
+ if (log)
+ log->Printf("[Get_Impl] stripping reference");
+ if (Get_Impl(valobj,type.getNonReferenceType(),entry, use_dynamic, reason) && !entry->SkipsReferences())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
+ return true;
+ }
+ }
+ else if (typePtr->isPointerType())
+ {
+ if (log)
+ log->Printf("[Get_Impl] stripping pointer");
+ clang::QualType pointee = typePtr->getPointeeType();
+ if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
+ return true;
+ }
+ }
+
+ bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(),
+ type.getAsOpaquePtr(),
+ NULL,
+ false, // no C++
+ true); // yes ObjC
+
+ if (canBeObjCDynamic)
+ {
+ if (use_dynamic != lldb::eNoDynamicValues)
+ {
+ if (log)
+ log->Printf("[Get_Impl] allowed to figure out dynamic ObjC type");
+ if (Get_ObjC(valobj,entry))
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCDiscovery;
+ return true;
+ }
+ }
+ if (log)
+ log->Printf("[Get_Impl] dynamic disabled or failed - stripping ObjC pointer");
+ clang::QualType pointee = typePtr->getPointeeType();
+ if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
+ return true;
+ }
+ }
+
+ // try to strip typedef chains
+ const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
+ if (type_tdef)
+ {
+ if (log)
+ log->Printf("[Get_Impl] stripping typedef");
+ if ((Get_Impl(valobj, type_tdef->getDecl()->getUnderlyingType(), entry, use_dynamic, reason)) && entry->Cascades())
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionNavigatedTypedefs;
+ return true;
+ }
+ }
+
+ // out of luck here
+ return false;
+ }
+
+ // we are separately passing in valobj and type because the valobj is fixed (and is used for ObjC discovery and bitfield size)
+ // but the type can change (e.g. stripping pointers, ...)
+ bool Get (ValueObject& valobj,
+ clang::QualType type,
+ MapValueType& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t& reason)
+ {
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+
+ if (Get_Impl (valobj,type,entry,use_dynamic,reason))
+ return true;
+
+ // if all else fails, go to static type
+ if (valobj.IsDynamic())
+ {
+ if (log)
+ log->Printf("[Get] going to static value");
+ lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
+ if (static_value_sp)
+ {
+ if (log)
+ log->Printf("[Get] has a static value - actually use it");
+ if (Get(*static_value_sp.get(), clang::QualType::getFromOpaquePtr(static_value_sp->GetClangType()) , entry, use_dynamic, reason))
+ {
+ reason |= lldb_private::eFormatterChoiceCriterionWentToStaticValue;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+};
+
+} // namespace lldb_private
+
+#endif // lldb_FormatNavigator_h_
Index: aze/lldb/include/lldb/DataFormatters/TypeCategory.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/TypeCategory.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,230 @@
+//===-- TypeCategory.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_TypeCategory_h_
+#define lldb_TypeCategory_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/DataFormatters/FormatNavigator.h"
+
+namespace lldb_private {
+ class TypeCategoryImpl
+ {
+ private:
+
+ typedef FormatNavigator<ConstString, TypeSummaryImpl> SummaryNavigator;
+ typedef FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl> RegexSummaryNavigator;
+
+ typedef FormatNavigator<ConstString, TypeFilterImpl> FilterNavigator;
+ typedef FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl> RegexFilterNavigator;
+
+#ifndef LLDB_DISABLE_PYTHON
+ typedef FormatNavigator<ConstString, ScriptedSyntheticChildren> SynthNavigator;
+ typedef FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren> RegexSynthNavigator;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ typedef SummaryNavigator::MapType SummaryMap;
+ typedef RegexSummaryNavigator::MapType RegexSummaryMap;
+ typedef FilterNavigator::MapType FilterMap;
+ typedef RegexFilterNavigator::MapType RegexFilterMap;
+#ifndef LLDB_DISABLE_PYTHON
+ typedef SynthNavigator::MapType SynthMap;
+ typedef RegexSynthNavigator::MapType RegexSynthMap;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ public:
+
+ typedef uint16_t FormatCategoryItems;
+ static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;
+
+ typedef SummaryNavigator::SharedPointer SummaryNavigatorSP;
+ typedef RegexSummaryNavigator::SharedPointer RegexSummaryNavigatorSP;
+ typedef FilterNavigator::SharedPointer FilterNavigatorSP;
+ typedef RegexFilterNavigator::SharedPointer RegexFilterNavigatorSP;
+#ifndef LLDB_DISABLE_PYTHON
+ typedef SynthNavigator::SharedPointer SynthNavigatorSP;
+ typedef RegexSynthNavigator::SharedPointer RegexSynthNavigatorSP;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ TypeCategoryImpl (IFormatChangeListener* clist,
+ ConstString name);
+
+ SummaryNavigatorSP
+ GetSummaryNavigator ()
+ {
+ return SummaryNavigatorSP(m_summary_nav);
+ }
+
+ RegexSummaryNavigatorSP
+ GetRegexSummaryNavigator ()
+ {
+ return RegexSummaryNavigatorSP(m_regex_summary_nav);
+ }
+
+ FilterNavigatorSP
+ GetFilterNavigator ()
+ {
+ return FilterNavigatorSP(m_filter_nav);
+ }
+
+ RegexFilterNavigatorSP
+ GetRegexFilterNavigator ()
+ {
+ return RegexFilterNavigatorSP(m_regex_filter_nav);
+ }
+
+ SummaryNavigator::MapValueType
+ GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+ FilterNavigator::MapValueType
+ GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SynthNavigator::MapValueType
+ GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
+#endif
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForSummaryAtIndex (size_t index);
+
+ SummaryNavigator::MapValueType
+ GetSummaryAtIndex (size_t index);
+
+ FilterNavigator::MapValueType
+ GetFilterAtIndex (size_t index);
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForFilterAtIndex (size_t index);
+
+#ifndef LLDB_DISABLE_PYTHON
+ SynthNavigatorSP
+ GetSyntheticNavigator ()
+ {
+ return SynthNavigatorSP(m_synth_nav);
+ }
+
+ RegexSynthNavigatorSP
+ GetRegexSyntheticNavigator ()
+ {
+ return RegexSynthNavigatorSP(m_regex_synth_nav);
+ }
+
+ SynthNavigator::MapValueType
+ GetSyntheticAtIndex (size_t index);
+
+ lldb::TypeNameSpecifierImplSP
+ GetTypeNameSpecifierForSyntheticAtIndex (size_t index);
+
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ bool
+ IsEnabled () const
+ {
+ return m_enabled;
+ }
+
+ uint32_t
+ GetEnabledPosition()
+ {
+ if (m_enabled == false)
+ return UINT32_MAX;
+ else
+ return m_enabled_position;
+ }
+
+ bool
+ Get (ValueObject& valobj,
+ lldb::TypeSummaryImplSP& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* reason = NULL);
+
+ bool
+ Get (ValueObject& valobj,
+ lldb::SyntheticChildrenSP& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* reason = NULL);
+
+ void
+ Clear (FormatCategoryItems items = ALL_ITEM_TYPES);
+
+ bool
+ Delete (ConstString name,
+ FormatCategoryItems items = ALL_ITEM_TYPES);
+
+ uint32_t
+ GetCount (FormatCategoryItems items = ALL_ITEM_TYPES);
+
+ const char*
+ GetName ()
+ {
+ return m_name.GetCString();
+ }
+
+ bool
+ AnyMatches (ConstString type_name,
+ FormatCategoryItems items = ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ FormatCategoryItems* matching_type = NULL);
+
+ typedef STD_SHARED_PTR(TypeCategoryImpl) SharedPointer;
+
+ private:
+ SummaryNavigator::SharedPointer m_summary_nav;
+ RegexSummaryNavigator::SharedPointer m_regex_summary_nav;
+ FilterNavigator::SharedPointer m_filter_nav;
+ RegexFilterNavigator::SharedPointer m_regex_filter_nav;
+#ifndef LLDB_DISABLE_PYTHON
+ SynthNavigator::SharedPointer m_synth_nav;
+ RegexSynthNavigator::SharedPointer m_regex_synth_nav;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+
+ bool m_enabled;
+
+ IFormatChangeListener* m_change_listener;
+
+ Mutex m_mutex;
+
+ ConstString m_name;
+
+ uint32_t m_enabled_position;
+
+ void
+ Enable (bool value, uint32_t position);
+
+ void
+ Disable ()
+ {
+ Enable(false, UINT32_MAX);
+ }
+
+ friend class TypeCategoryMap;
+
+ friend class FormatNavigator<ConstString, TypeSummaryImpl>;
+ friend class FormatNavigator<lldb::RegularExpressionSP, TypeSummaryImpl>;
+
+ friend class FormatNavigator<ConstString, TypeFilterImpl>;
+ friend class FormatNavigator<lldb::RegularExpressionSP, TypeFilterImpl>;
+
+#ifndef LLDB_DISABLE_PYTHON
+ friend class FormatNavigator<ConstString, ScriptedSyntheticChildren>;
+ friend class FormatNavigator<lldb::RegularExpressionSP, ScriptedSyntheticChildren>;
+#endif // #ifndef LLDB_DISABLE_PYTHON
+ };
+
+} // namespace lldb_private
+
+#endif // lldb_TypeCategory_h_
Index: aze/lldb/include/lldb/DataFormatters/TypeCategoryMap.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/TypeCategoryMap.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,148 @@
+//===-- TypeCategoryMap.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_TypeCategoryMap_h_
+#define lldb_TypeCategoryMap_h_
+
+// C Includes
+// C++ Includes
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/DataFormatters/FormatNavigator.h"
+#include "lldb/DataFormatters/TypeCategory.h"
+
+namespace lldb_private {
+ class TypeCategoryMap
+ {
+ private:
+ typedef ConstString KeyType;
+ typedef TypeCategoryImpl ValueType;
+ typedef ValueType::SharedPointer ValueSP;
+ typedef std::list<lldb::TypeCategoryImplSP> ActiveCategoriesList;
+ typedef ActiveCategoriesList::iterator ActiveCategoriesIterator;
+
+ public:
+ typedef std::map<KeyType, ValueSP> MapType;
+ typedef MapType::iterator MapIterator;
+ typedef bool(*CallbackType)(void*, const ValueSP&);
+ typedef uint32_t Position;
+
+ static const Position First = 0;
+ static const Position Default = 1;
+ static const Position Last = UINT32_MAX;
+
+ TypeCategoryMap (IFormatChangeListener* lst);
+
+ void
+ Add (KeyType name,
+ const ValueSP& entry);
+
+ bool
+ Delete (KeyType name);
+
+ bool
+ Enable (KeyType category_name,
+ Position pos = Default);
+
+ bool
+ Disable (KeyType category_name);
+
+ bool
+ Enable (ValueSP category,
+ Position pos = Default);
+
+ bool
+ Disable (ValueSP category);
+
+ void
+ Clear ();
+
+ bool
+ Get (KeyType name,
+ ValueSP& entry);
+
+ bool
+ Get (uint32_t pos,
+ ValueSP& entry);
+
+ void
+ LoopThrough (CallbackType callback, void* param);
+
+ lldb::TypeCategoryImplSP
+ GetAtIndex (uint32_t);
+
+ bool
+ AnyMatches (ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items = TypeCategoryImpl::ALL_ITEM_TYPES,
+ bool only_enabled = true,
+ const char** matching_category = NULL,
+ TypeCategoryImpl::FormatCategoryItems* matching_type = NULL);
+
+ uint32_t
+ GetCount ()
+ {
+ return m_map.size();
+ }
+
+ lldb::TypeSummaryImplSP
+ GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+
+#ifndef LLDB_DISABLE_PYTHON
+ lldb::SyntheticChildrenSP
+ GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic);
+#endif
+
+ private:
+
+ class delete_matching_categories
+ {
+ lldb::TypeCategoryImplSP ptr;
+ public:
+ delete_matching_categories(lldb::TypeCategoryImplSP p) : ptr(p)
+ {}
+
+ bool operator()(const lldb::TypeCategoryImplSP& other)
+ {
+ return ptr.get() == other.get();
+ }
+ };
+
+ Mutex m_map_mutex;
+ IFormatChangeListener* listener;
+
+ MapType m_map;
+ ActiveCategoriesList m_active_categories;
+
+ MapType& map ()
+ {
+ return m_map;
+ }
+
+ ActiveCategoriesList& active_list ()
+ {
+ return m_active_categories;
+ }
+
+ Mutex& mutex ()
+ {
+ return m_map_mutex;
+ }
+
+ friend class FormatNavigator<KeyType, ValueType>;
+ friend class FormatManager;
+ };
+} // namespace lldb_private
+
+#endif // lldb_TypeCategoryMap_h_
Index: aze/lldb/include/lldb/DataFormatters/TypeFormat.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/TypeFormat.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,220 @@
+//===-- TypeFormat.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_TypeFormat_h_
+#define lldb_TypeFormat_h_
+
+// C Includes
+
+// C++ Includes
+#include <string>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+
+namespace lldb_private {
+ class TypeFormatImpl
+ {
+ public:
+ class Flags
+ {
+ public:
+
+ Flags () :
+ m_flags (lldb::eTypeOptionCascade)
+ {}
+
+ Flags (const Flags& other) :
+ m_flags (other.m_flags)
+ {}
+
+ Flags (uint32_t value) :
+ m_flags (value)
+ {}
+
+ Flags&
+ operator = (const Flags& rhs)
+ {
+ if (&rhs != this)
+ m_flags = rhs.m_flags;
+
+ return *this;
+ }
+
+ Flags&
+ operator = (const uint32_t& rhs)
+ {
+ m_flags = rhs;
+ return *this;
+ }
+
+ Flags&
+ Clear()
+ {
+ m_flags = 0;
+ return *this;
+ }
+
+ bool
+ GetCascades () const
+ {
+ return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
+ }
+
+ Flags&
+ SetCascades (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionCascade;
+ else
+ m_flags &= ~lldb::eTypeOptionCascade;
+ return *this;
+ }
+
+ bool
+ GetSkipPointers () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
+ }
+
+ Flags&
+ SetSkipPointers (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipPointers;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipPointers;
+ return *this;
+ }
+
+ bool
+ GetSkipReferences () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
+ }
+
+ Flags&
+ SetSkipReferences (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipReferences;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipReferences;
+ return *this;
+ }
+
+ uint32_t
+ GetValue ()
+ {
+ return m_flags;
+ }
+
+ void
+ SetValue (uint32_t value)
+ {
+ m_flags = value;
+ }
+
+ private:
+ uint32_t m_flags;
+ };
+
+ TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid,
+ const Flags& flags = Flags());
+
+ typedef STD_SHARED_PTR(TypeFormatImpl) SharedPointer;
+ typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&);
+
+ ~TypeFormatImpl ()
+ {
+ }
+
+ bool
+ Cascades () const
+ {
+ return m_flags.GetCascades();
+ }
+ bool
+ SkipsPointers () const
+ {
+ return m_flags.GetSkipPointers();
+ }
+ bool
+ SkipsReferences () const
+ {
+ return m_flags.GetSkipReferences();
+ }
+
+ void
+ SetCascades (bool value)
+ {
+ m_flags.SetCascades(value);
+ }
+
+ void
+ SetSkipsPointers (bool value)
+ {
+ m_flags.SetSkipPointers(value);
+ }
+
+ void
+ SetSkipsReferences (bool value)
+ {
+ m_flags.SetSkipReferences(value);
+ }
+
+ lldb::Format
+ GetFormat () const
+ {
+ return m_format;
+ }
+
+ void
+ SetFormat (lldb::Format fmt)
+ {
+ m_format = fmt;
+ }
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ std::string
+ GetDescription();
+
+ protected:
+ Flags m_flags;
+ lldb::Format m_format;
+ uint32_t m_my_revision;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
+ };
+} // namespace lldb_private
+
+#endif // lldb_TypeFormat_h_
Index: aze/lldb/include/lldb/DataFormatters/TypeSummary.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/TypeSummary.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,547 @@
+//===-- TypeSummary.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_TypeSummary_h_
+#define lldb_TypeSummary_h_
+
+// C Includes
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+
+ class TypeSummaryImpl
+ {
+ public:
+ class Flags
+ {
+ public:
+
+ Flags () :
+ m_flags (lldb::eTypeOptionCascade)
+ {}
+
+ Flags (const Flags& other) :
+ m_flags (other.m_flags)
+ {}
+
+ Flags (uint32_t value) :
+ m_flags (value)
+ {}
+
+ Flags&
+ operator = (const Flags& rhs)
+ {
+ if (&rhs != this)
+ m_flags = rhs.m_flags;
+
+ return *this;
+ }
+
+ Flags&
+ operator = (const uint32_t& rhs)
+ {
+ m_flags = rhs;
+ return *this;
+ }
+
+ Flags&
+ Clear()
+ {
+ m_flags = 0;
+ return *this;
+ }
+
+ bool
+ GetCascades () const
+ {
+ return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
+ }
+
+ Flags&
+ SetCascades (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionCascade;
+ else
+ m_flags &= ~lldb::eTypeOptionCascade;
+ return *this;
+ }
+
+ bool
+ GetSkipPointers () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
+ }
+
+ Flags&
+ SetSkipPointers (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipPointers;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipPointers;
+ return *this;
+ }
+
+ bool
+ GetSkipReferences () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
+ }
+
+ Flags&
+ SetSkipReferences (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipReferences;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipReferences;
+ return *this;
+ }
+
+ bool
+ GetDontShowChildren () const
+ {
+ return (m_flags & lldb::eTypeOptionHideChildren) == lldb::eTypeOptionHideChildren;
+ }
+
+ Flags&
+ SetDontShowChildren (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionHideChildren;
+ else
+ m_flags &= ~lldb::eTypeOptionHideChildren;
+ return *this;
+ }
+
+ bool
+ GetDontShowValue () const
+ {
+ return (m_flags & lldb::eTypeOptionHideValue) == lldb::eTypeOptionHideValue;
+ }
+
+ Flags&
+ SetDontShowValue (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionHideValue;
+ else
+ m_flags &= ~lldb::eTypeOptionHideValue;
+ return *this;
+ }
+
+ bool
+ GetShowMembersOneLiner () const
+ {
+ return (m_flags & lldb::eTypeOptionShowOneLiner) == lldb::eTypeOptionShowOneLiner;
+ }
+
+ Flags&
+ SetShowMembersOneLiner (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionShowOneLiner;
+ else
+ m_flags &= ~lldb::eTypeOptionShowOneLiner;
+ return *this;
+ }
+
+ bool
+ GetHideItemNames () const
+ {
+ return (m_flags & lldb::eTypeOptionHideNames) == lldb::eTypeOptionHideNames;
+ }
+
+ Flags&
+ SetHideItemNames (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionHideNames;
+ else
+ m_flags &= ~lldb::eTypeOptionHideNames;
+ return *this;
+ }
+
+ uint32_t
+ GetValue ()
+ {
+ return m_flags;
+ }
+
+ void
+ SetValue (uint32_t value)
+ {
+ m_flags = value;
+ }
+
+ private:
+ uint32_t m_flags;
+ };
+
+ typedef enum Type
+ {
+ eTypeUnknown,
+ eTypeString,
+ eTypeScript,
+ eTypeCallback
+ } Type;
+
+ TypeSummaryImpl (const TypeSummaryImpl::Flags& flags);
+
+ bool
+ Cascades () const
+ {
+ return m_flags.GetCascades();
+ }
+ bool
+ SkipsPointers () const
+ {
+ return m_flags.GetSkipPointers();
+ }
+ bool
+ SkipsReferences () const
+ {
+ return m_flags.GetSkipReferences();
+ }
+
+ bool
+ DoesPrintChildren () const
+ {
+ return !m_flags.GetDontShowChildren();
+ }
+
+ bool
+ DoesPrintValue () const
+ {
+ return !m_flags.GetDontShowValue();
+ }
+
+ bool
+ IsOneliner () const
+ {
+ return m_flags.GetShowMembersOneLiner();
+ }
+
+ bool
+ HideNames () const
+ {
+ return m_flags.GetHideItemNames();
+ }
+
+ void
+ SetCascades (bool value)
+ {
+ m_flags.SetCascades(value);
+ }
+
+ void
+ SetSkipsPointers (bool value)
+ {
+ m_flags.SetSkipPointers(value);
+ }
+
+ void
+ SetSkipsReferences (bool value)
+ {
+ m_flags.SetSkipReferences(value);
+ }
+
+ void
+ SetDoesPrintChildren (bool value)
+ {
+ m_flags.SetDontShowChildren(!value);
+ }
+
+ void
+ SetDoesPrintValue (bool value)
+ {
+ m_flags.SetDontShowValue(!value);
+ }
+
+ void
+ SetIsOneliner (bool value)
+ {
+ m_flags.SetShowMembersOneLiner(value);
+ }
+
+ void
+ SetHideNames (bool value)
+ {
+ m_flags.SetHideItemNames(value);
+ }
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ virtual
+ ~TypeSummaryImpl ()
+ {
+ }
+
+ // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
+ // extended periods of time and we trust the ValueObject to stay around for as long as it is required
+ // for us to generate its summary
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest) = 0;
+
+ virtual std::string
+ GetDescription () = 0;
+
+ virtual bool
+ IsScripted () = 0;
+
+ virtual Type
+ GetType () = 0;
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ typedef STD_SHARED_PTR(TypeSummaryImpl) SharedPointer;
+ typedef bool(*SummaryCallback)(void*, ConstString, const lldb::TypeSummaryImplSP&);
+ typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const lldb::TypeSummaryImplSP&);
+
+ protected:
+ uint32_t m_my_revision;
+ Flags m_flags;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
+ };
+
+ // simple string-based summaries, using ${var to show data
+ struct StringSummaryFormat : public TypeSummaryImpl
+ {
+ std::string m_format;
+
+ StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
+ const char* f);
+
+ const char*
+ GetSummaryString () const
+ {
+ return m_format.c_str();
+ }
+
+ void
+ SetSummaryString (const char* data)
+ {
+ if (data)
+ m_format.assign(data);
+ else
+ m_format.clear();
+ }
+
+ virtual
+ ~StringSummaryFormat()
+ {
+ }
+
+ virtual bool
+ FormatObject(ValueObject *valobj,
+ std::string& dest);
+
+ virtual std::string
+ GetDescription();
+
+ virtual bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+
+ virtual Type
+ GetType ()
+ {
+ return TypeSummaryImpl::eTypeString;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
+ };
+
+ // summaries implemented via a C++ function
+ struct CXXFunctionSummaryFormat : public TypeSummaryImpl
+ {
+
+ // we should convert these to SBValue and SBStream if we ever cross
+ // the boundary towards the external world
+ typedef bool (*Callback)(ValueObject& valobj, Stream& dest);
+
+ Callback m_impl;
+ std::string m_description;
+
+ CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
+ Callback impl,
+ const char* description);
+
+ Callback
+ GetBackendFunction () const
+ {
+ return m_impl;
+ }
+
+ const char*
+ GetTextualInfo () const
+ {
+ return m_description.c_str();
+ }
+
+ void
+ SetBackendFunction (Callback cb_func)
+ {
+ m_impl = cb_func;
+ }
+
+ void
+ SetTextualInfo (const char* descr)
+ {
+ if (descr)
+ m_description.assign(descr);
+ else
+ m_description.clear();
+ }
+
+ virtual
+ ~CXXFunctionSummaryFormat ()
+ {
+ }
+
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest);
+
+ virtual std::string
+ GetDescription ();
+
+ virtual bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+ virtual Type
+ GetType ()
+ {
+ return TypeSummaryImpl::eTypeCallback;
+ }
+
+ typedef STD_SHARED_PTR(CXXFunctionSummaryFormat) SharedPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
+ };
+
+#ifndef LLDB_DISABLE_PYTHON
+
+ // Python-based summaries, running script code to show data
+ struct ScriptSummaryFormat : public TypeSummaryImpl
+ {
+ std::string m_function_name;
+ std::string m_python_script;
+ lldb::ScriptInterpreterObjectSP m_script_function_sp;
+
+ ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
+ const char *function_name,
+ const char* python_script = NULL);
+
+ const char*
+ GetFunctionName () const
+ {
+ return m_function_name.c_str();
+ }
+
+ const char*
+ GetPythonScript () const
+ {
+ return m_python_script.c_str();
+ }
+
+ void
+ SetFunctionName (const char* function_name)
+ {
+ if (function_name)
+ m_function_name.assign(function_name);
+ else
+ m_function_name.clear();
+ m_python_script.clear();
+ }
+
+ void
+ SetPythonScript (const char* script)
+ {
+ if (script)
+ m_python_script.assign(script);
+ else
+ m_python_script.clear();
+ }
+
+ virtual
+ ~ScriptSummaryFormat ()
+ {
+ }
+
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest);
+
+ virtual std::string
+ GetDescription ();
+
+ virtual bool
+ IsScripted ()
+ {
+ return true;
+ }
+
+ virtual Type
+ GetType ()
+ {
+ return TypeSummaryImpl::eTypeScript;
+ }
+
+ typedef STD_SHARED_PTR(ScriptSummaryFormat) SharedPointer;
+
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
+ };
+#endif
+} // namespace lldb_private
+
+#endif // lldb_TypeSummary_h_
Index: aze/lldb/include/lldb/DataFormatters/TypeSynthetic.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/DataFormatters/TypeSynthetic.h 2013-03-03 09:35:50.083457354 +0100
@@ -0,0 +1,594 @@
+//===-- TypeSynthetic.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_TypeSynthetic_h_
+#define lldb_TypeSynthetic_h_
+
+// C Includes
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ Includes
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Symbol/Type.h"
+
+namespace lldb_private {
+ class SyntheticChildrenFrontEnd
+ {
+ protected:
+ ValueObject &m_backend;
+ public:
+
+ SyntheticChildrenFrontEnd (ValueObject &backend) :
+ m_backend(backend)
+ {}
+
+ virtual
+ ~SyntheticChildrenFrontEnd ()
+ {
+ }
+
+ virtual size_t
+ CalculateNumChildren () = 0;
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx) = 0;
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name) = 0;
+
+ // this function is assumed to always succeed and it if fails, the front-end should know to deal
+ // with it in the correct way (most probably, by refusing to return any children)
+ // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
+ // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
+ // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
+ virtual bool
+ Update () = 0;
+
+ // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
+ // might validly decide not to inquire for children given a false return value from this call
+ // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
+ // it should if at all possible be more efficient than CalculateNumChildren()
+ virtual bool
+ MightHaveChildren () = 0;
+
+ typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
+ typedef std::auto_ptr<SyntheticChildrenFrontEnd> AutoPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
+ };
+
+ class SyntheticChildren
+ {
+ public:
+
+ class Flags
+ {
+ public:
+
+ Flags () :
+ m_flags (lldb::eTypeOptionCascade)
+ {}
+
+ Flags (const Flags& other) :
+ m_flags (other.m_flags)
+ {}
+
+ Flags (uint32_t value) :
+ m_flags (value)
+ {}
+
+ Flags&
+ operator = (const Flags& rhs)
+ {
+ if (&rhs != this)
+ m_flags = rhs.m_flags;
+
+ return *this;
+ }
+
+ Flags&
+ operator = (const uint32_t& rhs)
+ {
+ m_flags = rhs;
+ return *this;
+ }
+
+ Flags&
+ Clear()
+ {
+ m_flags = 0;
+ return *this;
+ }
+
+ bool
+ GetCascades () const
+ {
+ return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
+ }
+
+ Flags&
+ SetCascades (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionCascade;
+ else
+ m_flags &= ~lldb::eTypeOptionCascade;
+ return *this;
+ }
+
+ bool
+ GetSkipPointers () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
+ }
+
+ Flags&
+ SetSkipPointers (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipPointers;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipPointers;
+ return *this;
+ }
+
+ bool
+ GetSkipReferences () const
+ {
+ return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
+ }
+
+ Flags&
+ SetSkipReferences (bool value = true)
+ {
+ if (value)
+ m_flags |= lldb::eTypeOptionSkipReferences;
+ else
+ m_flags &= ~lldb::eTypeOptionSkipReferences;
+ return *this;
+ }
+
+ uint32_t
+ GetValue ()
+ {
+ return m_flags;
+ }
+
+ void
+ SetValue (uint32_t value)
+ {
+ m_flags = value;
+ }
+
+ private:
+ uint32_t m_flags;
+ };
+
+ SyntheticChildren (const Flags& flags) :
+ m_flags(flags)
+ {
+ }
+
+ virtual
+ ~SyntheticChildren ()
+ {
+ }
+
+ bool
+ Cascades () const
+ {
+ return m_flags.GetCascades();
+ }
+ bool
+ SkipsPointers () const
+ {
+ return m_flags.GetSkipPointers();
+ }
+ bool
+ SkipsReferences () const
+ {
+ return m_flags.GetSkipReferences();
+ }
+
+ void
+ SetCascades (bool value)
+ {
+ m_flags.SetCascades(value);
+ }
+
+ void
+ SetSkipsPointers (bool value)
+ {
+ m_flags.SetSkipPointers(value);
+ }
+
+ void
+ SetSkipsReferences (bool value)
+ {
+ m_flags.SetSkipReferences(value);
+ }
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ virtual bool
+ IsScripted () = 0;
+
+ virtual std::string
+ GetDescription () = 0;
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd (ValueObject &backend) = 0;
+
+ typedef STD_SHARED_PTR(SyntheticChildren) SharedPointer;
+ typedef bool(*SyntheticChildrenCallback)(void*, ConstString, const SyntheticChildren::SharedPointer&);
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ protected:
+ uint32_t m_my_revision;
+ Flags m_flags;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
+ };
+
+ class TypeFilterImpl : public SyntheticChildren
+ {
+ std::vector<std::string> m_expression_paths;
+ public:
+ TypeFilterImpl(const SyntheticChildren::Flags& flags) :
+ SyntheticChildren(flags),
+ m_expression_paths()
+ {
+ }
+
+ TypeFilterImpl(const SyntheticChildren::Flags& flags,
+ const std::initializer_list<const char*> items) :
+ SyntheticChildren(flags),
+ m_expression_paths()
+ {
+ for (auto path : items)
+ AddExpressionPath (path);
+ }
+
+ void
+ AddExpressionPath (const char* path)
+ {
+ AddExpressionPath(std::string(path));
+ }
+
+ void
+ Clear()
+ {
+ m_expression_paths.clear();
+ }
+
+ int
+ GetCount() const
+ {
+ return m_expression_paths.size();
+ }
+
+ const char*
+ GetExpressionPathAtIndex(int i) const
+ {
+ return m_expression_paths[i].c_str();
+ }
+
+ bool
+ SetExpressionPathAtIndex (int i, const char* path)
+ {
+ return SetExpressionPathAtIndex(i, std::string(path));
+ }
+
+ void
+ AddExpressionPath (const std::string& path)
+ {
+ bool need_add_dot = true;
+ if (path[0] == '.' ||
+ (path[0] == '-' && path[1] == '>') ||
+ path[0] == '[')
+ need_add_dot = false;
+ // add a '.' symbol to help forgetful users
+ if(!need_add_dot)
+ m_expression_paths.push_back(path);
+ else
+ m_expression_paths.push_back(std::string(".") + path);
+ }
+
+ bool
+ SetExpressionPathAtIndex (int i, const std::string& path)
+ {
+ if (i >= GetCount())
+ return false;
+ bool need_add_dot = true;
+ if (path[0] == '.' ||
+ (path[0] == '-' && path[1] == '>') ||
+ path[0] == '[')
+ need_add_dot = false;
+ // add a '.' symbol to help forgetful users
+ if(!need_add_dot)
+ m_expression_paths[i] = path;
+ else
+ m_expression_paths[i] = std::string(".") + path;
+ return true;
+ }
+
+ bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+ std::string
+ GetDescription ();
+
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ TypeFilterImpl* filter;
+ public:
+
+ FrontEnd(TypeFilterImpl* flt,
+ ValueObject &backend) :
+ SyntheticChildrenFrontEnd(backend),
+ filter(flt)
+ {}
+
+ virtual
+ ~FrontEnd ()
+ {
+ }
+
+ virtual size_t
+ CalculateNumChildren ()
+ {
+ return filter->GetCount();
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx)
+ {
+ if (idx >= filter->GetCount())
+ return lldb::ValueObjectSP();
+ return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
+ }
+
+ virtual bool
+ Update() { return false; }
+
+ virtual bool
+ MightHaveChildren ()
+ {
+ return filter->GetCount() > 0;
+ }
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name)
+ {
+ const char* name_cstr = name.GetCString();
+ for (int i = 0; i < filter->GetCount(); i++)
+ {
+ const char* expr_cstr = filter->GetExpressionPathAtIndex(i);
+ if (expr_cstr)
+ {
+ if (*expr_cstr == '.')
+ expr_cstr++;
+ else if (*expr_cstr == '-' && *(expr_cstr+1) == '>')
+ expr_cstr += 2;
+ }
+ if (!::strcmp(name_cstr, expr_cstr))
+ return i;
+ }
+ return UINT32_MAX;
+ }
+
+ typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrontEnd);
+ };
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd(ValueObject &backend)
+ {
+ return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
+ };
+
+ class CXXSyntheticChildren : public SyntheticChildren
+ {
+ public:
+ typedef SyntheticChildrenFrontEnd* (*CreateFrontEndCallback) (CXXSyntheticChildren*, lldb::ValueObjectSP);
+ protected:
+ CreateFrontEndCallback m_create_callback;
+ std::string m_description;
+ public:
+ CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
+ const char* description,
+ CreateFrontEndCallback callback) :
+ SyntheticChildren(flags),
+ m_create_callback(callback),
+ m_description(description ? description : "")
+ {
+ }
+
+ bool
+ IsScripted ()
+ {
+ return false;
+ }
+
+ std::string
+ GetDescription ();
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd (ValueObject &backend)
+ {
+ return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
+ };
+
+#ifndef LLDB_DISABLE_PYTHON
+
+ class ScriptedSyntheticChildren : public SyntheticChildren
+ {
+ std::string m_python_class;
+ std::string m_python_code;
+ public:
+
+ ScriptedSyntheticChildren (const SyntheticChildren::Flags& flags,
+ const char* pclass,
+ const char* pcode = NULL) :
+ SyntheticChildren(flags),
+ m_python_class(),
+ m_python_code()
+ {
+ if (pclass)
+ m_python_class = pclass;
+ if (pcode)
+ m_python_code = pcode;
+ }
+
+ const char*
+ GetPythonClassName ()
+ {
+ return m_python_class.c_str();
+ }
+
+ const char*
+ GetPythonCode ()
+ {
+ return m_python_code.c_str();
+ }
+
+ void
+ SetPythonClassName (const char* fname)
+ {
+ m_python_class.assign(fname);
+ m_python_code.clear();
+ }
+
+ void
+ SetPythonCode (const char* script)
+ {
+ m_python_code.assign(script);
+ }
+
+ std::string
+ GetDescription ();
+
+ bool
+ IsScripted ()
+ {
+ return true;
+ }
+
+ class FrontEnd : public SyntheticChildrenFrontEnd
+ {
+ private:
+ std::string m_python_class;
+ lldb::ScriptInterpreterObjectSP m_wrapper_sp;
+ ScriptInterpreter *m_interpreter;
+ public:
+
+ FrontEnd (std::string pclass,
+ ValueObject &backend);
+
+ virtual
+ ~FrontEnd ();
+
+ virtual size_t
+ CalculateNumChildren ()
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return 0;
+ return m_interpreter->CalculateNumChildren(m_wrapper_sp);
+ }
+
+ virtual lldb::ValueObjectSP
+ GetChildAtIndex (size_t idx);
+
+ virtual bool
+ Update ()
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return false;
+
+ return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
+ }
+
+ virtual bool
+ MightHaveChildren ()
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return false;
+
+ return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
+ }
+
+ virtual size_t
+ GetIndexOfChildWithName (const ConstString &name)
+ {
+ if (!m_wrapper_sp || m_interpreter == NULL)
+ return UINT32_MAX;
+ return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp, name.GetCString());
+ }
+
+ typedef STD_SHARED_PTR(SyntheticChildrenFrontEnd) SharedPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FrontEnd);
+ };
+
+ virtual SyntheticChildrenFrontEnd::AutoPointer
+ GetFrontEnd(ValueObject &backend)
+ {
+ return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
+ };
+#endif
+} // namespace lldb_private
+
+#endif // lldb_TypeSynthetic_h_
Index: aze/lldb/include/lldb/Expression/ClangASTSource.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/ClangASTSource.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/ClangASTSource.h 2013-03-03 09:35:50.083457354 +0100
@@ -98,7 +98,7 @@
/// @return
/// Whatever SetExternalVisibleDeclsForName returns.
//------------------------------------------------------------------
- clang::DeclContextLookupResult
+ bool
FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
clang::DeclarationName Name);
@@ -248,7 +248,7 @@
{
}
- clang::DeclContextLookupResult
+ bool
FindExternalVisibleDeclsByName (const clang::DeclContext *DC,
clang::DeclarationName Name)
{
Index: aze/lldb/include/lldb/Expression/ClangExpressionDeclMap.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/ClangExpressionDeclMap.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/ClangExpressionDeclMap.h 2013-03-03 09:35:50.083457354 +0100
@@ -328,6 +328,11 @@
/// The target to find the symbol in. If not provided,
/// then the current parsing context's Target.
///
+ /// @param[in] process
+ /// The process to use. For Objective-C symbols, the process's
+ /// Objective-C language runtime may be queried if the process
+ /// is non-NULL.
+ ///
/// @param[in] name
/// The name of the symbol.
///
@@ -336,6 +341,7 @@
//------------------------------------------------------------------
lldb::addr_t
GetSymbolAddress (Target &target,
+ Process *process,
const ConstString &name,
lldb::SymbolType symbol_type);
@@ -792,6 +798,16 @@
m_material_vars.reset();
}
+ //----------------------------------------------------------------------
+ /// Get this parser's ID for use in extracting parser- and JIT-specific
+ /// data from persistent variables.
+ //----------------------------------------------------------------------
+ uint64_t
+ GetParserID()
+ {
+ return (uint64_t)this;
+ }
+
//------------------------------------------------------------------
/// Given a stack frame, find a variable that matches the given name and
/// type. We need this for expression re-use; we may not always get the
@@ -834,7 +850,7 @@
/// @return
/// The LLDB Symbol found, or NULL if none was found.
//---------------------------------------------------------
- Symbol *
+ const Symbol *
FindGlobalDataSymbol (Target &target,
const ConstString &name);
@@ -952,7 +968,7 @@
//------------------------------------------------------------------
void
AddOneGenericVariable (NameSearchContext &context,
- Symbol &symbol,
+ const Symbol &symbol,
unsigned int current_id);
//------------------------------------------------------------------
@@ -1001,16 +1017,23 @@
///
/// @param[in] type
/// The type that needs to be created.
- ///
- /// @param[in] add_method
- /// True if a method with signature void $__lldb_expr(void*)
- /// should be added to the C++ class type passed in
//------------------------------------------------------------------
void
AddOneType (NameSearchContext &context,
TypeFromUser &type,
- unsigned int current_id,
- bool add_method);
+ unsigned int current_id);
+
+ //------------------------------------------------------------------
+ /// Copy a C++ class type into the parser's AST context and add a
+ /// member function declaration to it for the expression.
+ ///
+ /// @param[in] type
+ /// The type that needs to be created.
+ //------------------------------------------------------------------
+
+ TypeFromParser
+ CopyClassType(TypeFromUser &type,
+ unsigned int current_id);
//------------------------------------------------------------------
/// Actually do the task of materializing or dematerializing the struct.
@@ -1088,6 +1111,51 @@
Error &err);
//------------------------------------------------------------------
+ /// Create a temporary buffer in the target process to store the value
+ /// of a persistent variable that would otherwise not be accessible in
+ /// memory (e.g., register values or constants).
+ ///
+ /// @param[in] process
+ /// The process to use when allocating the memory.
+ ///
+ /// @param[in] expr_var
+ /// The variable whose live data will hold this buffer.
+ ///
+ /// @param[in] err
+ /// An Error to populate with any messages related to
+ /// allocating the memory.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ CreateLiveMemoryForExpressionVariable (Process &process,
+ lldb::ClangExpressionVariableSP &expr_var,
+ Error &err);
+
+ //------------------------------------------------------------------
+ /// Delete a temporary buffer created with
+ /// CreateLiveMemoryForExpressionVariable.
+ ///
+ /// @param[in] process
+ /// The process to use when deallocating the memory.
+ ///
+ /// @param[in] expr_var
+ /// The variable whose live data will hold this buffer.
+ ///
+ /// @param[in] err
+ /// An Error to populate with any messages related to
+ /// allocating the memory.
+ ///
+ /// @return
+ /// True on success; false otherwise.
+ //------------------------------------------------------------------
+ bool
+ DeleteLiveMemoryForExpressionVariable (Process &process,
+ lldb::ClangExpressionVariableSP &expr_var,
+ Error &err);
+
+ //------------------------------------------------------------------
/// Actually do the task of materializing or dematerializing a
/// variable.
///
Index: aze/lldb/include/lldb/Expression/ClangExpressionVariable.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/ClangExpressionVariable.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/ClangExpressionVariable.h 2013-03-03 09:35:50.083457354 +0100
@@ -16,6 +16,7 @@
#include <string.h>
// C++ Includes
+#include <map>
#include <string>
#include <vector>
@@ -108,29 +109,45 @@
llvm::Value *m_llvm_value; ///< The IR value corresponding to this variable; usually a GlobalValue
lldb_private::Value *m_lldb_value; ///< The value found in LLDB for this variable
lldb::VariableSP m_lldb_var; ///< The original variable for this variable
- lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
-
- private:
- DISALLOW_COPY_AND_ASSIGN (ParserVars);
+ const lldb_private::Symbol *m_lldb_sym; ///< The original symbol for this variable, if it was a symbol
};
+
+private:
+ typedef std::map <uint64_t, ParserVars> ParserVarMap;
+ ParserVarMap m_parser_vars;
+
+public:
//----------------------------------------------------------------------
/// Make this variable usable by the parser by allocating space for
/// parser-specific variables
//----------------------------------------------------------------------
void
- EnableParserVars()
+ EnableParserVars(uint64_t parser_id)
{
- if (!m_parser_vars.get())
- m_parser_vars.reset(new ParserVars);
+ m_parser_vars.insert(std::make_pair(parser_id, ParserVars()));
}
//----------------------------------------------------------------------
/// Deallocate parser-specific variables
//----------------------------------------------------------------------
void
- DisableParserVars()
+ DisableParserVars(uint64_t parser_id)
+ {
+ m_parser_vars.erase(parser_id);
+ }
+
+ //----------------------------------------------------------------------
+ /// Access parser-specific variables
+ //----------------------------------------------------------------------
+ ParserVars *
+ GetParserVars(uint64_t parser_id)
{
- m_parser_vars.reset();
+ ParserVarMap::iterator i = m_parser_vars.find(parser_id);
+
+ if (i == m_parser_vars.end())
+ return NULL;
+ else
+ return &i->second;
}
//----------------------------------------------------------------------
@@ -148,25 +165,39 @@
size_t m_size; ///< The space required for the variable, in bytes
off_t m_offset; ///< The offset of the variable in the struct, in bytes
};
-
+
+private:
+ typedef std::map <uint64_t, JITVars> JITVarMap;
+ JITVarMap m_jit_vars;
+
+public:
//----------------------------------------------------------------------
/// Make this variable usable for materializing for the JIT by allocating
/// space for JIT-specific variables
//----------------------------------------------------------------------
void
- EnableJITVars()
+ EnableJITVars(uint64_t parser_id)
{
- if (!m_jit_vars.get())
- m_jit_vars.reset(new JITVars);
+ m_jit_vars.insert(std::make_pair(parser_id, JITVars()));
}
//----------------------------------------------------------------------
/// Deallocate JIT-specific variables
//----------------------------------------------------------------------
void
- DisableJITVars()
+ DisableJITVars(uint64_t parser_id)
{
- m_jit_vars.reset();
+ m_jit_vars.erase(parser_id);
+ }
+
+ JITVars *GetJITVars(uint64_t parser_id)
+ {
+ JITVarMap::iterator i = m_jit_vars.find(parser_id);
+
+ if (i == m_jit_vars.end())
+ return NULL;
+ else
+ return &i->second;
}
//----------------------------------------------------------------------
@@ -222,9 +253,6 @@
//----------------------------------------------------------------------
/// Members
//----------------------------------------------------------------------
- std::auto_ptr<ParserVars> m_parser_vars;
- std::auto_ptr<JITVars> m_jit_vars;
-
enum Flags
{
EVNone = 0,
@@ -245,7 +273,7 @@
lldb::ValueObjectSP m_frozen_sp;
lldb::ValueObjectSP m_live_sp;
-private:
+
DISALLOW_COPY_AND_ASSIGN (ClangExpressionVariable);
};
@@ -348,13 +376,16 @@
/// The variable requested, or NULL if that variable is not in the list.
//----------------------------------------------------------------------
lldb::ClangExpressionVariableSP
- GetVariable (const clang::NamedDecl *decl)
+ GetVariable (const clang::NamedDecl *decl, uint64_t parser_id)
{
lldb::ClangExpressionVariableSP var_sp;
for (size_t index = 0, size = GetSize(); index < size; ++index)
{
var_sp = GetVariableAtIndex(index);
- if (var_sp->m_parser_vars.get() && var_sp->m_parser_vars->m_named_decl == decl)
+
+ ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(parser_id);
+
+ if (parser_vars && parser_vars->m_named_decl == decl)
return var_sp;
}
var_sp.reset();
Index: aze/lldb/include/lldb/Expression/ClangFunction.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/ClangFunction.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/ClangFunction.h 2013-03-03 09:35:50.083457354 +0100
@@ -132,7 +132,8 @@
/// @return
/// The number of errors.
//------------------------------------------------------------------
- unsigned CompileFunction (Stream &errors);
+ unsigned
+ CompileFunction (Stream &errors);
//------------------------------------------------------------------
/// Insert the default function wrapper and its default argument struct
@@ -152,9 +153,10 @@
/// @return
/// True on success; false otherwise.
//------------------------------------------------------------------
- bool InsertFunction (ExecutionContext &exe_ctx,
- lldb::addr_t &args_addr_ref,
- Stream &errors);
+ bool
+ InsertFunction (ExecutionContext &exe_ctx,
+ lldb::addr_t &args_addr_ref,
+ Stream &errors);
//------------------------------------------------------------------
/// Insert the default function wrapper (using the JIT)
@@ -246,7 +248,7 @@
/// If the timeout expires, true if other threads should run. If
/// the function may try to take locks, this is useful.
///
- /// @param[in] discard_on_error
+ /// @param[in] unwind_on_error
/// If true, and the execution stops before completion, we unwind the
/// function call, and return the program state to what it was before the
/// execution. If false, we leave the program in the stopped state.
@@ -272,7 +274,8 @@
lldb::addr_t &void_arg,
bool stop_others,
bool try_all_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
uint32_t timeout_usec,
Stream &errors,
lldb::addr_t* this_arg = 0);
@@ -404,7 +407,8 @@
bool stop_others,
uint32_t timeout_usec,
bool try_all_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
Value &results);
//------------------------------------------------------------------
@@ -426,9 +430,12 @@
/// @param[in] stop_others
/// True if other threads should pause during execution.
///
- /// @param[in] discard_on_error
+ /// @param[in] unwind_on_error
/// True if the thread plan may simply be discarded if an error occurs.
///
+ /// @param[in] ignore_breakpoints
+ /// True if the expression execution will ignore breakpoint hits and continue executing.
+ ///
/// @param[in] this_arg
/// If non-NULL (and cmd_arg is NULL), the function is invoked like a C++
/// method, with the value pointed to by the pointer as its 'this'
@@ -447,7 +454,8 @@
lldb::addr_t &args_addr_ref,
Stream &errors,
bool stop_others,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
lldb::addr_t *this_arg = 0,
lldb::addr_t *cmd_arg = 0);
@@ -470,7 +478,7 @@
/// @param[in] stop_others
/// True if other threads should pause during execution.
///
- /// @param[in] discard_on_error
+ /// @param[in] unwind_on_error
/// True if the thread plan may simply be discarded if an error occurs.
///
/// @return
@@ -481,14 +489,16 @@
lldb::addr_t &args_addr_ref,
Stream &errors,
bool stop_others,
- bool discard_on_error = true)
+ bool unwind_on_error = true,
+ bool ignore_breakpoints = true)
{
return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
m_jit_start_addr,
args_addr_ref,
errors,
stop_others,
- discard_on_error);
+ unwind_on_error,
+ ignore_breakpoints);
}
//------------------------------------------------------------------
@@ -599,6 +609,11 @@
return false;
}
+ ValueList
+ GetArgumentValues () const
+ {
+ return m_arg_values;
+ }
private:
//------------------------------------------------------------------
// For ClangFunction only
Index: aze/lldb/include/lldb/Expression/ClangUserExpression.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/ClangUserExpression.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/ClangUserExpression.h 2013-03-03 09:35:50.083457354 +0100
@@ -117,11 +117,14 @@
/// The execution context to use when looking up entities that
/// are needed for parsing (locations of variables, etc.)
///
- /// @param[in] discard_on_error
+ /// @param[in] unwind_on_error
/// If true, and the execution stops before completion, we unwind the
/// function call, and return the program state to what it was before the
/// execution. If false, we leave the program in the stopped state.
///
+ /// @param[in] ignore_breakpoints
+ /// If true, ignore breakpoints while executing the expression.
+ ///
/// @param[in] shared_ptr_to_me
/// This is a shared pointer to this ClangUserExpression. This is
/// needed because Execute can push a thread plan that will hold onto
@@ -150,7 +153,8 @@
ExecutionResults
Execute (Stream &error_stream,
ExecutionContext &exe_ctx,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
ClangUserExpressionSP &shared_ptr_to_me,
lldb::ClangExpressionVariableSP &result,
bool try_all_threads,
@@ -305,10 +309,13 @@
/// the expression. Currently restricted to those languages
/// supported by Clang.
///
- /// @param[in] discard_on_error
+ /// @param[in] unwind_on_error
/// True if the thread's state should be restored in the case
/// of an error.
///
+ /// @param[in] ignore_breakpoints
+ /// If true, ignore breakpoints while executing the expression.
+ ///
/// @param[in] result_type
/// If not eResultTypeAny, the type of the desired result. Will
/// result in parse errors if impossible.
@@ -341,7 +348,8 @@
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
ResultType desired_type,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp,
@@ -353,7 +361,8 @@
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
ResultType desired_type,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp,
Index: aze/lldb/include/lldb/Expression/DWARFExpression.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/DWARFExpression.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/DWARFExpression.h 2013-03-03 09:35:50.087457354 +0100
@@ -59,8 +59,8 @@
/// The byte length of the location expression.
//------------------------------------------------------------------
DWARFExpression(const DataExtractor& data,
- uint32_t data_offset,
- uint32_t data_length);
+ lldb::offset_t data_offset,
+ lldb::offset_t data_length);
//------------------------------------------------------------------
/// Copy constructor
@@ -184,7 +184,7 @@
/// The byte length of the location expression.
//------------------------------------------------------------------
void
- SetOpcodeData(const DataExtractor& data, uint32_t data_offset, uint32_t data_length);
+ SetOpcodeData(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length);
//------------------------------------------------------------------
/// Copy the DWARF location expression into a local buffer.
@@ -212,8 +212,8 @@
//------------------------------------------------------------------
void
CopyOpcodeData (const DataExtractor& data,
- uint32_t data_offset,
- uint32_t data_length);
+ lldb::offset_t data_offset,
+ lldb::offset_t data_length);
//------------------------------------------------------------------
@@ -340,8 +340,8 @@
ClangExpressionDeclMap *decl_map,
RegisterContext *reg_ctx,
const DataExtractor& opcodes,
- const uint32_t offset,
- const uint32_t length,
+ const lldb::offset_t offset,
+ const lldb::offset_t length,
const uint32_t reg_set,
const Value* initial_value_ptr,
Value& result,
@@ -403,16 +403,16 @@
//------------------------------------------------------------------
void
DumpLocation(Stream *s,
- uint32_t offset,
- uint32_t length,
+ lldb::offset_t offset,
+ lldb::offset_t length,
lldb::DescriptionLevel level,
ABI *abi) const;
bool
GetLocation (lldb::addr_t base_addr,
lldb::addr_t pc,
- uint32_t &offset,
- uint32_t &len);
+ lldb::offset_t &offset,
+ lldb::offset_t &len);
//------------------------------------------------------------------
/// Classes that inherit from DWARFExpression can see and modify these
Index: aze/lldb/include/lldb/Expression/ExpressionSourceCode.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/ExpressionSourceCode.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/ExpressionSourceCode.h 2013-03-03 09:35:50.087457354 +0100
@@ -20,6 +20,8 @@
class ExpressionSourceCode
{
public:
+ static const char * g_expression_prefix;
+
static ExpressionSourceCode *CreateWrapped (const char *prefix,
const char *body)
{
Index: aze/lldb/include/lldb/Expression/IRInterpreter.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/IRInterpreter.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/IRInterpreter.h 2013-03-03 09:35:50.087457354 +0100
@@ -95,7 +95,6 @@
private:
/// Flags
lldb_private::ClangExpressionDeclMap &m_decl_map; ///< The DeclMap containing the Decls
- lldb_private::Stream *m_error_stream;
bool
supportsFunction (llvm::Function &llvm_function,
Index: aze/lldb/include/lldb/Expression/RecordingMemoryManager.h
===================================================================
--- aze.orig/lldb/include/lldb/Expression/RecordingMemoryManager.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/Expression/RecordingMemoryManager.h 2013-03-03 09:35:50.087457354 +0100
@@ -184,11 +184,14 @@
/// @param[in] SectionID
/// A unique identifier for the section.
///
+ /// @param[in] IsReadOnly
+ /// Flag indicating the section is read-only.
+ ///
/// @return
/// Allocated space.
//------------------------------------------------------------------
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
//------------------------------------------------------------------
/// Allocate space for a global variable, and add it to the
@@ -207,6 +210,18 @@
unsigned Alignment);
//------------------------------------------------------------------
+ /// Called when object loading is complete and section page
+ /// permissions can be applied. Currently unimplemented for LLDB.
+ ///
+ /// @param[out] ErrMsg
+ /// The error that prevented the page protection from succeeding.
+ ///
+ /// @return
+ /// True in case of failure, false in case of success.
+ //------------------------------------------------------------------
+ bool applyPermissions(std::string *ErrMsg) { return false; }
+
+ //------------------------------------------------------------------
/// Passthrough interface stub
//------------------------------------------------------------------
virtual void deallocateFunctionBody(void *Body);
Index: aze/lldb/include/lldb/Host/File.h
===================================================================
--- aze.orig/lldb/include/lldb/Host/File.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Host/File.h 2013-03-03 09:35:50.087457354 +0100
@@ -457,10 +457,10 @@
/// Variable arguments that are needed for the printf style
/// format string \a format.
//------------------------------------------------------------------
- int
+ size_t
Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
- int
+ size_t
PrintfVarArg(const char *format, va_list args);
protected:
Index: aze/lldb/include/lldb/Host/Host.h
===================================================================
--- aze.orig/lldb/include/lldb/Host/Host.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Host/Host.h 2013-03-03 09:35:50.087457354 +0100
@@ -13,6 +13,8 @@
#include <stdarg.h>
+#include <string>
+
#include "lldb/lldb-private.h"
#include "lldb/Core/StringList.h"
@@ -98,6 +100,16 @@
static lldb::ByteOrder
GetByteOrder ();
+ //------------------------------------------------------------------
+ /// Returns the number of CPUs on this current host.
+ ///
+ /// @return
+ /// Number of CPUs on this current host, or zero if the number
+ /// of CPUs can't be determined on this host.
+ //------------------------------------------------------------------
+ static uint32_t
+ GetNumberCPUS ();
+
static bool
GetOSVersion (uint32_t &major,
uint32_t &minor,
@@ -266,11 +278,9 @@
/// The thread ID for which we are trying retrieve the name of.
///
/// @return
- /// A NULL terminate C string name that is owned by a static
- /// global string pool, or NULL if there is no matching thread
- /// name. This string does not need to be freed.
+ /// A std::string containing the thread name.
//------------------------------------------------------------------
- static const char *
+ static std::string
GetThreadName (lldb::pid_t pid, lldb::tid_t tid);
//------------------------------------------------------------------
Index: aze/lldb/include/lldb/Host/Mutex.h
===================================================================
--- aze.orig/lldb/include/lldb/Host/Mutex.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Host/Mutex.h 2013-03-03 09:35:50.087457354 +0100
@@ -193,6 +193,9 @@
/// @return
/// The error code from \c pthread_mutex_lock().
//------------------------------------------------------------------
+#ifdef LLDB_CONFIGURATION_DEBUG
+ virtual
+#endif
int
Lock();
@@ -280,6 +283,27 @@
pthread_t m_thread_that_tried;
std::string m_failure_message;
};
+
+class LoggingMutex : public Mutex
+{
+public:
+ LoggingMutex() : Mutex(),m_locked(false) {}
+ LoggingMutex(Mutex::Type type) : Mutex (type),m_locked(false) {}
+
+ virtual
+ ~LoggingMutex() {}
+
+ virtual int
+ Lock ();
+
+ virtual int
+ Unlock ();
+
+ virtual int
+ TryLock (const char *failure_message = NULL);
+protected:
+ bool m_locked;
+};
#endif
} // namespace lldb_private
Index: aze/lldb/include/lldb/Host/Terminal.h
===================================================================
--- aze.orig/lldb/include/lldb/Host/Terminal.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Host/Terminal.h 2013-03-03 09:35:50.087457354 +0100
@@ -132,6 +132,9 @@
//------------------------------------------------------------------
bool
IsValid() const;
+
+ void
+ Clear ();
protected:
Index: aze/lldb/include/lldb/Interpreter/Args.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/Args.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/Args.h 2013-03-03 09:35:50.087457354 +0100
@@ -268,7 +268,7 @@
// FIXME: Handle the quote character somehow.
//------------------------------------------------------------------
void
- SetArguments (int argc, const char **argv);
+ SetArguments (size_t argc, const char **argv);
void
SetArguments (const char **argv);
@@ -382,12 +382,15 @@
}
static lldb::addr_t
- StringToAddress (const char *s, lldb::addr_t fail_value = LLDB_INVALID_ADDRESS, bool *success_ptr = NULL);
+ StringToAddress (const ExecutionContext *exe_ctx,
+ const char *s,
+ lldb::addr_t fail_value,
+ Error *error);
static bool
StringToBoolean (const char *s, bool fail_value, bool *success_ptr);
- static int32_t
+ static int64_t
StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error);
static lldb::ScriptLanguage
@@ -396,7 +399,7 @@
static Error
StringToFormat (const char *s,
lldb::Format &format,
- uint32_t *byte_size_ptr); // If non-NULL, then a byte size can precede the format character
+ size_t *byte_size_ptr); // If non-NULL, then a byte size can precede the format character
static lldb::Encoding
StringToEncoding (const char *s,
Index: aze/lldb/include/lldb/Interpreter/CommandInterpreter.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/CommandInterpreter.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/CommandInterpreter.h 2013-03-03 09:35:50.087457354 +0100
@@ -278,7 +278,7 @@
const char *command_word,
const char *separator,
const char *help_text,
- uint32_t max_word_len);
+ size_t max_word_len);
// this mimics OutputFormattedHelpText but it does perform a much simpler
// formatting, basically ensuring line alignment. This is only good if you have
@@ -335,10 +335,6 @@
Initialize ();
void
- CrossRegisterCommand (const char *dest_cmd,
- const char *object_type);
-
- void
SetScriptLanguage (lldb::ScriptLanguage lang);
@@ -391,20 +387,6 @@
const char *
FindHistoryString (const char *input_str) const;
-
-#ifndef SWIG
- void
- AddLogChannel (const char *name,
- const Log::Callbacks &log_callbacks);
-
- bool
- GetLogChannelCallbacks (const char *channel,
- Log::Callbacks &log_callbacks);
-
- bool
- RemoveLogChannel (const char *name);
-#endif
-
size_t
FindLongestCommandWord (CommandObject::CommandMap &dict);
@@ -450,6 +432,9 @@
bool
GetExpandRegexAliases () const;
+ bool
+ GetPromptOnQuit () const;
+
protected:
friend class Debugger;
Index: aze/lldb/include/lldb/Interpreter/CommandObjectCrossref.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/CommandObjectCrossref.h 2013-03-03 09:35:47.779457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,60 +0,0 @@
-//===-- CommandObjectCrossref.h ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_CommandObjectCrossref_h_
-#define liblldb_CommandObjectCrossref_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Interpreter/CommandObject.h"
-#include "lldb/Interpreter/Args.h"
-
-namespace lldb_private {
-
-//-------------------------------------------------------------------------
-// CommandObjectCrossref
-//-------------------------------------------------------------------------
-
-class CommandObjectCrossref : public CommandObjectParsed
-{
-public:
- CommandObjectCrossref (CommandInterpreter &interpreter,
- const char *name,
- const char *help = NULL,
- const char *syntax = NULL);
-
- virtual
- ~CommandObjectCrossref ();
-
- virtual void
- GenerateHelpText (CommandReturnObject &result);
-
- virtual bool
- IsCrossRefObject ();
-
- virtual void
- AddObject (const char *obj_name);
-
- const char **
- GetObjectTypes () const;
-
-protected:
- virtual bool
- DoExecute (Args& command,
- CommandReturnObject &result);
-
-private:
- Args m_crossref_object_types;
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_CommandObjectCrossref_h_
Index: aze/lldb/include/lldb/Interpreter/CommandObject.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/CommandObject.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/CommandObject.h 2013-03-03 09:35:50.087457354 +0100
@@ -20,6 +20,8 @@
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/Flags.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/ExecutionContext.h"
namespace lldb_private {
@@ -122,12 +124,6 @@
void
SetSyntax (const char *str);
-
- virtual void
- AddObject (const char *obj_name) {}
-
- virtual bool
- IsCrossRefObject () { return false; }
// override this to return true if you want to enable the user to delete
// the Command object from the Command dictionary (aliases have their own
@@ -224,15 +220,91 @@
bool
IsPairType (ArgumentRepetitionType arg_repeat_type);
- enum
+ enum
{
- eFlagProcessMustBeLaunched = (1 << 0),
- eFlagProcessMustBePaused = (1 << 1)
+ //----------------------------------------------------------------------
+ // eFlagRequiresTarget
+ //
+ // Ensures a valid target is contained in m_exe_ctx prior to executing
+ // the command. If a target doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidTargetDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidTargetDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresTarget = (1u << 0),
+ //----------------------------------------------------------------------
+ // eFlagRequiresProcess
+ //
+ // Ensures a valid process is contained in m_exe_ctx prior to executing
+ // the command. If a process doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidProcessDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidProcessDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresProcess = (1u << 1),
+ //----------------------------------------------------------------------
+ // eFlagRequiresThread
+ //
+ // Ensures a valid thread is contained in m_exe_ctx prior to executing
+ // the command. If a thread doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidThreadDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidThreadDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresThread = (1u << 2),
+ //----------------------------------------------------------------------
+ // eFlagRequiresFrame
+ //
+ // Ensures a valid frame is contained in m_exe_ctx prior to executing
+ // the command. If a frame doesn't exist or is invalid, the command
+ // will fail and CommandObject::GetInvalidFrameDescription() will be
+ // returned as the error. CommandObject subclasses can override the
+ // virtual function for GetInvalidFrameDescription() to provide custom
+ // strings when needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresFrame = (1u << 3),
+ //----------------------------------------------------------------------
+ // eFlagRequiresRegContext
+ //
+ // Ensures a valid register context (from the selected frame if there
+ // is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
+ // is availble from m_exe_ctx prior to executing the command. If a
+ // target doesn't exist or is invalid, the command will fail and
+ // CommandObject::GetInvalidRegContextDescription() will be returned as
+ // the error. CommandObject subclasses can override the virtual function
+ // for GetInvalidRegContextDescription() to provide custom strings when
+ // needed.
+ //----------------------------------------------------------------------
+ eFlagRequiresRegContext = (1u << 4),
+ //----------------------------------------------------------------------
+ // eFlagTryTargetAPILock
+ //
+ // Attempts to acquire the target lock if a target is selected in the
+ // command interpreter. If the command object fails to acquire the API
+ // lock, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eFlagTryTargetAPILock = (1u << 5),
+ //----------------------------------------------------------------------
+ // eFlagProcessMustBeLaunched
+ //
+ // Verifies that there is a launched process in m_exe_ctx, if there
+ // isn't, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eFlagProcessMustBeLaunched = (1u << 6),
+ //----------------------------------------------------------------------
+ // eFlagProcessMustBePaused
+ //
+ // Verifies that there is a paused process in m_exe_ctx, if there
+ // isn't, the command will fail with an appropriate error message.
+ //----------------------------------------------------------------------
+ eFlagProcessMustBePaused = (1u << 7)
};
bool
- ParseOptions (Args& args,
- CommandReturnObject &result);
+ ParseOptions (Args& args, CommandReturnObject &result);
void
SetCommandName (const char *name);
@@ -331,7 +403,7 @@
/// total number of matches, and the window the user wants returned.
///
/// @return
- /// \btrue if we were in an option, \bfalse otherwise.
+ /// The number of completions.
//------------------------------------------------------------------
virtual int
@@ -375,19 +447,6 @@
}
//------------------------------------------------------------------
- /// Check the command flags against the interpreter's current execution context.
- ///
- /// @param[out] result
- /// A command result object, if it is not okay to run the command this will be
- /// filled in with a suitable error.
- ///
- /// @return
- /// \b true if it is okay to run this command, \b false otherwise.
- //------------------------------------------------------------------
- bool
- CheckFlags (CommandReturnObject &result);
-
- //------------------------------------------------------------------
/// Get the command that appropriate for a "repeat" of the current command.
///
/// @param[in] current_command_line
@@ -426,7 +485,56 @@
Execute (const char *args_string, CommandReturnObject &result) = 0;
protected:
+ virtual const char *
+ GetInvalidTargetDescription()
+ {
+ return "invalid target, create a target using the 'target create' command";
+ }
+
+ virtual const char *
+ GetInvalidProcessDescription()
+ {
+ return "invalid process";
+ }
+
+ virtual const char *
+ GetInvalidThreadDescription()
+ {
+ return "invalid thread";
+ }
+
+ virtual const char *
+ GetInvalidFrameDescription()
+ {
+ return "invalid frame";
+ }
+
+ virtual const char *
+ GetInvalidRegContextDescription ()
+ {
+ return "invalid frame, no registers";
+ }
+
+ //------------------------------------------------------------------
+ /// Check the command to make sure anything required by this
+ /// command is available.
+ ///
+ /// @param[out] result
+ /// A command result object, if it is not okay to run the command
+ /// this will be filled in with a suitable error.
+ ///
+ /// @return
+ /// \b true if it is okay to run this command, \b false otherwise.
+ //------------------------------------------------------------------
+ bool
+ CheckRequirements (CommandReturnObject &result);
+
+ void
+ Cleanup ();
+
CommandInterpreter &m_interpreter;
+ ExecutionContext m_exe_ctx;
+ Mutex::Locker m_api_locker;
std::string m_cmd_name;
std::string m_cmd_help_short;
std::string m_cmd_help_long;
Index: aze/lldb/include/lldb/Interpreter/CommandObjectMultiword.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/CommandObjectMultiword.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/CommandObjectMultiword.h 2013-03-03 09:35:50.087457354 +0100
@@ -115,12 +115,6 @@
virtual const char *
GetHelpLong ();
- virtual void
- AddObject (const char *obj_name);
-
- virtual bool
- IsCrossRefObject ();
-
virtual bool
IsRemovable() const;
Index: aze/lldb/include/lldb/Interpreter/CommandReturnObject.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/CommandReturnObject.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/CommandReturnObject.h 2013-03-03 09:35:50.087457354 +0100
@@ -118,25 +118,25 @@
Clear();
void
- AppendMessage (const char *in_string, int len = -1);
+ AppendMessage (const char *in_string);
void
AppendMessageWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
void
- AppendRawWarning (const char *in_string, int len = -1);
+ AppendRawWarning (const char *in_string);
void
- AppendWarning (const char *in_string, int len = -1);
+ AppendWarning (const char *in_string);
void
AppendWarningWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
void
- AppendError (const char *in_string, int len = -1);
+ AppendError (const char *in_string);
void
- AppendRawError (const char *in_string, int len = -1);
+ AppendRawError (const char *in_string);
void
AppendErrorWithFormat (const char *format, ...) __attribute__ ((format (printf, 2, 3)));
Index: aze/lldb/include/lldb/Interpreter/OptionGroupBoolean.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionGroupBoolean.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionGroupBoolean.h 2013-03-03 09:35:50.087457354 +0100
@@ -31,7 +31,7 @@
OptionGroupBoolean (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
const char *usage_text,
bool default_value,
bool no_argument_toggle_default);
Index: aze/lldb/include/lldb/Interpreter/OptionGroupFile.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionGroupFile.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionGroupFile.h 2013-03-03 09:35:50.087457354 +0100
@@ -31,7 +31,7 @@
OptionGroupFile (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text);
@@ -89,7 +89,7 @@
OptionGroupFileList (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text);
Index: aze/lldb/include/lldb/Interpreter/OptionGroupFormat.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionGroupFormat.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionGroupFormat.h 2013-03-03 09:35:50.087457354 +0100
@@ -97,6 +97,11 @@
return m_count;
}
+ bool
+ HasGDBFormat () const
+ {
+ return m_has_gdb_format;
+ }
bool
AnyOptionWasSet () const
@@ -109,13 +114,18 @@
protected:
bool
- ParserGDBFormatLetter (char format_letter, lldb::Format &format, uint32_t &byte_size);
+ ParserGDBFormatLetter (CommandInterpreter &interpreter,
+ char format_letter,
+ lldb::Format &format,
+ uint32_t &byte_size);
OptionValueFormat m_format;
OptionValueUInt64 m_byte_size;
OptionValueUInt64 m_count;
char m_prev_gdb_format;
char m_prev_gdb_size;
+
+ bool m_has_gdb_format;
};
} // namespace lldb_private
Index: aze/lldb/include/lldb/Interpreter/OptionGroupString.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionGroupString.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionGroupString.h 2013-03-03 09:35:50.087457354 +0100
@@ -29,7 +29,7 @@
OptionGroupString (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text,
Index: aze/lldb/include/lldb/Interpreter/OptionGroupUInt64.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionGroupUInt64.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionGroupUInt64.h 2013-03-03 09:35:50.087457354 +0100
@@ -29,7 +29,7 @@
OptionGroupUInt64 (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text,
Index: aze/lldb/include/lldb/Interpreter/Options.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/Options.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/Options.h 2013-03-03 09:35:50.087457354 +0100
@@ -25,6 +25,15 @@
namespace lldb_private {
+ static inline bool
+ isprint8 (int ch)
+ {
+ if (ch & 0xffffff00u)
+ return false;
+ return isprint(ch);
+ }
+
+
//----------------------------------------------------------------------
/// @class Options Options.h "lldb/Interpreter/Options.h"
/// @brief A command line option parsing protocol class.
@@ -296,7 +305,7 @@
protected:
// This is a set of options expressed as indexes into the options table for this Option.
- typedef std::set<char> OptionSet;
+ typedef std::set<int> OptionSet;
typedef std::vector<OptionSet> OptionSetVector;
CommandInterpreter &m_interpreter;
Index: aze/lldb/include/lldb/Interpreter/OptionValueArray.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionValueArray.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionValueArray.h 2013-03-03 09:35:50.091457355 +0100
@@ -79,14 +79,14 @@
// Subclass specific functions
//---------------------------------------------------------------------
- uint32_t
+ size_t
GetSize () const
{
return m_values.size();
}
lldb::OptionValueSP
- operator[](uint32_t idx) const
+ operator[](size_t idx) const
{
lldb::OptionValueSP value_sp;
if (idx < m_values.size())
@@ -95,7 +95,7 @@
}
lldb::OptionValueSP
- GetValueAtIndex (uint32_t idx) const
+ GetValueAtIndex (size_t idx) const
{
lldb::OptionValueSP value_sp;
if (idx < m_values.size())
@@ -117,7 +117,7 @@
}
bool
- InsertValue (uint32_t idx, const lldb::OptionValueSP &value_sp)
+ InsertValue (size_t idx, const lldb::OptionValueSP &value_sp)
{
// Make sure the value_sp object is allowed to contain
// values of the type passed in...
@@ -133,7 +133,7 @@
}
bool
- ReplaceValue (uint32_t idx, const lldb::OptionValueSP &value_sp)
+ ReplaceValue (size_t idx, const lldb::OptionValueSP &value_sp)
{
// Make sure the value_sp object is allowed to contain
// values of the type passed in...
@@ -149,7 +149,7 @@
}
bool
- DeleteValue (uint32_t idx)
+ DeleteValue (size_t idx)
{
if (idx < m_values.size())
{
Index: aze/lldb/include/lldb/Interpreter/OptionValueDictionary.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionValueDictionary.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionValueDictionary.h 2013-03-03 09:35:50.091457355 +0100
@@ -80,7 +80,7 @@
// Subclass specific functions
//---------------------------------------------------------------------
- uint32_t
+ size_t
GetNumValues() const
{
return m_values.size();
Index: aze/lldb/include/lldb/Interpreter/OptionValueString.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/OptionValueString.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/OptionValueString.h 2013-03-03 09:35:50.091457355 +0100
@@ -24,6 +24,10 @@
class OptionValueString : public OptionValue
{
public:
+
+ typedef Error (*ValidatorCallback) (const char* string,
+ void* baton);
+
enum Options
{
eOptionEncodeCharacterEscapeSequences = (1u << 0)
@@ -33,7 +37,20 @@
OptionValue(),
m_current_value (),
m_default_value (),
- m_options()
+ m_options(),
+ m_validator(),
+ m_validator_baton()
+ {
+ }
+
+ OptionValueString (ValidatorCallback validator,
+ void* baton = NULL) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(validator),
+ m_validator_baton(baton)
{
}
@@ -41,7 +58,9 @@
OptionValue(),
m_current_value (),
m_default_value (),
- m_options()
+ m_options(),
+ m_validator(),
+ m_validator_baton()
{
if (value && value[0])
{
@@ -55,7 +74,9 @@
OptionValue(),
m_current_value (),
m_default_value (),
- m_options()
+ m_options(),
+ m_validator(),
+ m_validator_baton()
{
if (current_value && current_value[0])
m_current_value.assign (current_value);
@@ -63,7 +84,41 @@
m_default_value.assign (default_value);
}
- virtual
+ OptionValueString (const char *value,
+ ValidatorCallback validator,
+ void* baton = NULL) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(validator),
+ m_validator_baton(baton)
+ {
+ if (value && value[0])
+ {
+ m_current_value.assign (value);
+ m_default_value.assign (value);
+ }
+ }
+
+ OptionValueString (const char *current_value,
+ const char *default_value,
+ ValidatorCallback validator,
+ void* baton = NULL) :
+ OptionValue(),
+ m_current_value (),
+ m_default_value (),
+ m_options(),
+ m_validator(validator),
+ m_validator_baton(baton)
+ {
+ if (current_value && current_value[0])
+ m_current_value.assign (current_value);
+ if (default_value && default_value[0])
+ m_default_value.assign (default_value);
+ }
+
+ virtual
~OptionValueString()
{
}
@@ -115,10 +170,7 @@
const char *
operator = (const char *value)
{
- if (value && value[0])
- m_current_value.assign (value);
- else
- m_current_value.clear();
+ SetCurrentValue(value);
return m_current_value.c_str();
}
@@ -134,21 +186,11 @@
return m_default_value.c_str();
}
- void
- SetCurrentValue (const char *value)
- {
- if (value && value[0])
- m_current_value.assign (value);
- else
- m_current_value.clear();
- }
-
- void
- AppendToCurrentValue (const char *value)
- {
- if (value && value[0])
- m_current_value.append (value);
- }
+ Error
+ SetCurrentValue (const char *value);
+
+ Error
+ AppendToCurrentValue (const char *value);
void
SetDefaultValue (const char *value)
@@ -176,6 +218,8 @@
std::string m_current_value;
std::string m_default_value;
Flags m_options;
+ ValidatorCallback m_validator;
+ void* m_validator_baton;
};
} // namespace lldb_private
Index: aze/lldb/include/lldb/Interpreter/PythonDataObjects.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/PythonDataObjects.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/PythonDataObjects.h 2013-03-03 09:35:50.091457355 +0100
@@ -27,68 +27,98 @@
namespace lldb_private {
- class PythonRefCountedObject
+ class PythonObject
{
public:
- PythonRefCountedObject (PyObject* obj = NULL) : m_object(obj)
+ PythonObject () :
+ m_py_obj(NULL)
{
- Py_XINCREF(m_object);
}
- PythonRefCountedObject (const PythonRefCountedObject &rhs) :
- m_object(rhs.m_object)
+ PythonObject (PyObject* py_obj) :
+ m_py_obj(NULL)
{
- Py_XINCREF(m_object);
+ Reset (py_obj);
}
- ~PythonRefCountedObject ()
+ PythonObject (const PythonObject &rhs) :
+ m_py_obj(NULL)
{
- Py_XDECREF(m_object);
+ Reset (rhs.m_py_obj);
}
+
+ PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp);
- const PythonRefCountedObject &
- operator = (const PythonRefCountedObject &rhs)
+ virtual
+ ~PythonObject ()
+ {
+ Reset (NULL);
+ }
+
+ const PythonObject &
+ operator = (const PythonObject &rhs)
{
if (this != &rhs)
- Reset (rhs.m_object);
+ Reset (rhs.m_py_obj);
return *this;
}
- void
- Reset (PyObject* object = NULL)
+ bool
+ Reset (const PythonObject &object)
{
- if (object != m_object)
+ return Reset(object.GetPythonObject());
+ }
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL)
+ {
+ if (py_obj != m_py_obj)
{
- Py_XDECREF(m_object);
- m_object = object;
- Py_XINCREF(m_object);
+ Py_XDECREF(m_py_obj);
+ m_py_obj = py_obj;
+ Py_XINCREF(m_py_obj);
}
+ return true;
}
+ void
+ Dump () const
+ {
+ if (m_py_obj)
+ _PyObject_Dump (m_py_obj);
+ else
+ puts ("NULL");
+ }
+
PyObject*
- GetPyhonObject () const
+ GetPythonObject () const
{
- return m_object;
+ return m_py_obj;
}
operator bool () const
{
- return m_object != NULL;
+ return m_py_obj != NULL;
}
- private:
- PyObject* m_object;
+ protected:
+ PyObject* m_py_obj;
};
- class PythonDataString
+ class PythonString: public PythonObject
{
public:
- PythonDataString (bool create_empty);
- PythonDataString (PyObject* object = NULL);
- PythonDataString (const char* string);
- ~PythonDataString ();
+ PythonString ();
+ PythonString (PyObject *o);
+ PythonString (const PythonObject &object);
+ PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ PythonString (const char* string);
+ virtual ~PythonString ();
+ virtual bool
+ Reset (PyObject* py_obj = NULL);
+
const char*
GetString() const;
@@ -96,170 +126,97 @@
GetSize() const;
void
- SetString (const char* string);
-
- operator bool () const
- {
- return m_object.operator bool();
- }
-
- PyObject*
- GetPythonObject() const
- {
- return m_object.GetPyhonObject();
- }
- private:
- PythonRefCountedObject m_object;
+ SetString (const char* string);
};
- class PythonDataInteger
+ class PythonInteger: public PythonObject
{
public:
- PythonDataInteger (bool create_empty = true);
- PythonDataInteger (PyObject* object);
- PythonDataInteger (int64_t value);
- ~PythonDataInteger ();
+ PythonInteger ();
+ PythonInteger (PyObject* py_obj);
+ PythonInteger (const PythonObject &object);
+ PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ PythonInteger (int64_t value);
+ virtual ~PythonInteger ();
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL);
int64_t
GetInteger();
void
SetInteger (int64_t value);
-
- operator bool () const
- {
- return m_object.operator bool();
- }
-
- PyObject*
- GetPythonObject() const
- {
- return m_object.GetPyhonObject();
- }
- private:
- PythonRefCountedObject m_object;
};
- class PythonDataArray
+ class PythonList: public PythonObject
{
public:
- PythonDataArray (bool create_empty = true);
- PythonDataArray (PyObject* object);
- PythonDataArray (uint32_t count);
- ~PythonDataArray ();
+ PythonList ();
+ PythonList (PyObject* py_obj);
+ PythonList (const PythonObject &object);
+ PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ PythonList (uint32_t count);
+ virtual ~PythonList ();
+
+ virtual bool
+ Reset (PyObject* py_obj = NULL);
uint32_t
GetSize();
- PythonDataObject
+ PythonObject
GetItemAtIndex (uint32_t index);
void
- SetItemAtIndex (uint32_t index, const PythonDataObject &object);
+ SetItemAtIndex (uint32_t index, const PythonObject &object);
void
- AppendItem (const PythonDataObject &object);
-
- operator bool () const
- {
- return m_object.operator bool();
- }
-
- PyObject*
- GetPythonObject() const
- {
- return m_object.GetPyhonObject();
- }
- private:
- PythonRefCountedObject m_object;
+ AppendItem (const PythonObject &object);
};
- class PythonDataDictionary
+ class PythonDictionary: public PythonObject
{
public:
- PythonDataDictionary (bool create_empty = true);
- PythonDataDictionary (PyObject* object);
- ~PythonDataDictionary ();
+ PythonDictionary ();
+ PythonDictionary (PyObject* object);
+ PythonDictionary (const PythonObject &object);
+ PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp);
+ virtual ~PythonDictionary ();
+
+ virtual bool
+ Reset (PyObject* object = NULL);
uint32_t GetSize();
- PythonDataObject
- GetItemForKey (const PythonDataString &key) const;
+ PythonObject
+ GetItemForKey (const PythonString &key) const;
const char *
- GetItemForKeyAsString (const PythonDataString &key, const char *fail_value = NULL) const;
+ GetItemForKeyAsString (const PythonString &key, const char *fail_value = NULL) const;
int64_t
- GetItemForKeyAsInteger (const PythonDataString &key, int64_t fail_value = 0) const;
+ GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value = 0) const;
- PythonDataObject
+ PythonObject
GetItemForKey (const char *key) const;
- typedef bool (*DictionaryIteratorCallback)(PythonDataString* key, PythonDataDictionary* dict);
+ typedef bool (*DictionaryIteratorCallback)(PythonString* key, PythonDictionary* dict);
- PythonDataArray
+ PythonList
GetKeys () const;
- PythonDataString
+ PythonString
GetKeyAtPosition (uint32_t pos) const;
- PythonDataObject
+ PythonObject
GetValueAtPosition (uint32_t pos) const;
void
- SetItemForKey (const PythonDataString &key, const PythonDataObject& value);
-
- operator bool () const
- {
- return m_object.operator bool();
- }
-
- PyObject*
- GetPythonObject() const
- {
- return m_object.GetPyhonObject();
- }
- private:
- PythonRefCountedObject m_object;
- };
-
- class PythonDataObject
- {
- public:
-
- PythonDataObject ();
- PythonDataObject (PyObject* object);
-
- ~PythonDataObject ();
-
- PythonDataString
- GetStringObject ();
-
- PythonDataInteger
- GetIntegerObject ();
-
- PythonDataArray
- GetArrayObject();
-
- PythonDataDictionary
- GetDictionaryObject();
-
- operator bool () const
- {
- return m_object.operator bool();
- }
-
- PyObject*
- GetPythonObject() const
- {
- return m_object.GetPyhonObject();
- }
-
- private:
- PythonRefCountedObject m_object;
+ SetItemForKey (const PythonString &key, const PythonObject& value);
};
} // namespace lldb_private
Index: aze/lldb/include/lldb/Interpreter/ScriptInterpreter.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/ScriptInterpreter.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/ScriptInterpreter.h 2013-03-03 09:35:50.091457355 +0100
@@ -41,6 +41,11 @@
return m_object;
}
+ operator bool ()
+ {
+ return m_object != NULL;
+ }
+
ScriptInterpreterObject&
operator = (const ScriptInterpreterObject& rhs)
{
@@ -79,11 +84,11 @@
void** pyfunct_wrapper,
std::string& retval);
- typedef void* (*SWIGPythonCreateSyntheticProvider) (const std::string python_class_name,
+ typedef void* (*SWIGPythonCreateSyntheticProvider) (const char *python_class_name,
const char *session_dictionary_name,
const lldb::ValueObjectSP& valobj_sp);
- typedef void* (*SWIGPythonCreateOSPlugin) (const std::string python_class_name,
+ typedef void* (*SWIGPythonCreateOSPlugin) (const char *python_class_name,
const char *session_dictionary_name,
const lldb::ProcessSP& process_sp);
@@ -102,7 +107,7 @@
std::string& err_msg,
lldb_private::CommandReturnObject& cmd_retobj);
- typedef bool (*SWIGPythonCallModuleInit) (const std::string python_module_name,
+ typedef bool (*SWIGPythonCallModuleInit) (const char *python_module_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger);
@@ -256,38 +261,46 @@
}
virtual lldb::ScriptInterpreterObjectSP
- CreateSyntheticScriptedProvider (std::string class_name,
+ CreateSyntheticScriptedProvider (const char *class_name,
lldb::ValueObjectSP valobj)
{
return lldb::ScriptInterpreterObjectSP();
}
virtual lldb::ScriptInterpreterObjectSP
- CreateOSPlugin (std::string class_name,
- lldb::ProcessSP process_sp)
+ OSPlugin_CreatePluginObject (const char *class_name,
+ lldb::ProcessSP process_sp)
{
return lldb::ScriptInterpreterObjectSP();
}
virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object)
+ OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
return lldb::ScriptInterpreterObjectSP();
}
virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterObjectSP object)
+ OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
return lldb::ScriptInterpreterObjectSP();
}
virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
- lldb::tid_t thread_id)
+ OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t thread_id)
{
return lldb::ScriptInterpreterObjectSP();
}
-
+
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid,
+ lldb::addr_t context)
+ {
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
virtual bool
GenerateFunction(const char *signature, const StringList &input)
{
@@ -327,7 +340,7 @@
return false;
}
- virtual uint32_t
+ virtual size_t
CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor)
{
return 0;
@@ -373,6 +386,12 @@
dest.clear();
return false;
}
+
+ virtual bool
+ CheckObjectExists (const char* name)
+ {
+ return false;
+ }
virtual bool
LoadScriptingModule (const char* filename,
Index: aze/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h
===================================================================
--- aze.orig/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Interpreter/ScriptInterpreterPython.h 2013-03-03 09:35:50.091457355 +0100
@@ -76,24 +76,29 @@
GenerateScriptAliasFunction (StringList &input, std::string& output);
lldb::ScriptInterpreterObjectSP
- CreateSyntheticScriptedProvider (std::string class_name,
+ CreateSyntheticScriptedProvider (const char *class_name,
lldb::ValueObjectSP valobj);
virtual lldb::ScriptInterpreterObjectSP
- CreateOSPlugin (std::string class_name,
- lldb::ProcessSP process_sp);
+ OSPlugin_CreatePluginObject (const char *class_name,
+ lldb::ProcessSP process_sp);
virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object);
+ OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp);
virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterObjectSP object);
+ OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp);
virtual lldb::ScriptInterpreterObjectSP
- OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
- lldb::tid_t thread_id);
+ OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t thread_id);
- virtual uint32_t
+ virtual lldb::ScriptInterpreterObjectSP
+ OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid,
+ lldb::addr_t context);
+
+ virtual size_t
CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor);
virtual lldb::ValueObjectSP
@@ -159,6 +164,15 @@
GetDocumentationForItem (const char* item, std::string& dest);
virtual bool
+ CheckObjectExists (const char* name)
+ {
+ if (!name || !name[0])
+ return false;
+ std::string temp;
+ return GetDocumentationForItem (name,temp);
+ }
+
+ virtual bool
LoadScriptingModule (const char* filename,
bool can_reload,
bool init_session,
@@ -202,8 +216,8 @@
protected:
- void
- EnterSession ();
+ bool
+ EnterSession (bool init_lldb_globals);
void
LeaveSession ();
@@ -241,6 +255,12 @@
Py_XINCREF(m_object);
}
+ operator bool ()
+ {
+ return m_object && m_object != Py_None;
+ }
+
+
virtual
~ScriptInterpreterPythonObject()
{
@@ -258,7 +278,8 @@
enum OnEntry
{
AcquireLock = 0x0001,
- InitSession = 0x0002
+ InitSession = 0x0002,
+ InitGlobals = 0x0004
};
enum OnLeave
@@ -281,7 +302,7 @@
DoAcquireLock ();
bool
- DoInitSession ();
+ DoInitSession (bool init_lldb_globals);
bool
DoFreeLock ();
@@ -292,7 +313,7 @@
static void
ReleasePythonLock ();
- bool m_need_session;
+ bool m_teardown_session;
ScriptInterpreterPython *m_python_interpreter;
FILE* m_tmp_fh;
PyGILState_STATE m_GILState;
@@ -350,6 +371,7 @@
bool m_session_is_active;
bool m_pty_slave_is_open;
bool m_valid_session;
+ PyThreadState *m_command_thread_state;
};
} // namespace lldb_private
Index: aze/lldb/include/lldb/lldb-defines.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-defines.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/lldb-defines.h 2013-03-03 09:35:50.091457355 +0100
@@ -77,6 +77,7 @@
#define LLDB_INVALID_THREAD_ID 0
#define LLDB_INVALID_FRAME_ID UINT32_MAX
#define LLDB_INVALID_SIGNAL_NUMBER INT32_MAX
+#define LLDB_INVALID_OFFSET UINT64_MAX // Must match max of lldb::offset_t
//----------------------------------------------------------------------
/// CPU Type defintions
Index: aze/lldb/include/lldb/lldb-enumerations.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-enumerations.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/lldb-enumerations.h 2013-03-03 09:35:50.091457355 +0100
@@ -176,7 +176,9 @@
eStopReasonWatchpoint,
eStopReasonSignal,
eStopReasonException,
- eStopReasonPlanComplete
+ eStopReasonExec, // Program was re-exec'ed
+ eStopReasonPlanComplete,
+ eStopReasonThreadExiting
} StopReason;
//----------------------------------------------------------------------
@@ -299,6 +301,20 @@
eBreakpointEventTypeThreadChanged = (1u << 11)
} BreakpointEventType;
+ typedef enum WatchpointEventType
+ {
+ eWatchpointEventTypeInvalidType = (1u << 0),
+ eWatchpointEventTypeAdded = (1u << 1),
+ eWatchpointEventTypeRemoved = (1u << 2),
+ eWatchpointEventTypeEnabled = (1u << 6),
+ eWatchpointEventTypeDisabled = (1u << 7),
+ eWatchpointEventTypeCommandChanged = (1u << 8),
+ eWatchpointEventTypeConditionChanged = (1u << 9),
+ eWatchpointEventTypeIgnoreChanged = (1u << 10),
+ eWatchpointEventTypeThreadChanged = (1u << 11),
+ eWatchpointEventTypeTypeChanged = (1u << 12)
+ } WatchpointEventType;
+
//----------------------------------------------------------------------
/// Programming language type.
@@ -353,6 +369,7 @@
typedef enum CommandArgumentType
{
eArgTypeAddress = 0,
+ eArgTypeAddressOrExpression,
eArgTypeAliasName,
eArgTypeAliasOptions,
eArgTypeArchitecture,
@@ -364,6 +381,7 @@
eArgTypeCommandName,
eArgTypeCount,
eArgTypeDirectoryName,
+ eArgTypeDisassemblyFlavor,
eArgTypeEndAddress,
eArgTypeExpression,
eArgTypeExpressionPath,
@@ -438,6 +456,7 @@
eSymbolTypeInvalid = 0,
eSymbolTypeAbsolute,
eSymbolTypeCode,
+ eSymbolTypeResolver,
eSymbolTypeData,
eSymbolTypeTrampoline,
eSymbolTypeRuntime,
Index: aze/lldb/include/lldb/lldb-forward.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-forward.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/lldb-forward.h 2013-03-03 09:35:50.091457355 +0100
@@ -166,11 +166,11 @@
class ProcessLaunchInfo;
class Property;
struct PropertyDefinition;
-class PythonDataArray;
-class PythonDataDictionary;
-class PythonDataInteger;
-class PythonDataObject;
-class PythonDataString;
+class PythonArray;
+class PythonDictionary;
+class PythonInteger;
+class PythonObject;
+class PythonString;
class RegisterContext;
class RegisterLocation;
class RegisterLocationList;
@@ -218,7 +218,7 @@
class SyntheticChildrenFrontEnd;
class TypeFilterImpl;
#ifndef LLDB_DISABLE_PYTHON
-class TypeSyntheticImpl;
+class ScriptedSyntheticChildren;
#endif
class Target;
class TargetList;
@@ -236,6 +236,7 @@
class ThreadSpec;
class TimeValue;
class Type;
+class TypeCategoryMap;
class TypeImpl;
class TypeAndOrName;
class TypeList;
@@ -350,6 +351,7 @@
typedef STD_SHARED_PTR(lldb_private::StopInfo) StopInfoSP;
typedef STD_SHARED_PTR(lldb_private::StoppointLocation) StoppointLocationSP;
typedef STD_SHARED_PTR(lldb_private::Stream) StreamSP;
+ typedef STD_WEAK_PTR (lldb_private::Stream) StreamWP;
typedef STD_SHARED_PTR(lldb_private::StringSummaryFormat) StringTypeSummaryImplSP;
typedef STD_SHARED_PTR(lldb_private::SymbolFile) SymbolFileSP;
typedef STD_SHARED_PTR(lldb_private::SymbolFileType) SymbolFileTypeSP;
@@ -372,7 +374,7 @@
typedef STD_SHARED_PTR(lldb_private::TypeNameSpecifierImpl) TypeNameSpecifierImplSP;
typedef STD_SHARED_PTR(lldb_private::TypeSummaryImpl) TypeSummaryImplSP;
#ifndef LLDB_DISABLE_PYTHON
- typedef STD_SHARED_PTR(lldb_private::TypeSyntheticImpl) TypeSyntheticImplSP;
+ typedef STD_SHARED_PTR(lldb_private::ScriptedSyntheticChildren) ScriptedSyntheticChildrenSP;
#endif
typedef STD_SHARED_PTR(lldb_private::UnwindPlan) UnwindPlanSP;
typedef lldb_private::SharingPtr<lldb_private::ValueObject> ValueObjectSP;
Index: aze/lldb/include/lldb/lldb-private-enumerations.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-private-enumerations.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/lldb-private-enumerations.h 2013-03-03 09:35:50.091457355 +0100
@@ -131,6 +131,7 @@
eExecutionCompleted,
eExecutionDiscarded,
eExecutionInterrupted,
+ eExecutionHitBreakpoint,
eExecutionTimedOut
} ExecutionResults;
@@ -213,7 +214,8 @@
eFormatterChoiceCriterionRegularExpressionSummary = 0x00000004,
eFormatterChoiceCriterionRegularExpressionFilter = 0x00000004,
eFormatterChoiceCriterionDynamicObjCDiscovery = 0x00000008,
- eFormatterChoiceCriterionStrippedBitField = 0x00000010
+ eFormatterChoiceCriterionStrippedBitField = 0x00000010,
+ eFormatterChoiceCriterionWentToStaticValue = 0x00000020
} FormatterChoiceCriterion;
//----------------------------------------------------------------------
Index: aze/lldb/include/lldb/lldb-private-interfaces.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-private-interfaces.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/lldb-private-interfaces.h 2013-03-03 09:35:50.091457355 +0100
@@ -17,11 +17,11 @@
namespace lldb_private
{
typedef lldb::ABISP (*ABICreateInstance) (const ArchSpec &arch);
- typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch);
+ typedef Disassembler* (*DisassemblerCreateInstance) (const ArchSpec &arch, const char *flavor);
typedef DynamicLoader* (*DynamicLoaderCreateInstance) (Process* process, bool force);
- typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& dataSP, const FileSpec *file, lldb::addr_t offset, lldb::addr_t length);
- typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& dataSP, const FileSpec* file, lldb::addr_t offset, lldb::addr_t length);
- typedef ObjectFile* (*ObjectFileCreateMemoryInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& dataSP, const lldb::ProcessSP &process_sp, lldb::addr_t offset);
+ typedef ObjectContainer* (*ObjectContainerCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec *file, lldb::offset_t offset, lldb::offset_t length);
+ typedef ObjectFile* (*ObjectFileCreateInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, lldb::offset_t data_offset, const FileSpec* file, lldb::offset_t file_offset, lldb::offset_t length);
+ typedef ObjectFile* (*ObjectFileCreateMemoryInstance) (const lldb::ModuleSP &module_sp, lldb::DataBufferSP& data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t offset);
typedef LogChannel* (*LogChannelCreateInstance) ();
typedef EmulateInstruction * (*EmulateInstructionCreateInstance) (const ArchSpec &arch, InstructionType inst_type);
typedef OperatingSystem* (*OperatingSystemCreateInstance) (Process *process, bool force);
@@ -29,7 +29,7 @@
typedef Platform* (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
typedef lldb::ProcessSP (*ProcessCreateInstance) (Target &target, Listener &listener, const FileSpec *crash_file_path);
typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file);
- typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp); // Module can be NULL for default system symbol vendor
+ typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor
typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id);
typedef ThreadPlan * (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton);
Index: aze/lldb/include/lldb/lldb-private-log.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-private-log.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/lldb-private-log.h 2013-03-03 09:35:50.091457355 +0100
@@ -41,6 +41,8 @@
#define LIBLLDB_LOG_TYPES (1u << 19)
#define LIBLLDB_LOG_SYMBOLS (1u << 20)
#define LIBLLDB_LOG_MODULES (1u << 21)
+#define LIBLLDB_LOG_TARGET (1u << 22)
+#define LIBLLDB_LOG_MMAP (1u << 23)
#define LIBLLDB_LOG_ALL (UINT32_MAX)
#define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\
LIBLLDB_LOG_THREAD |\
@@ -50,6 +52,7 @@
LIBLLDB_LOG_STEP |\
LIBLLDB_LOG_STATE |\
LIBLLDB_LOG_SYMBOLS |\
+ LIBLLDB_LOG_TARGET |\
LIBLLDB_LOG_COMMANDS)
namespace lldb_private {
Index: aze/lldb/include/lldb/lldb-private-types.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-private-types.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/lldb-private-types.h 2013-03-03 09:35:50.091457355 +0100
@@ -58,7 +58,7 @@
// then this option belongs to option set n.
bool required; // This option is required (in the current usage level)
const char *long_option; // Full name for this option.
- char short_option; // Single character for this option.
+ int short_option; // Single character for this option.
int option_has_arg; // no_argument, required_argument or optional_argument
OptionEnumValueElement *enum_values; // If non-NULL an array of enum values.
uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
Index: aze/lldb/include/lldb/lldb-python.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/include/lldb/lldb-python.h 2013-03-03 09:35:50.091457355 +0100
@@ -0,0 +1,29 @@
+//===-- lldb-python.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_lldb_python_h_
+#define LLDB_lldb_python_h_
+
+// Python.h needs to be included before any system headers in order to avoid redefinition of macros
+
+#ifdef LLDB_DISABLE_PYTHON
+
+// Python is disabled in this build
+
+#else
+
+#if defined (__APPLE__)
+#include <Python/Python.h>
+#else
+#include <Python.h>
+#endif
+
+#endif // LLDB_DISABLE_PYTHON
+
+#endif // LLDB_lldb_python_h_
Index: aze/lldb/include/lldb/lldb-types.h
===================================================================
--- aze.orig/lldb/include/lldb/lldb-types.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/include/lldb/lldb-types.h 2013-03-03 09:35:50.091457355 +0100
@@ -74,6 +74,7 @@
typedef uint64_t user_id_t;
typedef uint64_t pid_t;
typedef uint64_t tid_t;
+ typedef uint64_t offset_t;
typedef int32_t break_id_t;
typedef int32_t watch_id_t;
typedef void * clang_type_t;
Index: aze/lldb/include/lldb/Symbol/Block.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/Block.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/Block.h 2013-03-03 09:35:50.091457355 +0100
@@ -435,7 +435,7 @@
Block *
FindBlockByID (lldb::user_id_t block_id);
- uint32_t
+ size_t
GetNumRanges () const
{
return m_ranges.GetSize();
Index: aze/lldb/include/lldb/Symbol/ClangASTContext.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/ClangASTContext.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/ClangASTContext.h 2013-03-03 09:35:50.091457355 +0100
@@ -596,19 +596,19 @@
static lldb::clang_type_t
GetDirectBaseClassAtIndex (clang::ASTContext *ast,
lldb::clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
uint32_t *bit_offset_ptr);
static lldb::clang_type_t
GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
lldb::clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
uint32_t *bit_offset_ptr);
static lldb::clang_type_t
GetFieldAtIndex (clang::ASTContext *ast,
lldb::clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
std::string& name,
uint64_t *bit_offset_ptr,
uint32_t *bitfield_bit_size_ptr,
@@ -621,7 +621,7 @@
GetChildClangTypeAtIndex (ExecutionContext *exe_ctx,
const char *parent_name,
lldb::clang_type_t parent_clang_type,
- uint32_t idx,
+ size_t idx,
bool transparent_pointers,
bool omit_empty_base_classes,
bool ignore_array_bounds,
@@ -638,7 +638,7 @@
clang::ASTContext *ast,
const char *parent_name,
lldb::clang_type_t parent_clang_type,
- uint32_t idx,
+ size_t idx,
bool transparent_pointers,
bool omit_empty_base_classes,
bool ignore_array_bounds,
@@ -785,9 +785,8 @@
//------------------------------------------------------------------
lldb::clang_type_t
- CreateArrayType (lldb::clang_type_t element_type,
- size_t element_count,
- uint32_t bit_stride);
+ CreateArrayType (lldb::clang_type_t element_type,
+ size_t element_count);
//------------------------------------------------------------------
// Tag Declarations
@@ -887,15 +886,17 @@
static lldb::clang_type_t
GetAsArrayType (lldb::clang_type_t clang_type,
- lldb::clang_type_t *member_type = NULL,
- uint64_t *size = NULL);
+ lldb::clang_type_t *member_type,
+ uint64_t *size,
+ bool *is_incomplete);
static bool
IsArrayType (lldb::clang_type_t clang_type,
- lldb::clang_type_t *member_type = NULL,
- uint64_t *size = NULL)
+ lldb::clang_type_t *member_type,
+ uint64_t *size,
+ bool *is_incomplete)
{
- return GetAsArrayType(clang_type, member_type, size) != 0;
+ return GetAsArrayType(clang_type, member_type, size, is_incomplete) != 0;
}
//------------------------------------------------------------------
Index: aze/lldb/include/lldb/Symbol/ClangASTType.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/ClangASTType.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/ClangASTType.h 2013-03-03 09:35:50.091457355 +0100
@@ -82,6 +82,15 @@
ConstString
GetConstQualifiedTypeName ();
+ static lldb::BasicType
+ GetBasicTypeEnumeration (const ConstString &name);
+
+ static ClangASTType
+ GetBasicType (clang::ASTContext *ast, lldb::BasicType type);
+
+ static ClangASTType
+ GetBasicType (clang::ASTContext *ast, const ConstString &name);
+
static ConstString
GetConstTypeName (clang::ASTContext *ast,
lldb::clang_type_t clang_type);
@@ -99,6 +108,9 @@
lldb::clang_type_t opaque_qual_type);
uint32_t
+ GetClangTypeByteSize ();
+
+ uint32_t
GetClangTypeBitWidth ();
static uint32_t
Index: aze/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h 2013-03-03 09:35:50.095457355 +0100
@@ -113,7 +113,7 @@
return clang::ELR_Failure;
}
- virtual clang::DeclContextLookupResult
+ virtual bool
FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx,
clang::DeclarationName decl_name);
Index: aze/lldb/include/lldb/Symbol/LineTable.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/LineTable.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/LineTable.h 2013-03-03 09:35:50.095457355 +0100
@@ -16,10 +16,30 @@
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Core/ModuleChild.h"
#include "lldb/Core/Section.h"
+#include "lldb/Core/RangeMap.h"
namespace lldb_private {
//----------------------------------------------------------------------
+/// @class LineSequence LineTable.h "lldb/Symbol/LineTable.h"
+/// @brief An abstract base class used during symbol table creation.
+//----------------------------------------------------------------------
+class LineSequence
+{
+public:
+ LineSequence ();
+
+ virtual
+ ~LineSequence() {}
+
+ virtual void
+ Clear() = 0;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN (LineSequence);
+};
+
+//----------------------------------------------------------------------
/// @class LineTable LineTable.h "lldb/Symbol/LineTable.h"
/// @brief A line table class.
//----------------------------------------------------------------------
@@ -53,19 +73,6 @@
// void
// AddLineEntry (const LineEntry& line_entry);
- // Called when you can guarantee the addresses are in increasing order
- void
- AppendLineEntry (const lldb::SectionSP& section_sp,
- lldb::addr_t section_offset,
- uint32_t line,
- uint16_t column,
- uint16_t file_idx,
- bool is_start_of_statement,
- bool is_start_of_basic_block,
- bool is_prologue_end,
- bool is_epilogue_begin,
- bool is_terminal_entry);
-
// Called when you can't guarantee the addresses are in increasing order
void
InsertLineEntry (const lldb::SectionSP& section_sp,
@@ -79,6 +86,29 @@
bool is_epilogue_begin,
bool is_terminal_entry);
+ // Used to instantiate the LineSequence helper classw
+ LineSequence*
+ CreateLineSequenceContainer ();
+
+ // Append an entry to a caller-provided collection that will later be
+ // inserted in this line table.
+ void
+ AppendLineEntryToSequence (LineSequence* sequence,
+ const lldb::SectionSP& section_sp,
+ lldb::addr_t section_offset,
+ uint32_t line,
+ uint16_t column,
+ uint16_t file_idx,
+ bool is_start_of_statement,
+ bool is_start_of_basic_block,
+ bool is_prologue_end,
+ bool is_epilogue_begin,
+ bool is_terminal_entry);
+
+ // Insert a sequence of entries into this line table.
+ void
+ InsertSequence (LineSequence* sequence);
+
//------------------------------------------------------------------
/// Dump all line entries in this line table to the stream \a s.
///
@@ -204,6 +234,25 @@
uint32_t
GetSize () const;
+ typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32> FileAddressRanges;
+
+ //------------------------------------------------------------------
+ /// Gets all contiguous file address ranges for the entire line table.
+ ///
+ /// @param[out] file_ranges
+ /// A collection of file address ranges that will be filled in
+ /// by this function.
+ ///
+ /// @param[out] append
+ /// If \b true, then append to \a file_ranges, otherwise clear
+ /// \a file_ranges prior to adding any ranges.
+ ///
+ /// @return
+ /// The number of address ranges added to \a file_ranges
+ //------------------------------------------------------------------
+ size_t
+ GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append);
+
protected:
struct Entry
@@ -331,15 +380,35 @@
//------------------------------------------------------------------
// Types
//------------------------------------------------------------------
- typedef std::vector<lldb_private::Section*> section_collection; ///< The collection type for the line entries.
- typedef std::vector<Entry> entry_collection; ///< The collection type for the line entries.
+ typedef std::vector<lldb_private::Section*> section_collection; ///< The collection type for the sections.
+ typedef std::vector<Entry> entry_collection; ///< The collection type for the line entries.
//------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
- CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to.
+ CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to.
SectionList m_section_list; ///< The list of sections that at least one of the line entries exists in.
entry_collection m_entries; ///< The collection of line entries in this line table.
+ //------------------------------------------------------------------
+ // Helper class
+ //------------------------------------------------------------------
+ class LineSequenceImpl : public LineSequence
+ {
+ public:
+ LineSequenceImpl() :
+ LineSequence()
+ {}
+
+ virtual
+ ~LineSequenceImpl()
+ {}
+
+ virtual void
+ Clear();
+
+ entry_collection m_seq_entries; ///< The collection of line entries in this sequence.
+ };
+
bool
ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry);
Index: aze/lldb/include/lldb/Symbol/ObjectContainer.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/ObjectContainer.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/ObjectContainer.h 2013-03-03 09:35:50.095457355 +0100
@@ -49,19 +49,20 @@
//------------------------------------------------------------------
ObjectContainer (const lldb::ModuleSP &module_sp,
const FileSpec *file,
- lldb::addr_t file_offset,
- lldb::addr_t file_size,
- lldb::DataBufferSP& file_data_sp) :
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset) :
ModuleChild (module_sp),
m_file (), // This file can be different than the module's file spec
m_offset (file_offset),
- m_length (file_size),
+ m_length (length),
m_data ()
{
if (file)
m_file = *file;
- if (file_data_sp)
- m_data.SetData (file_data_sp, file_offset, file_size);
+ if (data_sp)
+ m_data.SetData (data_sp, data_offset, length);
}
//------------------------------------------------------------------
Index: aze/lldb/include/lldb/Symbol/ObjectFile.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/ObjectFile.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/ObjectFile.h 2013-03-03 09:35:50.095457355 +0100
@@ -88,14 +88,15 @@
//------------------------------------------------------------------
ObjectFile (const lldb::ModuleSP &module_sp,
const FileSpec *file_spec_ptr,
- lldb::addr_t offset,
- lldb::addr_t length,
- lldb::DataBufferSP& headerDataSP);
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset);
ObjectFile (const lldb::ModuleSP &module_sp,
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr,
- lldb::DataBufferSP& headerDataSP);
+ lldb::DataBufferSP& data_sp);
//------------------------------------------------------------------
/// Destructor.
@@ -148,9 +149,10 @@
static lldb::ObjectFileSP
FindPlugin (const lldb::ModuleSP &module_sp,
const FileSpec* file_spec,
- lldb::addr_t file_offset,
- lldb::addr_t file_size,
- lldb::DataBufferSP &data_sp);
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ lldb::DataBufferSP &data_sp,
+ lldb::offset_t &data_offset);
//------------------------------------------------------------------
/// Find a ObjectFile plug-in that can parse a file in memory.
@@ -204,7 +206,8 @@
static bool
SplitArchivePathWithObject (const char *path_with_object,
lldb_private::FileSpec &archive_file,
- lldb_private::ConstString &archive_object);
+ lldb_private::ConstString &archive_object,
+ bool must_exist);
//------------------------------------------------------------------
/// Gets the address size in bytes for the current object file.
@@ -214,7 +217,7 @@
/// architecture (and object for archives). Returns zero if no
/// architecture or object has been selected.
//------------------------------------------------------------------
- virtual size_t
+ virtual uint32_t
GetAddressByteSize () const = 0;
//------------------------------------------------------------------
@@ -278,8 +281,8 @@
/// simple object files that a represented by an entire file.
//------------------------------------------------------------------
virtual lldb::addr_t
- GetOffset () const
- { return m_offset; }
+ GetFileOffset () const
+ { return m_file_offset; }
virtual lldb::addr_t
GetByteSize () const
@@ -439,13 +442,13 @@
/// file is that describes the content of the file. If the header
/// doesn't appear in a section that is defined in the object file,
/// an address with no section is returned that has the file offset
- /// set in the m_offset member of the lldb_private::Address object.
+ /// set in the m_file_offset member of the lldb_private::Address object.
///
/// @return
/// Returns the entry address for this module.
//------------------------------------------------------------------
virtual lldb_private::Address
- GetHeaderAddress () { return Address();}
+ GetHeaderAddress () { return Address(m_memory_addr);}
virtual uint32_t
@@ -601,7 +604,7 @@
FileSpec m_file;
Type m_type;
Strata m_strata;
- lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory
+ lldb::addr_t m_file_offset; ///< The offset in bytes into the file, or the address in memory
lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined).
DataExtractor m_data; ///< The data for this object file so things can be parsed lazily.
lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions
Index: aze/lldb/include/lldb/Symbol/SymbolContext.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/SymbolContext.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/SymbolContext.h 2013-03-03 09:35:50.095457355 +0100
@@ -131,7 +131,7 @@
/// to their default state.
//------------------------------------------------------------------
void
- Clear ();
+ Clear (bool clear_target);
//------------------------------------------------------------------
/// Dump a description of this object to a Stream.
@@ -459,10 +459,10 @@
/// otherwise.
//------------------------------------------------------------------
bool
- GetContextAtIndex(uint32_t idx, SymbolContext& sc) const;
+ GetContextAtIndex(size_t idx, SymbolContext& sc) const;
bool
- RemoveContextAtIndex (uint32_t idx);
+ RemoveContextAtIndex (size_t idx);
//------------------------------------------------------------------
/// Get accessor for a symbol context list size.
///
Index: aze/lldb/include/lldb/Symbol/Symbol.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/Symbol.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/Symbol.h 2013-03-03 09:35:50.095457355 +0100
@@ -37,7 +37,7 @@
bool is_artificial,
const lldb::SectionSP &section_sp,
lldb::addr_t value,
- uint32_t size,
+ lldb::addr_t size,
uint32_t flags);
Symbol (uint32_t symID,
@@ -205,11 +205,14 @@
bool
IsTrampoline () const;
+ bool
+ IsIndirect () const;
+
lldb::addr_t
GetByteSize () const;
void
- SetByteSize (uint32_t size)
+ SetByteSize (lldb::addr_t size)
{
m_calculated_size = size > 0;
m_addr_range.SetByteSize(size);
@@ -250,6 +253,17 @@
uint32_t
GetPrologueByteSize ();
+ bool
+ GetDemangledNameIsSynthesized() const
+ {
+ return m_demangled_is_synthesized;
+ }
+ void
+ SetDemangledNameIsSynthesized(bool b)
+ {
+ m_demangled_is_synthesized = b;
+ }
+
//------------------------------------------------------------------
/// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*)
///
@@ -284,6 +298,7 @@
m_size_is_sibling:1, // m_size contains the index of this symbol's sibling
m_size_is_synthesized:1,// non-zero if this symbol's size was calculated using a delta between this symbol and the next
m_calculated_size:1,
+ m_demangled_is_synthesized:1, // The demangled name was created should not be used for expressions or other lookups
m_type:8;
uint32_t m_flags; // A copy of the flags from the original symbol table, the ObjectFile plug-in can interpret these
AddressRange m_addr_range; // Contains the value, or the section offset address when the value is an address in a section, and the size (if any)
Index: aze/lldb/include/lldb/Symbol/SymbolVendor.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/SymbolVendor.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/SymbolVendor.h 2013-03-03 09:35:50.095457355 +0100
@@ -46,7 +46,8 @@
static SymbolVendor*
- FindPlugin (const lldb::ModuleSP &module_sp);
+ FindPlugin (const lldb::ModuleSP &module_sp,
+ lldb_private::Stream *feedback_strm);
//------------------------------------------------------------------
// Constructors and Destructors
@@ -99,20 +100,20 @@
uint32_t resolve_scope,
SymbolContextList& sc_list);
- virtual uint32_t
+ virtual size_t
FindGlobalVariables (const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variables);
- virtual uint32_t
+ virtual size_t
FindGlobalVariables (const RegularExpression& regex,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variables);
- virtual uint32_t
+ virtual size_t
FindFunctions (const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
uint32_t name_type_mask,
@@ -120,18 +121,18 @@
bool append,
SymbolContextList& sc_list);
- virtual uint32_t
+ virtual size_t
FindFunctions (const RegularExpression& regex,
bool include_inlines,
bool append,
SymbolContextList& sc_list);
- virtual uint32_t
+ virtual size_t
FindTypes (const SymbolContext& sc,
const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& types);
virtual lldb_private::ClangNamespaceDecl
@@ -139,15 +140,15 @@
const ConstString &name,
const ClangNamespaceDecl *parent_namespace_decl);
- virtual uint32_t
+ virtual size_t
GetNumCompileUnits();
virtual bool
- SetCompileUnitAtIndex (uint32_t cu_idx,
+ SetCompileUnitAtIndex (size_t cu_idx,
const lldb::CompUnitSP &cu_sp);
virtual lldb::CompUnitSP
- GetCompileUnitAtIndex(uint32_t idx);
+ GetCompileUnitAtIndex(size_t idx);
TypeList&
GetTypeList()
Index: aze/lldb/include/lldb/Symbol/Symtab.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/Symtab.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/Symtab.h 2013-03-03 09:35:50.095457355 +0100
@@ -41,8 +41,8 @@
Symtab(ObjectFile *objfile);
~Symtab();
- void Reserve (uint32_t count);
- Symbol * Resize (uint32_t count);
+ void Reserve (size_t count);
+ Symbol * Resize (size_t count);
uint32_t AddSymbol(const Symbol& symbol);
size_t GetNumSymbols() const;
void Dump(Stream *s, Target *target, SortOrder sort_type);
@@ -53,10 +53,9 @@
return m_mutex;
}
Symbol * FindSymbolByID (lldb::user_id_t uid) const;
- Symbol * SymbolAtIndex (uint32_t idx);
- const Symbol * SymbolAtIndex (uint32_t idx) const;
+ Symbol * SymbolAtIndex (size_t idx);
+ const Symbol * SymbolAtIndex (size_t idx) const;
Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx);
-// const Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx) const;
uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
uint32_t AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
@@ -71,10 +70,9 @@
size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
Symbol * FindSymbolWithFileAddress (lldb::addr_t file_addr);
-// Symbol * FindSymbolContainingAddress (const Address& value, const uint32_t* indexes, uint32_t num_indexes);
-// Symbol * FindSymbolContainingAddress (const Address& value);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
+ size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
size_t CalculateSymbolSize (Symbol *symbol);
void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const;
@@ -109,13 +107,14 @@
collection m_symbols;
std::vector<uint32_t> m_addr_indexes;
UniqueCStringMap<uint32_t> m_name_to_index;
+ UniqueCStringMap<uint32_t> m_selector_to_index;
mutable Mutex m_mutex; // Provide thread safety for this symbol table
bool m_addr_indexes_computed:1,
m_name_indexes_computed:1;
private:
bool
- CheckSymbolAtIndex (uint32_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const
+ CheckSymbolAtIndex (size_t idx, Debug symbol_debug_type, Visibility symbol_visibility) const
{
switch (symbol_debug_type)
{
@@ -147,6 +146,9 @@
return false;
}
+ void
+ SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes,
+ SymbolContextList &sc_list);
DISALLOW_COPY_AND_ASSIGN (Symtab);
};
Index: aze/lldb/include/lldb/Symbol/Type.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/Type.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/Type.h 2013-03-03 09:35:50.095457355 +0100
@@ -302,7 +302,7 @@
SymbolFile *m_symbol_file;
SymbolContextScope *m_context; // The symbol context in which this type is defined
Type *m_encoding_type;
- uint32_t m_encoding_uid;
+ lldb::user_id_t m_encoding_uid;
EncodingDataType m_encoding_uid_type;
uint32_t m_byte_size;
Declaration m_decl;
@@ -340,6 +340,12 @@
TypeAndOrName &
operator= (const TypeAndOrName &rhs);
+ bool
+ operator==(const TypeAndOrName &other) const;
+
+ bool
+ operator!=(const TypeAndOrName &other) const;
+
ConstString GetName () const;
lldb::TypeSP
@@ -360,6 +366,21 @@
bool
IsEmpty ();
+ bool
+ HasName ();
+
+ bool
+ HasTypeSP ();
+
+ void
+ Clear ();
+
+ operator
+ bool ()
+ {
+ return !IsEmpty();
+ }
+
private:
lldb::TypeSP m_type_sp;
ConstString m_type_name;
Index: aze/lldb/include/lldb/Symbol/TypeVendor.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/TypeVendor.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/TypeVendor.h 2013-03-03 09:35:50.095457355 +0100
@@ -10,6 +10,8 @@
#ifndef liblldb_TypeVendor_h_
#define liblldb_TypeVendor_h_
+#include "lldb/Core/ClangForward.h"
+
namespace lldb_private {
//----------------------------------------------------------------------
@@ -37,6 +39,9 @@
bool append,
uint32_t max_matches,
std::vector <ClangASTType> &types) = 0;
+
+ virtual clang::ASTContext *
+ GetClangASTContext () = 0;
protected:
//------------------------------------------------------------------
Index: aze/lldb/include/lldb/Symbol/Variable.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/Variable.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/Variable.h 2013-03-03 09:35:50.095457355 +0100
@@ -144,9 +144,9 @@
m_loc_is_const_data = b;
}
- typedef uint32_t (*GetVariableCallback) (void *baton,
- const char *name,
- VariableList &var_list);
+ typedef size_t (*GetVariableCallback) (void *baton,
+ const char *name,
+ VariableList &var_list);
static Error
Index: aze/lldb/include/lldb/Symbol/VariableList.h
===================================================================
--- aze.orig/lldb/include/lldb/Symbol/VariableList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Symbol/VariableList.h 2013-03-03 09:35:50.095457355 +0100
@@ -42,10 +42,10 @@
Dump(Stream *s, bool show_context) const;
lldb::VariableSP
- GetVariableAtIndex(uint32_t idx);
+ GetVariableAtIndex(size_t idx) const;
lldb::VariableSP
- RemoveVariableAtIndex (uint32_t idx);
+ RemoveVariableAtIndex (size_t idx);
lldb::VariableSP
FindVariable (const ConstString& name);
Index: aze/lldb/include/lldb/Target/DynamicLoader.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/DynamicLoader.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/DynamicLoader.h 2013-03-03 09:35:50.095457355 +0100
@@ -93,7 +93,20 @@
DidLaunch () = 0;
-
+ //------------------------------------------------------------------
+ /// Helper function that can be used to detect when a process has
+ /// called exec and is now a new and different process. This can
+ /// be called when necessary to try and detect the exec. The process
+ /// might be able to answer this question, but sometimes it might
+ /// not be able and the dynamic loader often knows what the program
+ /// entry point is. So the process and the dynamic loader can work
+ /// together to detect this.
+ //------------------------------------------------------------------
+ virtual bool
+ ProcessDidExec ()
+ {
+ return false;
+ }
//------------------------------------------------------------------
/// Get whether the process should stop when images change.
///
@@ -216,7 +229,6 @@
// Member variables.
//------------------------------------------------------------------
Process* m_process; ///< The process that this dynamic loader plug-in is tracking.
- bool m_stop_when_images_change; ///< Boolean value that indicates if the process should stop when imamges change.
private:
DISALLOW_COPY_AND_ASSIGN (DynamicLoader);
Index: aze/lldb/include/lldb/Target/LanguageRuntime.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/LanguageRuntime.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/LanguageRuntime.h 2013-03-03 09:35:50.095457355 +0100
@@ -44,6 +44,7 @@
virtual bool
GetObjectDescription (Stream &str, Value &value, ExecutionContextScope *exe_scope) = 0;
+ // this call should return true if it could set the name and/or the type
virtual bool
GetDynamicTypeAndAddress (ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
Index: aze/lldb/include/lldb/Target/ObjCLanguageRuntime.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ObjCLanguageRuntime.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ObjCLanguageRuntime.h 2013-03-03 09:35:50.095457355 +0100
@@ -31,7 +31,109 @@
public LanguageRuntime
{
public:
-
+ class MethodName
+ {
+ public:
+ enum Type
+ {
+ eTypeUnspecified,
+ eTypeClassMethod,
+ eTypeInstanceMethod
+ };
+
+ MethodName () :
+ m_full(),
+ m_class(),
+ m_category(),
+ m_selector(),
+ m_type (eTypeUnspecified),
+ m_category_is_valid (false)
+ {
+ }
+
+ MethodName (const char *name, bool strict) :
+ m_full(),
+ m_class(),
+ m_category(),
+ m_selector(),
+ m_type (eTypeUnspecified),
+ m_category_is_valid (false)
+ {
+ SetName (name, strict);
+ }
+
+ void
+ Clear();
+
+ bool
+ IsValid (bool strict) const
+ {
+ // If "strict" is true, the name must have everything specified including
+ // the leading "+" or "-" on the method name
+ if (strict && m_type == eTypeUnspecified)
+ return false;
+ // Other than that, m_full will only be filled in if the objective C
+ // name is valid.
+ return (bool)m_full;
+ }
+
+ bool
+ HasCategory()
+ {
+ return (bool)GetCategory();
+ }
+
+ Type
+ GetType () const
+ {
+ return m_type;
+ }
+
+ const ConstString &
+ GetFullName () const
+ {
+ return m_full;
+ }
+
+ ConstString
+ GetFullNameWithoutCategory (bool empty_if_no_category);
+
+ bool
+ SetName (const char *name, bool strict);
+
+ const ConstString &
+ GetClassName ();
+
+ const ConstString &
+ GetClassNameWithCategory ();
+
+ const ConstString &
+ GetCategory ();
+
+ const ConstString &
+ GetSelector ();
+
+ // Get all possible names for a method. Examples:
+ // If name is "+[NSString(my_additions) myStringWithCString:]"
+ // names[0] => "+[NSString(my_additions) myStringWithCString:]"
+ // names[1] => "+[NSString myStringWithCString:]"
+ // If name is specified without the leading '+' or '-' like "[NSString(my_additions) myStringWithCString:]"
+ // names[0] => "+[NSString(my_additions) myStringWithCString:]"
+ // names[1] => "-[NSString(my_additions) myStringWithCString:]"
+ // names[2] => "+[NSString myStringWithCString:]"
+ // names[3] => "-[NSString myStringWithCString:]"
+ size_t
+ GetFullNames (std::vector<ConstString> &names, bool append);
+ protected:
+ ConstString m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]"
+ ConstString m_class; // Class name: "NSString"
+ ConstString m_class_category; // Class with category: "NSString(my_additions)"
+ ConstString m_category; // Category: "my_additions"
+ ConstString m_selector; // Selector: "myStringWithCString:"
+ Type m_type;
+ bool m_category_is_valid;
+
+ };
typedef lldb::addr_t ObjCISA;
class ClassDescriptor;
@@ -114,8 +216,9 @@
// This should return true iff the interface could be completed
virtual bool
Describe (std::function <void (ObjCISA)> const &superclass_func,
- std::function <void (const char*, const char*)> const &instance_method_func,
- std::function <void (const char*, const char*)> const &class_method_func)
+ std::function <bool (const char*, const char*)> const &instance_method_func,
+ std::function <bool (const char*, const char*)> const &class_method_func,
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
{
return false;
}
@@ -248,7 +351,7 @@
IsValidISA(ObjCISA isa)
{
UpdateISAToDescriptorMap();
- return m_isa_to_descriptor_cache.count(isa) > 0;
+ return m_isa_to_descriptor.count(isa) > 0;
}
virtual void
@@ -257,10 +360,9 @@
void
UpdateISAToDescriptorMap()
{
- if (m_process && m_process->GetStopID() != m_isa_to_descriptor_cache_stop_id)
+ if (m_process && m_process->GetStopID() != m_isa_to_descriptor_stop_id)
{
UpdateISAToDescriptorMapIfNeeded ();
- assert (m_process->GetStopID() == m_isa_to_descriptor_cache_stop_id); // REMOVE THIS PRIOR TO CHECKIN
}
}
@@ -285,6 +387,15 @@
virtual size_t
GetByteOffsetForIvar (ClangASTType &parent_qual_type, const char *ivar_name);
+ // Given the name of an Objective-C runtime symbol (e.g., ivar offset symbol),
+ // try to determine from the runtime what the value of that symbol would be.
+ // Useful when the underlying binary is stripped.
+ virtual lldb::addr_t
+ LookupRuntimeSymbol (const ConstString &name)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
//------------------------------------------------------------------
/// Chop up an objective C function prototype.
///
@@ -342,12 +453,12 @@
/// Returns the number of strings that were successfully filled
/// in.
//------------------------------------------------------------------
- static uint32_t
- ParseMethodName (const char *name,
- ConstString *class_name, // Class name (with category if there is one)
- ConstString *selector_name, // selector only
- ConstString *name_sans_category, // full function name with no category (empty if no category)
- ConstString *class_name_sans_category);// Class name without category (empty if no category)
+// static uint32_t
+// ParseMethodName (const char *name,
+// ConstString *class_name, // Class name (with category if there is one)
+// ConstString *selector_name, // selector only
+// ConstString *name_sans_category, // full function name with no category (empty if no category)
+// ConstString *class_name_sans_category);// Class name without category (empty if no category)
static bool
IsPossibleObjCMethodName (const char *name)
@@ -397,6 +508,40 @@
{
return false;
}
+
+
+ bool
+ ISAIsCached (ObjCISA isa) const
+ {
+ return m_isa_to_descriptor.find(isa) != m_isa_to_descriptor.end();
+ }
+
+ bool
+ AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp)
+ {
+ if (isa != 0)
+ {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ return true;
+ }
+ return false;
+ }
+
+ bool
+ AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name);
+
+ bool
+ AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, uint32_t class_name_hash)
+ {
+ if (isa != 0)
+ {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ m_hash_to_isa_map.insert(std::make_pair(class_name_hash, isa));
+ return true;
+ }
+ return false;
+ }
+
private:
// We keep a map of <Class,Selector>->Implementation so we don't have to call the resolver
// function over and over.
@@ -445,17 +590,25 @@
};
typedef std::map<ClassAndSel,lldb::addr_t> MsgImplMap;
+ typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
+ typedef std::multimap<uint32_t, ObjCISA> HashToISAMap;
+ typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
+ typedef HashToISAMap::iterator HashToISAIterator;
+
MsgImplMap m_impl_cache;
-
LazyBool m_has_new_literals_and_indexing;
+ ISAToDescriptorMap m_isa_to_descriptor;
+ HashToISAMap m_hash_to_isa_map;
+
protected:
- typedef std::map<ObjCISA, ClassDescriptorSP> ISAToDescriptorMap;
- typedef ISAToDescriptorMap::iterator ISAToDescriptorIterator;
- ISAToDescriptorMap m_isa_to_descriptor_cache;
- uint32_t m_isa_to_descriptor_cache_stop_id;
+ uint32_t m_isa_to_descriptor_stop_id;
typedef std::map<ConstString, lldb::TypeWP> CompleteClassMap;
CompleteClassMap m_complete_class_cache;
+
+ ISAToDescriptorIterator
+ GetDescriptorIterator (const ConstString &name);
+
DISALLOW_COPY_AND_ASSIGN (ObjCLanguageRuntime);
};
Index: aze/lldb/include/lldb/Target/OperatingSystem.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/OperatingSystem.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/OperatingSystem.h 2013-03-03 09:35:50.095457355 +0100
@@ -76,6 +76,11 @@
virtual lldb::StopInfoSP
CreateThreadStopReason (Thread *thread) = 0;
+ virtual lldb::ThreadSP
+ CreateThread (lldb::tid_t tid, lldb::addr_t context)
+ {
+ return lldb::ThreadSP();
+ }
protected:
//------------------------------------------------------------------
// Member variables.
Index: aze/lldb/include/lldb/Target/Platform.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/Platform.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/Platform.h 2013-03-03 09:35:50.095457355 +0100
@@ -297,8 +297,9 @@
// Locating the file should happen only on the local computer or using
// the current computers global settings.
//----------------------------------------------------------------------
- virtual FileSpec
- LocateExecutableScriptingResource (const ModuleSpec &module_spec);
+ virtual FileSpecList
+ LocateExecutableScriptingResources (Target *target,
+ Module &module);
virtual Error
GetSharedModule (const ModuleSpec &module_spec,
@@ -347,7 +348,9 @@
/// architecture and the target triple contained within.
//------------------------------------------------------------------
virtual bool
- IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr = NULL);
+ IsCompatibleArchitecture (const ArchSpec &arch,
+ bool exact_arch_match,
+ ArchSpec *compatible_arch_ptr);
//------------------------------------------------------------------
/// Not all platforms will support debugging a process by spawning
@@ -477,13 +480,13 @@
}
// Used for column widths
- uint32_t
+ size_t
GetMaxUserIDNameLength() const
{
return m_max_uid_name_len;
}
// Used for column widths
- uint32_t
+ size_t
GetMaxGroupIDNameLength() const
{
return m_max_gid_name_len;
@@ -547,8 +550,8 @@
Mutex m_gid_map_mutex;
IDToNameMap m_uid_map;
IDToNameMap m_gid_map;
- uint32_t m_max_uid_name_len;
- uint32_t m_max_gid_name_len;
+ size_t m_max_uid_name_len;
+ size_t m_max_gid_name_len;
const char *
GetCachedUserName (uint32_t uid)
Index: aze/lldb/include/lldb/Target/Process.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/Process.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/Process.h 2013-03-03 09:35:50.099457355 +0100
@@ -73,6 +73,24 @@
void
SetPythonOSPluginPath (const FileSpec &file);
+
+ bool
+ GetIgnoreBreakpointsInExpressions () const;
+
+ void
+ SetIgnoreBreakpointsInExpressions (bool ignore);
+
+ bool
+ GetUnwindOnErrorInExpressions () const;
+
+ void
+ SetUnwindOnErrorInExpressions (bool ignore);
+
+ bool
+ GetStopOnSharedLibraryEvents () const;
+
+ void
+ SetStopOnSharedLibraryEvents (bool stop);
};
typedef STD_SHARED_PTR(ProcessProperties) ProcessPropertiesSP;
@@ -625,7 +643,7 @@
const FileAction *
GetFileActionForFD (int fd) const
{
- for (uint32_t idx=0, count=m_file_actions.size(); idx < count; ++idx)
+ for (size_t idx=0, count=m_file_actions.size(); idx < count; ++idx)
{
if (m_file_actions[idx].GetFD () == fd)
return &m_file_actions[idx];
@@ -1057,7 +1075,7 @@
m_infos.clear();
}
- uint32_t
+ size_t
GetSize()
{
return m_infos.size();
@@ -1070,7 +1088,7 @@
}
const char *
- GetProcessNameAtIndex (uint32_t idx)
+ GetProcessNameAtIndex (size_t idx)
{
if (idx < m_infos.size())
return m_infos[idx].GetName();
@@ -1078,7 +1096,7 @@
}
size_t
- GetProcessNameLengthAtIndex (uint32_t idx)
+ GetProcessNameLengthAtIndex (size_t idx)
{
if (idx < m_infos.size())
return m_infos[idx].GetNameLength();
@@ -1086,7 +1104,7 @@
}
lldb::pid_t
- GetProcessIDAtIndex (uint32_t idx)
+ GetProcessIDAtIndex (size_t idx)
{
if (idx < m_infos.size())
return m_infos[idx].GetProcessID();
@@ -1094,7 +1112,7 @@
}
bool
- GetInfoAtIndex (uint32_t idx, ProcessInstanceInfo &info)
+ GetInfoAtIndex (size_t idx, ProcessInstanceInfo &info)
{
if (idx < m_infos.size())
{
@@ -1106,7 +1124,7 @@
// You must ensure "idx" is valid before calling this function
const ProcessInstanceInfo &
- GetProcessInfoAtIndex (uint32_t idx) const
+ GetProcessInfoAtIndex (size_t idx) const
{
assert (idx < m_infos.size());
return m_infos[idx];
@@ -1129,6 +1147,7 @@
public:
ProcessModID () :
m_stop_id (0),
+ m_last_natural_stop_id(0),
m_resume_id (0),
m_memory_id (0),
m_last_user_expression_resume (0),
@@ -1153,7 +1172,9 @@
~ProcessModID () {}
void BumpStopID () {
- m_stop_id++;
+ m_stop_id++;
+ if (!IsLastResumeForUserExpression())
+ m_last_natural_stop_id++;
}
void BumpMemoryID () { m_memory_id++; }
@@ -1165,6 +1186,7 @@
}
uint32_t GetStopID() const { return m_stop_id; }
+ uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; }
uint32_t GetMemoryID () const { return m_memory_id; }
uint32_t GetResumeID () const { return m_resume_id; }
uint32_t GetLastUserExpressionResumeID () const { return m_last_user_expression_resume; }
@@ -1207,6 +1229,7 @@
private:
uint32_t m_stop_id;
+ uint32_t m_last_natural_stop_id;
uint32_t m_resume_id;
uint32_t m_memory_id;
uint32_t m_last_user_expression_resume;
@@ -1344,7 +1367,8 @@
eBroadcastBitStateChanged = (1 << 0),
eBroadcastBitInterrupt = (1 << 1),
eBroadcastBitSTDOUT = (1 << 2),
- eBroadcastBitSTDERR = (1 << 3)
+ eBroadcastBitSTDERR = (1 << 3),
+ eBroadcastBitProfileData = (1 << 4)
};
enum
@@ -1374,6 +1398,7 @@
return GetStaticBroadcasterClass();
}
+
//------------------------------------------------------------------
/// A notification structure that can be used by clients to listen
/// for changes in a process's lifetime.
@@ -1421,6 +1446,22 @@
{
return m_restarted;
}
+
+ size_t
+ GetNumRestartedReasons ()
+ {
+ return m_restarted_reasons.size();
+ }
+
+ const char *
+ GetRestartedReasonAtIndex(size_t idx)
+ {
+ if (idx > m_restarted_reasons.size())
+ return NULL;
+ else
+ return m_restarted_reasons[idx].c_str();
+ }
+
bool
GetInterrupted () const
{
@@ -1444,6 +1485,15 @@
static bool
GetRestartedFromEvent (const Event *event_ptr);
+
+ static size_t
+ GetNumRestartedReasons(const Event *event_ptr);
+
+ static const char *
+ GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx);
+
+ static void
+ AddRestartedReason (Event *event_ptr, const char *reason);
static void
SetRestartedInEvent (Event *event_ptr, bool new_value);
@@ -1474,9 +1524,15 @@
{
m_interrupted = new_value;
}
+ void
+ AddRestartedReason (const char *reason)
+ {
+ m_restarted_reasons.push_back(reason);
+ }
lldb::ProcessSP m_process_sp;
lldb::StateType m_state;
+ std::vector<std::string> m_restarted_reasons;
bool m_restarted; // For "eStateStopped" events, this is true if the target was automatically restarted.
int m_update_state;
bool m_interrupted;
@@ -1562,6 +1618,11 @@
uint32_t
GetAddressByteSize () const;
+ uint32_t
+ GetUniqueID() const
+ {
+ return m_process_unique_id;
+ }
//------------------------------------------------------------------
/// Check if a plug-in instance can debug the file in \a module.
///
@@ -2054,6 +2115,27 @@
//------------------------------------------------------------------
+ /// Called after a process re-execs itself.
+ ///
+ /// Allow Process plug-ins to execute some code after a process has
+ /// exec'ed itself. Subclasses typically should override DoDidExec()
+ /// as the lldb_private::Process class needs to remove its dynamic
+ /// loader, runtime, ABI and other plug-ins, as well as unload all
+ /// shared libraries.
+ //------------------------------------------------------------------
+ virtual void
+ DidExec ();
+
+ //------------------------------------------------------------------
+ /// Subclasses of Process should implement this function if they
+ /// need to do anything after a process exec's itself.
+ //------------------------------------------------------------------
+ virtual void
+ DoDidExec ()
+ {
+ }
+
+ //------------------------------------------------------------------
/// Called before launching to a process.
///
/// Allow Process plug-ins to execute some code before launching a
@@ -2387,7 +2469,8 @@
lldb::ThreadPlanSP &thread_plan_sp,
bool stop_others,
bool run_others,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
uint32_t timeout_usec,
Stream &errors);
@@ -2494,6 +2577,12 @@
return m_mod_id.GetLastUserExpressionResumeID();
}
+ uint32_t
+ GetLastNaturalStopID()
+ {
+ return m_mod_id.GetLastNaturalStopID();
+ }
+
//------------------------------------------------------------------
/// Set accessor for the process exit status (return code).
///
@@ -2717,7 +2806,7 @@
size_t
WriteScalarToMemory (lldb::addr_t vm_addr,
const Scalar &scalar,
- uint32_t size,
+ size_t size,
Error &error);
size_t
@@ -2805,6 +2894,28 @@
lldb::addr_t
AllocateMemory (size_t size, uint32_t permissions, Error &error);
+
+ //------------------------------------------------------------------
+ /// Resolve dynamically loaded indirect functions.
+ ///
+ /// @param[in] address
+ /// The load address of the indirect function to resolve.
+ ///
+ /// @param[out] error
+ /// An error value in case the resolve fails.
+ ///
+ /// @return
+ /// The address of the resolved function.
+ /// LLDB_INVALID_ADDRESS if the resolution failed.
+ //------------------------------------------------------------------
+
+ virtual lldb::addr_t
+ ResolveIndirectFunction(const Address *address, Error &error)
+ {
+ error.SetErrorStringWithFormat("error: %s does not support indirect functions in the debug process", GetShortPluginName());
+ return LLDB_INVALID_ADDRESS;
+ }
+
virtual Error
GetMemoryRegionInfo (lldb::addr_t load_addr,
MemoryRegionInfo &range_info)
@@ -2832,9 +2943,7 @@
lldb::ModuleSP
ReadModuleFromMemory (const FileSpec& file_spec,
- lldb::addr_t header_addr,
- bool add_image_to_target,
- bool load_sections_in_target);
+ lldb::addr_t header_addr);
//------------------------------------------------------------------
/// Attempt to get the attributes for a region of memory in the process.
@@ -2942,7 +3051,7 @@
Error
DeallocateMemory (lldb::addr_t ptr);
-
+
//------------------------------------------------------------------
/// Get any available STDOUT.
///
@@ -2998,6 +3107,24 @@
return 0;
}
+ //------------------------------------------------------------------
+ /// Get any available profile data.
+ ///
+ /// @param[out] buf
+ /// A buffer that will receive any profile data bytes that are
+ /// currently available.
+ ///
+ /// @param[out] buf_size
+ /// The size in bytes for the buffer \a buf.
+ ///
+ /// @return
+ /// The number of bytes written into \a buf. If this value is
+ /// equal to \a buf_size, another call to this function should
+ /// be made to retrieve more profile data.
+ //------------------------------------------------------------------
+ virtual size_t
+ GetAsyncProfileData (char *buf, size_t buf_size, Error &error);
+
//----------------------------------------------------------------------
// Process Breakpoints
//----------------------------------------------------------------------
@@ -3005,7 +3132,7 @@
GetSoftwareBreakpointTrapOpcode (BreakpointSite* bp_site);
virtual Error
- EnableBreakpoint (BreakpointSite *bp_site)
+ EnableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
error.SetErrorStringWithFormat("error: %s does not support enabling breakpoints", GetShortPluginName());
@@ -3014,7 +3141,7 @@
virtual Error
- DisableBreakpoint (BreakpointSite *bp_site)
+ DisableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
error.SetErrorStringWithFormat("error: %s does not support disabling breakpoints", GetShortPluginName());
@@ -3073,10 +3200,10 @@
// Process Watchpoints (optional)
//----------------------------------------------------------------------
virtual Error
- EnableWatchpoint (Watchpoint *wp);
+ EnableWatchpoint (Watchpoint *wp, bool notify = true);
virtual Error
- DisableWatchpoint (Watchpoint *wp);
+ DisableWatchpoint (Watchpoint *wp, bool notify = true);
//------------------------------------------------------------------
// Thread Queries
@@ -3092,10 +3219,25 @@
{
return m_thread_list;
}
-
-
+
+ // This is obsoleted and will be removed very soon.
uint32_t
GetNextThreadIndexID ();
+
+ uint32_t
+ GetNextThreadIndexID (uint64_t thread_id);
+
+ lldb::ThreadSP
+ CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
+
+ // Returns true if an index id has been assigned to a thread.
+ bool
+ HasAssignedIndexIDToThread(uint64_t sb_thread_id);
+
+ // Given a thread_id, it will assign a more reasonable index id for display to the user.
+ // If the thread_id has previously been assigned, the same index id will be used.
+ uint32_t
+ AssignIndexIDToThread(uint64_t thread_id);
//------------------------------------------------------------------
// Event Handling
@@ -3118,8 +3260,7 @@
{
public:
ProcessEventHijacker (Process &process, Listener *listener) :
- m_process (process),
- m_listener (listener)
+ m_process (process)
{
m_process.HijackProcessEvents (listener);
}
@@ -3130,7 +3271,6 @@
private:
Process &m_process;
- Listener *m_listener;
};
friend class ProcessEventHijacker;
//------------------------------------------------------------------
@@ -3425,7 +3565,9 @@
Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete.
lldb::thread_t m_private_state_thread; // Thread ID for the thread that watches interal state events
ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations.
+ uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance
uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used.
+ std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map;
int m_exit_status; ///< The exit status of the process, or -1 if not set.
std::string m_exit_string; ///< A textual description of why a process exited.
ThreadList m_thread_list; ///< The threads for this process.
@@ -3439,20 +3581,24 @@
UnixSignals m_unix_signals; /// This is the current signal set for this process.
lldb::ABISP m_abi_sp;
lldb::InputReaderSP m_process_input_reader;
- Communication m_stdio_communication;
- Mutex m_stdio_communication_mutex;
+ Communication m_stdio_communication;
+ Mutex m_stdio_communication_mutex;
std::string m_stdout_data;
std::string m_stderr_data;
+ Mutex m_profile_data_comm_mutex;
+ std::vector<std::string> m_profile_data;
MemoryCache m_memory_cache;
AllocatedMemoryCache m_allocated_memory_cache;
bool m_should_detach; /// Should we detach if the process object goes away with an explicit call to Kill or Detach?
- LanguageRuntimeCollection m_language_runtimes;
+ LanguageRuntimeCollection m_language_runtimes;
std::auto_ptr<NextEventAction> m_next_event_action_ap;
std::vector<PreResumeCallbackAndBaton> m_pre_resume_actions;
ReadWriteLock m_run_lock;
Predicate<bool> m_currently_handling_event;
bool m_finalize_called;
-
+ lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent.
+ bool m_destroy_in_process;
+
enum {
eCanJITDontKnow= 0,
eCanJITYes,
@@ -3518,6 +3664,9 @@
void
AppendSTDERR (const char *s, size_t len);
+ void
+ BroadcastAsyncProfileData(const char *s, size_t len);
+
static void
STDIOReadThreadBytesReceived (void *baton, const void *src, size_t src_len);
@@ -3543,7 +3692,7 @@
// For Process only
//------------------------------------------------------------------
void ControlPrivateStateThread (uint32_t signal);
-
+
DISALLOW_COPY_AND_ASSIGN (Process);
};
Index: aze/lldb/include/lldb/Target/RegisterContext.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/RegisterContext.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/RegisterContext.h 2013-03-03 09:35:50.099457355 +0100
@@ -45,13 +45,13 @@
GetRegisterCount () = 0;
virtual const RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg) = 0;
+ GetRegisterInfoAtIndex (size_t reg) = 0;
virtual size_t
GetRegisterSetCount () = 0;
virtual const RegisterSet *
- GetRegisterSet (uint32_t reg_set) = 0;
+ GetRegisterSet (size_t reg_set) = 0;
virtual bool
ReadRegister (const RegisterInfo *reg_info, RegisterValue &reg_value) = 0;
Index: aze/lldb/include/lldb/Target/StopInfo.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/StopInfo.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/StopInfo.h 2013-03-03 09:35:50.099457355 +0100
@@ -23,7 +23,7 @@
class StopInfo
{
- friend Process::ProcessEventData;
+ friend class Process::ProcessEventData;
friend class ThreadPlanBase;
public:
@@ -106,7 +106,32 @@
else
m_description.clear();
}
-
+
+ // Sometimes the thread plan logic will know that it wants a given stop to stop or not,
+ // regardless of what the ordinary logic for that StopInfo would dictate. The main example
+ // of this is the ThreadPlanCallFunction, which for instance knows - based on how that particular
+ // expression was executed - whether it wants all breakpoints to auto-continue or not.
+ // Use OverrideShouldStop on the StopInfo to implement this.
+
+ void
+ OverrideShouldStop (bool override_value)
+ {
+ m_override_set = true;
+ m_override_value = override_value;
+ }
+
+ bool
+ GetOverrideShouldStop()
+ {
+ return m_override_set;
+ }
+
+ bool
+ GetOverriddenShouldStopValue ()
+ {
+ return m_override_value;
+ }
+
static lldb::StopInfoSP
CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id);
@@ -129,12 +154,16 @@
static lldb::StopInfoSP
CreateStopReasonWithException (Thread &thread, const char *description);
+ static lldb::StopInfoSP
+ CreateStopReasonWithExec (Thread &thread);
+
static lldb::ValueObjectSP
GetReturnValueObject (lldb::StopInfoSP &stop_info_sp);
protected:
// Perform any action that is associated with this stop. This is done as the
// Event is removed from the event queue. ProcessEventData::DoOnRemoval does the job.
+
virtual void
PerformAction (Event *event_ptr)
{
@@ -160,6 +189,8 @@
uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
uint64_t m_value; // A generic value that can be used for things pertaining to this stop info
std::string m_description; // A textual description describing this stop.
+ bool m_override_set;
+ bool m_override_value;
// This determines whether the target has run since this stop info.
// N.B. running to evaluate a user expression does not count.
Index: aze/lldb/include/lldb/Target/Target.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/Target.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/Target.h 2013-03-03 09:35:50.099457355 +0100
@@ -79,6 +79,12 @@
void
SetDisableSTDIO (bool b);
+ const char *
+ GetDisassemblyFlavor() const;
+
+// void
+// SetDisassemblyFlavor(const char *flavor);
+
InlineStrategy
GetInlineStrategy () const;
@@ -151,6 +157,7 @@
m_execution_policy(eExecutionPolicyOnlyWhenNeeded),
m_coerce_to_id(false),
m_unwind_on_error(true),
+ m_ignore_breakpoints (false),
m_keep_in_memory(false),
m_run_others(true),
m_use_dynamic(lldb::eNoDynamicValues),
@@ -197,6 +204,19 @@
}
bool
+ DoesIgnoreBreakpoints () const
+ {
+ return m_ignore_breakpoints;
+ }
+
+ EvaluateExpressionOptions&
+ SetIgnoreBreakpoints (bool ignore = false)
+ {
+ m_ignore_breakpoints = ignore;
+ return *this;
+ }
+
+ bool
DoesKeepInMemory () const
{
return m_keep_in_memory;
@@ -252,6 +272,7 @@
ExecutionPolicy m_execution_policy;
bool m_coerce_to_id;
bool m_unwind_on_error;
+ bool m_ignore_breakpoints;
bool m_keep_in_memory;
bool m_run_others;
lldb::DynamicValueType m_use_dynamic;
@@ -278,7 +299,8 @@
{
eBroadcastBitBreakpointChanged = (1 << 0),
eBroadcastBitModulesLoaded = (1 << 1),
- eBroadcastBitModulesUnloaded = (1 << 2)
+ eBroadcastBitModulesUnloaded = (1 << 2),
+ eBroadcastBitWatchpointChanged = (1 << 3)
};
// These two functions fill out the Broadcaster interface:
@@ -390,6 +412,8 @@
void
DeleteCurrentProcess ();
+ void
+ CleanupProcess ();
//------------------------------------------------------------------
/// Dump a description of this object to a Stream.
///
@@ -828,7 +852,13 @@
size_t dst_len,
Error &error,
lldb::addr_t *load_addr_ptr = NULL);
-
+
+ size_t
+ ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error);
+
+ size_t
+ ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error);
+
size_t
ReadScalarIntegerFromMemory (const Address& addr,
bool prefer_file_cache,
Index: aze/lldb/include/lldb/Target/Thread.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/Thread.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/Thread.h 2013-03-03 09:35:50.099457355 +0100
@@ -57,6 +57,7 @@
public Broadcaster
{
friend class ThreadEventData;
+friend class ThreadList;
public:
//------------------------------------------------------------------
@@ -67,7 +68,8 @@
eBroadcastBitStackChanged = (1 << 0),
eBroadcastBitThreadSuspended = (1 << 1),
eBroadcastBitThreadResumed = (1 << 2),
- eBroadcastBitSelectedFrameChanged = (1 << 3)
+ eBroadcastBitSelectedFrameChanged = (1 << 3),
+ eBroadcastBitThreadSelected = (1 << 4)
};
static ConstString &GetStaticBroadcasterClass ();
@@ -392,9 +394,13 @@
uint32_t
SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast = false);
+
bool
SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast = false);
+ bool
+ SetSelectedFrameByIndexNoisily (uint32_t frame_idx, Stream &output_stream);
+
void
SetDefaultFileAndLineToSelectedFrame()
{
@@ -478,8 +484,40 @@
bool stop_other_threads);
//------------------------------------------------------------------
- /// Queues the plan used to step through an address range, stepping into or over
- /// function calls depending on the value of StepType.
+ /// Queues the plan used to step through an address range, stepping over
+ /// function calls.
+ ///
+ /// @param[in] abort_other_plans
+ /// \b true if we discard the currently queued plans and replace them with this one.
+ /// Otherwise this plan will go on the end of the plan stack.
+ ///
+ /// @param[in] type
+ /// Type of step to do, only eStepTypeInto and eStepTypeOver are supported by this plan.
+ ///
+ /// @param[in] range
+ /// The address range to step through.
+ ///
+ /// @param[in] addr_context
+ /// When dealing with stepping through inlined functions the current PC is not enough information to know
+ /// what "step" means. For instance a series of nested inline functions might start at the same address.
+ // The \a addr_context provides the current symbol context the step
+ /// is supposed to be out of.
+ // FIXME: Currently unused.
+ ///
+ /// @param[in] stop_other_threads
+ /// \b true if we will stop other threads while we single step this one.
+ ///
+ /// @return
+ /// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
+ //------------------------------------------------------------------
+ virtual ThreadPlan *
+ QueueThreadPlanForStepOverRange (bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_other_threads);
+
+ //------------------------------------------------------------------
+ /// Queues the plan used to step through an address range, stepping into functions.
///
/// @param[in] abort_other_plans
/// \b true if we discard the currently queued plans and replace them with this one.
@@ -498,17 +536,23 @@
/// is supposed to be out of.
// FIXME: Currently unused.
///
+ /// @param[in] step_in_target
+ /// Name if function we are trying to step into. We will step out if we don't land in that function.
+ ///
/// @param[in] stop_other_threads
/// \b true if we will stop other threads while we single step this one.
///
+ /// @param[in] avoid_code_without_debug_info
+ /// If \b true we will step out if we step into code with no debug info.
+ ///
/// @return
/// A pointer to the newly queued thread plan, or NULL if the plan could not be queued.
//------------------------------------------------------------------
virtual ThreadPlan *
- QueueThreadPlanForStepRange (bool abort_other_plans,
- StepType type,
+ QueueThreadPlanForStepInRange (bool abort_other_plans,
const AddressRange &range,
const SymbolContext &addr_context,
+ const char *step_in_target,
lldb::RunMode stop_other_threads,
bool avoid_code_without_debug_info);
@@ -608,7 +652,8 @@
Address& function,
lldb::addr_t arg,
bool stop_other_threads,
- bool discard_on_error = false);
+ bool unwind_on_error = false,
+ bool ignore_breakpoints = true);
//------------------------------------------------------------------
// Thread Plan accessors:
@@ -622,6 +667,17 @@
//------------------------------------------------------------------
ThreadPlan *
GetCurrentPlan ();
+
+ //------------------------------------------------------------------
+ /// Unwinds the thread stack for the innermost expression plan currently
+ /// on the thread plan stack.
+ ///
+ /// @return
+ /// An error if the thread plan could not be unwound.
+ //------------------------------------------------------------------
+
+ Error
+ UnwindInnermostExpression();
private:
bool
@@ -732,6 +788,9 @@
CheckpointThreadState (ThreadStateCheckpoint &saved_state);
virtual bool
+ RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state);
+
+ virtual bool
RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state);
void
@@ -859,7 +918,7 @@
GetUnwinder ();
// Check to see whether the thread is still at the last breakpoint hit that stopped it.
- virtual const bool
+ virtual bool
IsStillAtLastBreakpointHit();
lldb::StackFrameListSP
Index: aze/lldb/include/lldb/Target/ThreadList.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadList.h 2013-03-03 09:35:50.099457355 +0100
@@ -51,10 +51,10 @@
GetSelectedThread ();
bool
- SetSelectedThreadByID (lldb::tid_t tid);
+ SetSelectedThreadByID (lldb::tid_t tid, bool notify = false);
bool
- SetSelectedThreadByIndexID (uint32_t index_id);
+ SetSelectedThreadByIndexID (uint32_t index_id, bool notify = false);
void
Clear();
@@ -75,6 +75,9 @@
FindThreadByID (lldb::tid_t tid, bool can_update = true);
lldb::ThreadSP
+ RemoveThreadByID (lldb::tid_t tid, bool can_update = true);
+
+ lldb::ThreadSP
FindThreadByIndexID (uint32_t index_id, bool can_update = true);
lldb::ThreadSP
@@ -131,6 +134,9 @@
protected:
+ void
+ NotifySelectedThreadChanged (lldb::tid_t tid);
+
typedef std::vector<lldb::ThreadSP> collection;
//------------------------------------------------------------------
// Classes that inherit from Process can see and modify these
Index: aze/lldb/include/lldb/Target/ThreadPlanBase.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanBase.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanBase.h 2013-03-03 09:35:50.099457355 +0100
@@ -35,7 +35,7 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ValidatePlan (Stream *error);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool ShouldStop (Event *event_ptr);
virtual bool StopOthers ();
virtual lldb::StateType GetPlanRunState ();
Index: aze/lldb/include/lldb/Target/ThreadPlanCallFunction.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanCallFunction.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanCallFunction.h 2013-03-03 09:35:50.099457355 +0100
@@ -27,19 +27,21 @@
// return type, otherwise just pass in an invalid ClangASTType.
public:
ThreadPlanCallFunction (Thread &thread,
- Address &function,
+ const Address &function,
const ClangASTType &return_type,
lldb::addr_t arg,
bool stop_other_threads,
- bool discard_on_error = true,
+ bool unwind_on_error = true,
+ bool ignore_breakpoints = false,
lldb::addr_t *this_arg = 0,
lldb::addr_t *cmd_arg = 0);
ThreadPlanCallFunction (Thread &thread,
- Address &function,
+ const Address &function,
const ClangASTType &return_type,
bool stop_other_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
lldb::addr_t *arg1_ptr = NULL,
lldb::addr_t *arg2_ptr = NULL,
lldb::addr_t *arg3_ptr = NULL,
@@ -57,10 +59,13 @@
ValidatePlan (Stream *error);
virtual bool
- PlanExplainsStop ();
+ PlanExplainsStop (Event *event_ptr);
virtual bool
ShouldStop (Event *event_ptr);
+
+ virtual Vote
+ ShouldReportStop(Event *event_ptr);
virtual bool
StopOthers ();
@@ -127,6 +132,9 @@
return m_stop_address;
}
+ virtual bool
+ RestoreThreadState();
+
protected:
void ReportRegisterState (const char *message);
private:
@@ -154,8 +162,6 @@
Address m_function_addr;
Address m_start_addr;
lldb::addr_t m_function_sp;
-// Process &m_process;
-// Thread &m_thread;
Thread::RegisterCheckpoint m_register_backup;
lldb::ThreadPlanSP m_subplan_sp;
LanguageRuntime *m_cxx_language_runtime;
@@ -169,7 +175,8 @@
lldb::ValueObjectSP m_return_valobj_sp; // If this contains a valid pointer, use the ABI to extract values when complete
bool m_takedown_done; // We want to ensure we only do the takedown once. This ensures that.
lldb::addr_t m_stop_address; // This is the address we stopped at. Also set in DoTakedown;
- bool m_discard_on_error;
+ bool m_unwind_on_error;
+ bool m_ignore_breakpoints;
DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction);
};
Index: aze/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h 2013-03-03 09:35:50.099457355 +0100
@@ -29,7 +29,8 @@
Address &function,
lldb::addr_t arg,
bool stop_other_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
lldb::addr_t *this_arg,
lldb::addr_t *cmd_arg,
ClangUserExpression::ClangUserExpressionSP &user_expression_sp);
Index: aze/lldb/include/lldb/Target/ThreadPlan.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlan.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlan.h 2013-03-03 09:35:50.099457355 +0100
@@ -332,7 +332,7 @@
ValidatePlan (Stream *error) = 0;
virtual bool
- PlanExplainsStop () = 0;
+ PlanExplainsStop (Event *event_ptr) = 0;
bool
TracerExplainsStop ()
@@ -494,6 +494,17 @@
return lldb::ValueObjectSP();
}
+ // If a thread plan stores the state before it was run, then you might
+ // want to restore the state when it is done. This will do that job.
+ // This is mostly useful for artificial plans like CallFunction plans.
+
+ virtual bool
+ RestoreThreadState()
+ {
+ // Nothing to do in general.
+ return true;
+ }
+
protected:
//------------------------------------------------------------------
// Classes that inherit from ThreadPlan can see and modify these
Index: aze/lldb/include/lldb/Target/ThreadPlanRunToAddress.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanRunToAddress.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanRunToAddress.h 2013-03-03 09:35:50.099457355 +0100
@@ -47,7 +47,7 @@
ValidatePlan (Stream *error);
virtual bool
- PlanExplainsStop ();
+ PlanExplainsStop (Event *event_ptr);
virtual bool
ShouldStop (Event *event_ptr);
Index: aze/lldb/include/lldb/Target/ThreadPlanStepInRange.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepInRange.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepInRange.h 2013-03-03 09:35:50.099457355 +0100
@@ -32,6 +32,12 @@
const SymbolContext &addr_context,
lldb::RunMode stop_others);
+ ThreadPlanStepInRange (Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_into_function_name,
+ lldb::RunMode stop_others);
+
virtual
~ThreadPlanStepInRange ();
@@ -43,6 +49,11 @@
void SetAvoidRegexp(const char *name);
+ void SetStepInTarget (const char *target)
+ {
+ m_step_into_target.SetCString(target);
+ }
+
static ThreadPlan *
DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, void *baton);
@@ -50,7 +61,7 @@
SetDefaultFlagValue (uint32_t new_value);
virtual bool
- PlanExplainsStop ();
+ PlanExplainsStop (Event *event_ptr);
virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
@@ -65,10 +76,15 @@
private:
friend ThreadPlan *
- Thread::QueueThreadPlanForStepRange (bool abort_other_plans,
- StepType type,
+ Thread::QueueThreadPlanForStepOverRange (bool abort_other_plans,
const AddressRange &range,
const SymbolContext &addr_context,
+ lldb::RunMode stop_others);
+ friend ThreadPlan *
+ Thread::QueueThreadPlanForStepInRange (bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_in_target,
lldb::RunMode stop_others,
bool avoid_code_without_debug_info);
@@ -81,7 +97,7 @@
bool m_step_past_prologue; // FIXME: For now hard-coded to true, we could put a switch in for this if there's
// demand for that.
bool m_virtual_step; // true if we've just done a "virtual step", i.e. just moved the inline stack depth.
-
+ ConstString m_step_into_target;
DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepInRange);
};
Index: aze/lldb/include/lldb/Target/ThreadPlanStepInstruction.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepInstruction.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepInstruction.h 2013-03-03 09:35:50.099457355 +0100
@@ -27,7 +27,7 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ValidatePlan (Stream *error);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool ShouldStop (Event *event_ptr);
virtual bool StopOthers ();
virtual lldb::StateType GetPlanRunState ();
Index: aze/lldb/include/lldb/Target/ThreadPlanStepOut.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepOut.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepOut.h 2013-03-03 09:35:50.099457355 +0100
@@ -34,7 +34,7 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ValidatePlan (Stream *error);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool ShouldStop (Event *event_ptr);
virtual bool StopOthers ();
virtual lldb::StateType GetPlanRunState ();
Index: aze/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h 2013-03-03 09:35:50.099457355 +0100
@@ -27,7 +27,7 @@
ThreadPlanStepOverBreakpoint (Thread &thread);
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ValidatePlan (Stream *error);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool ShouldStop (Event *event_ptr);
virtual bool StopOthers ();
virtual lldb::StateType GetPlanRunState ();
Index: aze/lldb/include/lldb/Target/ThreadPlanStepOverRange.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepOverRange.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepOverRange.h 2013-03-03 09:35:50.103457355 +0100
@@ -34,20 +34,13 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ShouldStop (Event *event_ptr);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool WillResume (lldb::StateType resume_state, bool current_plan);
protected:
private:
- friend ThreadPlan *
- Thread::QueueThreadPlanForStepRange (bool abort_other_plans,
- StepType type,
- const AddressRange &range,
- const SymbolContext &addr_context,
- lldb::RunMode stop_others,
- bool avoid_code_without_debug_info);
bool m_first_resume;
DISALLOW_COPY_AND_ASSIGN (ThreadPlanStepOverRange);
Index: aze/lldb/include/lldb/Target/ThreadPlanStepThrough.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepThrough.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepThrough.h 2013-03-03 09:35:50.103457355 +0100
@@ -26,7 +26,7 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ValidatePlan (Stream *error);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool ShouldStop (Event *event_ptr);
virtual bool StopOthers ();
virtual lldb::StateType GetPlanRunState ();
Index: aze/lldb/include/lldb/Target/ThreadPlanStepUntil.h
===================================================================
--- aze.orig/lldb/include/lldb/Target/ThreadPlanStepUntil.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/include/lldb/Target/ThreadPlanStepUntil.h 2013-03-03 09:35:50.103457355 +0100
@@ -27,7 +27,7 @@
virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
virtual bool ValidatePlan (Stream *error);
- virtual bool PlanExplainsStop ();
+ virtual bool PlanExplainsStop (Event *event_ptr);
virtual bool ShouldStop (Event *event_ptr);
virtual bool StopOthers ();
virtual lldb::StateType GetPlanRunState ();
Index: aze/lldb/INSTALL.txt
===================================================================
--- aze.orig/lldb/INSTALL.txt 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/INSTALL.txt 2013-03-03 09:35:50.103457355 +0100
@@ -1,9 +1,13 @@
LLDB Installation Instructions
==============================
-Note that LLDB currently only builds out of the box on Mac OS X with Xcode, but
-patches to improve portability are definitely welcome.
+LLDB builds on Mac OS X (with Xcode) and Linux (with GCC or Clang).
-In addition to using Xcode you'll need to enable code signing on your system
-to either build lldb or debug using lldb. Please see the code signing
-documentation in docs/code-signing.txt for more detailed directions.
+On Mac OS X, in addition to using Xcode you'll need to enable code signing
+on your system to either build lldb or debug using lldb. Please see the code
+signing documentation in docs/code-signing.txt for more detailed directions.
+
+For instructions to build LLDB on Linux, or more details about supported
+compiler versions, other dependencies, and build flags, see:
+
+ http://lldb.llvm.org/build.html
Index: aze/lldb/lib/Makefile
===================================================================
--- aze.orig/lldb/lib/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/lib/Makefile 2013-03-03 09:35:50.103457355 +0100
@@ -24,6 +24,7 @@
lldbBreakpoint.a \
lldbCommands.a \
lldbCore.a \
+ lldbDataFormatters.a \
lldbExpression.a \
lldbHostCommon.a \
lldbInitAndLog.a \
@@ -67,6 +68,14 @@
lldbPluginPlatformLinux.a \
lldbPluginPlatformFreeBSD.a
+# Because GCC requires RTTI enabled for lldbCore (see source/Core/Makefile) it is
+# necessary to also link the clang rewriter libraries so vtable references can
+# be resolved correctly, if we are building with GCC.
+ifeq (g++,$(shell basename $(CXX)))
+ USEDLIBS += clangRewriteCore.a \
+ clangRewriteFrontend.a
+endif
+
include $(LLDB_LEVEL)/../../Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader bitwriter codegen \
@@ -127,7 +136,7 @@
endif
endif
-ifeq ($(HOST_OS),Linux)
+ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux GNU))
# Include everything from the .a's into the shared library.
ProjLibsOptions := -Wl,--whole-archive $(ProjLibsOptions) \
-Wl,--no-whole-archive
@@ -135,6 +144,7 @@
LLVMLibsOptions += -Wl,--no-undefined
# Link in python
LLVMLibsOptions += $(PYTHON_BUILD_FLAGS) -lrt
+ LLVMLibsOptions += -Wl,--soname,lib$(LIBRARYNAME)$(SHLIBEXT)
endif
ifeq ($(HOST_OS),FreeBSD)
Index: aze/lldb/lldb.xcodeproj/project.pbxproj
===================================================================
--- aze.orig/lldb/lldb.xcodeproj/project.pbxproj 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/lldb.xcodeproj/project.pbxproj 2013-03-03 09:35:50.111457353 +0100
@@ -153,6 +153,9 @@
26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
+ 268648C416531BF800F04704 /* com.apple.debugserver.posix.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C116531BF800F04704 /* com.apple.debugserver.posix.plist */; };
+ 268648C516531BF800F04704 /* com.apple.debugserver.applist.internal.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C216531BF800F04704 /* com.apple.debugserver.applist.internal.plist */; };
+ 268648C616531BF800F04704 /* com.apple.debugserver.internal.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 268648C316531BF800F04704 /* com.apple.debugserver.internal.plist */; };
2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */; };
268653701370AE7200D186A3 /* OptionGroupUInt64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536F1370AE7200D186A3 /* OptionGroupUInt64.cpp */; };
2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */; };
@@ -272,7 +275,6 @@
2689007F13353E2200698AC0 /* CommandCompletions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C09CB74116BD98B00C7A725 /* CommandCompletions.cpp */; };
2689008013353E2200698AC0 /* CommandInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0810F1B8DD00F91463 /* CommandInterpreter.cpp */; };
2689008113353E2200698AC0 /* CommandObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0910F1B8DD00F91463 /* CommandObject.cpp */; };
- 2689008213353E2200698AC0 /* CommandObjectCrossref.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DFBC57113B48F300DD817F /* CommandObjectCrossref.cpp */; };
2689008313353E2200698AC0 /* CommandObjectMultiword.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DFBC58113B48F300DD817F /* CommandObjectMultiword.cpp */; };
2689008413353E2200698AC0 /* CommandObjectRegexCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26DFBC59113B48F300DD817F /* CommandObjectRegexCommand.cpp */; };
2689008513353E2200698AC0 /* CommandReturnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0A10F1B8DD00F91463 /* CommandReturnObject.cpp */; };
@@ -280,7 +282,6 @@
2689008713353E2200698AC0 /* ScriptInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A82010B10FFB49800182560 /* ScriptInterpreter.cpp */; };
2689008813353E2200698AC0 /* ScriptInterpreterNone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A2771FC1135A37500E6ADB6 /* ScriptInterpreterNone.cpp */; };
2689008913353E2200698AC0 /* ScriptInterpreterPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7F0C10F1B8DD00F91463 /* ScriptInterpreterPython.cpp */; };
- 2689008C13353E4200698AC0 /* DisassemblerLLVM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C897410F57C5600BB2B04 /* DisassemblerLLVM.cpp */; };
2689008D13353E4200698AC0 /* DynamicLoaderMacOSXDYLD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260C897A10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.cpp */; };
2689008E13353E4200698AC0 /* DynamicLoaderStatic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 268A683D1321B53B000E3FB8 /* DynamicLoaderStatic.cpp */; };
2689009613353E4200698AC0 /* ObjectContainerBSDArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A3B4AC1181454800381BC2 /* ObjectContainerBSDArchive.cpp */; };
@@ -439,6 +440,10 @@
26BD407F135D2AE000237D80 /* FileLineResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BD407E135D2ADF00237D80 /* FileLineResolver.cpp */; };
26C72C94124322890068DC16 /* SBStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C72C93124322890068DC16 /* SBStream.h */; settings = {ATTRIBUTES = (Public, ); }; };
26C72C961243229A0068DC16 /* SBStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C72C951243229A0068DC16 /* SBStream.cpp */; };
+ 26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D1803C16CEBFD300EDFB5B /* KQueue.cpp */; };
+ 26D1804216CEDF0700EDFB5B /* TimeSpecTimeout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D1804016CEDF0700EDFB5B /* TimeSpecTimeout.cpp */; };
+ 26D1804516CEE12500EDFB5B /* KQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D1804416CEE12500EDFB5B /* KQueue.h */; };
+ 26D1804716CEE12C00EDFB5B /* TimeSpecTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D1804616CEE12C00EDFB5B /* TimeSpecTimeout.h */; };
26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 261B5A5311C3F2AD00AABD0A /* SharingPtr.h */; settings = {ATTRIBUTES = (Public, ); }; };
26D265BC136B4269002EEE45 /* lldb-public.h in Headers */ = {isa = PBXBuildFile; fileRef = 26651A14133BEC76005B64B7 /* lldb-public.h */; settings = {ATTRIBUTES = (Public, ); }; };
26D55235159A7DB100708D8D /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 26D55234159A7DB100708D8D /* libxml2.dylib */; };
@@ -512,7 +517,6 @@
4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */; };
94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /* ValueObjectCast.cpp */; };
- 9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */; };
941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
941BCC8014E48C4000BB969C /* SBTypeFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568714E355F2003A195C /* SBTypeFormat.h */; settings = {ATTRIBUTES = (Public, ); }; };
941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568814E355F2003A195C /* SBTypeSummary.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -528,7 +532,6 @@
9461569D14E358A6003A195C /* SBTypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9461568D14E35621003A195C /* SBTypeSynthetic.cpp */; };
9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9463D4CC13B1798800C230D4 /* CommandObjectType.cpp */; };
9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */; };
- 9470A8F01402DFFB0056FF61 /* DataVisualization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9470A8EF1402DFFB0056FF61 /* DataVisualization.cpp */; };
9475C18814E5E9FA001BFC6D /* SBTypeCategory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18714E5E9FA001BFC6D /* SBTypeCategory.cpp */; };
9475C18914E5EA08001BFC6D /* SBTypeCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */; settings = {ATTRIBUTES = (Public, ); }; };
9475C18E14E5F834001BFC6D /* SBTypeNameSpecifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9475C18D14E5F834001BFC6D /* SBTypeNameSpecifier.cpp */; };
@@ -537,7 +540,21 @@
947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 947A1D631616476A0017C8D1 /* CommandObjectPlugin.h */; };
949ADF031406F648004833E1 /* ValueObjectConstResultImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */; };
94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */; };
- 94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */; };
+ 94CB255B16B069770059775D /* CXXFormatterFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB255716B069770059775D /* CXXFormatterFunctions.cpp */; };
+ 94CB255C16B069770059775D /* DataVisualization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB255816B069770059775D /* DataVisualization.cpp */; };
+ 94CB255D16B069770059775D /* FormatClasses.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB255916B069770059775D /* FormatClasses.cpp */; };
+ 94CB255E16B069770059775D /* FormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB255A16B069770059775D /* FormatManager.cpp */; };
+ 94CB256616B096F10059775D /* TypeCategory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256416B096F10059775D /* TypeCategory.cpp */; };
+ 94CB256716B096F10059775D /* TypeCategoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256516B096F10059775D /* TypeCategoryMap.cpp */; };
+ 94CB257016B0A4270059775D /* TypeFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256D16B0A4260059775D /* TypeFormat.cpp */; };
+ 94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256E16B0A4260059775D /* TypeSummary.cpp */; };
+ 94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB256F16B0A4270059775D /* TypeSynthetic.cpp */; };
+ 94CB257416B1D3880059775D /* FormatCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94CB257316B1D3870059775D /* FormatCache.cpp */; };
+ 94D0B10C16D5535900EA9C70 /* LibCxx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */; };
+ 94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */; };
+ 94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A716CEB55F00833B6E /* NSArray.cpp */; };
+ 94D6A0AB16CEB55F00833B6E /* NSDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */; };
+ 94D6A0AC16CEB55F00833B6E /* NSSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94D6A0A916CEB55F00833B6E /* NSSet.cpp */; };
94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94EA1D5B15E6C9B400D4171A /* PythonDataObjects.cpp */; };
94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94FA3DDF1405D50300833217 /* ValueObjectConstResultChild.cpp */; };
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -566,7 +583,6 @@
B207C4931429607D00F36E4E /* CommandObjectWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B207C4921429607D00F36E4E /* CommandObjectWatchpoint.cpp */; };
B21EB71515CC99F100E60059 /* cxa_demangle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B21EB71415CC99F100E60059 /* cxa_demangle.cpp */; settings = {COMPILER_FLAGS = "-frtti"; }; };
B2462247141AD37D00F3D409 /* OptionGroupWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2462246141AD37D00F3D409 /* OptionGroupWatchpoint.cpp */; };
- B271B11413D6139300C3FEDB /* FormatClasses.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */; };
B27318421416AC12006039C8 /* WatchpointList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B27318411416AC12006039C8 /* WatchpointList.cpp */; };
B28058A1139988B0002D96D0 /* InferiorCallPOSIX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B28058A0139988B0002D96D0 /* InferiorCallPOSIX.cpp */; };
B299580B14F2FA1400050A04 /* DisassemblerLLVMC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B299580A14F2FA1400050A04 /* DisassemblerLLVMC.cpp */; };
@@ -700,6 +716,9 @@
dstPath = /Developer/Library/Lockdown/ServiceAgents/;
dstSubfolderSpec = 0;
files = (
+ 268648C416531BF800F04704 /* com.apple.debugserver.posix.plist in CopyFiles */,
+ 268648C516531BF800F04704 /* com.apple.debugserver.applist.internal.plist in CopyFiles */,
+ 268648C616531BF800F04704 /* com.apple.debugserver.internal.plist in CopyFiles */,
AFF87C87150FF669000E1742 /* com.apple.debugserver.plist in CopyFiles */,
AFF87C89150FF672000E1742 /* com.apple.debugserver-secure.plist in CopyFiles */,
AFF87C8F150FF688000E1742 /* com.apple.debugserver.applist.plist in CopyFiles */,
@@ -729,8 +748,6 @@
260C848310F50F0A00BB2B04 /* ThreadPlanStepThrough.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepThrough.h; path = include/lldb/Target/ThreadPlanStepThrough.h; sourceTree = "<group>"; };
260C848410F50F0A00BB2B04 /* ThreadPlanStepRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepRange.h; path = include/lldb/Target/ThreadPlanStepRange.h; sourceTree = "<group>"; };
260C876910F538E700BB2B04 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
- 260C897410F57C5600BB2B04 /* DisassemblerLLVM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DisassemblerLLVM.cpp; sourceTree = "<group>"; };
- 260C897510F57C5600BB2B04 /* DisassemblerLLVM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisassemblerLLVM.h; sourceTree = "<group>"; };
260C897A10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DynamicLoaderMacOSXDYLD.cpp; sourceTree = "<group>"; };
260C897B10F57C5600BB2B04 /* DynamicLoaderMacOSXDYLD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderMacOSXDYLD.h; sourceTree = "<group>"; };
260C898010F57C5600BB2B04 /* ObjectContainerUniversalMachO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectContainerUniversalMachO.cpp; sourceTree = "<group>"; };
@@ -971,6 +988,9 @@
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PseudoTerminal.h; path = include/lldb/Utility/PseudoTerminal.h; sourceTree = "<group>"; };
2682F284115EF3A700CCFF99 /* SBError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBError.cpp; path = source/API/SBError.cpp; sourceTree = "<group>"; };
2682F286115EF3BD00CCFF99 /* SBError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBError.h; path = include/lldb/API/SBError.h; sourceTree = "<group>"; };
+ 268648C116531BF800F04704 /* com.apple.debugserver.posix.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.debugserver.posix.plist; path = tools/debugserver/source/com.apple.debugserver.posix.plist; sourceTree = "<group>"; };
+ 268648C216531BF800F04704 /* com.apple.debugserver.applist.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.debugserver.applist.internal.plist; path = tools/debugserver/source/com.apple.debugserver.applist.internal.plist; sourceTree = "<group>"; };
+ 268648C316531BF800F04704 /* com.apple.debugserver.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = com.apple.debugserver.internal.plist; path = tools/debugserver/source/com.apple.debugserver.internal.plist; sourceTree = "<group>"; };
2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupBoolean.cpp; path = source/Interpreter/OptionGroupBoolean.cpp; sourceTree = "<group>"; };
2686536D1370ACC600D186A3 /* OptionGroupBoolean.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupBoolean.h; path = include/lldb/Interpreter/OptionGroupBoolean.h; sourceTree = "<group>"; };
2686536E1370AE5A00D186A3 /* OptionGroupUInt64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupUInt64.h; path = include/lldb/Interpreter/OptionGroupUInt64.h; sourceTree = "<group>"; };
@@ -1311,6 +1331,10 @@
26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BreakpointResolverAddress.cpp; path = source/Breakpoint/BreakpointResolverAddress.cpp; sourceTree = "<group>"; };
26D0DD5410FE555900271C65 /* BreakpointResolverFileLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BreakpointResolverFileLine.cpp; path = source/Breakpoint/BreakpointResolverFileLine.cpp; sourceTree = "<group>"; };
26D0DD5510FE555900271C65 /* BreakpointResolverName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BreakpointResolverName.cpp; path = source/Breakpoint/BreakpointResolverName.cpp; sourceTree = "<group>"; };
+ 26D1803C16CEBFD300EDFB5B /* KQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = KQueue.cpp; path = source/Utility/KQueue.cpp; sourceTree = "<group>"; };
+ 26D1804016CEDF0700EDFB5B /* TimeSpecTimeout.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TimeSpecTimeout.cpp; path = source/Utility/TimeSpecTimeout.cpp; sourceTree = "<group>"; };
+ 26D1804416CEE12500EDFB5B /* KQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KQueue.h; path = source/Utility/KQueue.h; sourceTree = "<group>"; };
+ 26D1804616CEE12C00EDFB5B /* TimeSpecTimeout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimeSpecTimeout.h; path = source/Utility/TimeSpecTimeout.h; sourceTree = "<group>"; };
26D27C9D11ED3A4E0024D721 /* ELFHeader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ELFHeader.cpp; sourceTree = "<group>"; };
26D27C9E11ED3A4E0024D721 /* ELFHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELFHeader.h; sourceTree = "<group>"; };
26D55234159A7DB100708D8D /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = /usr/lib/libxml2.dylib; sourceTree = "<absolute>"; };
@@ -1350,10 +1374,8 @@
26DE20601161902600A093E2 /* SBBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBBlock.cpp; path = source/API/SBBlock.cpp; sourceTree = "<group>"; };
26DE20621161904200A093E2 /* SBLineEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBLineEntry.cpp; path = source/API/SBLineEntry.cpp; sourceTree = "<group>"; };
26DE20641161904E00A093E2 /* SBSymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBSymbol.cpp; path = source/API/SBSymbol.cpp; sourceTree = "<group>"; };
- 26DFBC50113B48D600DD817F /* CommandObjectCrossref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectCrossref.h; path = include/lldb/Interpreter/CommandObjectCrossref.h; sourceTree = "<group>"; };
26DFBC51113B48D600DD817F /* CommandObjectMultiword.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectMultiword.h; path = include/lldb/Interpreter/CommandObjectMultiword.h; sourceTree = "<group>"; };
26DFBC52113B48D600DD817F /* CommandObjectRegexCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectRegexCommand.h; path = include/lldb/Interpreter/CommandObjectRegexCommand.h; sourceTree = "<group>"; };
- 26DFBC57113B48F300DD817F /* CommandObjectCrossref.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectCrossref.cpp; path = source/Commands/CommandObjectCrossref.cpp; sourceTree = "<group>"; };
26DFBC58113B48F300DD817F /* CommandObjectMultiword.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectMultiword.cpp; path = source/Commands/CommandObjectMultiword.cpp; sourceTree = "<group>"; };
26DFBC59113B48F300DD817F /* CommandObjectRegexCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectRegexCommand.cpp; path = source/Interpreter/CommandObjectRegexCommand.cpp; sourceTree = "<group>"; };
26E152231419CACA007967D0 /* ObjectFilePECOFF.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ObjectFilePECOFF.cpp; sourceTree = "<group>"; };
@@ -1513,8 +1535,6 @@
94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = "<group>"; };
94094C68163B6CCC0083A547 /* ValueObjectCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectCast.h; path = include/lldb/Core/ValueObjectCast.h; sourceTree = "<group>"; };
94094C69163B6CD90083A547 /* ValueObjectCast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectCast.cpp; path = source/Core/ValueObjectCast.cpp; sourceTree = "<group>"; };
- 9415F61613B2C0DC00A52B36 /* FormatManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = FormatManager.h; path = include/lldb/Core/FormatManager.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
- 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = FormatManager.cpp; path = source/Core/FormatManager.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
9443B120140C18A90013457C /* SBData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBData.h; path = include/lldb/API/SBData.h; sourceTree = "<group>"; };
9443B121140C18C10013457C /* SBData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBData.cpp; path = source/API/SBData.cpp; sourceTree = "<group>"; };
9452573616262CD000325455 /* SBDeclaration.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBDeclaration.i; sourceTree = "<group>"; };
@@ -1540,8 +1560,6 @@
9463D4CE13B179A500C230D4 /* CommandObjectType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CommandObjectType.h; path = source/Commands/CommandObjectType.h; sourceTree = "<group>"; };
9467E65113C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeHierarchyNavigator.cpp; path = source/Symbol/TypeHierarchyNavigator.cpp; sourceTree = "<group>"; };
9467E65413C3D98900B3B6F3 /* TypeHierarchyNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeHierarchyNavigator.h; path = include/lldb/Symbol/TypeHierarchyNavigator.h; sourceTree = "<group>"; };
- 9470A8EE1402DF940056FF61 /* DataVisualization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = DataVisualization.h; path = include/lldb/Core/DataVisualization.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
- 9470A8EF1402DFFB0056FF61 /* DataVisualization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = DataVisualization.cpp; path = source/Core/DataVisualization.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBTypeCategory.h; path = include/lldb/API/SBTypeCategory.h; sourceTree = "<group>"; };
9475C18714E5E9FA001BFC6D /* SBTypeCategory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBTypeCategory.cpp; path = source/API/SBTypeCategory.cpp; sourceTree = "<group>"; };
9475C18A14E5EA1C001BFC6D /* SBTypeCategory.i */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBTypeCategory.i; sourceTree = "<group>"; };
@@ -1552,13 +1570,34 @@
947A1D631616476A0017C8D1 /* CommandObjectPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectPlugin.h; path = source/Commands/CommandObjectPlugin.h; sourceTree = "<group>"; };
949ADF001406F62E004833E1 /* ValueObjectConstResultImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectConstResultImpl.h; path = include/lldb/Core/ValueObjectConstResultImpl.h; sourceTree = "<group>"; };
949ADF021406F648004833E1 /* ValueObjectConstResultImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectConstResultImpl.cpp; path = source/Core/ValueObjectConstResultImpl.cpp; sourceTree = "<group>"; };
- 94A8287514031D05006C37A8 /* FormatNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatNavigator.h; path = include/lldb/Core/FormatNavigator.h; sourceTree = "<group>"; };
- 94A9112B13D5DEF80046D8A6 /* FormatClasses.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatClasses.h; path = include/lldb/Core/FormatClasses.h; sourceTree = "<group>"; };
- 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatClasses.cpp; path = source/Core/FormatClasses.cpp; sourceTree = "<group>"; };
94B6E76013D8833C005F417F /* ValueObjectSyntheticFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ValueObjectSyntheticFilter.h; path = include/lldb/Core/ValueObjectSyntheticFilter.h; sourceTree = "<group>"; };
94B6E76113D88362005F417F /* ValueObjectSyntheticFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectSyntheticFilter.cpp; path = source/Core/ValueObjectSyntheticFilter.cpp; sourceTree = "<group>"; };
- 94CDEB9A15F0226900DD2A7A /* CXXFormatterFunctions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CXXFormatterFunctions.h; path = include/lldb/Core/CXXFormatterFunctions.h; sourceTree = "<group>"; };
- 94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CXXFormatterFunctions.cpp; path = source/Core/CXXFormatterFunctions.cpp; sourceTree = "<group>"; };
+ 94CB255716B069770059775D /* CXXFormatterFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CXXFormatterFunctions.cpp; path = source/DataFormatters/CXXFormatterFunctions.cpp; sourceTree = "<group>"; };
+ 94CB255816B069770059775D /* DataVisualization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DataVisualization.cpp; path = source/DataFormatters/DataVisualization.cpp; sourceTree = "<group>"; };
+ 94CB255916B069770059775D /* FormatClasses.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatClasses.cpp; path = source/DataFormatters/FormatClasses.cpp; sourceTree = "<group>"; };
+ 94CB255A16B069770059775D /* FormatManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatManager.cpp; path = source/DataFormatters/FormatManager.cpp; sourceTree = "<group>"; };
+ 94CB255F16B069800059775D /* CXXFormatterFunctions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CXXFormatterFunctions.h; path = include/lldb/DataFormatters/CXXFormatterFunctions.h; sourceTree = "<group>"; };
+ 94CB256016B069800059775D /* DataVisualization.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = DataVisualization.h; path = include/lldb/DataFormatters/DataVisualization.h; sourceTree = "<group>"; };
+ 94CB256116B069800059775D /* FormatClasses.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatClasses.h; path = include/lldb/DataFormatters/FormatClasses.h; sourceTree = "<group>"; };
+ 94CB256216B069800059775D /* FormatManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatManager.h; path = include/lldb/DataFormatters/FormatManager.h; sourceTree = "<group>"; };
+ 94CB256316B069800059775D /* FormatNavigator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatNavigator.h; path = include/lldb/DataFormatters/FormatNavigator.h; sourceTree = "<group>"; };
+ 94CB256416B096F10059775D /* TypeCategory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeCategory.cpp; path = source/DataFormatters/TypeCategory.cpp; sourceTree = "<group>"; };
+ 94CB256516B096F10059775D /* TypeCategoryMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeCategoryMap.cpp; path = source/DataFormatters/TypeCategoryMap.cpp; sourceTree = "<group>"; };
+ 94CB256816B096F90059775D /* TypeCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeCategory.h; path = include/lldb/DataFormatters/TypeCategory.h; sourceTree = "<group>"; };
+ 94CB256916B096FA0059775D /* TypeCategoryMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeCategoryMap.h; path = include/lldb/DataFormatters/TypeCategoryMap.h; sourceTree = "<group>"; };
+ 94CB256A16B0A4030059775D /* TypeFormat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeFormat.h; path = include/lldb/DataFormatters/TypeFormat.h; sourceTree = "<group>"; };
+ 94CB256B16B0A4030059775D /* TypeSummary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeSummary.h; path = include/lldb/DataFormatters/TypeSummary.h; sourceTree = "<group>"; };
+ 94CB256C16B0A4040059775D /* TypeSynthetic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeSynthetic.h; path = include/lldb/DataFormatters/TypeSynthetic.h; sourceTree = "<group>"; };
+ 94CB256D16B0A4260059775D /* TypeFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeFormat.cpp; path = source/DataFormatters/TypeFormat.cpp; sourceTree = "<group>"; };
+ 94CB256E16B0A4260059775D /* TypeSummary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSummary.cpp; path = source/DataFormatters/TypeSummary.cpp; sourceTree = "<group>"; };
+ 94CB256F16B0A4270059775D /* TypeSynthetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeSynthetic.cpp; path = source/DataFormatters/TypeSynthetic.cpp; sourceTree = "<group>"; };
+ 94CB257316B1D3870059775D /* FormatCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FormatCache.cpp; path = source/DataFormatters/FormatCache.cpp; sourceTree = "<group>"; };
+ 94CB257516B1D3910059775D /* FormatCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = FormatCache.h; path = include/lldb/DataFormatters/FormatCache.h; sourceTree = "<group>"; };
+ 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibCxx.cpp; path = source/DataFormatters/LibCxx.cpp; sourceTree = "<group>"; };
+ 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LibStdcpp.cpp; path = source/DataFormatters/LibStdcpp.cpp; sourceTree = "<group>"; };
+ 94D6A0A716CEB55F00833B6E /* NSArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSArray.cpp; path = source/DataFormatters/NSArray.cpp; sourceTree = "<group>"; };
+ 94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSDictionary.cpp; path = source/DataFormatters/NSDictionary.cpp; sourceTree = "<group>"; };
+ 94D6A0A916CEB55F00833B6E /* NSSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NSSet.cpp; path = source/DataFormatters/NSSet.cpp; sourceTree = "<group>"; };
94E367CC140C4EC4001C7A5A /* modify-python-lldb.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = "modify-python-lldb.py"; sourceTree = "<group>"; };
94E367CE140C4EEA001C7A5A /* python-typemaps.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-typemaps.swig"; sourceTree = "<group>"; };
94EA1D5A15E6C99B00D4171A /* PythonDataObjects.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PythonDataObjects.h; path = include/lldb/Interpreter/PythonDataObjects.h; sourceTree = "<group>"; };
@@ -1779,6 +1818,7 @@
26BC7CEB10F1B70800F91463 /* Breakpoint */,
26BC7D0D10F1B71D00F91463 /* Commands */,
26BC7C1010F1B34800F91463 /* Core */,
+ 94CB255616B0683B0059775D /* DataFormatters */,
26BC7DBE10F1B78200F91463 /* Expression */,
26BC7DD010F1B7C100F91463 /* Host */,
26BC7DDF10F1B7E200F91463 /* Interpreter */,
@@ -1837,8 +1877,6 @@
260C897310F57C5600BB2B04 /* llvm */ = {
isa = PBXGroup;
children = (
- 260C897410F57C5600BB2B04 /* DisassemblerLLVM.cpp */,
- 260C897510F57C5600BB2B04 /* DisassemblerLLVM.h */,
B299580A14F2FA1400050A04 /* DisassemblerLLVMC.cpp */,
B299580C14F2FA1F00050A04 /* DisassemblerLLVMC.h */,
);
@@ -2229,6 +2267,9 @@
isa = PBXGroup;
children = (
AF90106315AB7C5700FF120D /* lldb.1 */,
+ 268648C116531BF800F04704 /* com.apple.debugserver.posix.plist */,
+ 268648C216531BF800F04704 /* com.apple.debugserver.applist.internal.plist */,
+ 268648C316531BF800F04704 /* com.apple.debugserver.internal.plist */,
AFF87C8E150FF688000E1742 /* com.apple.debugserver.applist.plist */,
AFF87C8C150FF680000E1742 /* com.apple.debugserver.applist.plist */,
AFF87C8A150FF677000E1742 /* com.apple.debugserver.applist.plist */,
@@ -2318,6 +2359,8 @@
26ECA04213665FED008D1F18 /* ARM_DWARF_Registers.cpp */,
26F996A8119B79C300412154 /* ARM_GCC_Registers.h */,
264723A511FA076E00DE380C /* CleanUp.h */,
+ 26D1804416CEE12500EDFB5B /* KQueue.h */,
+ 26D1803C16CEBFD300EDFB5B /* KQueue.cpp */,
94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */,
2682F16B115EDA0D00CCFF99 /* PseudoTerminal.h */,
2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */,
@@ -2330,6 +2373,8 @@
2660D9F611922A1300958FBD /* StringExtractor.cpp */,
2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */,
2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */,
+ 26D1804616CEE12C00EDFB5B /* TimeSpecTimeout.h */,
+ 26D1804016CEDF0700EDFB5B /* TimeSpecTimeout.cpp */,
94EBAC8313D9EE26009BA64E /* PythonPointer.h */,
B2462249141AE62200F3D409 /* Utils.h */,
);
@@ -2485,8 +2530,6 @@
266603C91345B5A8004DA8B6 /* ConnectionSharedMemory.cpp */,
26BC7D7C10F1B77400F91463 /* ConstString.h */,
26BC7E9410F1B85900F91463 /* ConstString.cpp */,
- 94CDEB9A15F0226900DD2A7A /* CXXFormatterFunctions.h */,
- 94CDEB9C15F0258400DD2A7A /* CXXFormatterFunctions.cpp */,
26BC7D5910F1B77400F91463 /* DataBuffer.h */,
26BC7D5B10F1B77400F91463 /* DataBufferHeap.h */,
26BC7E7210F1B85900F91463 /* DataBufferHeap.cpp */,
@@ -2496,8 +2539,6 @@
268ED0A4140FF54200DE830F /* DataEncoder.cpp */,
26BC7D5A10F1B77400F91463 /* DataExtractor.h */,
26BC7E7110F1B85900F91463 /* DataExtractor.cpp */,
- 9470A8EE1402DF940056FF61 /* DataVisualization.h */,
- 9470A8EF1402DFFB0056FF61 /* DataVisualization.cpp */,
263664941140A4C10075843B /* Debugger.h */,
263664921140A4930075843B /* Debugger.cpp */,
26BC7D5E10F1B77400F91463 /* Disassembler.h */,
@@ -2514,11 +2555,6 @@
26BC7D6310F1B77400F91463 /* FileSpecList.h */,
26BC7E7B10F1B85900F91463 /* FileSpecList.cpp */,
26BC7D6410F1B77400F91463 /* Flags.h */,
- 94A9112B13D5DEF80046D8A6 /* FormatClasses.h */,
- 94A9112D13D5DF210046D8A6 /* FormatClasses.cpp */,
- 9415F61613B2C0DC00A52B36 /* FormatManager.h */,
- 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */,
- 94A8287514031D05006C37A8 /* FormatNavigator.h */,
26F7305F139D8FC900FD51C7 /* History.h */,
26F73061139D8FDB00FD51C7 /* History.cpp */,
9AA69DBB118A029E00D753A0 /* InputReader.h */,
@@ -2881,8 +2917,6 @@
26BC7F0810F1B8DD00F91463 /* CommandInterpreter.cpp */,
26BC7DE310F1B7F900F91463 /* CommandObject.h */,
26BC7F0910F1B8DD00F91463 /* CommandObject.cpp */,
- 26DFBC50113B48D600DD817F /* CommandObjectCrossref.h */,
- 26DFBC57113B48F300DD817F /* CommandObjectCrossref.cpp */,
26DFBC51113B48D600DD817F /* CommandObjectMultiword.h */,
26DFBC58113B48F300DD817F /* CommandObjectMultiword.cpp */,
26DFBC52113B48D600DD817F /* CommandObjectRegexCommand.h */,
@@ -3321,6 +3355,39 @@
path = source/Host/common;
sourceTree = "<group>";
};
+ 94CB255616B0683B0059775D /* DataFormatters */ = {
+ isa = PBXGroup;
+ children = (
+ 94CB255F16B069800059775D /* CXXFormatterFunctions.h */,
+ 94CB255716B069770059775D /* CXXFormatterFunctions.cpp */,
+ 94CB256016B069800059775D /* DataVisualization.h */,
+ 94CB255816B069770059775D /* DataVisualization.cpp */,
+ 94CB257516B1D3910059775D /* FormatCache.h */,
+ 94CB257316B1D3870059775D /* FormatCache.cpp */,
+ 94CB256116B069800059775D /* FormatClasses.h */,
+ 94CB255916B069770059775D /* FormatClasses.cpp */,
+ 94CB256216B069800059775D /* FormatManager.h */,
+ 94CB255A16B069770059775D /* FormatManager.cpp */,
+ 94CB256316B069800059775D /* FormatNavigator.h */,
+ 94D0B10A16D5535900EA9C70 /* LibCxx.cpp */,
+ 94D0B10B16D5535900EA9C70 /* LibStdcpp.cpp */,
+ 94D6A0A716CEB55F00833B6E /* NSArray.cpp */,
+ 94D6A0A816CEB55F00833B6E /* NSDictionary.cpp */,
+ 94D6A0A916CEB55F00833B6E /* NSSet.cpp */,
+ 94CB256816B096F90059775D /* TypeCategory.h */,
+ 94CB256416B096F10059775D /* TypeCategory.cpp */,
+ 94CB256916B096FA0059775D /* TypeCategoryMap.h */,
+ 94CB256516B096F10059775D /* TypeCategoryMap.cpp */,
+ 94CB256A16B0A4030059775D /* TypeFormat.h */,
+ 94CB256D16B0A4260059775D /* TypeFormat.cpp */,
+ 94CB256B16B0A4030059775D /* TypeSummary.h */,
+ 94CB256E16B0A4260059775D /* TypeSummary.cpp */,
+ 94CB256C16B0A4040059775D /* TypeSynthetic.h */,
+ 94CB256F16B0A4270059775D /* TypeSynthetic.cpp */,
+ );
+ name = DataFormatters;
+ sourceTree = "<group>";
+ };
EDC6D49114E5C15C001B75F8 /* launcherXPCService */ = {
isa = PBXGroup;
children = (
@@ -3422,8 +3489,10 @@
260CC63215D04377002BF2E0 /* OptionValueDictionary.h in Headers */,
260CC63315D04377002BF2E0 /* OptionValueEnumeration.h in Headers */,
260CC63415D04377002BF2E0 /* OptionValueFileSpec.h in Headers */,
+ 26D1804716CEE12C00EDFB5B /* TimeSpecTimeout.h in Headers */,
260CC63515D04377002BF2E0 /* OptionValueFileSpecList.h in Headers */,
260CC63615D04377002BF2E0 /* OptionValueFormat.h in Headers */,
+ 26D1804516CEE12500EDFB5B /* KQueue.h in Headers */,
260CC63715D04377002BF2E0 /* OptionValueSInt64.h in Headers */,
260CC63815D04377002BF2E0 /* OptionValueString.h in Headers */,
260CC63915D04377002BF2E0 /* OptionValueUInt64.h in Headers */,
@@ -3592,7 +3661,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0450;
+ LastUpgradeCheck = 0500;
};
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
compatibilityVersion = "Xcode 3.2";
@@ -3799,6 +3868,7 @@
buildActionMask = 2147483647;
files = (
9456F2241616671900656F91 /* DynamicLibrary.cpp in Sources */,
+ 26D1804216CEDF0700EDFB5B /* TimeSpecTimeout.cpp in Sources */,
49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */,
2689FFDA13353D9D00698AC0 /* lldb.cpp in Sources */,
2689FFDB13353DA300698AC0 /* lldb-log.cpp in Sources */,
@@ -3878,6 +3948,7 @@
2689004B13353E0400698AC0 /* Section.cpp in Sources */,
2689004C13353E0400698AC0 /* SourceManager.cpp in Sources */,
2689004D13353E0400698AC0 /* State.cpp in Sources */,
+ 94D0B10D16D5535900EA9C70 /* LibStdcpp.cpp in Sources */,
2689004E13353E0400698AC0 /* Stream.cpp in Sources */,
2689004F13353E0400698AC0 /* StreamFile.cpp in Sources */,
2689005013353E0400698AC0 /* StreamString.cpp in Sources */,
@@ -3910,6 +3981,7 @@
2689006B13353E0E00698AC0 /* IRForTarget.cpp in Sources */,
2689006D13353E0E00698AC0 /* RecordingMemoryManager.cpp in Sources */,
2689006E13353E1A00698AC0 /* File.cpp in Sources */,
+ 94D6A0AB16CEB55F00833B6E /* NSDictionary.cpp in Sources */,
2689006F13353E1A00698AC0 /* FileSpec.cpp in Sources */,
2689007013353E1A00698AC0 /* Condition.cpp in Sources */,
2689007113353E1A00698AC0 /* Host.cpp in Sources */,
@@ -3928,7 +4000,6 @@
2689007F13353E2200698AC0 /* CommandCompletions.cpp in Sources */,
2689008013353E2200698AC0 /* CommandInterpreter.cpp in Sources */,
2689008113353E2200698AC0 /* CommandObject.cpp in Sources */,
- 2689008213353E2200698AC0 /* CommandObjectCrossref.cpp in Sources */,
2689008313353E2200698AC0 /* CommandObjectMultiword.cpp in Sources */,
2689008413353E2200698AC0 /* CommandObjectRegexCommand.cpp in Sources */,
2689008513353E2200698AC0 /* CommandReturnObject.cpp in Sources */,
@@ -3936,7 +4007,6 @@
2689008713353E2200698AC0 /* ScriptInterpreter.cpp in Sources */,
2689008813353E2200698AC0 /* ScriptInterpreterNone.cpp in Sources */,
2689008913353E2200698AC0 /* ScriptInterpreterPython.cpp in Sources */,
- 2689008C13353E4200698AC0 /* DisassemblerLLVM.cpp in Sources */,
2689008D13353E4200698AC0 /* DynamicLoaderMacOSXDYLD.cpp in Sources */,
2689008E13353E4200698AC0 /* DynamicLoaderStatic.cpp in Sources */,
2689009613353E4200698AC0 /* ObjectContainerBSDArchive.cpp in Sources */,
@@ -3970,6 +4040,7 @@
268900C213353E5F00698AC0 /* DWARFDebugPubnamesSet.cpp in Sources */,
268900C313353E5F00698AC0 /* DWARFDebugRanges.cpp in Sources */,
268900C413353E5F00698AC0 /* DWARFDefines.cpp in Sources */,
+ 94D0B10C16D5535900EA9C70 /* LibCxx.cpp in Sources */,
268900C513353E5F00698AC0 /* DWARFDIECollection.cpp in Sources */,
268900C613353E5F00698AC0 /* DWARFFormValue.cpp in Sources */,
268900C713353E5F00698AC0 /* DWARFLocationDescription.cpp in Sources */,
@@ -4045,6 +4116,7 @@
2689011113353E8200698AC0 /* StringExtractor.cpp in Sources */,
2689011213353E8200698AC0 /* StringExtractorGDBRemote.cpp in Sources */,
2689011313353E8200698AC0 /* PseudoTerminal.cpp in Sources */,
+ 94D6A0AA16CEB55F00833B6E /* NSArray.cpp in Sources */,
26B1FCC21338115F002886E2 /* Host.mm in Sources */,
26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */,
26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */,
@@ -4076,6 +4148,7 @@
26DB3E161379E7AD0080DC73 /* ABIMacOSX_arm.cpp in Sources */,
26DB3E1C1379E7AD0080DC73 /* ABIMacOSX_i386.cpp in Sources */,
26DB3E1F1379E7AD0080DC73 /* ABISysV_x86_64.cpp in Sources */,
+ 26D1803E16CEBFD300EDFB5B /* KQueue.cpp in Sources */,
26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */,
2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */,
9A9E1EFF1398086D005AC039 /* InputReaderStack.cpp in Sources */,
@@ -4088,7 +4161,6 @@
4CCA645613B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp in Sources */,
4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */,
9463D4CD13B1798800C230D4 /* CommandObjectType.cpp in Sources */,
- 9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */,
49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */,
9467E65213C3D97600B3B6F3 /* TypeHierarchyNavigator.cpp in Sources */,
26ED3D6D13C563810017D45E /* OptionGroupVariable.cpp in Sources */,
@@ -4105,13 +4177,11 @@
265205AC13D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp in Sources */,
2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */,
26D7E45D13D5E30A007FD12B /* SocketAddress.cpp in Sources */,
- B271B11413D6139300C3FEDB /* FormatClasses.cpp in Sources */,
94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */,
262D24E613FB8710002D1960 /* RegisterContextMemory.cpp in Sources */,
26F4A21C13FBA31A0064B613 /* ThreadMemory.cpp in Sources */,
266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */,
26954EBE1401EE8B00294D09 /* DynamicRegisterInfo.cpp in Sources */,
- 9470A8F01402DFFB0056FF61 /* DataVisualization.cpp in Sources */,
26274FA214030EEF006BA130 /* OperatingSystemDarwinKernel.cpp in Sources */,
26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */,
94FA3DE01405D50400833217 /* ValueObjectConstResultChild.cpp in Sources */,
@@ -4158,11 +4228,21 @@
26491E3E15E1DB9F00CBFFC2 /* OptionValueRegex.cpp in Sources */,
2697A39315E404B1003E682C /* OptionValueArch.cpp in Sources */,
94EA1D5C15E6C9B400D4171A /* PythonDataObjects.cpp in Sources */,
+ 94D6A0AC16CEB55F00833B6E /* NSSet.cpp in Sources */,
2698699B15E6CBD0002415FF /* OperatingSystemPython.cpp in Sources */,
- 94CDEB9D15F0258500DD2A7A /* CXXFormatterFunctions.cpp in Sources */,
947A1D641616476B0017C8D1 /* CommandObjectPlugin.cpp in Sources */,
262ED0081631FA3A00879631 /* OptionGroupString.cpp in Sources */,
94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */,
+ 94CB255B16B069770059775D /* CXXFormatterFunctions.cpp in Sources */,
+ 94CB255C16B069770059775D /* DataVisualization.cpp in Sources */,
+ 94CB255D16B069770059775D /* FormatClasses.cpp in Sources */,
+ 94CB255E16B069770059775D /* FormatManager.cpp in Sources */,
+ 94CB256616B096F10059775D /* TypeCategory.cpp in Sources */,
+ 94CB256716B096F10059775D /* TypeCategoryMap.cpp in Sources */,
+ 94CB257016B0A4270059775D /* TypeFormat.cpp in Sources */,
+ 94CB257116B0A4270059775D /* TypeSummary.cpp in Sources */,
+ 94CB257216B0A4270059775D /* TypeSynthetic.cpp in Sources */,
+ 94CB257416B1D3880059775D /* FormatCache.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4285,6 +4365,11 @@
);
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_C_LANGUAGE_STANDARD = c99;
@@ -4345,6 +4430,11 @@
"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = c99;
@@ -4441,9 +4531,9 @@
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 168;
+ DYLIB_CURRENT_VERSION = 178;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4498,10 +4588,10 @@
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 168;
+ DYLIB_CURRENT_VERSION = 178;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4556,7 +4646,7 @@
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
@@ -4582,7 +4672,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
OTHER_CFLAGS = "";
@@ -4599,7 +4689,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
OTHER_CFLAGS = "";
@@ -4613,8 +4703,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
- DYLIB_CURRENT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
+ DYLIB_CURRENT_VERSION = 178;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4643,8 +4733,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
- DYLIB_CURRENT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
+ DYLIB_CURRENT_VERSION = 178;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4673,8 +4763,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
- DYLIB_CURRENT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
+ DYLIB_CURRENT_VERSION = 178;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -4711,6 +4801,11 @@
);
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_C_LANGUAGE_STANDARD = c99;
@@ -4766,7 +4861,7 @@
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -4791,6 +4886,7 @@
"$(PROJECT_DIR)/tools/driver/lldb-Info.plist",
"-Wl,-rpath,@loader_path/../../../SharedFrameworks",
"-Wl,-rpath,@loader_path/../../System/Library/PrivateFrameworks",
+ "-Wl,-rpath,@loader_path/../../Library/PrivateFrameworks",
);
PRODUCT_NAME = lldb;
STRIP_INSTALLED_PRODUCT = YES;
@@ -4807,10 +4903,10 @@
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
DEAD_CODE_STRIPPING = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 168;
+ DYLIB_CURRENT_VERSION = 178;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -5128,7 +5224,7 @@
26F5C26C10F3D9A5009D5894 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -5158,7 +5254,7 @@
26F5C26D10F3D9A5009D5894 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -5194,6 +5290,11 @@
);
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_C_LANGUAGE_STANDARD = c99;
@@ -5273,7 +5374,7 @@
49BB8F381611172B00BDD462 /* DebugClang */ = {
isa = XCBuildConfiguration;
buildSettings = {
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"",
@@ -5307,9 +5408,9 @@
CLANG_LINK_OBJC_RUNTIME = NO;
CLANG_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
DYLIB_COMPATIBILITY_VERSION = 1;
- DYLIB_CURRENT_VERSION = 168;
+ DYLIB_CURRENT_VERSION = 178;
EXPORTED_SYMBOLS_FILE = "resources/lldb-framework-exports";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -5374,8 +5475,8 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
- DYLIB_CURRENT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
+ DYLIB_CURRENT_VERSION = 178;
EXECUTABLE_EXTENSION = a;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -5542,7 +5643,7 @@
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COMBINE_HIDPI_IMAGES = YES;
- CURRENT_PROJECT_VERSION = 168;
+ CURRENT_PROJECT_VERSION = 178;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
Index: aze/lldb/resources/LLDB-Info.plist
===================================================================
--- aze.orig/lldb/resources/LLDB-Info.plist 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/resources/LLDB-Info.plist 2013-03-03 09:35:50.111457353 +0100
@@ -17,7 +17,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>168</string>
+ <string>178</string>
<key>CFBundleName</key>
<string>${EXECUTABLE_NAME}</string>
</dict>
Index: aze/lldb/scripts/build-llvm.pl
===================================================================
--- aze.orig/lldb/scripts/build-llvm.pl 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/build-llvm.pl 2013-03-03 09:35:50.111457353 +0100
@@ -31,75 +31,75 @@
my $original_env_path = $ENV{PATH};
our %llvm_config_info = (
- 'Debug' => { configure_options => '--disable-optimized --disable-assertions --enable-libcpp', make_options => 'DEBUG_SYMBOLS=1'},
- 'Debug+Asserts' => { configure_options => '--disable-optimized --enable-assertions --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
- 'Release' => { configure_options => '--enable-optimized --disable-assertions --enable-libcpp' , make_options => ''},
- 'Release+Debug' => { configure_options => '--enable-optimized --disable-assertions --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
- 'Release+Asserts' => { configure_options => '--enable-optimized --enable-assertions --enable-libcpp' , make_options => ''},
+ 'Debug' => { configure_options => '--disable-optimized --disable-assertions --enable-libcpp', make_options => 'DEBUG_SYMBOLS=1'},
+ 'Debug+Asserts' => { configure_options => '--disable-optimized --enable-assertions --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
+ 'Release' => { configure_options => '--enable-optimized --disable-assertions --enable-libcpp' , make_options => ''},
+ 'Release+Debug' => { configure_options => '--enable-optimized --disable-assertions --enable-libcpp' , make_options => 'DEBUG_SYMBOLS=1'},
+ 'Release+Asserts' => { configure_options => '--enable-optimized --enable-assertions --enable-libcpp' , make_options => ''},
);
our $llvm_config_href = undef;
if (exists $llvm_config_info{"$llvm_configuration"})
{
- $llvm_config_href = $llvm_config_info{$llvm_configuration};
+ $llvm_config_href = $llvm_config_info{$llvm_configuration};
}
else
{
- die "Unsupported LLVM configuration: '$llvm_configuration'\n";
+ die "Unsupported LLVM configuration: '$llvm_configuration'\n";
}
-our @archive_files = (
+our @archive_files = (
"$llvm_configuration/lib/libclang.a",
- "$llvm_configuration/lib/libclangAnalysis.a",
- "$llvm_configuration/lib/libclangAST.a",
- "$llvm_configuration/lib/libclangBasic.a",
- "$llvm_configuration/lib/libclangCodeGen.a",
+ "$llvm_configuration/lib/libclangAnalysis.a",
+ "$llvm_configuration/lib/libclangAST.a",
+ "$llvm_configuration/lib/libclangBasic.a",
+ "$llvm_configuration/lib/libclangCodeGen.a",
"$llvm_configuration/lib/libclangEdit.a",
- "$llvm_configuration/lib/libclangFrontend.a",
- "$llvm_configuration/lib/libclangDriver.a",
- "$llvm_configuration/lib/libclangLex.a",
- "$llvm_configuration/lib/libclangParse.a",
- "$llvm_configuration/lib/libclangSema.a",
+ "$llvm_configuration/lib/libclangFrontend.a",
+ "$llvm_configuration/lib/libclangDriver.a",
+ "$llvm_configuration/lib/libclangLex.a",
+ "$llvm_configuration/lib/libclangParse.a",
+ "$llvm_configuration/lib/libclangSema.a",
"$llvm_configuration/lib/libclangSerialization.a",
- "$llvm_configuration/lib/libLLVMAnalysis.a",
- "$llvm_configuration/lib/libLLVMArchive.a",
- "$llvm_configuration/lib/libLLVMARMAsmParser.a",
- "$llvm_configuration/lib/libLLVMARMAsmPrinter.a",
- "$llvm_configuration/lib/libLLVMARMCodeGen.a",
+ "$llvm_configuration/lib/libLLVMAnalysis.a",
+ "$llvm_configuration/lib/libLLVMArchive.a",
+ "$llvm_configuration/lib/libLLVMARMAsmParser.a",
+ "$llvm_configuration/lib/libLLVMARMAsmPrinter.a",
+ "$llvm_configuration/lib/libLLVMARMCodeGen.a",
"$llvm_configuration/lib/libLLVMARMDesc.a",
- "$llvm_configuration/lib/libLLVMARMDisassembler.a",
- "$llvm_configuration/lib/libLLVMARMInfo.a",
- "$llvm_configuration/lib/libLLVMAsmParser.a",
- "$llvm_configuration/lib/libLLVMAsmPrinter.a",
- "$llvm_configuration/lib/libLLVMBitReader.a",
- "$llvm_configuration/lib/libLLVMBitWriter.a",
- "$llvm_configuration/lib/libLLVMCodeGen.a",
- "$llvm_configuration/lib/libLLVMCore.a",
- "$llvm_configuration/lib/libLLVMExecutionEngine.a",
- "$llvm_configuration/lib/libLLVMInstCombine.a",
- "$llvm_configuration/lib/libLLVMInstrumentation.a",
- "$llvm_configuration/lib/libLLVMipa.a",
- "$llvm_configuration/lib/libLLVMInterpreter.a",
- "$llvm_configuration/lib/libLLVMipo.a",
- "$llvm_configuration/lib/libLLVMJIT.a",
- "$llvm_configuration/lib/libLLVMLinker.a",
- "$llvm_configuration/lib/libLLVMMC.a",
- "$llvm_configuration/lib/libLLVMMCParser.a",
- "$llvm_configuration/lib/libLLVMMCDisassembler.a",
+ "$llvm_configuration/lib/libLLVMARMDisassembler.a",
+ "$llvm_configuration/lib/libLLVMARMInfo.a",
+ "$llvm_configuration/lib/libLLVMAsmParser.a",
+ "$llvm_configuration/lib/libLLVMAsmPrinter.a",
+ "$llvm_configuration/lib/libLLVMBitReader.a",
+ "$llvm_configuration/lib/libLLVMBitWriter.a",
+ "$llvm_configuration/lib/libLLVMCodeGen.a",
+ "$llvm_configuration/lib/libLLVMCore.a",
+ "$llvm_configuration/lib/libLLVMExecutionEngine.a",
+ "$llvm_configuration/lib/libLLVMInstCombine.a",
+ "$llvm_configuration/lib/libLLVMInstrumentation.a",
+ "$llvm_configuration/lib/libLLVMipa.a",
+ "$llvm_configuration/lib/libLLVMInterpreter.a",
+ "$llvm_configuration/lib/libLLVMipo.a",
+ "$llvm_configuration/lib/libLLVMJIT.a",
+ "$llvm_configuration/lib/libLLVMLinker.a",
+ "$llvm_configuration/lib/libLLVMMC.a",
+ "$llvm_configuration/lib/libLLVMMCParser.a",
+ "$llvm_configuration/lib/libLLVMMCDisassembler.a",
"$llvm_configuration/lib/libLLVMMCJIT.a",
"$llvm_configuration/lib/libLLVMObject.a",
"$llvm_configuration/lib/libLLVMRuntimeDyld.a",
- "$llvm_configuration/lib/libLLVMScalarOpts.a",
- "$llvm_configuration/lib/libLLVMSelectionDAG.a",
- "$llvm_configuration/lib/libLLVMSupport.a",
- "$llvm_configuration/lib/libLLVMTarget.a",
- "$llvm_configuration/lib/libLLVMTransformUtils.a",
- "$llvm_configuration/lib/libLLVMX86AsmParser.a",
- "$llvm_configuration/lib/libLLVMX86AsmPrinter.a",
- "$llvm_configuration/lib/libLLVMX86CodeGen.a",
+ "$llvm_configuration/lib/libLLVMScalarOpts.a",
+ "$llvm_configuration/lib/libLLVMSelectionDAG.a",
+ "$llvm_configuration/lib/libLLVMSupport.a",
+ "$llvm_configuration/lib/libLLVMTarget.a",
+ "$llvm_configuration/lib/libLLVMTransformUtils.a",
+ "$llvm_configuration/lib/libLLVMX86AsmParser.a",
+ "$llvm_configuration/lib/libLLVMX86AsmPrinter.a",
+ "$llvm_configuration/lib/libLLVMX86CodeGen.a",
"$llvm_configuration/lib/libLLVMX86Desc.a",
- "$llvm_configuration/lib/libLLVMX86Disassembler.a",
- "$llvm_configuration/lib/libLLVMX86Info.a",
+ "$llvm_configuration/lib/libLLVMX86Disassembler.a",
+ "$llvm_configuration/lib/libLLVMX86Info.a",
"$llvm_configuration/lib/libLLVMX86Utils.a",
);
@@ -111,20 +111,18 @@
else
{
print "Checking out llvm sources from revision $llvm_revision...\n";
- do_command ("cd '$SRCROOT' && svn co --quiet --revision $llvm_revision http://llvm.org/svn/llvm-project/llvm/trunk llvm", "checking out llvm from repository", 1);
+ do_command ("cd '$SRCROOT' && svn co --quiet --revision $llvm_revision http://llvm.org/svn/llvm-project/llvm/trunk llvm", "checking out llvm from repository", 1);
print "Checking out clang sources from revision $clang_revision...\n";
do_command ("cd '$llvm_srcroot/tools' && svn co --quiet --revision $clang_revision http://llvm.org/svn/llvm-project/cfe/trunk clang", "checking out clang from repository", 1);
print "Applying any local patches to LLVM/Clang...";
-
+
my @llvm_patches = bsd_glob("$ENV{SRCROOT}/scripts/llvm.*.diff");
-
foreach my $patch (@llvm_patches)
{
do_command ("cd '$llvm_srcroot' && patch -p0 < $patch");
}
my @clang_patches = bsd_glob("$ENV{SRCROOT}/scripts/clang.*.diff");
-
foreach my $patch (@clang_patches)
{
do_command ("cd '$llvm_srcroot/tools/clang' && patch -p0 < $patch");
@@ -134,7 +132,7 @@
# If our output file already exists then we need not generate it again.
if (-e $llvm_clang_outfile)
{
- exit 0;
+ exit 0;
}
@@ -144,249 +142,258 @@
sub parallel_guess
{
- my $cpus = `sysctl -n hw.availcpu`;
- chomp ($cpus);
- my $memsize = `sysctl -n hw.memsize`;
- chomp ($memsize);
- my $max_cpus_by_memory = int($memsize / (750 * 1024 * 1024));
- return min($max_cpus_by_memory, $cpus);
+ my $cpus = `sysctl -n hw.availcpu`;
+ chomp ($cpus);
+ my $memsize = `sysctl -n hw.memsize`;
+ chomp ($memsize);
+ my $max_cpus_by_memory = int($memsize / (750 * 1024 * 1024));
+ return min($max_cpus_by_memory, $cpus);
}
+
sub build_llvm
{
- #my $extra_svn_options = $debug ? "" : "--quiet";
- # Make the llvm build directory
+ #my $extra_svn_options = $debug ? "" : "--quiet";
+ # Make the llvm build directory
my $arch_idx = 0;
foreach my $arch (@archs)
{
my $llvm_dstroot_arch = "${llvm_dstroot}/${arch}";
- # if the arch destination root exists we have already built it
- my $do_configure = 0;
- my $do_make = 0;
- my $is_arm = $arch =~ /^arm/;
-
- my $llvm_dstroot_arch_archive = "$llvm_dstroot_arch/$llvm_clang_basename";
- print "LLVM architecture root for ${arch} exists at '$llvm_dstroot_arch'...";
- if (-e $llvm_dstroot_arch)
- {
- print "YES\n";
- $do_configure = !-e "$llvm_dstroot_arch/config.log";
-
- # dstroot for llvm build exists, make sure all .a files are built
- for my $llvm_lib (@archive_files)
- {
- if (!-e "$llvm_dstroot_arch/$llvm_lib")
- {
- print "missing archive: '$llvm_dstroot_arch/$llvm_lib'\n";
- $do_make = 1;
- }
- }
- if (!-e $llvm_dstroot_arch_archive)
- {
- $do_make = 1;
- }
- else
- {
- print "LLVM architecture archive for ${arch} is '$llvm_dstroot_arch_archive'\n";
- }
- }
- else
- {
- print "NO\n";
- do_command ("mkdir -p '$llvm_dstroot_arch'", "making llvm build directory '$llvm_dstroot_arch'", 1);
- $do_configure = 1;
- $do_make = 1;
+ # if the arch destination root exists we have already built it
+ my $do_configure = 0;
+ my $do_make = 0;
+ my $is_arm = $arch =~ /^arm/;
+
+ my $llvm_dstroot_arch_archive = "$llvm_dstroot_arch/$llvm_clang_basename";
+ print "LLVM architecture root for ${arch} exists at '$llvm_dstroot_arch'...";
+ if (-e $llvm_dstroot_arch)
+ {
+ print "YES\n";
+ $do_configure = !-e "$llvm_dstroot_arch/config.log";
- if ($is_arm)
- {
- my $llvm_dstroot_arch_bin = "${llvm_dstroot_arch}/bin";
+ # dstroot for llvm build exists, make sure all .a files are built
+ for my $llvm_lib (@archive_files)
+ {
+ if (!-e "$llvm_dstroot_arch/$llvm_lib")
+ {
+ print "missing archive: '$llvm_dstroot_arch/$llvm_lib'\n";
+ $do_make = 1;
+ }
+ }
+ if (!-e $llvm_dstroot_arch_archive)
+ {
+ $do_make = 1;
+ }
+ else
+ {
+ print "LLVM architecture archive for ${arch} is '$llvm_dstroot_arch_archive'\n";
+ }
+ }
+ else
+ {
+ print "NO\n";
+ do_command ("mkdir -p '$llvm_dstroot_arch'", "making llvm build directory '$llvm_dstroot_arch'", 1);
+ $do_configure = 1;
+ $do_make = 1;
- if (!-d $llvm_dstroot_arch_bin)
- {
- do_command ("mkdir -p '$llvm_dstroot_arch_bin'", "making llvm build arch bin directory '$llvm_dstroot_arch_bin'", 1);
- my @tools = ("ar", "nm", "ranlib", "strip", "lipo", "ld", "as");
- my $script_mode = 0755;
- my $prog;
- for $prog (@tools)
- {
- chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
- my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
- open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
- print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' \"\$\@\"\n";
- close (SCRIPT);
- chmod($script_mode, $script_prog_path);
- }
- # Tools that must have the "-arch" and "-sysroot" specified
- my @arch_sysroot_tools = ("clang", "clang++", "gcc", "g++");
- for $prog (@arch_sysroot_tools)
- {
- chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
- my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
- open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
- print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' -arch ${arch} -isysroot '$ENV{SDKROOT}' \"\$\@\"\n";
- close (SCRIPT);
- chmod($script_mode, $script_prog_path);
- }
- my $new_path = "$original_env_path:$llvm_dstroot_arch_bin";
- print "Setting new environment PATH = '$new_path'\n";
- $ENV{PATH} = $new_path;
- }
- }
- }
-
- if ($do_configure)
- {
- # Build llvm and clang
- print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n";
- my $lldb_configuration_options = "--enable-targets=x86_64,arm $llvm_config_href->{configure_options}";
+ if ($is_arm)
+ {
+ my $llvm_dstroot_arch_bin = "${llvm_dstroot_arch}/bin";
+ if (!-d $llvm_dstroot_arch_bin)
+ {
+ do_command ("mkdir -p '$llvm_dstroot_arch_bin'", "making llvm build arch bin directory '$llvm_dstroot_arch_bin'", 1);
+ my @tools = ("ar", "nm", "ranlib", "strip", "lipo", "ld", "as");
+ my $script_mode = 0755;
+ my $prog;
+ for $prog (@tools)
+ {
+ chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
+ symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}");
+ my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
+ open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
+ print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' \"\$\@\"\n";
+ close (SCRIPT);
+ chmod($script_mode, $script_prog_path);
+ }
+ # Tools that must have the "-arch" and "-sysroot" specified
+ my @arch_sysroot_tools = ("clang", "clang++", "gcc", "g++");
+ for $prog (@arch_sysroot_tools)
+ {
+ chomp(my $actual_prog_path = `xcrun -sdk '$ENV{SDKROOT}' -find ${prog}`);
+ symlink($actual_prog_path, "$llvm_dstroot_arch_bin/${prog}");
+ my $script_prog_path = "$llvm_dstroot_arch_bin/arm-apple-darwin${os_release}-${prog}";
+ open (SCRIPT, ">$script_prog_path") or die "Can't open $! for writing...\n";
+ print SCRIPT "#!/bin/sh\nexec '$actual_prog_path' -arch ${arch} -isysroot '$ENV{SDKROOT}' \"\$\@\"\n";
+ close (SCRIPT);
+ chmod($script_mode, $script_prog_path);
+ }
+ my $new_path = "$original_env_path:$llvm_dstroot_arch_bin";
+ print "Setting new environment PATH = '$new_path'\n";
+ $ENV{PATH} = $new_path;
+ }
+ }
+ }
+
+ if ($do_configure)
+ {
+ # Build llvm and clang
+ print "Configuring clang ($arch) in '$llvm_dstroot_arch'...\n";
+ my $lldb_configuration_options = "--enable-targets=x86_64,arm $llvm_config_href->{configure_options}";
if ($is_arm)
{
- $lldb_configuration_options .= " --host=arm-apple-darwin${os_release} --target=arm-apple-darwin${os_release} --build=i686-apple-darwin${os_release}";
+ $lldb_configuration_options .= " --host=arm-apple-darwin${os_release} --target=arm-apple-darwin${os_release} --build=i686-apple-darwin${os_release} --program-prefix=\"\"";
}
else
{
$lldb_configuration_options .= " --build=$arch-apple-darwin${os_release}";
}
- do_command ("cd '$llvm_dstroot_arch' && '$llvm_srcroot/configure' $lldb_configuration_options",
- "configuring llvm build", 1);
- }
-
- if ($do_make)
- {
- # Build llvm and clang
- my $num_cpus = parallel_guess();
- print "Building clang using $num_cpus cpus ($arch)...\n";
+ if ($is_arm)
+ {
+ # Unset "SDKROOT" for ARM builds
+ do_command ("cd '$llvm_dstroot_arch' && unset SDKROOT && '$llvm_srcroot/configure' $lldb_configuration_options",
+ "configuring llvm build", 1);
+ }
+ else
+ {
+ do_command ("cd '$llvm_dstroot_arch' && '$llvm_srcroot/configure' $lldb_configuration_options",
+ "configuring llvm build", 1);
+ }
+ }
+
+ if ($do_make)
+ {
+ # Build llvm and clang
+ my $num_cpus = parallel_guess();
+ print "Building clang using $num_cpus cpus ($arch)...\n";
my $extra_make_flags = '';
if ($is_arm)
{
- $extra_make_flags = "UNIVERSAL=1 UNIVERSAL_ARCH=${arch} UNIVERSAL_SDK_PATH='$ENV{SDKROOT}'";
+ $extra_make_flags = "UNIVERSAL=1 UNIVERSAL_ARCH=${arch} UNIVERSAL_SDK_PATH='$ENV{SDKROOT}' SDKROOT=";
}
- do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus clang-only VERBOSE=1 $llvm_config_href->{make_options} NO_RUNTIME_LIBS=1 PROJECT_NAME='llvm' $extra_make_flags", "making llvm and clang", 1);
- do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus tools-only VERBOSE=1 $llvm_config_href->{make_options} NO_RUNTIME_LIBS=1 PROJECT_NAME='llvm' $extra_make_flags EDIS_VERSION=1", "making libedis", 1);
- # Combine all .o files from a bunch of static libraries from llvm
- # and clang into a single .a file.
- create_single_llvm_arhive_for_arch ($llvm_dstroot_arch, 1);
- }
+ do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus clang-only VERBOSE=1 $llvm_config_href->{make_options} NO_RUNTIME_LIBS=1 PROJECT_NAME='llvm' $extra_make_flags", "making llvm and clang", 1);
+ do_command ("cd '$llvm_dstroot_arch' && make -j$num_cpus tools-only VERBOSE=1 $llvm_config_href->{make_options} NO_RUNTIME_LIBS=1 PROJECT_NAME='llvm' $extra_make_flags EDIS_VERSION=1", "making libedis", 1);
+ # Combine all .o files from a bunch of static libraries from llvm
+ # and clang into a single .a file.
+ create_single_llvm_archive_for_arch ($llvm_dstroot_arch, 1);
+ }
- ++$arch_idx;
- }
+ ++$arch_idx;
+ }
}
#----------------------------------------------------------------------
-# quote the path if needed and realpath it if the -r option was
+# quote the path if needed and realpath it if the -r option was
# specified
#----------------------------------------------------------------------
sub finalize_path
{
- my $path = shift;
- # Realpath all paths that don't start with "/"
- $path =~ /^[^\/]/ and $path = abs_path($path);
-
- # Quote the path if asked to, or if there are special shell characters
- # in the path name
- my $has_double_quotes = $path =~ /["]/;
- my $has_single_quotes = $path =~ /[']/;
- my $needs_quotes = $path =~ /[ \$\&\*'"]/;
- if ($needs_quotes)
- {
- # escape and double quotes in the path
- $has_double_quotes and $path =~ s/"/\\"/g;
- $path = "\"$path\"";
- }
- return $path;
+ my $path = shift;
+ # Realpath all paths that don't start with "/"
+ $path =~ /^[^\/]/ and $path = abs_path($path);
+
+ # Quote the path if asked to, or if there are special shell characters
+ # in the path name
+ my $has_double_quotes = $path =~ /["]/;
+ my $has_single_quotes = $path =~ /[']/;
+ my $needs_quotes = $path =~ /[ \$\&\*'"]/;
+ if ($needs_quotes)
+ {
+ # escape and double quotes in the path
+ $has_double_quotes and $path =~ s/"/\\"/g;
+ $path = "\"$path\"";
+ }
+ return $path;
}
sub do_command
{
- my $cmd = shift;
- my $description = @_ ? shift : "command";
- my $die_on_fail = @_ ? shift : undef;
- $debug and print "% $cmd\n";
- system ($cmd);
- if ($? == -1)
- {
+ my $cmd = shift;
+ my $description = @_ ? shift : "command";
+ my $die_on_fail = @_ ? shift : undef;
+ $debug and print "% $cmd\n";
+ system ($cmd);
+ if ($? == -1)
+ {
$debug and printf ("error: %s failed to execute: $!\n", $description);
- $die_on_fail and $? and exit(1);
- return $?;
+ $die_on_fail and $? and exit(1);
+ return $?;
}
- elsif ($? & 127)
- {
- $debug and printf("error: %s child died with signal %d, %s coredump\n",
- $description,
- ($? & 127),
- ($? & 128) ? 'with' : 'without');
- $die_on_fail and $? and exit(1);
- return $?;
+ elsif ($? & 127)
+ {
+ $debug and printf("error: %s child died with signal %d, %s coredump\n",
+ $description,
+ ($? & 127),
+ ($? & 128) ? 'with' : 'without');
+ $die_on_fail and $? and exit(1);
+ return $?;
}
- else
- {
- my $exit = $? >> 8;
- if ($exit)
- {
- $debug and printf("error: %s child exited with value %d\n", $description, $exit);
- $die_on_fail and exit(1);
- }
- return $exit;
+ else
+ {
+ my $exit = $? >> 8;
+ if ($exit)
+ {
+ $debug and printf("error: %s child exited with value %d\n", $description, $exit);
+ $die_on_fail and exit(1);
+ }
+ return $exit;
}
}
-sub create_single_llvm_arhive_for_arch
+sub create_single_llvm_archive_for_arch
{
- my $arch_dstroot = shift;
+ my $arch_dstroot = shift;
my $split_into_objects = shift;
- my @object_dirs;
- my $object_dir;
- my $tmp_dir = $arch_dstroot;
- my $arch_output_file = "$arch_dstroot/$llvm_clang_basename";
+ my @object_dirs;
+ my $object_dir;
+ my $tmp_dir = $arch_dstroot;
+ my $arch_output_file = "$arch_dstroot/$llvm_clang_basename";
-e $arch_output_file and return;
- my $files = "$arch_dstroot/files.txt";
- open (FILES, ">$files") or die "Can't open $! for writing...\n";
+ my $files = "$arch_dstroot/files.txt";
+ open (FILES, ">$files") or die "Can't open $! for writing...\n";
- for my $path (@archive_files)
- {
- my $archive_fullpath = finalize_path ("$arch_dstroot/$path");
- if (-e $archive_fullpath)
- {
+ for my $path (@archive_files)
+ {
+ my $archive_fullpath = finalize_path ("$arch_dstroot/$path");
+ if (-e $archive_fullpath)
+ {
if ($split_into_objects)
{
my ($archive_file, $archive_dir, $archive_ext) = fileparse($archive_fullpath, ('.a'));
-
$object_dir = "$tmp_dir/$archive_file";
push @object_dirs, $object_dir;
-
+
do_command ("cd '$tmp_dir'; mkdir '$archive_file'; cd '$archive_file'; ar -x $archive_fullpath");
-
+
my @objects = bsd_glob("$object_dir/*.o");
-
foreach my $object (@objects)
{
my ($o_file, $o_dir) = fileparse($object);
my $new_object = "$object_dir/${archive_file}-$o_file";
print FILES "$new_object\n";
do_command ("mv '$object' '$new_object'");
- }
+ }
}
else
{
# just add the .a files into the file list
print FILES "$archive_fullpath\n";
}
- }
+ }
else
{
print "warning: archive doesn't exist: '$archive_fullpath'\n";
}
- }
- close (FILES);
+ }
+ close (FILES);
do_command ("libtool -static -o '$arch_output_file' -filelist '$files'");
do_command ("ranlib '$arch_output_file'");
- foreach $object_dir (@object_dirs)
- {
- do_command ("rm -rf '$object_dir'");
- }
- do_command ("rm -rf '$files'");
+ foreach $object_dir (@object_dirs)
+ {
+ do_command ("rm -rf '$object_dir'");
+ }
+ do_command ("rm -rf '$files'");
}
build_llvm();
Index: aze/lldb/scripts/build-swig-wrapper-classes.sh
===================================================================
--- aze.orig/lldb/scripts/build-swig-wrapper-classes.sh 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/build-swig-wrapper-classes.sh 2013-03-03 09:35:50.111457353 +0100
@@ -83,8 +83,8 @@
# Next look for swig
#
-SWIG=
-if [ -f /usr/bin/swig ]
+SWIG=`which swig`
+if [ ! -x "$SWIG" -a -f /usr/bin/swig ]
then
SWIG=/usr/bin/swig
else
Index: aze/lldb/scripts/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/scripts/CMakeLists.txt 2013-03-03 09:35:50.111457353 +0100
@@ -0,0 +1,15 @@
+set(LLVM_NO_RTTI 1)
+
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp
+ DEPENDS ${LLDB_SOURCE_DIR}/scripts/lldb.swig
+ # swig was directly invoked on Windows (where the Python API is not being generated) but on other platforms, we need to run the *swig-wrapper-classes.sh shell-scripts.
+ #COMMAND swig -c++ -shadow -python -I${LLDB_SOURCE_DIR}/include -I./. -outdir ${LLDB_SOURCE_DIR}/scripts/Python -o ${LLDB_SOURCE_DIR}/source/LLDBWrapPython.cpp ${LLDB_SOURCE_DIR}/scripts/lldb.swig
+ COMMAND SRCROOT=${LLDB_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/build-swig-wrapper-classes.sh ${LLDB_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} -debug -m
+ COMMAND SRCROOT=${LLDB_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/finish-swig-wrapper-classes.sh ${LLDB_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} -debug -m
+ COMMENT "Building lldb python wrapper")
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp PROPERTIES GENERATED 1)
+
+ADD_CUSTOM_TARGET(swig_wrapper ALL echo
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp
+ )
Index: aze/lldb/scripts/disasm-gdb-remote.pl
===================================================================
--- aze.orig/lldb/scripts/disasm-gdb-remote.pl 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/disasm-gdb-remote.pl 2013-03-03 09:35:50.115457353 +0100
@@ -771,22 +771,24 @@
my $reg_name = undef;
my $byte_size = 0;
+ my $pseudo = 0;
foreach (@name_and_values)
{
my ($name, $value) = split /:/;
if ($name eq "name") { $reg_name = $value; }
- elsif ($name eq "bitsize") { $byte_size = $value / 8; last; }
+ elsif ($name eq "bitsize") { $byte_size = $value / 8; }
+ elsif ($name eq "container-regs") { $pseudo = 1; }
}
if (defined $reg_name and $byte_size > 0)
{
- if ($byte_size == 4) {push @$registers_aref, { name => $reg_name, info => $reg32_href };}
- elsif ($byte_size == 8) {push @$registers_aref, { name => $reg_name, info => $reg64_href };}
- elsif ($byte_size == 1) {push @$registers_aref, { name => $reg_name, info => $reg8_href };}
- elsif ($byte_size == 2) {push @$registers_aref, { name => $reg_name, info => $reg16_href };}
- elsif ($byte_size == 10) {push @$registers_aref, { name => $reg_name, info => $reg80_href };}
- elsif ($byte_size == 12) {push @$registers_aref, { name => $reg_name, info => $float96_href };}
- elsif ($byte_size == 16) {push @$registers_aref, { name => $reg_name, info => $reg128_href };}
- elsif ($byte_size == 32) {push @$registers_aref, { name => $reg_name, info => $reg256_href };}
+ if ($byte_size == 4) {push @$registers_aref, { name => $reg_name, info => $reg32_href , pseudo => $pseudo };}
+ elsif ($byte_size == 8) {push @$registers_aref, { name => $reg_name, info => $reg64_href , pseudo => $pseudo };}
+ elsif ($byte_size == 1) {push @$registers_aref, { name => $reg_name, info => $reg8_href , pseudo => $pseudo };}
+ elsif ($byte_size == 2) {push @$registers_aref, { name => $reg_name, info => $reg16_href , pseudo => $pseudo };}
+ elsif ($byte_size == 10) {push @$registers_aref, { name => $reg_name, info => $reg80_href , pseudo => $pseudo };}
+ elsif ($byte_size == 12) {push @$registers_aref, { name => $reg_name, info => $float96_href , pseudo => $pseudo };}
+ elsif ($byte_size == 16) {push @$registers_aref, { name => $reg_name, info => $reg128_href , pseudo => $pseudo };}
+ elsif ($byte_size == 32) {push @$registers_aref, { name => $reg_name, info => $reg256_href , pseudo => $pseudo };}
}
}
elsif ($gen_query_rsp_len == 3 and index($gen_query_rsp, 'E') == 0)
@@ -883,12 +885,15 @@
foreach my $reg_href (@$registers_aref)
{
last if ($_[0] eq '#');
- my $reg_info_href = $reg_href->{info};
- my $reg_name = $reg_href->{name};
- my $reg_extract = $reg_info_href->{extract};
- my $reg_format = $reg_info_href->{format};
- my $reg_val = &$reg_extract(\@_);
- printf("\t%*s = $reg_format\n", $max_register_name_len, $reg_name, $reg_val);
+ if ($reg_href->{pseudo} == 0)
+ {
+ my $reg_info_href = $reg_href->{info};
+ my $reg_name = $reg_href->{name};
+ my $reg_extract = $reg_info_href->{extract};
+ my $reg_format = $reg_info_href->{format};
+ my $reg_val = &$reg_extract(\@_);
+ printf("\t%*s = $reg_format\n", $max_register_name_len, $reg_name, $reg_val);
+ }
}
}
@@ -901,12 +906,15 @@
foreach my $reg_href (@$registers_aref)
{
last if ($_[0] eq '#');
- my $reg_info_href = $reg_href->{info};
- my $reg_name = $reg_href->{name};
- my $reg_extract = $reg_info_href->{extract};
- my $reg_format = $reg_info_href->{format};
- my $reg_val = &$reg_extract(\@_);
- printf("\t%*s = $reg_format\n", $max_register_name_len, $reg_name, $reg_val);
+ if ($reg_href->{pseudo} == 0)
+ {
+ my $reg_info_href = $reg_href->{info};
+ my $reg_name = $reg_href->{name};
+ my $reg_extract = $reg_info_href->{extract};
+ my $reg_format = $reg_info_href->{format};
+ my $reg_val = &$reg_extract(\@_);
+ printf("\t%*s = $reg_format\n", $max_register_name_len, $reg_name, $reg_val);
+ }
}
}
}
@@ -1237,6 +1245,10 @@
{
dump_extended_continue_cmd(splice(@_,5));
}
+ elsif (join('', @_[0..7]) eq 'vAttach;')
+ {
+ dump_attach_command (splice(@_,8));
+ }
elsif (join('', @_[0..11]) eq 'vAttachWait;')
{
dump_attach_wait_command (splice(@_,12));
@@ -1270,6 +1282,15 @@
}
#----------------------------------------------------------------------
+# 'vAttach' command
+#----------------------------------------------------------------------
+sub dump_attach_command
+{
+ printf("attach ( pid = %i )", get_hex(\@_));
+ $extended_rsp_callback = \&dump_stop_reply_packet;
+}
+
+#----------------------------------------------------------------------
# 'vCont' command
#----------------------------------------------------------------------
sub dump_extended_continue_cmd
Index: aze/lldb/scripts/Python/finish-swig-Python-LLDB.sh
===================================================================
--- aze.orig/lldb/scripts/Python/finish-swig-Python-LLDB.sh 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/finish-swig-Python-LLDB.sh 2013-03-03 09:35:50.115457353 +0100
@@ -192,14 +192,14 @@
package_init_file="${package_dir}/__init__.py"
if [ ! -f "${package_init_file}" ]
then
- echo -n "__all__ = [" > "${package_init_file}"
+ printf "__all__ = [" > "${package_init_file}"
python_module_separator=""
for package_file in $package_files
do
if [ -f "${package_file}" ]
then
package_file_basename=$(basename "${package_file}")
- echo -n "${python_module_separator}\"${package_file_basename%.*}\"" >> "${package_init_file}"
+ printf "${python_module_separator}\"${package_file_basename%.*}\"" >> "${package_init_file}"
python_module_separator=", "
fi
done
Index: aze/lldb/scripts/Python/interface/SBBlock.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBBlock.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBBlock.i 2013-03-03 09:35:50.115457353 +0100
@@ -106,7 +106,7 @@
%pythoncode %{
def get_range_at_index(self, idx):
if idx < self.GetNumRanges():
- return [self.sbblock.GetRangeStartAddress(key), self.sbblock.GetRangeEndAddress(key)]
+ return [self.GetRangeStartAddress(idx), self.GetRangeEndAddress(idx)]
return []
class ranges_access(object):
@@ -137,11 +137,11 @@
def get_ranges_array(self):
'''An accessor function that returns an array object that contains all ranges in this block object.'''
- if not hasattr(self, 'ranges'):
- self.ranges = []
+ if not hasattr(self, 'ranges_array'):
+ self.ranges_array = []
for idx in range(self.num_ranges):
- self.ranges.append (self.get_range_at_index (idx))
- return self.ranges
+ self.ranges_array.append ([self.GetRangeStartAddress(idx), self.GetRangeEndAddress(idx)])
+ return self.ranges_array
def get_call_site(self):
return declaration(self.GetInlinedCallSiteFile(), self.GetInlinedCallSiteLine(), self.GetInlinedCallSiteColumn())
Index: aze/lldb/scripts/Python/interface/SBData.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBData.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBData.i 2013-03-03 09:35:50.115457353 +0100
@@ -42,50 +42,50 @@
SetByteOrder (lldb::ByteOrder endian);
float
- GetFloat (lldb::SBError& error, uint32_t offset);
+ GetFloat (lldb::SBError& error, lldb::offset_t offset);
double
- GetDouble (lldb::SBError& error, uint32_t offset);
+ GetDouble (lldb::SBError& error, lldb::offset_t offset);
long double
- GetLongDouble (lldb::SBError& error, uint32_t offset);
+ GetLongDouble (lldb::SBError& error, lldb::offset_t offset);
lldb::addr_t
- GetAddress (lldb::SBError& error, uint32_t offset);
+ GetAddress (lldb::SBError& error, lldb::offset_t offset);
uint8_t
- GetUnsignedInt8 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset);
uint16_t
- GetUnsignedInt16 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset);
uint32_t
- GetUnsignedInt32 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset);
uint64_t
- GetUnsignedInt64 (lldb::SBError& error, uint32_t offset);
+ GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset);
int8_t
- GetSignedInt8 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset);
int16_t
- GetSignedInt16 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset);
int32_t
- GetSignedInt32 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset);
int64_t
- GetSignedInt64 (lldb::SBError& error, uint32_t offset);
+ GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset);
const char*
- GetString (lldb::SBError& error, uint32_t offset);
+ GetString (lldb::SBError& error, lldb::offset_t offset);
bool
GetDescription (lldb::SBStream &description, lldb::addr_t base_addr);
size_t
ReadRawData (lldb::SBError& error,
- uint32_t offset,
+ lldb::offset_t offset,
void *buf,
size_t size);
Index: aze/lldb/scripts/Python/interface/SBDebugger.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBDebugger.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBDebugger.i 2013-03-03 09:35:50.115457353 +0100
@@ -87,7 +87,7 @@
#print value
print '%s (number of children = %d):' % (value.GetName(), value.GetNumChildren())
for child in value:
- print 'Name: ', child.GetName(), ' Value: ', child.GetValue(frame)
+ print 'Name: ', child.GetName(), ' Value: ', child.GetValue()
print 'Hit the breakpoint at main, enter to continue and wait for program to exit or \'Ctrl-D\'/\'quit\' to terminate the program'
next = sys.stdin.readline()
Index: aze/lldb/scripts/Python/interface/SBExpressionOptions.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBExpressionOptions.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBExpressionOptions.i 2013-03-03 09:35:50.115457353 +0100
@@ -39,7 +39,15 @@
%feature("docstring", "Sets whether to unwind the expression stack on error.") SetUnwindOnError;
void
- SetUnwindOnError (bool unwind = false);
+ SetUnwindOnError (bool unwind = true);
+
+ bool
+ GetIgnoreBreakpoints () const;
+
+ %feature("docstring", "Sets whether to ignore breakpoint hits while running expressions.") SetUnwindOnError;
+
+ void
+ SetIgnoreBreakpoints (bool ignore = true);
lldb::DynamicValueType
GetFetchDynamicValue () const;
Index: aze/lldb/scripts/Python/interface/SBFunction.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBFunction.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBFunction.i 2013-03-03 09:35:50.115457353 +0100
@@ -65,6 +65,9 @@
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor);
+
lldb::SBAddress
GetStartAddress ();
Index: aze/lldb/scripts/Python/interface/SBModule.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBModule.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBModule.i 2013-03-03 09:35:50.115457353 +0100
@@ -177,6 +177,15 @@
lldb::SBSymbol
GetSymbolAtIndex (size_t idx);
+ lldb::SBSymbol
+ FindSymbol (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
+ lldb::SBSymbolContextList
+ FindSymbols (const char *name,
+ lldb::SymbolType type = eSymbolTypeAny);
+
+
size_t
GetNumSections ();
@@ -213,6 +222,8 @@
lldb::SBTypeList
FindTypes (const char* type);
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
%feature("docstring", "
//------------------------------------------------------------------
@@ -237,6 +248,24 @@
const char *name,
uint32_t max_matches);
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Find the first global (or static) variable by name.
+ ///
+ /// @param[in] target
+ /// A valid SBTarget instance representing the debuggee.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @return
+ /// An SBValue that gets filled in with the found variable (if any).
+ //------------------------------------------------------------------
+ ") FindFirstGlobalVariable;
+ lldb::SBValue
+ FindFirstGlobalVariable (lldb::SBTarget &target, const char *name);
+
lldb::ByteOrder
GetByteOrder ();
@@ -269,9 +298,10 @@
return self.sbmodule.GetSymbolAtIndex(key)
elif type(key) is str:
matches = []
- for idx in range(count):
- symbol = self.sbmodule.GetSymbolAtIndex(idx)
- if symbol.name == key or symbol.mangled == key:
+ sc_list = self.sbmodule.FindSymbols(key)
+ for sc in sc_list:
+ symbol = sc.symbol
+ if symbol:
matches.append(symbol)
return matches
elif isinstance(key, self.re_compile_type):
@@ -348,11 +378,11 @@
def get_sections_array(self):
'''An accessor function that returns an array object that contains all sections in this module object.'''
- if not hasattr(self, 'sections'):
- self.sections = []
+ if not hasattr(self, 'sections_array'):
+ self.sections_array = []
for idx in range(self.num_sections):
- self.sections.append(self.GetSectionAtIndex(idx))
- return self.sections
+ self.sections_array.append(self.GetSectionAtIndex(idx))
+ return self.sections_array
__swig_getmethods__["symbols"] = get_symbols_array
if _newclass: symbols = property(get_symbols_array, None, doc='''A read only property that returns a list() of lldb.SBSymbol objects contained in this module.''')
Index: aze/lldb/scripts/Python/interface/SBProcess.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBProcess.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBProcess.i 2013-03-03 09:35:50.115457353 +0100
@@ -43,7 +43,8 @@
eBroadcastBitStateChanged = (1 << 0),
eBroadcastBitInterrupt = (1 << 1),
eBroadcastBitSTDOUT = (1 << 2),
- eBroadcastBitSTDERR = (1 << 3)
+ eBroadcastBitSTDERR = (1 << 3),
+ eBroadcastBitProfileData = (1 << 4)
};
SBProcess ();
@@ -96,6 +97,9 @@
size_t
GetSTDERR (char *dst, size_t dst_len) const;
+ size_t
+ GetAsyncProfileData(char *dst, size_t dst_len) const;
+
void
ReportEventState (const lldb::SBEvent &event, FILE *out) const;
@@ -160,6 +164,12 @@
lldb::SBThread
GetSelectedThread () const;
+ %feature("autodoc", "
+ Lazily create a thread on demand through the current OperatingSystem plug-in, if the current OperatingSystem plug-in supports it.
+ ") CreateOSPluginThread;
+ lldb::SBThread
+ CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context);
+
bool
SetSelectedThread (const lldb::SBThread &thread);
@@ -182,8 +192,17 @@
const char *
GetExitDescription ();
+ %feature("autodoc", "
+ Returns the process ID of the process.
+ ") GetProcessID;
lldb::pid_t
GetProcessID ();
+
+ %feature("autodoc", "
+ Returns an integer ID that is guaranteed to be unique across all process instances. This is not the process ID, just a unique integer for comparison and caching purposes.
+ ") GetUniqueID;
+ uint32_t
+ GetUniqueID();
uint32_t
GetAddressByteSize() const;
@@ -212,6 +231,16 @@
lldb::SBError
Signal (int signal);
+ %feature("docstring", "
+ Returns a stop id that will increase every time the process executes. If
+ include_expression_stops is true, then stops caused by expression evaluation
+ will cause the returned value to increase, otherwise the counter returned will
+ only increase when execution is continued explicitly by the user. Note, the value
+ will always increase, but may increase by more than one per stop.
+ ") GetStopID;
+ uint32_t
+ GetStopID(bool include_expression_stops = false);
+
void
SendAsyncInterrupt();
@@ -299,6 +328,12 @@
static bool
GetRestartedFromEvent (const lldb::SBEvent &event);
+ static size_t
+ GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event);
+
+ static const char *
+ GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx);
+
static lldb::SBProcess
GetProcessFromEvent (const lldb::SBEvent &event);
Index: aze/lldb/scripts/Python/interface/SBSymbol.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBSymbol.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBSymbol.i 2013-03-03 09:35:50.115457353 +0100
@@ -38,6 +38,9 @@
lldb::SBInstructionList
GetInstructions (lldb::SBTarget target);
+ lldb::SBInstructionList
+ GetInstructions (lldb::SBTarget target, const char *flavor_string);
+
SBAddress
GetStartAddress ();
Index: aze/lldb/scripts/Python/interface/SBTarget.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBTarget.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBTarget.i 2013-03-03 09:35:50.115457353 +0100
@@ -238,7 +238,8 @@
{
eBroadcastBitBreakpointChanged = (1 << 0),
eBroadcastBitModulesLoaded = (1 << 1),
- eBroadcastBitModulesUnloaded = (1 << 2)
+ eBroadcastBitModulesUnloaded = (1 << 2),
+ eBroadcastBitWatchpointChanged = (1 << 3)
};
//------------------------------------------------------------------
@@ -560,6 +561,9 @@
lldb::SBTypeList
FindTypes (const char* type);
+ lldb::SBType
+ GetBasicType(lldb::BasicType type);
+
lldb::SBSourceManager
GetSourceManager ();
@@ -582,6 +586,21 @@
FindGlobalVariables (const char *name,
uint32_t max_matches);
+ %feature("docstring", "
+ //------------------------------------------------------------------
+ /// Find the first global (or static) variable by name.
+ ///
+ /// @param[in] name
+ /// The name of the global or static variable we are looking
+ /// for.
+ ///
+ /// @return
+ /// An SBValue that gets filled in with the found variable (if any).
+ //------------------------------------------------------------------
+ ") FindFirstGlobalVariable;
+ lldb::SBValue
+ FindFirstGlobalVariable (const char* name);
+
void
Clear ();
@@ -685,11 +704,25 @@
ReadInstructions (lldb::SBAddress base_addr, uint32_t count);
lldb::SBInstructionList
+ ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string);
+
+ lldb::SBInstructionList
GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size);
+ lldb::SBInstructionList
+ GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size);
+
+ lldb::SBSymbolContextList
+ FindSymbols (const char *name, lldb::SymbolType type = eSymbolTypeAny);
+
bool
GetDescription (lldb::SBStream &description, lldb::DescriptionLevel description_level);
+ lldb::addr_t
+ GetStackRedZoneSize();
+
+ lldb::SBValue
+ EvaluateExpression (const char *expr, const lldb::SBExpressionOptions &options);
%pythoncode %{
class modules_access(object):
'''A helper object that will lazily hand out lldb.SBModule objects for a target when supplied an index, or by full or partial path.'''
Index: aze/lldb/scripts/Python/interface/SBThread.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBThread.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBThread.i 2013-03-03 09:35:50.115457353 +0100
@@ -88,6 +88,7 @@
/// eStopReasonWatchpoint 1 watchpoint id
/// eStopReasonSignal 1 unix signal number
/// eStopReasonException N exception data
+ /// eStopReasonExec 0
/// eStopReasonPlanComplete 0
//--------------------------------------------------------------------------
") GetStopReasonDataAtIndex;
@@ -123,6 +124,9 @@
StepInto (lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
void
+ StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping);
+
+ void
StepOut ();
void
Index: aze/lldb/scripts/Python/interface/SBType.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBType.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBType.i 2013-03-03 09:35:50.115457353 +0100
@@ -180,6 +180,9 @@
lldb::SBType
GetUnqualifiedType();
+ lldb::SBType
+ GetCanonicalType();
+
lldb::BasicType
GetBasicType();
Index: aze/lldb/scripts/Python/interface/SBWatchpoint.i
===================================================================
--- aze.orig/lldb/scripts/Python/interface/SBWatchpoint.i 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/interface/SBWatchpoint.i 2013-03-03 09:35:50.115457353 +0100
@@ -84,6 +84,16 @@
bool
GetDescription (lldb::SBStream &description, DescriptionLevel level);
+
+ static bool
+ EventIsWatchpointEvent (const lldb::SBEvent &event);
+
+ static lldb::WatchpointEventType
+ GetWatchpointEventTypeFromEvent (const lldb::SBEvent& event);
+
+ static lldb::SBWatchpoint
+ GetWatchpointFromEvent (const lldb::SBEvent& event);
+
};
} // namespace lldb
Index: aze/lldb/scripts/Python/modify-python-lldb.py
===================================================================
--- aze.orig/lldb/scripts/Python/modify-python-lldb.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/modify-python-lldb.py 2013-03-03 09:35:50.115457353 +0100
@@ -433,5 +433,11 @@
with open(output_name, 'w') as f_out:
f_out.write(new_content.getvalue())
- f_out.write("debugger_unique_id = 0\n")
- f_out.write("SBDebugger.Initialize()\n")
+ f_out.write('''debugger_unique_id = 0
+SBDebugger.Initialize()
+debugger = None
+target = SBTarget()
+process = SBProcess()
+thread = SBThread()
+frame = SBFrame()''')
+
Index: aze/lldb/scripts/Python/python-wrapper.swig
===================================================================
--- aze.orig/lldb/scripts/Python/python-wrapper.swig 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/scripts/Python/python-wrapper.swig 2013-03-03 09:35:50.119457354 +0100
@@ -267,6 +267,8 @@
{
lldb::SBValue sb_value (valobj_sp);
+ retval.clear();
+
PyObject *ValObj_PyObj = SWIG_NewPointerObj((void *) &sb_value, SWIGTYPE_p_lldb__SBValue, 0);
if (ValObj_PyObj == NULL)
@@ -323,14 +325,14 @@
SWIGEXPORT void*
LLDBSwigPythonCreateSyntheticProvider
(
- const std::string python_class_name,
+ const char *python_class_name,
const char *session_dictionary_name,
const lldb::ValueObjectSP& valobj_sp
)
{
PyObject* retval = NULL;
- if (python_class_name.empty() || !session_dictionary_name)
+ if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
Py_RETURN_NONE;
// I do not want the SBValue to be deallocated when going out of scope because python
@@ -343,7 +345,7 @@
if (ValObj_PyObj == NULL)
Py_RETURN_NONE;
- const char* python_function_name = python_class_name.c_str();
+ const char* python_function_name = python_class_name;
PyObject *session_dict, *pfunc;
PyObject *pvalue;
@@ -778,14 +780,14 @@
SWIGEXPORT void*
LLDBSWIGPythonCreateOSPlugin
(
- const std::string python_class_name,
+ const char *python_class_name,
const char *session_dictionary_name,
const lldb::ProcessSP& process_sp
)
{
PyObject* retval = NULL;
- if (python_class_name.empty() || !session_dictionary_name)
+ if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
Py_RETURN_NONE;
// I do not want the SBValue to be deallocated when going out of scope because python
@@ -797,7 +799,7 @@
if (SBProc_PyObj == NULL)
Py_RETURN_NONE;
- const char* python_function_name = python_class_name.c_str();
+ const char* python_function_name = python_class_name;
PyObject *session_dict, *pfunc;
PyObject *pvalue;
@@ -875,7 +877,7 @@
SWIGEXPORT bool
LLDBSwigPythonCallModuleInit
(
- const std::string python_module_name,
+ const char *python_module_name,
const char *session_dictionary_name,
lldb::DebuggerSP& debugger
)
@@ -890,7 +892,7 @@
if (DebuggerObj_PyObj == NULL)
return retval;
- if (!(python_module_name.length()) || !session_dictionary_name)
+ if (python_module_name == NULL || python_module_name[0] == '\0' || !session_dictionary_name)
return retval;
PyObject *session_dict, *pfunc;
@@ -898,7 +900,8 @@
session_dict = FindSessionDictionary (session_dictionary_name);
- std::string python_function_name_string = python_module_name + (".__lldb_init_module");
+ std::string python_function_name_string = python_module_name;
+ python_function_name_string += ".__lldb_init_module";
const char* python_function_name = python_function_name_string.c_str();
if (session_dict != NULL)
@@ -964,6 +967,10 @@
#include "lldb/API/SBInputReader.h"
#include "lldb/API/SBDebugger.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
size_t
LLDBSwigPythonCallSBInputReaderCallback(void *baton,
lldb::SBInputReader *reader,
@@ -972,6 +979,10 @@
size_t bytes_len);
void LLDBSwigPythonCallPythonLogOutputCallback(const char *str, void *baton);
+
+#ifdef __cplusplus
+}
+#endif
%}
%wrapper %{
Index: aze/lldb/source/API/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/API/CMakeLists.txt 2013-03-03 09:35:50.119457354 +0100
@@ -0,0 +1,50 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbAPI
+ SBAddress.cpp
+ SBBlock.cpp
+ SBBreakpoint.cpp
+ SBBreakpointLocation.cpp
+ SBBroadcaster.cpp
+ SBCommandInterpreter.cpp
+ SBCommandReturnObject.cpp
+ SBCommunication.cpp
+ SBCompileUnit.cpp
+ SBData.cpp
+ SBDebugger.cpp
+ SBDeclaration.cpp
+ SBError.cpp
+ SBEvent.cpp
+ SBExpressionOptions.cpp
+ SBFileSpec.cpp
+ SBFileSpecList.cpp
+ SBFrame.cpp
+ SBFunction.cpp
+ SBHostOS.cpp
+ SBInputReader.cpp
+ SBInstruction.cpp
+ SBInstructionList.cpp
+ SBLineEntry.cpp
+ SBListener.cpp
+ SBModule.cpp
+ SBProcess.cpp
+ SBSection.cpp
+ SBSourceManager.cpp
+ SBStream.cpp
+ SBStringList.cpp
+ SBSymbol.cpp
+ SBSymbolContext.cpp
+ SBSymbolContextList.cpp
+ SBTarget.cpp
+ SBThread.cpp
+ SBType.cpp
+ SBTypeCategory.cpp
+ SBTypeFilter.cpp
+ SBTypeFormat.cpp
+ SBTypeNameSpecifier.cpp
+ SBTypeSummary.cpp
+ SBTypeSynthetic.cpp
+ SBValue.cpp
+ SBValueList.cpp
+ SBWatchpoint.cpp
+ )
Index: aze/lldb/source/API/SBAddress.cpp
===================================================================
--- aze.orig/lldb/source/API/SBAddress.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBAddress.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -133,7 +133,7 @@
if (addr == LLDB_INVALID_ADDRESS)
log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", target_sp.get());
else
- log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%llx", target_sp.get(), addr);
+ log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, target_sp.get(), addr);
}
return addr;
Index: aze/lldb/source/API/SBBlock.cpp
===================================================================
--- aze.orig/lldb/source/API/SBBlock.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBBlock.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -183,7 +183,7 @@
if (m_opaque_ptr)
{
lldb::user_id_t id = m_opaque_ptr->GetID();
- strm.Printf ("Block: {id: %llu} ", id);
+ strm.Printf ("Block: {id: %" PRIu64 "} ", id);
if (IsInlined())
{
strm.Printf (" (inlined, '%s') ", GetInlinedName());
Index: aze/lldb/source/API/SBBreakpoint.cpp
===================================================================
--- aze.orig/lldb/source/API/SBBreakpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBBreakpoint.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -353,7 +353,7 @@
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4llx)", m_opaque_sp.get(), tid);
+ log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", m_opaque_sp.get(), tid);
}
@@ -369,7 +369,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4llx", m_opaque_sp.get(), tid);
+ log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, m_opaque_sp.get(), tid);
return tid;
}
@@ -479,7 +479,7 @@
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %llu", m_opaque_sp.get(), (uint64_t)num_resolved);
+ log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_resolved);
return num_resolved;
}
@@ -494,7 +494,7 @@
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %llu", m_opaque_sp.get(), (uint64_t)num_locs);
+ log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_locs);
return num_locs;
}
@@ -508,7 +508,7 @@
m_opaque_sp->GetResolverDescription (s.get());
m_opaque_sp->GetFilterDescription (s.get());
const size_t num_locations = m_opaque_sp->GetNumLocations ();
- s.Printf(", locations = %llu", (uint64_t)num_locations);
+ s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
return true;
}
s.Printf ("No value");
Index: aze/lldb/source/API/SBCommandInterpreter.cpp
===================================================================
--- aze.orig/lldb/source/API/SBCommandInterpreter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBCommandInterpreter.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/lldb-types.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Core/Listener.h"
@@ -117,10 +119,6 @@
result.Clear();
if (command_line && m_opaque_ptr)
{
- TargetSP target_sp(m_opaque_ptr->GetDebugger().GetSelectedTarget());
- Mutex::Locker api_locker;
- if (target_sp)
- api_locker.Lock(target_sp->GetAPIMutex());
m_opaque_ptr->HandleCommand (command_line, add_to_history ? eLazyBoolYes : eLazyBoolNo, result.ref());
}
else
@@ -166,7 +164,7 @@
return 0;
if (log)
- log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %lld, last char at: %lld, match_start_point: %d, max_return_elements: %d)",
+ log->Printf ("SBCommandInterpreter(%p)::HandleCompletion (current_line=\"%s\", cursor at: %" PRId64 ", last char at: %" PRId64 ", match_start_point: %d, max_return_elements: %d)",
m_opaque_ptr, current_line, (uint64_t) (cursor - current_line), (uint64_t) (last_char - current_line), match_start_point, max_return_elements);
if (m_opaque_ptr)
Index: aze/lldb/source/API/SBCommandReturnObject.cpp
===================================================================
--- aze.orig/lldb/source/API/SBCommandReturnObject.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBCommandReturnObject.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -281,7 +281,17 @@
{
if (m_opaque_ap.get())
{
- m_opaque_ap->AppendMessage(string, len);
+ if (len == 0)
+ {
+ return;
+ }
+ else if (len > 0)
+ {
+ std::string buffer(string, len);
+ m_opaque_ap->AppendMessage(buffer.c_str());
+ }
+ else
+ m_opaque_ap->AppendMessage(string);
}
}
Index: aze/lldb/source/API/SBCommunication.cpp
===================================================================
--- aze.orig/lldb/source/API/SBCommunication.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBCommunication.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -139,7 +139,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%llu, timeout_usec=%u, &status)...",
+ log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status)...",
m_opaque,
dst,
(uint64_t)dst_len,
@@ -151,7 +151,7 @@
status = eConnectionStatusNoConnection;
if (log)
- log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%llu, timeout_usec=%u, &status=%s) => %llu",
+ log->Printf ("SBCommunication(%p)::Read (dst=%p, dst_len=%" PRIu64 ", timeout_usec=%u, &status=%s) => %" PRIu64,
m_opaque,
dst,
(uint64_t)dst_len,
@@ -173,7 +173,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBCommunication(%p)::Write (src=%p, src_len=%llu, &status=%s) => %llu",
+ log->Printf ("SBCommunication(%p)::Write (src=%p, src_len=%" PRIu64 ", &status=%s) => %" PRIu64,
m_opaque, src, (uint64_t)src_len, Communication::ConnectionStatusAsCString (status), (uint64_t)bytes_written);
return 0;
Index: aze/lldb/source/API/SBData.cpp
===================================================================
--- aze.orig/lldb/source/API/SBData.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBData.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -151,7 +151,7 @@
float
-SBData::GetFloat (lldb::SBError& error, uint32_t offset)
+SBData::GetFloat (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
float value = 0;
@@ -167,13 +167,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetFloat (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetFloat (error=%p,offset=%" PRIu64 ") => "
"(%f)", error.get(), offset, value);
return value;
}
double
-SBData::GetDouble (lldb::SBError& error, uint32_t offset)
+SBData::GetDouble (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
double value = 0;
@@ -189,13 +189,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetDouble (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetDouble (error=%p,offset=%" PRIu64 ") => "
"(%f)", error.get(), offset, value);
return value;
}
long double
-SBData::GetLongDouble (lldb::SBError& error, uint32_t offset)
+SBData::GetLongDouble (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
long double value = 0;
@@ -211,13 +211,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetLongDouble (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetLongDouble (error=%p,offset=%" PRIu64 ") => "
"(%Lf)", error.get(), offset, value);
return value;
}
lldb::addr_t
-SBData::GetAddress (lldb::SBError& error, uint32_t offset)
+SBData::GetAddress (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
lldb::addr_t value = 0;
@@ -233,13 +233,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetAddress (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetAddress (error=%p,offset=%" PRIu64 ") => "
"(%p)", error.get(), offset, (void*)value);
return value;
}
uint8_t
-SBData::GetUnsignedInt8 (lldb::SBError& error, uint32_t offset)
+SBData::GetUnsignedInt8 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
uint8_t value = 0;
@@ -255,13 +255,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%" PRIu64 ") => "
"(%c)", error.get(), offset, value);
return value;
}
uint16_t
-SBData::GetUnsignedInt16 (lldb::SBError& error, uint32_t offset)
+SBData::GetUnsignedInt16 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
uint16_t value = 0;
@@ -277,13 +277,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%" PRIu64 ") => "
"(%hd)", error.get(), offset, value);
return value;
}
uint32_t
-SBData::GetUnsignedInt32 (lldb::SBError& error, uint32_t offset)
+SBData::GetUnsignedInt32 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
uint32_t value = 0;
@@ -299,13 +299,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%" PRIu64 ") => "
"(%d)", error.get(), offset, value);
return value;
}
uint64_t
-SBData::GetUnsignedInt64 (lldb::SBError& error, uint32_t offset)
+SBData::GetUnsignedInt64 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
uint64_t value = 0;
@@ -321,13 +321,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%d) => "
- "(%lld)", error.get(), offset, value);
+ log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%" PRIu64 ") => "
+ "(%" PRId64 ")", error.get(), offset, value);
return value;
}
int8_t
-SBData::GetSignedInt8 (lldb::SBError& error, uint32_t offset)
+SBData::GetSignedInt8 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
int8_t value = 0;
@@ -343,13 +343,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%" PRIu64 ") => "
"(%c)", error.get(), offset, value);
return value;
}
int16_t
-SBData::GetSignedInt16 (lldb::SBError& error, uint32_t offset)
+SBData::GetSignedInt16 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
int16_t value = 0;
@@ -365,13 +365,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%" PRIu64 ") => "
"(%hd)", error.get(), offset, value);
return value;
}
int32_t
-SBData::GetSignedInt32 (lldb::SBError& error, uint32_t offset)
+SBData::GetSignedInt32 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
int32_t value = 0;
@@ -387,13 +387,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%" PRIu64 ") => "
"(%d)", error.get(), offset, value);
return value;
}
int64_t
-SBData::GetSignedInt64 (lldb::SBError& error, uint32_t offset)
+SBData::GetSignedInt64 (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
int64_t value = 0;
@@ -409,13 +409,13 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%d) => "
- "(%lld)", error.get(), offset, value);
+ log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%" PRIu64 ") => "
+ "(%" PRId64 ")", error.get(), offset, value);
return value;
}
const char*
-SBData::GetString (lldb::SBError& error, uint32_t offset)
+SBData::GetString (lldb::SBError& error, lldb::offset_t offset)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const char* value = 0;
@@ -431,7 +431,7 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::GetString (error=%p,offset=%d) => "
+ log->Printf ("SBData::GetString (error=%p,offset=%" PRIu64 ") => "
"(%p)", error.get(), offset, value);
return value;
}
@@ -461,7 +461,7 @@
size_t
SBData::ReadRawData (lldb::SBError& error,
- uint32_t offset,
+ lldb::offset_t offset,
void *buf,
size_t size)
{
@@ -479,7 +479,7 @@
error.SetErrorString("unable to read data");
}
if (log)
- log->Printf ("SBData::ReadRawData (error=%p,offset=%d,buf=%p,size=%lu) => "
+ log->Printf ("SBData::ReadRawData (error=%p,offset=%" PRIu64 ",buf=%p,size=%lu) => "
"(%p)", error.get(), offset, buf, size, ok);
return ok ? size : 0;
}
Index: aze/lldb/source/API/SBDebugger.cpp
===================================================================
--- aze.orig/lldb/source/API/SBDebugger.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBDebugger.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBDebugger.h"
#include "lldb/lldb-private.h"
@@ -33,9 +35,9 @@
#include "lldb/API/SBTypeSynthetic.h"
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionGroupPlatform.h"
@@ -291,6 +293,20 @@
return NULL;
}
+void
+SBDebugger::SaveInputTerminalState()
+{
+ if (m_opaque_sp)
+ m_opaque_sp->SaveInputTerminalState();
+}
+
+void
+SBDebugger::RestoreInputTerminalState()
+{
+ if (m_opaque_sp)
+ m_opaque_sp->RestoreInputTerminalState();
+
+}
SBCommandInterpreter
SBDebugger::GetCommandInterpreter ()
{
@@ -800,7 +816,7 @@
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%llu)",
+ log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", size_t=%" PRIu64 ")",
m_opaque_sp.get(),
(int) data_len,
(const char *) data,
@@ -1049,7 +1065,7 @@
{
const char *name = m_opaque_sp->GetInstanceName().AsCString();
user_id_t id = m_opaque_sp->GetID();
- strm.Printf ("Debugger (instance: \"%s\", id: %llu)", name, id);
+ strm.Printf ("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id);
}
else
strm.PutCString ("No value");
Index: aze/lldb/source/API/SBEvent.cpp
===================================================================
--- aze.orig/lldb/source/API/SBEvent.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBEvent.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBStream.h"
Index: aze/lldb/source/API/SBExpressionOptions.cpp
===================================================================
--- aze.orig/lldb/source/API/SBExpressionOptions.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBExpressionOptions.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -65,6 +65,18 @@
m_opaque_ap->SetUnwindOnError (unwind);
}
+bool
+SBExpressionOptions::GetIgnoreBreakpoints () const
+{
+ return m_opaque_ap->DoesIgnoreBreakpoints ();
+}
+
+void
+SBExpressionOptions::SetIgnoreBreakpoints (bool ignore)
+{
+ m_opaque_ap->SetIgnoreBreakpoints (ignore);
+}
+
lldb::DynamicValueType
SBExpressionOptions::GetFetchDynamicValue () const
{
Index: aze/lldb/source/API/SBFileSpec.cpp
===================================================================
--- aze.orig/lldb/source/API/SBFileSpec.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBFileSpec.cpp 2013-03-03 09:35:50.119457354 +0100
@@ -154,7 +154,7 @@
result = m_opaque_ap->GetPath (dst_path, dst_len);
if (log)
- log->Printf ("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%llu) => %u",
+ log->Printf ("SBFileSpec(%p)::GetPath (dst_path=\"%.*s\", dst_len=%" PRIu64 ") => %u",
m_opaque_ap.get(), result, dst_path, (uint64_t)dst_len, result);
if (result == 0 && dst_path && dst_len > 0)
Index: aze/lldb/source/API/SBFrame.cpp
===================================================================
--- aze.orig/lldb/source/API/SBFrame.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBFrame.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -114,19 +114,29 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext (resolve_scope));
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext (resolve_scope));
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetVariables () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetSymbolContext () => error: process is running", frame);
+ log->Printf ("SBFrame::GetSymbolContext () => error: process is running");
}
}
@@ -146,20 +156,30 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- module_sp = frame->GetSymbolContext (eSymbolContextModule).module_sp;
- sb_module.SetSP (module_sp);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ module_sp = frame->GetSymbolContext (eSymbolContextModule).module_sp;
+ sb_module.SetSP (module_sp);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetModule () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetModule () => error: process is running", frame);
+ log->Printf ("SBFrame::GetModule () => error: process is running");
}
}
@@ -178,19 +198,29 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_comp_unit.reset (frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_comp_unit.reset (frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetCompileUnit () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetCompileUnit () => error: process is running", frame);
+ log->Printf ("SBFrame::GetCompileUnit () => error: process is running");
}
}
if (log)
@@ -208,19 +238,29 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_function.reset(frame->GetSymbolContext (eSymbolContextFunction).function);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_function.reset(frame->GetSymbolContext (eSymbolContextFunction).function);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetFunction () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetFunction () => error: process is running", frame);
+ log->Printf ("SBFrame::GetFunction () => error: process is running");
}
}
if (log)
@@ -238,19 +278,29 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_symbol.reset(frame->GetSymbolContext (eSymbolContextSymbol).symbol);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_symbol.reset(frame->GetSymbolContext (eSymbolContextSymbol).symbol);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetSymbol () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetSymbol () => error: process is running", frame);
+ log->Printf ("SBFrame::GetSymbol () => error: process is running");
}
}
if (log)
@@ -267,14 +317,24 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_block.SetPtr (frame->GetSymbolContext (eSymbolContextBlock).block);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_block.SetPtr (frame->GetSymbolContext (eSymbolContextBlock).block);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetBlock () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
@@ -295,20 +355,30 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_block.SetPtr(frame->GetFrameBlock ());
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_block.SetPtr(frame->GetFrameBlock ());
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetFrameBlock () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetFrameBlock () => error: process is running", frame);
+ log->Printf ("SBFrame::GetFrameBlock () => error: process is running");
}
}
if (log)
@@ -325,19 +395,29 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_line_entry.SetLineEntry (frame->GetSymbolContext (eSymbolContextLineEntry).line_entry);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_line_entry.SetLineEntry (frame->GetSymbolContext (eSymbolContextLineEntry).line_entry);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetLineEntry () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetLineEntry () => error: process is running", frame);
+ log->Printf ("SBFrame::GetLineEntry () => error: process is running");
}
}
if (log)
@@ -371,24 +451,34 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress (target);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress (target);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetPC () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetPC () => error: process is running", frame);
+ log->Printf ("SBFrame::GetPC () => error: process is running");
}
}
if (log)
- log->Printf ("SBFrame(%p)::GetPC () => 0x%llx", frame, addr);
+ log->Printf ("SBFrame(%p)::GetPC () => 0x%" PRIx64, frame, addr);
return addr;
}
@@ -401,24 +491,34 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- ret_val = frame->GetRegisterContext()->SetPC (new_pc);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ ret_val = frame->GetRegisterContext()->SetPC (new_pc);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::SetPC () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::SetPC () => error: process is running", frame);
+ log->Printf ("SBFrame::SetPC () => error: process is running");
}
}
if (log)
- log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%llx) => %i",
+ log->Printf ("SBFrame(%p)::SetPC (new_pc=0x%" PRIx64 ") => %i",
frame, new_pc, ret_val);
return ret_val;
@@ -432,23 +532,33 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- addr = frame->GetRegisterContext()->GetSP();
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ addr = frame->GetRegisterContext()->GetSP();
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetSP () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetSP () => error: process is running", frame);
+ log->Printf ("SBFrame::GetSP () => error: process is running");
}
}
if (log)
- log->Printf ("SBFrame(%p)::GetSP () => 0x%llx", frame, addr);
+ log->Printf ("SBFrame(%p)::GetSP () => 0x%" PRIx64, frame, addr);
return addr;
}
@@ -462,24 +572,34 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- addr = frame->GetRegisterContext()->GetFP();
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ addr = frame->GetRegisterContext()->GetFP();
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetFP () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetFP () => error: process is running", frame);
+ log->Printf ("SBFrame::GetFP () => error: process is running");
}
}
if (log)
- log->Printf ("SBFrame(%p)::GetFP () => 0x%llx", frame, addr);
+ log->Printf ("SBFrame(%p)::GetFP () => 0x%" PRIx64, frame, addr);
return addr;
}
@@ -494,17 +614,27 @@
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- sb_addr.SetAddress (&frame->GetFrameCodeAddress());
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ sb_addr.SetAddress (&frame->GetFrameCodeAddress());
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetPCAddress () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetPCAddress () => error: process is running", frame);
+ log->Printf ("SBFrame::GetPCAddress () => error: process is running");
}
}
if (log)
@@ -538,29 +668,46 @@
{
SBValue sb_value;
Mutex::Locker api_locker;
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (var_path == NULL || var_path[0] == '\0')
+ {
+ if (log)
+ log->Printf ("SBFrame::GetValueForVariablePath called with empty variable path.");
+ return sb_value;
+ }
+
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
StackFrame *frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target && var_path && var_path[0])
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- VariableSP var_sp;
- Error error;
- ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path,
- eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
- var_sp,
- error));
- sb_value.SetSP(value_sp, use_dynamic);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ VariableSP var_sp;
+ Error error;
+ ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path,
+ eNoDynamicValues,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+ var_sp,
+ error));
+ sb_value.SetSP(value_sp, use_dynamic);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetValueForVariablePath () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBFrame(%p)::GetValueForVariablePath () => error: process is running", frame);
+ log->Printf ("SBFrame::GetValueForVariablePath () => error: process is running");
}
}
return sb_value;
@@ -588,45 +735,63 @@
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
VariableSP var_sp;
SBValue sb_value;
+
+ if (name == NULL || name[0] == '\0')
+ {
+ if (log)
+ log->Printf ("SBFrame::FindVariable called with empty name");
+ return sb_value;
+ }
+
ValueObjectSP value_sp;
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target && name && name[0])
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- VariableList variable_list;
- SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock));
-
- if (sc.block)
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
{
- const bool can_create = true;
- const bool get_parent_variables = true;
- const bool stop_if_block_is_inlined_function = true;
-
- if (sc.block->AppendVariables (can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- &variable_list))
+ VariableList variable_list;
+ SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock));
+
+ if (sc.block)
+ {
+ const bool can_create = true;
+ const bool get_parent_variables = true;
+ const bool stop_if_block_is_inlined_function = true;
+
+ if (sc.block->AppendVariables (can_create,
+ get_parent_variables,
+ stop_if_block_is_inlined_function,
+ &variable_list))
+ {
+ var_sp = variable_list.FindVariable (ConstString(name));
+ }
+ }
+
+ if (var_sp)
{
- var_sp = variable_list.FindVariable (ConstString(name));
+ value_sp = frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
+ sb_value.SetSP(value_sp, use_dynamic);
}
}
-
- if (var_sp)
+ else
{
- value_sp = frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
- sb_value.SetSP(value_sp, use_dynamic);
+ if (log)
+ log->Printf ("SBFrame::FindVariable () => error: could not reconstruct frame object for this SBFrame.");
}
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::FindVariable () => error: process is running", frame);
+ log->Printf ("SBFrame::FindVariable () => error: process is running");
}
}
@@ -657,119 +822,137 @@
{
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
SBValue sb_value;
+
+ if (name == NULL || name[0] == '\0')
+ {
+ if (log)
+ log->Printf ("SBFrame::FindValue called with empty name.");
+ return sb_value;
+ }
+
ValueObjectSP value_sp;
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target && name && name[0])
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- switch (value_type)
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
{
- case eValueTypeVariableGlobal: // global variable
- case eValueTypeVariableStatic: // static variable
- case eValueTypeVariableArgument: // function argument variables
- case eValueTypeVariableLocal: // function local variables
+ switch (value_type)
{
- VariableList *variable_list = frame->GetVariableList(true);
-
- SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock));
+ case eValueTypeVariableGlobal: // global variable
+ case eValueTypeVariableStatic: // static variable
+ case eValueTypeVariableArgument: // function argument variables
+ case eValueTypeVariableLocal: // function local variables
+ {
+ VariableList *variable_list = frame->GetVariableList(true);
- const bool can_create = true;
- const bool get_parent_variables = true;
- const bool stop_if_block_is_inlined_function = true;
+ SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock));
- if (sc.block && sc.block->AppendVariables (can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- variable_list))
- {
- ConstString const_name(name);
- const uint32_t num_variables = variable_list->GetSize();
- for (uint32_t i = 0; i < num_variables; ++i)
+ const bool can_create = true;
+ const bool get_parent_variables = true;
+ const bool stop_if_block_is_inlined_function = true;
+
+ if (sc.block && sc.block->AppendVariables (can_create,
+ get_parent_variables,
+ stop_if_block_is_inlined_function,
+ variable_list))
{
- VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
- if (variable_sp &&
- variable_sp->GetScope() == value_type &&
- variable_sp->GetName() == const_name)
+ ConstString const_name(name);
+ const uint32_t num_variables = variable_list->GetSize();
+ for (uint32_t i = 0; i < num_variables; ++i)
{
- value_sp = frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues);
- sb_value.SetSP (value_sp, use_dynamic);
- break;
+ VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
+ if (variable_sp &&
+ variable_sp->GetScope() == value_type &&
+ variable_sp->GetName() == const_name)
+ {
+ value_sp = frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues);
+ sb_value.SetSP (value_sp, use_dynamic);
+ break;
+ }
}
}
}
- }
- break;
+ break;
- case eValueTypeRegister: // stack frame register value
- {
- RegisterContextSP reg_ctx (frame->GetRegisterContext());
- if (reg_ctx)
+ case eValueTypeRegister: // stack frame register value
{
- const uint32_t num_regs = reg_ctx->GetRegisterCount();
- for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
+ RegisterContextSP reg_ctx (frame->GetRegisterContext());
+ if (reg_ctx)
{
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
- if (reg_info &&
- ((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
- (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
+ const uint32_t num_regs = reg_ctx->GetRegisterCount();
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
{
- value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx);
- sb_value.SetSP (value_sp);
- break;
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
+ if (reg_info &&
+ ((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
+ (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
+ {
+ value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx);
+ sb_value.SetSP (value_sp);
+ break;
+ }
}
}
}
- }
- break;
+ break;
- case eValueTypeRegisterSet: // A collection of stack frame register values
- {
- RegisterContextSP reg_ctx (frame->GetRegisterContext());
- if (reg_ctx)
+ case eValueTypeRegisterSet: // A collection of stack frame register values
{
- const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
- for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
+ RegisterContextSP reg_ctx (frame->GetRegisterContext());
+ if (reg_ctx)
{
- const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx);
- if (reg_set &&
- ((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
- (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
+ const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
+ for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
{
- value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx);
- sb_value.SetSP (value_sp);
- break;
+ const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx);
+ if (reg_set &&
+ ((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
+ (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
+ {
+ value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx);
+ sb_value.SetSP (value_sp);
+ break;
+ }
}
}
}
- }
- break;
+ break;
- case eValueTypeConstResult: // constant result variables
- {
- ConstString const_name(name);
- ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name));
- if (expr_var_sp)
+ case eValueTypeConstResult: // constant result variables
{
- value_sp = expr_var_sp->GetValueObject();
- sb_value.SetSP (value_sp, use_dynamic);
+ ConstString const_name(name);
+ ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name));
+ if (expr_var_sp)
+ {
+ value_sp = expr_var_sp->GetValueObject();
+ sb_value.SetSP (value_sp, use_dynamic);
+ }
}
- }
- break;
+ break;
- default:
- break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::FindValue () => error: could not reconstruct frame object for this SBFrame.");
}
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::FindValue () => error: process is running", frame);
+ log->Printf ("SBFrame::FindValue () => error: process is running");
}
}
@@ -831,19 +1014,29 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- disassembly = frame->Disassemble();
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ disassembly = frame->Disassemble();
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::Disassemble () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::Disassemble () => error: process is running", frame);
+ log->Printf ("SBFrame::Disassemble () => error: process is running");
}
}
@@ -885,81 +1078,88 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
if (log)
- log->Printf ("SBFrame(%p)::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)",
- frame,
+ log->Printf ("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)",
arguments,
locals,
statics,
in_scope_only);
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
-
- size_t i;
- VariableList *variable_list = NULL;
- variable_list = frame->GetVariableList(true);
- if (variable_list)
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
{
- const size_t num_variables = variable_list->GetSize();
- if (num_variables)
+ size_t i;
+ VariableList *variable_list = NULL;
+ variable_list = frame->GetVariableList(true);
+ if (variable_list)
{
- for (i = 0; i < num_variables; ++i)
+ const size_t num_variables = variable_list->GetSize();
+ if (num_variables)
{
- VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
- if (variable_sp)
+ for (i = 0; i < num_variables; ++i)
{
- bool add_variable = false;
- switch (variable_sp->GetScope())
- {
- case eValueTypeVariableGlobal:
- case eValueTypeVariableStatic:
- add_variable = statics;
- break;
-
- case eValueTypeVariableArgument:
- add_variable = arguments;
- break;
-
- case eValueTypeVariableLocal:
- add_variable = locals;
- break;
-
- default:
- break;
- }
- if (add_variable)
+ VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
+ if (variable_sp)
{
- if (in_scope_only && !variable_sp->IsInScope(frame))
- continue;
-
- ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues));
- SBValue value_sb;
- value_sb.SetSP(valobj_sp,use_dynamic);
- value_list.Append(value_sb);
+ bool add_variable = false;
+ switch (variable_sp->GetScope())
+ {
+ case eValueTypeVariableGlobal:
+ case eValueTypeVariableStatic:
+ add_variable = statics;
+ break;
+
+ case eValueTypeVariableArgument:
+ add_variable = arguments;
+ break;
+
+ case eValueTypeVariableLocal:
+ add_variable = locals;
+ break;
+
+ default:
+ break;
+ }
+ if (add_variable)
+ {
+ if (in_scope_only && !variable_sp->IsInScope(frame))
+ continue;
+
+ ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues));
+ SBValue value_sb;
+ value_sb.SetSP(valobj_sp,use_dynamic);
+ value_list.Append(value_sb);
+ }
}
}
}
}
}
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetVariables () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetVariables () => error: process is running", frame);
+ log->Printf ("SBFrame::GetVariables () => error: process is running");
}
}
if (log)
{
- log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame,
- value_list.get());
+ log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame, value_list.opaque_ptr());
}
return value_list;
@@ -974,32 +1174,42 @@
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- RegisterContextSP reg_ctx (frame->GetRegisterContext());
- if (reg_ctx)
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
{
- const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
- for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
+ RegisterContextSP reg_ctx (frame->GetRegisterContext());
+ if (reg_ctx)
{
- value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx));
+ const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
+ for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
+ {
+ value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx));
+ }
}
}
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetRegisters () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::GetRegisters () => error: process is running", frame);
+ log->Printf ("SBFrame::GetRegisters () => error: process is running");
}
}
if (log)
- log->Printf ("SBFrame(%p)::GetRegisters () => SBValueList(%p)", frame, value_list.get());
+ log->Printf ("SBFrame(%p)::GetRegisters () => SBValueList(%p)", frame, value_list.opaque_ptr());
return value_list;
}
@@ -1007,25 +1217,35 @@
bool
SBFrame::GetDescription (SBStream &description)
{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Stream &strm = description.ref();
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- frame->DumpUsingSettingsFormat (&strm);
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
+ frame->DumpUsingSettingsFormat (&strm);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::GetDescription () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBFrame(%p)::GetDescription () => error: process is running", frame);
+ log->Printf ("SBFrame::GetDescription () => error: process is running");
}
}
@@ -1080,40 +1300,59 @@
ExecutionResults exe_results = eExecutionSetupError;
SBValue expr_result;
+
+ if (expr == NULL || expr[0] == '\0')
+ {
+ if (log)
+ log->Printf ("SBFrame::EvaluateExpression called with an empty expression");
+ return expr_result;
+ }
+
ValueObjectSP expr_value_sp;
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
- StackFrame *frame = exe_ctx.GetFramePtr();
- Target *target = exe_ctx.GetTargetPtr();
if (log)
- log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\")...", frame, expr);
+ log->Printf ("SBFrame()::EvaluateExpression (expr=\"%s\")...", expr);
- if (frame && target)
- {
+ StackFrame *frame = NULL;
+ Target *target = exe_ctx.GetTargetPtr();
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (target && process)
+ {
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
#ifdef LLDB_CONFIGURATION_DEBUG
- StreamString frame_description;
- frame->DumpUsingSettingsFormat (&frame_description);
- Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
- expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
+ StreamString frame_description;
+ frame->DumpUsingSettingsFormat (&frame_description);
+ Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
+ expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
#endif
- exe_results = target->EvaluateExpression (expr,
- frame,
- expr_value_sp,
- options.ref());
- expr_result.SetSP(expr_value_sp,options.GetFetchDynamicValue());
+ exe_results = target->EvaluateExpression (expr,
+ frame,
+ expr_value_sp,
+ options.ref());
+ expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
#ifdef LLDB_CONFIGURATION_DEBUG
- Host::SetCrashDescription (NULL);
+ Host::SetCrashDescription (NULL);
#endif
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::EvaluateExpression () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
if (log)
- log->Printf ("SBFrame(%p)::EvaluateExpression () => error: process is running", frame);
+ log->Printf ("SBFrame::EvaluateExpression () => error: process is running");
}
}
@@ -1137,24 +1376,34 @@
bool
SBFrame::IsInlined()
{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
ExecutionContext exe_ctx(m_opaque_sp.get());
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ {
- Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
- if (block)
- return block->GetContainingInlinedBlock () != NULL;
+ Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
+ if (block)
+ return block->GetContainingInlinedBlock () != NULL;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBFrame::IsInlined () => error: could not reconstruct frame object for this SBFrame.");
+ }
}
else
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBFrame(%p)::IsInlined () => error: process is running", frame);
+ log->Printf ("SBFrame::IsInlined () => error: process is running");
}
}
@@ -1164,43 +1413,53 @@
const char *
SBFrame::GetFunctionName()
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
const char *name = NULL;
ExecutionContext exe_ctx(m_opaque_sp.get());
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = NULL;
Target *target = exe_ctx.GetTargetPtr();
- if (frame && target)
+ Process *process = exe_ctx.GetProcessPtr();
+ if (target && process)
{
Process::StopLocker stop_locker;
- if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
+ if (stop_locker.TryLock(&process->GetRunLock()))
{
- SymbolContext sc (frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol));
- if (sc.block)
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
{
- Block *inlined_block = sc.block->GetContainingInlinedBlock ();
- if (inlined_block)
+ SymbolContext sc (frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol));
+ if (sc.block)
{
- const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo();
- name = inlined_info->GetName().AsCString();
+ Block *inlined_block = sc.block->GetContainingInlinedBlock ();
+ if (inlined_block)
+ {
+ const InlineFunctionInfo* inlined_info = inlined_block->GetInlinedFunctionInfo();
+ name = inlined_info->GetName().AsCString();
+ }
+ }
+
+ if (name == NULL)
+ {
+ if (sc.function)
+ name = sc.function->GetName().GetCString();
}
- }
-
- if (name == NULL)
- {
- if (sc.function)
- name = sc.function->GetName().GetCString();
- }
- if (name == NULL)
+ if (name == NULL)
+ {
+ if (sc.symbol)
+ name = sc.symbol->GetName().GetCString();
+ }
+ }
+ else
{
- if (sc.symbol)
- name = sc.symbol->GetName().GetCString();
+ if (log)
+ log->Printf ("SBFrame::GetFunctionName () => error: could not reconstruct frame object for this SBFrame.");
}
}
else
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBFrame(%p)::GetFunctionName() => error: process is running", frame);
+ log->Printf ("SBFrame::GetFunctionName() => error: process is running");
}
}
Index: aze/lldb/source/API/SBFunction.cpp
===================================================================
--- aze.orig/lldb/source/API/SBFunction.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBFunction.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -107,7 +107,7 @@
{
if (m_opaque_ptr)
{
- s.Printf ("SBFunction: id = 0x%8.8llx, name = %s",
+ s.Printf ("SBFunction: id = 0x%8.8" PRIx64 ", name = %s",
m_opaque_ptr->GetID(),
m_opaque_ptr->GetName().AsCString());
Type *func_type = m_opaque_ptr->GetType();
@@ -122,6 +122,12 @@
SBInstructionList
SBFunction::GetInstructions (SBTarget target)
{
+ return GetInstructions (target, NULL);
+}
+
+SBInstructionList
+SBFunction::GetInstructions (SBTarget target, const char *flavor)
+{
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
@@ -139,6 +145,7 @@
{
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(),
NULL,
+ flavor,
exe_ctx,
m_opaque_ptr->GetAddressRange()));
}
Index: aze/lldb/source/API/SBHostOS.cpp
===================================================================
--- aze.orig/lldb/source/API/SBHostOS.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBHostOS.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -26,6 +26,18 @@
return sb_filespec;
}
+SBFileSpec
+SBHostOS::GetLLDBPythonPath ()
+{
+ SBFileSpec sb_lldb_python_filespec;
+ FileSpec lldb_python_spec;
+ if (Host::GetLLDBPath (ePathTypePythonDir, lldb_python_spec))
+ {
+ sb_lldb_python_filespec.SetFileSpec (lldb_python_spec);
+ }
+ return sb_lldb_python_filespec;
+}
+
lldb::thread_t
SBHostOS::ThreadCreate
(
Index: aze/lldb/source/API/SBListener.cpp
===================================================================
--- aze.orig/lldb/source/API/SBListener.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBListener.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBListener.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBDebugger.h"
Index: aze/lldb/source/API/SBModule.cpp
===================================================================
--- aze.orig/lldb/source/API/SBModule.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBModule.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -50,12 +50,14 @@
ProcessSP process_sp (process.GetSP());
if (process_sp)
{
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = true;
- m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(),
- header_addr,
- add_image_to_target,
- load_image_sections_in_target);
+ m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr);
+ if (m_opaque_sp)
+ {
+ Target &target = process_sp->GetTarget();
+ bool changed = false;
+ m_opaque_sp->SetLoadAddress(target, 0, changed);
+ target.GetImages().Append(m_opaque_sp);
+ }
}
}
@@ -328,6 +330,68 @@
return sb_symbol;
}
+lldb::SBSymbol
+SBModule::FindSymbol (const char *name,
+ lldb::SymbolType symbol_type)
+{
+ SBSymbol sb_symbol;
+ if (name && name[0])
+ {
+ ModuleSP module_sp (GetSP ());
+ if (module_sp)
+ {
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (obj_file)
+ {
+ Symtab *symtab = obj_file->GetSymtab();
+ if (symtab)
+ sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(ConstString(name), symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny));
+ }
+ }
+ }
+ return sb_symbol;
+}
+
+
+lldb::SBSymbolContextList
+SBModule::FindSymbols (const char *name, lldb::SymbolType symbol_type)
+{
+ SBSymbolContextList sb_sc_list;
+ if (name && name[0])
+ {
+ ModuleSP module_sp (GetSP ());
+ if (module_sp)
+ {
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (obj_file)
+ {
+ Symtab *symtab = obj_file->GetSymtab();
+ if (symtab)
+ {
+ std::vector<uint32_t> matching_symbol_indexes;
+ const size_t num_matches = symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type, matching_symbol_indexes);
+ if (num_matches)
+ {
+ SymbolContext sc;
+ sc.module_sp = module_sp;
+ SymbolContextList &sc_list = *sb_sc_list;
+ for (size_t i=0; i<num_matches; ++i)
+ {
+ sc.symbol = symtab->SymbolAtIndex (matching_symbol_indexes[i]);
+ if (sc.symbol)
+ sc_list.Append(sc);
+ }
+ }
+ }
+ }
+ }
+ }
+ return sb_sc_list;
+
+}
+
+
+
size_t
SBModule::GetNumSections ()
{
@@ -403,14 +467,13 @@
if (match_count > 0)
{
- ValueObjectList &value_object_list = sb_value_list.ref();
for (uint32_t i=0; i<match_count; ++i)
{
lldb::ValueObjectSP valobj_sp;
TargetSP target_sp (target.GetSP());
valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i));
if (valobj_sp)
- value_object_list.Append(valobj_sp);
+ sb_value_list.Append(SBValue(valobj_sp));
}
}
}
@@ -418,6 +481,15 @@
return sb_value_list;
}
+lldb::SBValue
+SBModule::FindFirstGlobalVariable (lldb::SBTarget &target, const char *name)
+{
+ SBValueList sb_value_list(FindGlobalVariables(target, name, 1));
+ if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
+ return sb_value_list.GetValueAtIndex(0);
+ return SBValue();
+}
+
lldb::SBType
SBModule::FindFirstType (const char *name_cstr)
{
@@ -426,27 +498,29 @@
if (name_cstr && module_sp)
{
SymbolContext sc;
- TypeList type_list;
- uint32_t num_matches = 0;
const bool exact_match = false;
ConstString name(name_cstr);
- num_matches = module_sp->FindTypes (sc,
- name,
- exact_match,
- 1,
- type_list);
+ sb_type = SBType (module_sp->FindFirstType(sc, name, exact_match));
- if (num_matches)
- sb_type = lldb::SBType(type_list.GetTypeAtIndex(0));
+ if (!sb_type.IsValid())
+ sb_type = SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
}
return sb_type;
}
+lldb::SBType
+SBModule::GetBasicType(lldb::BasicType type)
+{
+ ModuleSP module_sp (GetSP ());
+ if (module_sp)
+ return SBType (ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), type));
+ return SBType();
+}
+
lldb::SBTypeList
SBModule::FindTypes (const char *type)
{
-
SBTypeList retval;
ModuleSP module_sp (GetSP ());
@@ -455,20 +529,27 @@
SymbolContext sc;
TypeList type_list;
const bool exact_match = false;
- uint32_t num_matches = 0;
ConstString name(type);
+ const uint32_t num_matches = module_sp->FindTypes (sc,
+ name,
+ exact_match,
+ UINT32_MAX,
+ type_list);
- num_matches = module_sp->FindTypes (sc,
- name,
- exact_match,
- UINT32_MAX,
- type_list);
-
- for (size_t idx = 0; idx < num_matches; idx++)
- {
- TypeSP type_sp (type_list.GetTypeAtIndex(idx));
- if (type_sp)
- retval.Append(SBType(type_sp));
+ if (num_matches > 0)
+ {
+ for (size_t idx = 0; idx < num_matches; idx++)
+ {
+ TypeSP type_sp (type_list.GetTypeAtIndex(idx));
+ if (type_sp)
+ retval.Append(SBType(type_sp));
+ }
+ }
+ else
+ {
+ SBType sb_type(ClangASTType::GetBasicType (module_sp->GetClangASTContext().getASTContext(), name));
+ if (sb_type.IsValid())
+ retval.Append(sb_type);
}
}
Index: aze/lldb/source/API/SBProcess.cpp
===================================================================
--- aze.orig/lldb/source/API/SBProcess.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBProcess.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBProcess.h"
#include "lldb/lldb-defines.h"
@@ -224,7 +226,7 @@
if (log) {
SBStream sstr;
error.GetDescription (sstr);
- log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%llu) => SBError (%p): %s", process_sp.get(), pid, error.get(), sstr.GetData());
+ log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s", process_sp.get(), pid, error.get(), sstr.GetData());
}
return error.Success();
@@ -276,6 +278,27 @@
return sb_thread;
}
+SBThread
+SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ SBThread sb_thread;
+ ThreadSP thread_sp;
+ ProcessSP process_sp(GetSP());
+ if (process_sp)
+ {
+ Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ thread_sp = process_sp->CreateOSPluginThread(tid, context);
+ sb_thread.SetThread (thread_sp);
+ }
+
+ if (log)
+ log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)", process_sp.get(), tid, context, thread_sp.get());
+
+ return sb_thread;
+}
+
SBTarget
SBProcess::GetTarget() const
{
@@ -333,7 +356,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%llu) => %llu",
+ log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
process_sp.get(),
(int) bytes_read,
dst,
@@ -356,7 +379,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%llu) => %llu",
+ log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
process_sp.get(),
(int) bytes_read,
dst,
@@ -366,6 +389,29 @@
return bytes_read;
}
+size_t
+SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const
+{
+ size_t bytes_read = 0;
+ ProcessSP process_sp(GetSP());
+ if (process_sp)
+ {
+ Error error;
+ bytes_read = process_sp->GetAsyncProfileData (dst, dst_len, error);
+ }
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBProcess(%p)::GetProfileData (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
+ process_sp.get(),
+ (int) bytes_read,
+ dst,
+ (uint64_t)dst_len,
+ (uint64_t)bytes_read);
+
+ return bytes_read;
+}
+
void
SBProcess::ReportEventState (const SBEvent &event, FILE *out) const
{
@@ -379,7 +425,7 @@
char message[1024];
int message_len = ::snprintf (message,
sizeof (message),
- "Process %llu %s\n",
+ "Process %" PRIu64 " %s\n",
process_sp->GetID(),
SBDebugger::StateAsCString (event_state));
@@ -398,7 +444,7 @@
char message[1024];
::snprintf (message,
sizeof (message),
- "Process %llu %s\n",
+ "Process %" PRIu64 " %s\n",
process_sp->GetID(),
SBDebugger::StateAsCString (event_state));
@@ -432,7 +478,7 @@
}
if (log)
- log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4llx) => %s",
+ log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4" PRIx64 ") => %s",
process_sp.get(), tid, (ret_val ? "true" : "false"));
return ret_val;
@@ -484,6 +530,21 @@
return sb_thread;
}
+uint32_t
+SBProcess::GetStopID(bool include_expression_stops)
+{
+ ProcessSP process_sp(GetSP());
+ if (process_sp)
+ {
+ Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
+ if (include_expression_stops)
+ return process_sp->GetStopID();
+ else
+ return process_sp->GetLastNaturalStopID();
+ }
+ return 0;
+}
+
StateType
SBProcess::GetState ()
{
@@ -551,11 +612,24 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBProcess(%p)::GetProcessID () => %llu", process_sp.get(), ret_val);
+ log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64, process_sp.get(), ret_val);
return ret_val;
}
+uint32_t
+SBProcess::GetUniqueID()
+{
+ uint32_t ret_val = 0;
+ ProcessSP process_sp(GetSP());
+ if (process_sp)
+ ret_val = process_sp->GetUniqueID();
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32, process_sp.get(), ret_val);
+ return ret_val;
+}
+
ByteOrder
SBProcess::GetByteOrder () const
{
@@ -779,7 +853,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
- log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4llx) => SBThread (%p)",
+ log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4" PRIx64 ") => SBThread (%p)",
process_sp.get(),
tid,
thread_sp.get());
@@ -835,6 +909,18 @@
return Process::ProcessEventData::GetRestartedFromEvent (event.get());
}
+size_t
+SBProcess::GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event)
+{
+ return Process::ProcessEventData::GetNumRestartedReasons(event.get());
+}
+
+const char *
+SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx)
+{
+ return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx);
+}
+
SBProcess
SBProcess::GetProcessFromEvent (const SBEvent &event)
{
@@ -881,7 +967,7 @@
if (log)
{
- log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%llu, SBError (%p))...",
+ log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...",
process_sp.get(),
addr,
dst,
@@ -913,7 +999,7 @@
{
SBStream sstr;
sb_error.GetDescription (sstr);
- log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%llu, SBError (%p): %s) => %llu",
+ log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
process_sp.get(),
addr,
dst,
@@ -1021,7 +1107,7 @@
if (log)
{
- log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, src_len=%llu, SBError (%p))...",
+ log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...",
process_sp.get(),
addr,
src,
@@ -1049,7 +1135,7 @@
{
SBStream sstr;
sb_error.GetDescription (sstr);
- log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, src_len=%llu, SBError (%p): %s) => %llu",
+ log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
process_sp.get(),
addr,
src,
@@ -1077,7 +1163,7 @@
if (exe_module)
exe_name = exe_module->GetFileSpec().GetFilename().AsCString();
- strm.Printf ("SBProcess: pid = %llu, state = %s, threads = %d%s%s",
+ strm.Printf ("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s",
process_sp->GetID(),
lldb_private::StateAsCString (GetState()),
GetNumThreads(),
Index: aze/lldb/source/API/SBSection.cpp
===================================================================
--- aze.orig/lldb/source/API/SBSection.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBSection.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -163,7 +163,7 @@
{
ObjectFile *objfile = module_sp->GetObjectFile();
if (objfile)
- return objfile->GetOffset() + section_sp->GetFileOffset();
+ return objfile->GetFileOffset() + section_sp->GetFileOffset();
}
}
return UINT64_MAX;
@@ -200,7 +200,7 @@
ObjectFile *objfile = module_sp->GetObjectFile();
if (objfile)
{
- const uint64_t sect_file_offset = objfile->GetOffset() + section_sp->GetFileOffset();
+ const uint64_t sect_file_offset = objfile->GetFileOffset() + section_sp->GetFileOffset();
const uint64_t file_offset = sect_file_offset + offset;
uint64_t file_size = size;
if (file_size == UINT64_MAX)
@@ -264,7 +264,7 @@
if (section_sp)
{
const addr_t file_addr = section_sp->GetFileAddress();
- strm.Printf ("[0x%16.16llx-0x%16.16llx) ", file_addr, file_addr + section_sp->GetByteSize());
+ strm.Printf ("[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") ", file_addr, file_addr + section_sp->GetByteSize());
section_sp->DumpName(&strm);
}
else
Index: aze/lldb/source/API/SBSourceManager.cpp
===================================================================
--- aze.orig/lldb/source/API/SBSourceManager.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBSourceManager.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBTarget.h"
Index: aze/lldb/source/API/SBSymbolContext.cpp
===================================================================
--- aze.orig/lldb/source/API/SBSymbolContext.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBSymbolContext.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -72,7 +72,7 @@
else
{
if (m_opaque_ap.get())
- m_opaque_ap->Clear();
+ m_opaque_ap->Clear(true);
}
}
Index: aze/lldb/source/API/SBSymbol.cpp
===================================================================
--- aze.orig/lldb/source/API/SBSymbol.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBSymbol.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -113,11 +113,15 @@
return true;
}
-
-
SBInstructionList
SBSymbol::GetInstructions (SBTarget target)
{
+ return GetInstructions (target, NULL);
+}
+
+SBInstructionList
+SBSymbol::GetInstructions (SBTarget target, const char *flavor_string)
+{
SBInstructionList sb_instructions;
if (m_opaque_ptr)
{
@@ -137,6 +141,7 @@
AddressRange symbol_range (m_opaque_ptr->GetAddress(), m_opaque_ptr->GetByteSize());
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture (),
NULL,
+ flavor_string,
exe_ctx,
symbol_range));
}
Index: aze/lldb/source/API/SBTarget.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTarget.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTarget.cpp 2013-03-03 09:35:50.123457355 +0100
@@ -7,12 +7,15 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTarget.h"
#include "lldb/lldb-public.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBBreakpoint.h"
+#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBModule.h"
@@ -876,7 +879,7 @@
}
else
{
- error.ref().SetErrorStringWithFormat("no process found with process ID %llu", attach_pid);
+ error.ref().SetErrorStringWithFormat("no process found with process ID %" PRIu64, attach_pid);
if (log)
{
log->Printf ("SBTarget(%p)::Attach (...) => error %s",
@@ -944,7 +947,7 @@
if (log)
{
- log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%lld, error)...", target_sp.get(), pid);
+ log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%" PRId64 ", error)...", target_sp.get(), pid);
}
if (target_sp)
@@ -1487,7 +1490,7 @@
if (log)
{
- log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%llu) => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get());
+ log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get());
}
return sb_bp;
@@ -1792,7 +1795,7 @@
if (log)
{
- log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%llx, 0x%u) => SBWatchpoint(%p)",
+ log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%" PRIx64 ", 0x%u) => SBWatchpoint(%p)",
target_sp.get(), addr, (uint32_t) size, watchpoint_sp.get());
}
@@ -2062,52 +2065,138 @@
}
lldb::SBType
-SBTarget::FindFirstType (const char* type)
+SBTarget::FindFirstType (const char* typename_cstr)
{
TargetSP target_sp(GetSP());
- if (type && target_sp)
+ if (typename_cstr && typename_cstr[0] && target_sp)
{
- size_t count = target_sp->GetImages().GetSize();
+ ConstString const_typename(typename_cstr);
+ SymbolContext sc;
+ const bool exact_match = false;
+
+ const ModuleList &module_list = target_sp->GetImages();
+ size_t count = module_list.GetSize();
for (size_t idx = 0; idx < count; idx++)
{
- SBType found_at_idx = GetModuleAtIndex(idx).FindFirstType(type);
+ ModuleSP module_sp (module_list.GetModuleAtIndex(idx));
+ if (module_sp)
+ {
+ TypeSP type_sp (module_sp->FindFirstType(sc, const_typename, exact_match));
+ if (type_sp)
+ return SBType(type_sp);
+ }
+ }
+
+ // Didn't find the type in the symbols; try the Objective-C runtime
+ // if one is installed
+
+ ProcessSP process_sp(target_sp->GetProcessSP());
+
+ if (process_sp)
+ {
+ ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime();
- if (found_at_idx.IsValid())
- return found_at_idx;
+ if (objc_language_runtime)
+ {
+ TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor();
+
+ if (objc_type_vendor)
+ {
+ std::vector <ClangASTType> types;
+
+ if (objc_type_vendor->FindTypes(const_typename, true, 1, types) > 0)
+ return SBType(types[0]);
+ }
+ }
}
+
+ // No matches, search for basic typename matches
+ ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
+ if (clang_ast)
+ return SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), const_typename));
}
return SBType();
}
+SBType
+SBTarget::GetBasicType(lldb::BasicType type)
+{
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
+ if (clang_ast)
+ return SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), type));
+ }
+ return SBType();
+}
+
+
lldb::SBTypeList
-SBTarget::FindTypes (const char* type)
+SBTarget::FindTypes (const char* typename_cstr)
{
-
- SBTypeList retval;
-
+ SBTypeList sb_type_list;
TargetSP target_sp(GetSP());
- if (type && target_sp)
+ if (typename_cstr && typename_cstr[0] && target_sp)
{
ModuleList& images = target_sp->GetImages();
- ConstString name_const(type);
+ ConstString const_typename(typename_cstr);
bool exact_match = false;
SymbolContext sc;
TypeList type_list;
uint32_t num_matches = images.FindTypes (sc,
- name_const,
+ const_typename,
exact_match,
UINT32_MAX,
type_list);
- for (size_t idx = 0; idx < num_matches; idx++)
+ if (num_matches > 0)
{
- TypeSP type_sp (type_list.GetTypeAtIndex(idx));
- if (type_sp)
- retval.Append(SBType(type_sp));
+ for (size_t idx = 0; idx < num_matches; idx++)
+ {
+ TypeSP type_sp (type_list.GetTypeAtIndex(idx));
+ if (type_sp)
+ sb_type_list.Append(SBType(type_sp));
+ }
+ }
+
+ // Try the Objective-C runtime if one is installed
+
+ ProcessSP process_sp(target_sp->GetProcessSP());
+
+ if (process_sp)
+ {
+ ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime();
+
+ if (objc_language_runtime)
+ {
+ TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor();
+
+ if (objc_type_vendor)
+ {
+ std::vector <ClangASTType> types;
+
+ if (objc_type_vendor->FindTypes(const_typename, true, UINT32_MAX, types))
+ {
+ for (ClangASTType &type : types)
+ {
+ sb_type_list.Append(SBType(type));
+ }
+ }
+ }
+ }
+ }
+
+ if (sb_type_list.GetSize() == 0)
+ {
+ // No matches, search for basic typename matches
+ ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
+ if (clang_ast)
+ sb_type_list.Append (SBType (ClangASTType::GetBasicType (clang_ast->getASTContext(), const_typename)));
}
}
- return retval;
+ return sb_type_list;
}
SBValueList
@@ -2130,12 +2219,11 @@
ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
if (exe_scope == NULL)
exe_scope = target_sp.get();
- ValueObjectList &value_object_list = sb_value_list.ref();
for (uint32_t i=0; i<match_count; ++i)
{
lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i)));
if (valobj_sp)
- value_object_list.Append(valobj_sp);
+ sb_value_list.Append(SBValue(valobj_sp));
}
}
}
@@ -2143,6 +2231,15 @@
return sb_value_list;
}
+lldb::SBValue
+SBTarget::FindFirstGlobalVariable (const char* name)
+{
+ SBValueList sb_value_list(FindGlobalVariables(name, 1));
+ if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
+ return sb_value_list.GetValueAtIndex(0);
+ return SBValue();
+}
+
SBSourceManager
SBTarget::GetSourceManager()
{
@@ -2153,6 +2250,12 @@
lldb::SBInstructionList
SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count)
{
+ return ReadInstructions (base_addr, count, NULL);
+}
+
+lldb::SBInstructionList
+SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string)
+{
SBInstructionList sb_instructions;
TargetSP target_sp(GetSP());
@@ -2168,6 +2271,7 @@
const size_t bytes_read = target_sp->ReadMemory(*addr_ptr, prefer_file_cache, data.GetBytes(), data.GetByteSize(), error);
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
NULL,
+ flavor_string,
*addr_ptr,
data.GetBytes(),
bytes_read,
@@ -2182,6 +2286,12 @@
lldb::SBInstructionList
SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size)
{
+ return GetInstructionsWithFlavor (base_addr, NULL, buf, size);
+}
+
+lldb::SBInstructionList
+SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size)
+{
SBInstructionList sb_instructions;
TargetSP target_sp(GetSP());
@@ -2194,6 +2304,7 @@
sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
NULL,
+ flavor_string,
addr,
buf,
size));
@@ -2205,7 +2316,13 @@
lldb::SBInstructionList
SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size)
{
- return GetInstructions (ResolveLoadAddress(base_addr), buf, size);
+ return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), NULL, buf, size);
+}
+
+lldb::SBInstructionList
+SBTarget::GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size)
+{
+ return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), flavor_string, buf, size);
}
SBError
@@ -2231,7 +2348,13 @@
}
else
{
- target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr);
+ if (target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr))
+ {
+ // Flush info in the process (stack frames, etc)
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Flush();
+ }
}
}
}
@@ -2257,7 +2380,13 @@
}
else
{
- target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP());
+ if (target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP()))
+ {
+ // Flush info in the process (stack frames, etc)
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Flush();
+ }
}
}
else
@@ -2288,6 +2417,10 @@
ModuleList module_list;
module_list.Append(module_sp);
target_sp->ModulesDidLoad (module_list);
+ // Flush info in the process (stack frames, etc)
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Flush();
}
}
}
@@ -2322,12 +2455,20 @@
SectionList *section_list = objfile->GetSectionList();
if (section_list)
{
+ bool changed = false;
const size_t num_sections = section_list->GetSize();
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
{
SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
if (section_sp)
- target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp);
+ changed |= target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp) > 0;
+ }
+ if (changed)
+ {
+ // Flush info in the process (stack frames, etc)
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Flush();
}
}
else
@@ -2355,3 +2496,113 @@
}
+lldb::SBSymbolContextList
+SBTarget::FindSymbols (const char *name, lldb::SymbolType symbol_type)
+{
+ SBSymbolContextList sb_sc_list;
+ if (name && name[0])
+ {
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ bool append = true;
+ target_sp->GetImages().FindSymbolsWithNameAndType (ConstString(name),
+ symbol_type,
+ *sb_sc_list,
+ append);
+ }
+ }
+ return sb_sc_list;
+
+}
+
+
+lldb::SBValue
+SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
+{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ SBValue expr_result;
+ ExecutionResults exe_results = eExecutionSetupError;
+ ValueObjectSP expr_value_sp;
+ TargetSP target_sp(GetSP());
+ StackFrame *frame = NULL;
+ if (target_sp)
+ {
+ if (expr == NULL || expr[0] == '\0')
+ {
+ if (log)
+ log->Printf ("SBTarget::EvaluateExpression called with an empty expression");
+ return expr_result;
+ }
+
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ ExecutionContext exe_ctx (m_opaque_sp.get());
+
+ if (log)
+ log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr);
+
+ frame = exe_ctx.GetFramePtr();
+ Target *target = exe_ctx.GetTargetPtr();
+
+ if (target)
+ {
+#ifdef LLDB_CONFIGURATION_DEBUG
+ StreamString frame_description;
+ if (frame)
+ frame->DumpUsingSettingsFormat (&frame_description);
+ Host::SetCrashDescriptionWithFormat ("SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
+ expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
+#endif
+ exe_results = target->EvaluateExpression (expr,
+ frame,
+ expr_value_sp,
+ options.ref());
+
+ expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
+#ifdef LLDB_CONFIGURATION_DEBUG
+ Host::SetCrashDescription (NULL);
+#endif
+ }
+ else
+ {
+ if (log)
+ log->Printf ("SBTarget::EvaluateExpression () => error: could not reconstruct frame object for this SBTarget.");
+ }
+ }
+#ifndef LLDB_DISABLE_PYTHON
+ if (expr_log)
+ expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **",
+ expr_result.GetValue(),
+ expr_result.GetSummary());
+
+ if (log)
+ log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)",
+ frame,
+ expr,
+ expr_value_sp.get(),
+ exe_results);
+#endif
+
+ return expr_result;
+}
+
+
+lldb::addr_t
+SBTarget::GetStackRedZoneSize()
+{
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ ABISP abi_sp;
+ ProcessSP process_sp (target_sp->GetProcessSP());
+ if (process_sp)
+ abi_sp = process_sp->GetABI();
+ else
+ abi_sp = ABI::FindPlugin(target_sp->GetArchitecture());
+ if (abi_sp)
+ return abi_sp->GetRedZoneSize();
+ }
+ return 0;
+}
+
Index: aze/lldb/source/API/SBThread.cpp
===================================================================
--- aze.orig/lldb/source/API/SBThread.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBThread.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBThread.h"
#include "lldb/API/SBSymbolContext.h"
@@ -147,7 +149,9 @@
case eStopReasonInvalid:
case eStopReasonNone:
case eStopReasonTrace:
+ case eStopReasonExec:
case eStopReasonPlanComplete:
+ case eStopReasonThreadExiting:
// There is no data for these stop reasons.
return 0;
@@ -204,7 +208,9 @@
case eStopReasonInvalid:
case eStopReasonNone:
case eStopReasonTrace:
+ case eStopReasonExec:
case eStopReasonPlanComplete:
+ case eStopReasonThreadExiting:
// There is no data for these stop reasons.
return 0;
@@ -336,6 +342,21 @@
}
break;
+ case eStopReasonExec:
+ {
+ char exc_desc[] = "exec";
+ stop_desc = exc_desc;
+ stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
+ }
+ break;
+
+ case eStopReasonThreadExiting:
+ {
+ char limbo_desc[] = "thread exiting";
+ stop_desc = limbo_desc;
+ stop_desc_len = sizeof(limbo_desc);
+ }
+ break;
default:
break;
}
@@ -552,13 +573,10 @@
if (frame_sp->HasDebugInformation ())
{
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
- eStepTypeOver,
- sc.line_entry.range,
- sc,
- stop_other_threads,
- false);
-
+ new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
+ sc.line_entry.range,
+ sc,
+ stop_other_threads);
}
else
{
@@ -576,14 +594,23 @@
void
SBThread::StepInto (lldb::RunMode stop_other_threads)
{
+ StepInto (NULL, stop_other_threads);
+}
+
+void
+SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
+{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
if (log)
- log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
+ log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
+ exe_ctx.GetThreadPtr(),
+ target_name? target_name: "<NULL>",
Thread::RunModeAsCString (stop_other_threads));
+
if (exe_ctx.HasThreadScope())
{
bool abort_other_plans = false;
@@ -596,12 +623,12 @@
{
bool avoid_code_without_debug_info = true;
SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
- new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
- eStepTypeInto,
- sc.line_entry.range,
- sc,
- stop_other_threads,
- avoid_code_without_debug_info);
+ new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
+ sc.line_entry.range,
+ sc,
+ target_name,
+ stop_other_threads,
+ avoid_code_without_debug_info);
}
else
{
@@ -715,7 +742,7 @@
if (log)
- log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
+ log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
if (exe_ctx.HasThreadScope())
{
@@ -967,9 +994,7 @@
SBProcess
SBThread::GetProcess ()
{
-
SBProcess sb_process;
- ProcessSP process_sp;
ExecutionContext exe_ctx (m_opaque_sp.get());
if (exe_ctx.HasThreadScope())
{
@@ -983,7 +1008,7 @@
SBStream frame_desc_strm;
sb_process.GetDescription (frame_desc_strm);
log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
- process_sp.get(), frame_desc_strm.GetData());
+ sb_process.GetSP().get(), frame_desc_strm.GetData());
}
return sb_process;
@@ -1185,7 +1210,7 @@
ExecutionContext exe_ctx (m_opaque_sp.get());
if (exe_ctx.HasThreadScope())
{
- strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID());
+ strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
}
else
strm.PutCString ("No value");
Index: aze/lldb/source/API/SBTypeCategory.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTypeCategory.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTypeCategory.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeFilter.h"
@@ -16,8 +18,8 @@
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBStream.h"
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
@@ -231,7 +233,7 @@
if (!children_sp)
return lldb::SBTypeSynthetic();
- TypeSyntheticImplSP synth_sp = STD_STATIC_POINTER_CAST(TypeSyntheticImpl,children_sp);
+ ScriptedSyntheticChildrenSP synth_sp = STD_STATIC_POINTER_CAST(ScriptedSyntheticChildren,children_sp);
return lldb::SBTypeSynthetic(synth_sp);
}
@@ -283,7 +285,7 @@
if (!children_sp.get())
return lldb::SBTypeSynthetic();
- TypeSyntheticImplSP synth_sp = STD_STATIC_POINTER_CAST(TypeSyntheticImpl,children_sp);
+ ScriptedSyntheticChildrenSP synth_sp = STD_STATIC_POINTER_CAST(ScriptedSyntheticChildren,children_sp);
return lldb::SBTypeSynthetic(synth_sp);
}
Index: aze/lldb/source/API/SBType.cpp
===================================================================
--- aze.orig/lldb/source/API/SBType.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBType.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -274,6 +274,18 @@
return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getUnqualifiedType().getAsOpaquePtr()));
}
+lldb::SBType
+SBType::GetCanonicalType()
+{
+ if (IsValid())
+ {
+ QualType qt (QualType::getFromOpaquePtr(m_opaque_sp->GetOpaqueQualType()));
+ return SBType(ClangASTType(m_opaque_sp->GetASTContext(),qt.getCanonicalType().getAsOpaquePtr()));
+ }
+ return SBType();
+}
+
+
lldb::BasicType
SBType::GetBasicType()
{
@@ -285,111 +297,9 @@
SBType
SBType::GetBasicType(lldb::BasicType type)
{
- if (!IsValid())
- return SBType();
-
- clang::QualType base_type_qual;
-
- switch (type)
- {
- case eBasicTypeVoid:
- base_type_qual = m_opaque_sp->GetASTContext()->VoidTy;
- break;
- case eBasicTypeChar:
- base_type_qual = m_opaque_sp->GetASTContext()->CharTy;
- break;
- case eBasicTypeSignedChar:
- base_type_qual = m_opaque_sp->GetASTContext()->SignedCharTy;
- break;
- case eBasicTypeUnsignedChar:
- base_type_qual = m_opaque_sp->GetASTContext()->UnsignedCharTy;
- break;
- case eBasicTypeWChar:
- base_type_qual = m_opaque_sp->GetASTContext()->getWCharType();
- break;
- case eBasicTypeSignedWChar:
- base_type_qual = m_opaque_sp->GetASTContext()->getSignedWCharType();
- break;
- case eBasicTypeUnsignedWChar:
- base_type_qual = m_opaque_sp->GetASTContext()->getUnsignedWCharType();
- break;
- case eBasicTypeChar16:
- base_type_qual = m_opaque_sp->GetASTContext()->Char16Ty;
- break;
- case eBasicTypeChar32:
- base_type_qual = m_opaque_sp->GetASTContext()->Char32Ty;
- break;
- case eBasicTypeShort:
- base_type_qual = m_opaque_sp->GetASTContext()->ShortTy;
- break;
- case eBasicTypeUnsignedShort:
- base_type_qual = m_opaque_sp->GetASTContext()->UnsignedShortTy;
- break;
- case eBasicTypeInt:
- base_type_qual = m_opaque_sp->GetASTContext()->IntTy;
- break;
- case eBasicTypeUnsignedInt:
- base_type_qual = m_opaque_sp->GetASTContext()->UnsignedIntTy;
- break;
- case eBasicTypeLong:
- base_type_qual = m_opaque_sp->GetASTContext()->LongTy;
- break;
- case eBasicTypeUnsignedLong:
- base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongTy;
- break;
- case eBasicTypeLongLong:
- base_type_qual = m_opaque_sp->GetASTContext()->LongLongTy;
- break;
- case eBasicTypeUnsignedLongLong:
- base_type_qual = m_opaque_sp->GetASTContext()->UnsignedLongLongTy;
- break;
- case eBasicTypeInt128:
- base_type_qual = m_opaque_sp->GetASTContext()->Int128Ty;
- break;
- case eBasicTypeUnsignedInt128:
- base_type_qual = m_opaque_sp->GetASTContext()->UnsignedInt128Ty;
- break;
- case eBasicTypeBool:
- base_type_qual = m_opaque_sp->GetASTContext()->BoolTy;
- break;
- case eBasicTypeHalf:
- base_type_qual = m_opaque_sp->GetASTContext()->HalfTy;
- break;
- case eBasicTypeFloat:
- base_type_qual = m_opaque_sp->GetASTContext()->FloatTy;
- break;
- case eBasicTypeDouble:
- base_type_qual = m_opaque_sp->GetASTContext()->DoubleTy;
- break;
- case eBasicTypeLongDouble:
- base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleTy;
- break;
- case eBasicTypeFloatComplex:
- base_type_qual = m_opaque_sp->GetASTContext()->FloatComplexTy;
- break;
- case eBasicTypeDoubleComplex:
- base_type_qual = m_opaque_sp->GetASTContext()->DoubleComplexTy;
- break;
- case eBasicTypeLongDoubleComplex:
- base_type_qual = m_opaque_sp->GetASTContext()->LongDoubleComplexTy;
- break;
- case eBasicTypeObjCID:
- base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinIdTy;
- break;
- case eBasicTypeObjCClass:
- base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinClassTy;
- break;
- case eBasicTypeObjCSel:
- base_type_qual = m_opaque_sp->GetASTContext()->ObjCBuiltinSelTy;
- break;
- case eBasicTypeNullPtr:
- base_type_qual = m_opaque_sp->GetASTContext()->NullPtrTy;
- break;
- default:
- return SBType();
- }
-
- return SBType(ClangASTType(m_opaque_sp->GetASTContext(), base_type_qual.getAsOpaquePtr()));
+ if (IsValid())
+ return SBType (ClangASTType::GetBasicType (m_opaque_sp->GetASTContext(), type));
+ return SBType();
}
uint32_t
Index: aze/lldb/source/API/SBTypeFilter.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTypeFilter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTypeFilter.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,11 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBStream.h"
-#include "lldb/Core/DataVisualization.h"
+#include "lldb/DataFormatters/DataVisualization.h"
using namespace lldb;
using namespace lldb_private;
Index: aze/lldb/source/API/SBTypeFormat.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTypeFormat.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTypeFormat.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,11 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBStream.h"
-#include "lldb/Core/DataVisualization.h"
+#include "lldb/DataFormatters/DataVisualization.h"
using namespace lldb;
using namespace lldb_private;
Index: aze/lldb/source/API/SBTypeNameSpecifier.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTypeNameSpecifier.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTypeNameSpecifier.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,12 +7,14 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBType.h"
-#include "lldb/Core/DataVisualization.h"
+#include "lldb/DataFormatters/DataVisualization.h"
using namespace lldb;
using namespace lldb_private;
Index: aze/lldb/source/API/SBTypeSummary.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTypeSummary.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTypeSummary.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,11 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBStream.h"
-#include "lldb/Core/DataVisualization.h"
+#include "lldb/DataFormatters/DataVisualization.h"
using namespace lldb;
using namespace lldb_private;
Index: aze/lldb/source/API/SBTypeSynthetic.cpp
===================================================================
--- aze.orig/lldb/source/API/SBTypeSynthetic.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBTypeSynthetic.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,11 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBTypeSynthetic.h"
#include "lldb/API/SBStream.h"
-#include "lldb/Core/DataVisualization.h"
+#include "lldb/DataFormatters/DataVisualization.h"
using namespace lldb;
using namespace lldb_private;
@@ -28,7 +30,7 @@
{
if (!data || data[0] == 0)
return SBTypeSynthetic();
- return SBTypeSynthetic(TypeSyntheticImplSP(new TypeSyntheticImpl(options, data, "")));
+ return SBTypeSynthetic(ScriptedSyntheticChildrenSP(new ScriptedSyntheticChildren(options, data, "")));
}
SBTypeSynthetic
@@ -36,7 +38,7 @@
{
if (!data || data[0] == 0)
return SBTypeSynthetic();
- return SBTypeSynthetic(TypeSyntheticImplSP(new TypeSyntheticImpl(options, "", data)));
+ return SBTypeSynthetic(ScriptedSyntheticChildrenSP(new ScriptedSyntheticChildren(options, "", data)));
}
SBTypeSynthetic::SBTypeSynthetic (const lldb::SBTypeSynthetic &rhs) :
@@ -170,19 +172,19 @@
return m_opaque_sp != rhs.m_opaque_sp;
}
-lldb::TypeSyntheticImplSP
+lldb::ScriptedSyntheticChildrenSP
SBTypeSynthetic::GetSP ()
{
return m_opaque_sp;
}
void
-SBTypeSynthetic::SetSP (const lldb::TypeSyntheticImplSP &TypeSynthetic_impl_sp)
+SBTypeSynthetic::SetSP (const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp)
{
m_opaque_sp = TypeSynthetic_impl_sp;
}
-SBTypeSynthetic::SBTypeSynthetic (const lldb::TypeSyntheticImplSP &TypeSynthetic_impl_sp) :
+SBTypeSynthetic::SBTypeSynthetic (const lldb::ScriptedSyntheticChildrenSP &TypeSynthetic_impl_sp) :
m_opaque_sp(TypeSynthetic_impl_sp)
{
}
@@ -195,7 +197,7 @@
if (m_opaque_sp.unique())
return true;
- TypeSyntheticImplSP new_sp(new TypeSyntheticImpl(m_opaque_sp->GetOptions(),
+ ScriptedSyntheticChildrenSP new_sp(new ScriptedSyntheticChildren(m_opaque_sp->GetOptions(),
m_opaque_sp->GetPythonClassName(),
m_opaque_sp->GetPythonCode()));
Index: aze/lldb/source/API/SBValue.cpp
===================================================================
--- aze.orig/lldb/source/API/SBValue.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBValue.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBValue.h"
#include "lldb/API/SBDeclaration.h"
@@ -18,7 +20,6 @@
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Scalar.h"
@@ -28,6 +29,7 @@
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Declaration.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -301,7 +303,7 @@
}
if (log)
- log->Printf ("SBValue(%p)::GetByteSize () => %llu", value_sp.get(), (uint64_t)result);
+ log->Printf ("SBValue(%p)::GetByteSize () => %" PRIu64, value_sp.get(), (uint64_t)result);
return result;
}
@@ -386,7 +388,6 @@
case eValueTypeRegister: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegister", value_sp.get()); break;
case eValueTypeRegisterSet: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeRegisterSet", value_sp.get()); break;
case eValueTypeConstResult: log->Printf ("SBValue(%p)::GetValueType () => eValueTypeConstResult", value_sp.get()); break;
- default: log->Printf ("SBValue(%p)::GetValueType () => %i ???", value_sp.get(), result); break;
}
}
return result;
@@ -739,7 +740,7 @@
if (children_sp && children_sp->IsScripted())
{
- TypeSyntheticImplSP synth_sp = STD_STATIC_POINTER_CAST(TypeSyntheticImpl,children_sp);
+ ScriptedSyntheticChildrenSP synth_sp = STD_STATIC_POINTER_CAST(ScriptedSyntheticChildren,children_sp);
synthetic.SetSP(synth_sp);
}
}
@@ -1364,7 +1365,7 @@
has_children = value_sp->MightHaveChildren();
if (log)
- log->Printf ("SBValue(%p)::HasChildren() => %i", value_sp.get(), has_children);
+ log->Printf ("SBValue(%p)::MightHaveChildren() => %i", value_sp.get(), has_children);
return has_children;
}
@@ -1755,7 +1756,7 @@
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBValue(%p)::GetLoadAddress () => (%llu)", value_sp.get(), value);
+ log->Printf ("SBValue(%p)::GetLoadAddress () => (%" PRIu64 ")", value_sp.get(), value);
return value;
}
@@ -1792,7 +1793,7 @@
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
- log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", value_sp.get(),
+ log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", value_sp.get(),
(addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"),
addr.GetOffset());
return SBAddress(new Address(addr));
Index: aze/lldb/source/API/SBValueList.cpp
===================================================================
--- aze.orig/lldb/source/API/SBValueList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBValueList.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -14,9 +14,78 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/ValueObjectList.h"
+#include <vector>
+
using namespace lldb;
using namespace lldb_private;
+namespace {
+ class ValueListImpl
+ {
+ public:
+ ValueListImpl () :
+ m_values()
+ {
+ }
+
+ ValueListImpl (const ValueListImpl& rhs) :
+ m_values(rhs.m_values)
+ {
+ }
+
+ ValueListImpl&
+ operator = (const ValueListImpl& rhs)
+ {
+ if (this == &rhs)
+ return *this;
+ m_values = rhs.m_values;
+ return *this;
+ };
+
+ uint32_t
+ GetSize ()
+ {
+ return m_values.size();
+ }
+
+ void
+ Append (const lldb::SBValue& sb_value)
+ {
+ m_values.push_back(sb_value);
+ }
+
+ void
+ Append (const ValueListImpl& list)
+ {
+ for (auto val : list.m_values)
+ Append (val);
+ }
+
+ lldb::SBValue
+ GetValueAtIndex (uint32_t index)
+ {
+ if (index >= GetSize())
+ return lldb::SBValue();
+ return m_values[index];
+ }
+
+ lldb::SBValue
+ FindValueByUID (lldb::user_id_t uid)
+ {
+ for (auto val : m_values)
+ {
+ if (val.IsValid() && val.GetID() == uid)
+ return val;
+ }
+ return lldb::SBValue();
+ }
+
+ private:
+ std::vector<lldb::SBValue> m_values;
+ };
+}
+
+
SBValueList::SBValueList () :
m_opaque_ap ()
{
@@ -28,7 +97,7 @@
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (rhs.IsValid())
- m_opaque_ap.reset (new ValueObjectList (*rhs));
+ m_opaque_ap.reset (new ValueListImpl (*rhs));
if (log)
{
@@ -38,13 +107,13 @@
}
}
-SBValueList::SBValueList (const ValueObjectList *lldb_object_ptr) :
+SBValueList::SBValueList (const ValueListImpl *lldb_object_ptr) :
m_opaque_ap ()
{
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (lldb_object_ptr)
- m_opaque_ap.reset (new ValueObjectList (*lldb_object_ptr));
+ m_opaque_ap.reset (new ValueListImpl (*lldb_object_ptr));
if (log)
{
@@ -76,32 +145,32 @@
if (this != &rhs)
{
if (rhs.IsValid())
- m_opaque_ap.reset (new ValueObjectList (*rhs));
+ m_opaque_ap.reset (new ValueListImpl (*rhs));
else
m_opaque_ap.reset ();
}
return *this;
}
-ValueObjectList *
+ValueListImpl *
SBValueList::operator->()
{
return m_opaque_ap.get();
}
-ValueObjectList &
+ValueListImpl &
SBValueList::operator*()
{
return *m_opaque_ap;
}
-const ValueObjectList *
+const ValueListImpl *
SBValueList::operator->() const
{
return m_opaque_ap.get();
}
-const ValueObjectList &
+const ValueListImpl &
SBValueList::operator*() const
{
return *m_opaque_ap;
@@ -110,12 +179,8 @@
void
SBValueList::Append (const SBValue &val_obj)
{
- ValueObjectSP value_sp (val_obj.GetSP());
- if (value_sp)
- {
- CreateIfNeeded ();
- m_opaque_ap->Append (value_sp);
- }
+ CreateIfNeeded ();
+ m_opaque_ap->Append (val_obj);
}
void
@@ -124,7 +189,7 @@
if (val_obj_sp)
{
CreateIfNeeded ();
- m_opaque_ap->Append (val_obj_sp);
+ m_opaque_ap->Append (SBValue(val_obj_sp));
}
}
@@ -148,19 +213,15 @@
// log->Printf ("SBValueList::GetValueAtIndex (uint32_t idx) idx = %d", idx);
SBValue sb_value;
- ValueObjectSP value_sp;
if (m_opaque_ap.get())
- {
- value_sp = m_opaque_ap->GetValueObjectAtIndex (idx);
- sb_value.SetSP (value_sp);
- }
+ sb_value = m_opaque_ap->GetValueAtIndex (idx);
if (log)
{
SBStream sstr;
sb_value.GetDescription (sstr);
log->Printf ("SBValueList::GetValueAtIndex (this.ap=%p, idx=%d) => SBValue (this.sp = %p, '%s')",
- m_opaque_ap.get(), idx, value_sp.get(), sstr.GetData());
+ m_opaque_ap.get(), idx, sb_value.GetSP().get(), sstr.GetData());
}
return sb_value;
@@ -188,7 +249,7 @@
SBValueList::CreateIfNeeded ()
{
if (m_opaque_ap.get() == NULL)
- m_opaque_ap.reset (new ValueObjectList());
+ m_opaque_ap.reset (new ValueListImpl());
}
@@ -197,17 +258,17 @@
{
SBValue sb_value;
if (m_opaque_ap.get())
- sb_value.SetSP (m_opaque_ap->FindValueObjectByUID (uid));
+ sb_value = m_opaque_ap->FindValueByUID(uid);
return sb_value;
}
-ValueObjectList *
-SBValueList::get ()
+void *
+SBValueList::opaque_ptr ()
{
return m_opaque_ap.get();
}
-ValueObjectList &
+ValueListImpl &
SBValueList::ref ()
{
CreateIfNeeded();
Index: aze/lldb/source/API/SBWatchpoint.cpp
===================================================================
--- aze.orig/lldb/source/API/SBWatchpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/API/SBWatchpoint.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -11,6 +11,7 @@
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBDebugger.h"
+#include "lldb/API/SBEvent.h"
#include "lldb/API/SBStream.h"
#include "lldb/lldb-types.h"
@@ -271,3 +272,27 @@
{
m_opaque_sp = sp;
}
+
+bool
+SBWatchpoint::EventIsWatchpointEvent (const lldb::SBEvent &event)
+{
+ return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != NULL;
+
+}
+
+WatchpointEventType
+SBWatchpoint::GetWatchpointEventTypeFromEvent (const SBEvent& event)
+{
+ if (event.IsValid())
+ return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent (event.GetSP());
+ return eWatchpointEventTypeInvalidType;
+}
+
+SBWatchpoint
+SBWatchpoint::GetWatchpointFromEvent (const lldb::SBEvent& event)
+{
+ SBWatchpoint sb_watchpoint;
+ if (event.IsValid())
+ sb_watchpoint.m_opaque_sp = Watchpoint::WatchpointEventData::GetWatchpointFromEvent (event.GetSP());
+ return sb_watchpoint;
+}
Index: aze/lldb/source/Breakpoint/Breakpoint.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/Breakpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/Breakpoint.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -108,7 +108,7 @@
}
BreakpointLocationSP
-Breakpoint::GetLocationAtIndex (uint32_t index)
+Breakpoint::GetLocationAtIndex (size_t index)
{
return m_locations.GetByIndex(index);
}
@@ -242,7 +242,8 @@
void
Breakpoint::SetThreadName (const char *thread_name)
{
- if (::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
+ if (m_options.GetThreadSpec()->GetName() != NULL
+ && ::strcmp (m_options.GetThreadSpec()->GetName(), thread_name) == 0)
return;
m_options.GetThreadSpec()->SetName (thread_name);
@@ -261,7 +262,8 @@
void
Breakpoint::SetQueueName (const char *queue_name)
{
- if (::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
+ if (m_options.GetThreadSpec()->GetQueueName() != NULL
+ && ::strcmp (m_options.GetThreadSpec()->GetQueueName(), queue_name) == 0)
return;
m_options.GetThreadSpec()->SetQueueName (queue_name);
@@ -523,12 +525,21 @@
void
Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_locations)
{
- const size_t num_locations = GetNumLocations ();
- const size_t num_resolved_locations = GetNumResolvedLocations ();
-
assert (s != NULL);
-
+ if (!m_kind_description.empty())
+ {
+ if (eDescriptionLevelBrief)
+ {
+ s->PutCString (GetBreakpointKind());
+ return;
+ }
+ else
+ s->Printf("Kind: %s\n", GetBreakpointKind ());
+ }
+
+ const size_t num_locations = GetNumLocations ();
+ const size_t num_resolved_locations = GetNumResolvedLocations ();
// They just made the breakpoint, they don't need to be told HOW they made it...
// Also, we'll print the breakpoint number differently depending on whether there is 1 or more locations.
@@ -545,9 +556,9 @@
case lldb::eDescriptionLevelFull:
if (num_locations > 0)
{
- s->Printf(", locations = %llu", (uint64_t)num_locations);
+ s->Printf(", locations = %" PRIu64, (uint64_t)num_locations);
if (num_resolved_locations > 0)
- s->Printf(", resolved = %llu", (uint64_t)num_resolved_locations);
+ s->Printf(", resolved = %" PRIu64, (uint64_t)num_resolved_locations);
}
else
{
@@ -758,7 +769,7 @@
return bp_sp;
}
-uint32_t
+size_t
Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (const EventSP &event_sp)
{
const BreakpointEventData *data = GetEventDataFromEvent (event_sp.get());
Index: aze/lldb/source/Breakpoint/BreakpointIDList.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointIDList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointIDList.cpp 2013-03-03 09:35:50.127457355 +0100
@@ -38,7 +38,7 @@
}
BreakpointID &
-BreakpointIDList::GetBreakpointIDAtIndex (uint32_t index)
+BreakpointIDList::GetBreakpointIDAtIndex (size_t index)
{
if (index < m_breakpoint_ids.size())
return m_breakpoint_ids[index];
@@ -47,7 +47,7 @@
}
bool
-BreakpointIDList::RemoveBreakpointIDAtIndex (uint32_t index)
+BreakpointIDList::RemoveBreakpointIDAtIndex (size_t index)
{
if (index >= m_breakpoint_ids.size())
return false;
@@ -89,10 +89,8 @@
}
bool
-BreakpointIDList::FindBreakpointID (BreakpointID &bp_id, uint32_t *position)
+BreakpointIDList::FindBreakpointID (BreakpointID &bp_id, size_t *position)
{
- BreakpointIDArray::iterator tmp_pos;
-
for (size_t i = 0; i < m_breakpoint_ids.size(); ++i)
{
BreakpointID tmp_id = m_breakpoint_ids[i];
@@ -108,7 +106,7 @@
}
bool
-BreakpointIDList::FindBreakpointID (const char *bp_id_str, uint32_t *position)
+BreakpointIDList::FindBreakpointID (const char *bp_id_str, size_t *position)
{
BreakpointID temp_bp_id;
break_id_t bp_id;
@@ -124,7 +122,7 @@
}
void
-BreakpointIDList::InsertStringArray (const char **string_array, uint32_t array_size, CommandReturnObject &result)
+BreakpointIDList::InsertStringArray (const char **string_array, size_t array_size, CommandReturnObject &result)
{
if (string_array == NULL)
return;
@@ -174,8 +172,8 @@
bool is_range = false;
current_arg = old_args.GetArgumentAtIndex (i);
- uint32_t range_start_len = 0;
- uint32_t range_end_pos = 0;
+ size_t range_start_len = 0;
+ size_t range_end_pos = 0;
if (BreakpointIDList::StringContainsIDRangeExpression (current_arg, &range_start_len, &range_end_pos))
{
is_range = true;
@@ -350,8 +348,8 @@
bool
BreakpointIDList::StringContainsIDRangeExpression (const char *in_string,
- uint32_t *range_start_len,
- uint32_t *range_end_pos)
+ size_t *range_start_len,
+ size_t *range_end_pos)
{
bool is_range_expression = false;
std::string arg_str = in_string;
@@ -368,7 +366,7 @@
for (int i = 0; i < specifiers_size && !is_range_expression; ++i)
{
const char *specifier_str = BreakpointID::g_range_specifiers[i];
- int len = strlen (specifier_str);
+ size_t len = strlen (specifier_str);
idx = arg_str.find (BreakpointID::g_range_specifiers[i]);
if (idx != std::string::npos)
{
Index: aze/lldb/source/Breakpoint/BreakpointList.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointList.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -88,9 +88,14 @@
{
bp_collection::iterator pos, end = m_breakpoints.end();
for (pos = m_breakpoints.begin(); pos != end; ++pos)
+ {
if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
+ {
(*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged,
- new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved, *pos));
+ new Breakpoint::BreakpointEventData (eBreakpointEventTypeRemoved,
+ *pos));
+ }
+ }
}
m_breakpoints.erase (m_breakpoints.begin(), m_breakpoints.end());
}
@@ -167,13 +172,13 @@
BreakpointSP
-BreakpointList::GetBreakpointAtIndex (uint32_t i)
+BreakpointList::GetBreakpointAtIndex (size_t i)
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
bp_collection::iterator end = m_breakpoints.end();
bp_collection::iterator pos;
- uint32_t curr_i = 0;
+ size_t curr_i = 0;
for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
{
if (curr_i == i)
@@ -183,13 +188,13 @@
}
const BreakpointSP
-BreakpointList::GetBreakpointAtIndex (uint32_t i) const
+BreakpointList::GetBreakpointAtIndex (size_t i) const
{
Mutex::Locker locker(m_mutex);
BreakpointSP stop_sp;
bp_collection::const_iterator end = m_breakpoints.end();
bp_collection::const_iterator pos;
- uint32_t curr_i = 0;
+ size_t curr_i = 0;
for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i)
{
if (curr_i == i)
Index: aze/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointLocationCollection.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointLocationCollection.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -115,7 +115,7 @@
}
BreakpointLocationSP
-BreakpointLocationCollection::GetByIndex (uint32_t i)
+BreakpointLocationCollection::GetByIndex (size_t i)
{
BreakpointLocationSP stop_sp;
if (i < m_break_loc_collection.size())
@@ -125,7 +125,7 @@
}
const BreakpointLocationSP
-BreakpointLocationCollection::GetByIndex (uint32_t i) const
+BreakpointLocationCollection::GetByIndex (size_t i) const
{
BreakpointLocationSP stop_sp;
if (i < m_break_loc_collection.size())
@@ -162,6 +162,25 @@
return false;
}
+bool
+BreakpointLocationCollection::IsInternal () const
+{
+ collection::const_iterator pos,
+ begin = m_break_loc_collection.begin(),
+ end = m_break_loc_collection.end();
+
+ bool is_internal = true;
+
+ for (pos = begin; pos != end; ++pos)
+ {
+ if (!(*pos)->GetBreakpoint().IsInternal ())
+ {
+ is_internal = false;
+ break;
+ }
+ }
+ return is_internal;
+}
void
BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
Index: aze/lldb/source/Breakpoint/BreakpointLocation.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointLocation.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointLocation.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
// C++ Includes
#include <string>
@@ -378,7 +380,7 @@
{
LogSP log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
if (log)
- log->Warning ("Tried to add breakpoint site at 0x%llx but it was already present.\n",
+ log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
return false;
}
@@ -537,7 +539,7 @@
if (s == NULL)
return;
- s->Printf("BreakpointLocation %u: tid = %4.4llx load addr = 0x%8.8llx state = %s type = %s breakpoint "
+ s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint "
"hw_index = %i hit_count = %-4u ignore_count = %-4u",
GetID(),
GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
Index: aze/lldb/source/Breakpoint/BreakpointLocationList.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointLocationList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointLocationList.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -128,7 +128,7 @@
s->Printf("%p: ", this);
//s->Indent();
Mutex::Locker locker (m_mutex);
- s->Printf("BreakpointLocationList with %llu BreakpointLocations:\n", (uint64_t)m_locations.size());
+ s->Printf("BreakpointLocationList with %" PRIu64 " BreakpointLocations:\n", (uint64_t)m_locations.size());
s->IndentMore();
collection::const_iterator pos, end = m_locations.end();
for (pos = m_locations.begin(); pos != end; ++pos)
@@ -138,7 +138,7 @@
BreakpointLocationSP
-BreakpointLocationList::GetByIndex (uint32_t i)
+BreakpointLocationList::GetByIndex (size_t i)
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP bp_loc_sp;
@@ -149,7 +149,7 @@
}
const BreakpointLocationSP
-BreakpointLocationList::GetByIndex (uint32_t i) const
+BreakpointLocationList::GetByIndex (size_t i) const
{
Mutex::Locker locker (m_mutex);
BreakpointLocationSP bp_loc_sp;
Index: aze/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -73,8 +73,8 @@
// So we go through the match list and pull out the sets that have the same file spec in their line_entry
// and treat each set separately.
- uint32_t num_comp_units = context.module_sp->GetNumCompileUnits();
- for (uint32_t i = 0; i < num_comp_units; i++)
+ const size_t num_comp_units = context.module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_comp_units; i++)
{
CompUnitSP cu_sp (context.module_sp->GetCompileUnitAtIndex (i));
if (cu_sp)
@@ -174,7 +174,7 @@
}
else if (log)
{
- log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass the filter.\n",
+ log->Printf ("Breakpoint at file address 0x%" PRIx64 " for %s:%d didn't pass the filter.\n",
line_start.GetFileAddress(),
m_file_spec.GetFilename().AsCString("<Unknown>"),
m_line_number);
@@ -183,7 +183,7 @@
else
{
if (log)
- log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n",
+ log->Printf ("error: Unable to set breakpoint at file address 0x%" PRIx64 " for %s:%d\n",
line_start.GetFileAddress(),
m_file_spec.GetFilename().AsCString("<Unknown>"),
m_line_number);
Index: aze/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -92,7 +92,7 @@
}
else if (log)
{
- log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass filter.\n",
+ log->Printf ("Breakpoint at file address 0x%" PRIx64 " for %s:%d didn't pass filter.\n",
line_start.GetFileAddress(),
cu_file_spec.GetFilename().AsCString("<Unknown>"),
line_matches[i]);
@@ -101,7 +101,7 @@
else
{
if (log)
- log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n",
+ log->Printf ("error: Unable to set breakpoint at file address 0x%" PRIx64 " for %s:%d\n",
line_start.GetFileAddress(),
cu_file_spec.GetFilename().AsCString("<Unknown>"),
line_matches[i]);
Index: aze/lldb/source/Breakpoint/BreakpointResolverName.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointResolverName.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointResolverName.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -22,6 +22,7 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
using namespace lldb;
using namespace lldb_private;
@@ -54,7 +55,12 @@
}
else
{
- m_func_names.push_back(ConstString(func_name));
+ const bool append = true;
+ ObjCLanguageRuntime::MethodName objc_name(func_name, false);
+ if (objc_name.IsValid(false))
+ objc_name.GetFullNames(m_func_names, append);
+ else
+ m_func_names.push_back(ConstString(func_name));
}
}
@@ -68,9 +74,14 @@
m_match_type (Breakpoint::Exact),
m_skip_prologue (skip_prologue)
{
+ const bool append = true;
for (size_t i = 0; i < num_names; i++)
{
- m_func_names.push_back (ConstString (names[i]));
+ ObjCLanguageRuntime::MethodName objc_name(names[i], false);
+ if (objc_name.IsValid(false))
+ objc_name.GetFullNames(m_func_names, append);
+ else
+ m_func_names.push_back (ConstString (names[i]));
}
}
@@ -84,10 +95,14 @@
m_skip_prologue (skip_prologue)
{
size_t num_names = names.size();
-
+ const bool append = true;
for (size_t i = 0; i < num_names; i++)
{
- m_func_names.push_back (ConstString (names[i].c_str()));
+ ObjCLanguageRuntime::MethodName objc_name(names[i].c_str(), false);
+ if (objc_name.IsValid(false))
+ objc_name.GetFullNames(m_func_names, append);
+ else
+ m_func_names.push_back (ConstString (names[i].c_str()));
}
}
@@ -170,20 +185,19 @@
size_t num_names = m_func_names.size();
for (int j = 0; j < num_names; j++)
{
- uint32_t num_functions = context.module_sp->FindFunctions (m_func_names[j],
- NULL,
- m_func_name_type_mask,
- include_symbols,
- include_inlines,
- append,
- func_list);
+ size_t num_functions = context.module_sp->FindFunctions (m_func_names[j],
+ NULL,
+ m_func_name_type_mask,
+ include_symbols,
+ include_inlines,
+ append,
+ func_list);
// If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
// symbols, since all the ones from a set compilation unit will have been found above already.
if (num_functions == 0 && !filter_by_cu)
{
- if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
- context.module_sp->FindSymbolsWithNameAndType (m_func_names[j], eSymbolTypeCode, sym_list);
+ context.module_sp->FindFunctionSymbols (m_func_names[j], m_func_name_type_mask, sym_list);
}
}
}
Index: aze/lldb/source/Breakpoint/BreakpointSite.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointSite.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointSite.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -25,10 +25,9 @@
BreakpointSiteList *list,
const BreakpointLocationSP& owner,
lldb::addr_t addr,
- lldb::tid_t tid,
bool use_hardware
) :
- StoppointLocation(GetNextID(), addr, tid, use_hardware),
+ StoppointLocation(GetNextID(), addr, 0, use_hardware),
m_type (eSoftware), // Process subclasses need to set this correctly using SetType()
m_saved_opcode(),
m_trap_opcode(),
@@ -83,7 +82,7 @@
if (s == NULL)
return;
- s->Printf("BreakpointSite %u: addr = 0x%8.8llx type = %s breakpoint hw_index = %i hit_count = %-4u",
+ s->Printf("BreakpointSite %u: addr = 0x%8.8" PRIx64 " type = %s breakpoint hw_index = %i hit_count = %-4u",
GetID(),
(uint64_t)m_addr,
IsHardware() ? "hardware" : "software",
@@ -95,10 +94,16 @@
BreakpointSite::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
if (level != lldb::eDescriptionLevelBrief)
- s->Printf ("breakpoint site: %d at 0x%8.8llx", GetID(), GetLoadAddress());
+ s->Printf ("breakpoint site: %d at 0x%8.8" PRIx64, GetID(), GetLoadAddress());
m_owners.GetDescription (s, level);
}
+bool
+BreakpointSite::IsInternal() const
+{
+ return m_owners.IsInternal();
+}
+
uint8_t *
BreakpointSite::GetTrapOpcodeBytes()
{
@@ -118,7 +123,7 @@
}
bool
-BreakpointSite::SetTrapOpcode (const uint8_t *trap_opcode, size_t trap_opcode_size)
+BreakpointSite::SetTrapOpcode (const uint8_t *trap_opcode, uint32_t trap_opcode_size)
{
if (trap_opcode_size > 0 && trap_opcode_size <= sizeof(m_trap_opcode))
{
@@ -160,21 +165,21 @@
m_owners.Add(owner);
}
-uint32_t
+size_t
BreakpointSite::RemoveOwner (lldb::break_id_t break_id, lldb::break_id_t break_loc_id)
{
m_owners.Remove(break_id, break_loc_id);
return m_owners.GetSize();
}
-uint32_t
+size_t
BreakpointSite::GetNumberOfOwners ()
{
return m_owners.GetSize();
}
BreakpointLocationSP
-BreakpointSite::GetOwnerAtIndex (uint32_t index)
+BreakpointSite::GetOwnerAtIndex (size_t index)
{
return m_owners.GetByIndex (index);
}
Index: aze/lldb/source/Breakpoint/BreakpointSiteList.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/BreakpointSiteList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/BreakpointSiteList.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -69,10 +69,10 @@
BreakpointSiteSP bp = FindByAddress (addr);
if (bp)
{
- //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
+ //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" PRIx64 " ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID());
return bp.get()->GetID();
}
- //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8llx ) => NONE", __FUNCTION__, (uint64_t)addr);
+ //DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" PRIx64 " ) => NONE", __FUNCTION__, (uint64_t)addr);
return LLDB_INVALID_BREAK_ID;
}
@@ -169,7 +169,7 @@
{
collection::const_iterator pos = GetIDConstIterator(bp_site_id);
if (pos != m_bp_site_list.end())
- pos->second->IsBreakpointAtThisSite (bp_id);
+ return pos->second->IsBreakpointAtThisSite (bp_id);
return false;
}
Index: aze/lldb/source/Breakpoint/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Breakpoint/CMakeLists.txt 2013-03-03 09:35:50.131457355 +0100
@@ -0,0 +1,25 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbBreakpoint
+ Breakpoint.cpp
+ BreakpointID.cpp
+ BreakpointIDList.cpp
+ BreakpointList.cpp
+ BreakpointLocation.cpp
+ BreakpointLocationCollection.cpp
+ BreakpointLocationList.cpp
+ BreakpointOptions.cpp
+ BreakpointResolver.cpp
+ BreakpointResolverAddress.cpp
+ BreakpointResolverFileLine.cpp
+ BreakpointResolverFileRegex.cpp
+ BreakpointResolverName.cpp
+ BreakpointSite.cpp
+ BreakpointSiteList.cpp
+ Stoppoint.cpp
+ StoppointCallbackContext.cpp
+ StoppointLocation.cpp
+ Watchpoint.cpp
+ WatchpointList.cpp
+ WatchpointOptions.cpp
+ )
Index: aze/lldb/source/Breakpoint/Watchpoint.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/Watchpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/Watchpoint.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -27,7 +27,7 @@
using namespace lldb;
using namespace lldb_private;
-Watchpoint::Watchpoint (Target& target, lldb::addr_t addr, size_t size, const ClangASTType *type, bool hardware) :
+Watchpoint::Watchpoint (Target& target, lldb::addr_t addr, uint32_t size, const ClangASTType *type, bool hardware) :
StoppointLocation (0, addr, size, hardware),
m_target(target),
m_enabled(false),
@@ -45,7 +45,8 @@
m_watch_spec_str(),
m_type(),
m_error(),
- m_options ()
+ m_options (),
+ m_being_created(true)
{
if (type && type->IsValid())
m_type = *type;
@@ -64,6 +65,7 @@
m_target.GetProcessSP()->CalculateExecutionContext(exe_ctx);
CaptureWatchedValue (exe_ctx);
}
+ m_being_created = false;
}
Watchpoint::~Watchpoint()
@@ -78,7 +80,7 @@
// or delete it when it goes goes out of scope.
m_options.SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
- //SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
+ SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
}
// This function is used when a baton needs to be freed and therefore is
@@ -87,12 +89,14 @@
Watchpoint::SetCallback (WatchpointHitCallback callback, const BatonSP &callback_baton_sp, bool is_synchronous)
{
m_options.SetCallback(callback, callback_baton_sp, is_synchronous);
+ SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
}
void
Watchpoint::ClearCallback ()
{
m_options.ClearCallback ();
+ SendWatchpointChangedEvent (eWatchpointEventTypeCommandChanged);
}
void
@@ -235,7 +239,7 @@
assert(description_level >= lldb::eDescriptionLevelBrief &&
description_level <= lldb::eDescriptionLevelVerbose);
- s->Printf("Watchpoint %u: addr = 0x%8.8llx size = %u state = %s type = %s%s",
+ s->Printf("Watchpoint %u: addr = 0x%8.8" PRIx64 " size = %u state = %s type = %s%s",
GetID(),
GetLoadAddress(),
m_byte_size,
@@ -297,7 +301,7 @@
}
void
-Watchpoint::SetEnabled(bool enabled)
+Watchpoint::SetEnabled(bool enabled, bool notify)
{
if (!enabled)
{
@@ -309,14 +313,21 @@
// Don't clear the snapshots for now.
// Within StopInfo.cpp, we purposely do disable/enable watchpoint while performing watchpoint actions.
}
+ bool changed = enabled != m_enabled;
m_enabled = enabled;
+ if (notify && !m_is_ephemeral && changed)
+ SendWatchpointChangedEvent (enabled ? eWatchpointEventTypeEnabled : eWatchpointEventTypeDisabled);
}
void
-Watchpoint::SetWatchpointType (uint32_t type)
+Watchpoint::SetWatchpointType (uint32_t type, bool notify)
{
+ int old_watch_read = m_watch_read;
+ int old_watch_write = m_watch_write;
m_watch_read = (type & LLDB_WATCH_TYPE_READ) != 0;
m_watch_write = (type & LLDB_WATCH_TYPE_WRITE) != 0;
+ if (notify && (old_watch_read != m_watch_read || old_watch_write != m_watch_write))
+ SendWatchpointChangedEvent (eWatchpointEventTypeTypeChanged);
}
bool
@@ -338,7 +349,10 @@
void
Watchpoint::SetIgnoreCount (uint32_t n)
{
+ bool changed = m_ignore_count != n;
m_ignore_count = n;
+ if (changed)
+ SendWatchpointChangedEvent (eWatchpointEventTypeIgnoreChanged);
}
bool
@@ -360,6 +374,7 @@
// Pass NULL for expr_prefix (no translation-unit level definitions).
m_condition_ap.reset(new ClangUserExpression (condition, NULL, lldb::eLanguageTypeUnknown, ClangUserExpression::eResultTypeAny));
}
+ SendWatchpointChangedEvent (eWatchpointEventTypeConditionChanged);
}
const char *
@@ -371,3 +386,105 @@
return NULL;
}
+void
+Watchpoint::SendWatchpointChangedEvent (lldb::WatchpointEventType eventKind)
+{
+ if (!m_being_created
+ && GetTarget().EventTypeHasListeners(Target::eBroadcastBitWatchpointChanged))
+ {
+ WatchpointEventData *data = new Watchpoint::WatchpointEventData (eventKind, shared_from_this());
+ GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged, data);
+ }
+}
+
+void
+Watchpoint::SendWatchpointChangedEvent (WatchpointEventData *data)
+{
+
+ if (data == NULL)
+ return;
+
+ if (!m_being_created
+ && GetTarget().EventTypeHasListeners(Target::eBroadcastBitWatchpointChanged))
+ GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged, data);
+ else
+ delete data;
+}
+
+Watchpoint::WatchpointEventData::WatchpointEventData (WatchpointEventType sub_type,
+ const WatchpointSP &new_watchpoint_sp) :
+ EventData (),
+ m_watchpoint_event (sub_type),
+ m_new_watchpoint_sp (new_watchpoint_sp)
+{
+}
+
+Watchpoint::WatchpointEventData::~WatchpointEventData ()
+{
+}
+
+const ConstString &
+Watchpoint::WatchpointEventData::GetFlavorString ()
+{
+ static ConstString g_flavor ("Watchpoint::WatchpointEventData");
+ return g_flavor;
+}
+
+const ConstString &
+Watchpoint::WatchpointEventData::GetFlavor () const
+{
+ return WatchpointEventData::GetFlavorString ();
+}
+
+
+WatchpointSP &
+Watchpoint::WatchpointEventData::GetWatchpoint ()
+{
+ return m_new_watchpoint_sp;
+}
+
+WatchpointEventType
+Watchpoint::WatchpointEventData::GetWatchpointEventType () const
+{
+ return m_watchpoint_event;
+}
+
+void
+Watchpoint::WatchpointEventData::Dump (Stream *s) const
+{
+}
+
+const Watchpoint::WatchpointEventData *
+Watchpoint::WatchpointEventData::GetEventDataFromEvent (const Event *event)
+{
+ if (event)
+ {
+ const EventData *event_data = event->GetData();
+ if (event_data && event_data->GetFlavor() == WatchpointEventData::GetFlavorString())
+ return static_cast <const WatchpointEventData *> (event->GetData());
+ }
+ return NULL;
+}
+
+WatchpointEventType
+Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent (const EventSP &event_sp)
+{
+ const WatchpointEventData *data = GetEventDataFromEvent (event_sp.get());
+
+ if (data == NULL)
+ return eWatchpointEventTypeInvalidType;
+ else
+ return data->GetWatchpointEventType();
+}
+
+WatchpointSP
+Watchpoint::WatchpointEventData::GetWatchpointFromEvent (const EventSP &event_sp)
+{
+ WatchpointSP wp_sp;
+
+ const WatchpointEventData *data = GetEventDataFromEvent (event_sp.get());
+ if (data)
+ wp_sp = data->m_new_watchpoint_sp;
+
+ return wp_sp;
+}
Index: aze/lldb/source/Breakpoint/WatchpointList.cpp
===================================================================
--- aze.orig/lldb/source/Breakpoint/WatchpointList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Breakpoint/WatchpointList.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -31,11 +31,17 @@
// Add a watchpoint to the list.
lldb::watch_id_t
-WatchpointList::Add (const WatchpointSP &wp_sp)
+WatchpointList::Add (const WatchpointSP &wp_sp, bool notify)
{
Mutex::Locker locker (m_mutex);
wp_sp->SetID(++m_next_wp_id);
m_watchpoints.push_back(wp_sp);
+ if (notify)
+ {
+ if (wp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitWatchpointChanged))
+ wp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged,
+ new Watchpoint::WatchpointEventData (eWatchpointEventTypeAdded, wp_sp));
+ }
return wp_sp->GetID();
}
@@ -51,7 +57,7 @@
Mutex::Locker locker (m_mutex);
s->Printf("%p: ", this);
//s->Indent();
- s->Printf("WatchpointList with %llu Watchpoints:\n",
+ s->Printf("WatchpointList with %" PRIu64 " Watchpoints:\n",
(uint64_t)m_watchpoints.size());
s->IndentMore();
wp_collection::const_iterator pos, end = m_watchpoints.end();
@@ -200,12 +206,19 @@
}
bool
-WatchpointList::Remove (lldb::watch_id_t watch_id)
+WatchpointList::Remove (lldb::watch_id_t watch_id, bool notify)
{
Mutex::Locker locker (m_mutex);
wp_collection::iterator pos = GetIDIterator(watch_id);
if (pos != m_watchpoints.end())
{
+ WatchpointSP wp_sp = *pos;
+ if (notify)
+ {
+ if (wp_sp->GetTarget().EventTypeHasListeners(Target::eBroadcastBitWatchpointChanged))
+ wp_sp->GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged,
+ new Watchpoint::WatchpointEventData (eWatchpointEventTypeRemoved, wp_sp));
+ }
m_watchpoints.erase(pos);
return true;
}
@@ -264,9 +277,25 @@
}
void
-WatchpointList::RemoveAll ()
+WatchpointList::RemoveAll (bool notify)
{
Mutex::Locker locker(m_mutex);
+ if (notify)
+ {
+
+ {
+ wp_collection::iterator pos, end = m_watchpoints.end();
+ for (pos = m_watchpoints.begin(); pos != end; ++pos)
+ {
+ if ((*pos)->GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
+ {
+ (*pos)->GetTarget().BroadcastEvent (Target::eBroadcastBitWatchpointChanged,
+ new Watchpoint::WatchpointEventData (eWatchpointEventTypeRemoved,
+ *pos));
+ }
+ }
+ }
+ }
m_watchpoints.clear();
}
Index: aze/lldb/source/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/CMakeLists.txt 2013-03-03 09:35:50.131457355 +0100
@@ -0,0 +1,161 @@
+include_directories(.)
+
+if ( CMAKE_SYSTEM_NAME MATCHES "Linux" )
+include_directories(
+ Plugins/Process/Linux
+ Plugins/Process/POSIX
+ )
+endif ()
+
+add_subdirectory(API)
+add_subdirectory(Breakpoint)
+add_subdirectory(Commands)
+add_subdirectory(Core)
+add_subdirectory(DataFormatters)
+add_subdirectory(Expression)
+add_subdirectory(Host)
+add_subdirectory(Interpreter)
+add_subdirectory(Plugins)
+add_subdirectory(Symbol)
+add_subdirectory(Target)
+add_subdirectory(Utility)
+
+set( LLDB_USED_LIBS
+ lldbAPI
+ lldbBreakpoint
+ lldbCommands
+ lldbDataFormatters
+ lldbHostCommon
+ lldbCore
+ lldbExpression
+ lldbInterpreter
+ lldbSymbol
+ lldbTarget
+ lldbUtility
+
+ # Plugins
+ lldbPluginDisassemblerLLVM
+ lldbPluginSymbolFileDWARF
+ lldbPluginSymbolFileSymtab
+ lldbPluginDynamicLoaderStatic
+
+ lldbPluginObjectFileMachO
+ lldbPluginObjectFileELF
+ lldbPluginObjectContainerBSDArchive
+ lldbPluginObjectContainerMachOArchive
+ lldbPluginProcessGDBRemote
+ lldbPluginProcessUtility
+ lldbPluginPlatformGDB
+ lldbPluginPlatformFreeBSD
+ lldbPluginPlatformLinux
+ lldbPluginObjectFileMachO
+ lldbPluginObjectContainerMachOArchive
+ lldbPluginObjectContainerBSDArchive
+ lldbPluginPlatformMacOSX
+ lldbPluginDynamicLoaderMacOSXDYLD
+ lldbPluginDynamicLoaderPosixDYLD
+ lldbPluginUnwindAssemblyInstEmulation
+ lldbPluginUnwindAssemblyX86
+ lldbPluginDynamicLoaderDarwinKernel
+ lldbPluginAppleObjCRuntime
+ lldbPluginCXXItaniumABI
+ lldbPluginABIMacOSX_arm
+ lldbPluginABIMacOSX_i386
+ lldbPluginABISysV_x86_64
+ lldbPluginInstructionARM
+ lldbPluginObjectFilePECOFF
+ lldbPluginOSPython
+ )
+
+# Windows-only libraries
+if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
+ list(APPEND LLDB_USED_LIBS
+ #lldbHostWindows
+ #lldbPluginPlatformWindows
+ #Ws2_32
+ )
+endif ()
+
+# Linux-only libraries
+if ( CMAKE_SYSTEM_NAME MATCHES "Linux" )
+ list(APPEND LLDB_USED_LIBS
+ lldbHostLinux
+ lldbPluginProcessLinux
+ lldbPluginProcessPOSIX
+ )
+endif ()
+
+set( CLANG_USED_LIBS
+ clangAnalysis
+ clangAST
+ clangBasic
+ clangCodeGen
+ clangDriver
+ clangEdit
+ clangFrontend
+ clangLex
+ clangParse
+ clangRewriteCore
+ clangRewriteFrontend
+ clangSema
+ clangSerialization
+ )
+
+set( LLDB_SYSTEM_LIBS
+ edit
+ python2.7
+ )
+
+set( LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
+ jit
+ interpreter
+ nativecodegen
+ asmparser
+ bitreader
+ bitwriter
+ codegen
+ ipo
+ selectiondag
+ bitreader
+ mc
+ mcjit
+ core
+ mcdisassembler
+ executionengine
+ )
+
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/../scripts/LLDBWrapPython.cpp PROPERTIES GENERATED 1)
+set(SHARED_LIBRARY 1)
+
+add_lldb_library(liblldb
+ lldb.cpp
+ lldb-log.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/../scripts/LLDBWrapPython.cpp
+ )
+set_target_properties(liblldb PROPERTIES OUTPUT_NAME lldb)
+
+# Determine LLDB revision and repository. GetSourceVersion and GetRepositoryPath are shell-scripts, and as
+# such will not work on Windows.
+if ( NOT CMAKE_SYSTEM_NAME MATCHES "Windows" )
+ execute_process(COMMAND ${CMAKE_SOURCE_DIR}/utils/GetSourceVersion ${LLDB_SOURCE_DIR}
+ OUTPUT_VARIABLE LLDB_REVISION)
+ string(REGEX REPLACE "(\r?\n)+$" "" LLDB_REVISION ${LLDB_REVISION})
+
+ execute_process(COMMAND ${CMAKE_SOURCE_DIR}/utils/GetRepositoryPath ${LLDB_SOURCE_DIR}
+ OUTPUT_VARIABLE LLDB_REPOSITORY)
+ string(REGEX REPLACE "(\r?\n)+$" "" LLDB_REPOSITORY ${LLDB_REPOSITORY})
+ string(REPLACE " " "" LLDB_REPOSITORY ${LLDB_REPOSITORY})
+
+ set_property(
+ SOURCE lldb.cpp
+ PROPERTY COMPILE_DEFINITIONS "LLDB_REVISION=\"${LLDB_REVISION}\"" "LLDB_REPOSITORY=\"${LLDB_REPOSITORY}\"")
+endif ()
+# FIXME: implement svn/git revision and repository parsing solution on Windows. There is an SVN-only
+# revision parsing solution in tools/clang/lib/Basic/CMakelists.txt.
+
+target_link_libraries(liblldb ${LLDB_SYSTEM_LIBS})
+add_dependencies(liblldb swig_wrapper)
+
+install(TARGETS liblldb
+ LIBRARY DESTINATION lib)
Index: aze/lldb/source/Commands/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Commands/CMakeLists.txt 2013-03-03 09:35:50.131457355 +0100
@@ -0,0 +1,31 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbCommands
+ CommandCompletions.cpp
+ CommandObjectApropos.cpp
+ CommandObjectArgs.cpp
+ CommandObjectBreakpoint.cpp
+ CommandObjectBreakpointCommand.cpp
+ CommandObjectCommands.cpp
+ CommandObjectDisassemble.cpp
+ CommandObjectExpression.cpp
+ CommandObjectFrame.cpp
+ CommandObjectHelp.cpp
+ CommandObjectLog.cpp
+ CommandObjectMemory.cpp
+ CommandObjectMultiword.cpp
+ CommandObjectPlatform.cpp
+ CommandObjectPlugin.cpp
+ CommandObjectProcess.cpp
+ CommandObjectQuit.cpp
+ CommandObjectRegister.cpp
+ CommandObjectSettings.cpp
+ CommandObjectSource.cpp
+ CommandObjectSyntax.cpp
+ CommandObjectTarget.cpp
+ CommandObjectThread.cpp
+ CommandObjectType.cpp
+ CommandObjectVersion.cpp
+ CommandObjectWatchpoint.cpp
+ CommandObjectWatchpointCommand.cpp
+ )
Index: aze/lldb/source/Commands/CommandCompletions.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandCompletions.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandCompletions.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
// C Includes
#include <sys/stat.h>
@@ -130,7 +131,7 @@
// I'm going to use the "glob" function with GLOB_TILDE for user directory expansion.
// If it is not defined on your host system, you'll need to implement it yourself...
- int partial_name_len = strlen(partial_file_name);
+ size_t partial_name_len = strlen(partial_file_name);
if (partial_name_len >= PATH_MAX)
return matches.GetSize();
Index: aze/lldb/source/Commands/CommandObjectApropos.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectApropos.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectApropos.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectApropos.h"
// C Includes
@@ -54,7 +56,7 @@
bool
CommandObjectApropos::DoExecute (Args& args, CommandReturnObject &result)
{
- const int argc = args.GetArgumentCount ();
+ const size_t argc = args.GetArgumentCount ();
if (argc == 1)
{
Index: aze/lldb/source/Commands/CommandObjectArgs.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectArgs.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectArgs.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectArgs.h"
// C Includes
@@ -54,7 +56,7 @@
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -102,7 +104,7 @@
ConstString target_triple;
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (!process)
{
result.AppendError ("Args found no process.");
@@ -118,7 +120,7 @@
return false;
}
- int num_args = args.GetArgumentCount ();
+ const size_t num_args = args.GetArgumentCount ();
int arg_index;
if (!num_args)
@@ -128,7 +130,7 @@
return false;
}
- Thread *thread = m_interpreter.GetExecutionContext ().GetThreadPtr();
+ Thread *thread = m_exe_ctx.GetThreadPtr();
if (!thread)
{
Index: aze/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectBreakpointCommand.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectBreakpointCommand.cpp 2013-03-03 09:35:50.131457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
// C++ Includes
@@ -413,7 +415,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -532,6 +534,13 @@
if (result.Succeeded())
{
const size_t count = valid_bp_ids.GetSize();
+ if (count > 1)
+ {
+ result.AppendError ("can only add commands to one breakpoint at a time.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
for (size_t i = 0; i < count; ++i)
{
BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
Index: aze/lldb/source/Commands/CommandObjectBreakpoint.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectBreakpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectBreakpoint.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectBreakpoint.h"
#include "CommandObjectBreakpointCommand.h"
@@ -118,17 +120,15 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
case 'a':
- m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
- if (m_load_addr == LLDB_INVALID_ADDRESS)
- m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
-
- if (m_load_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
+ {
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+ m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+ }
break;
case 'b':
@@ -396,7 +396,7 @@
case eSetTypeFileAndLine: // Breakpoint by source position
{
FileSpec file;
- uint32_t num_files = m_options.m_filenames.GetSize();
+ const size_t num_files = m_options.m_filenames.GetSize();
if (num_files == 0)
{
if (!GetDefaultFile (target, file, result))
@@ -469,7 +469,7 @@
break;
case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
{
- int num_files = m_options.m_filenames.GetSize();
+ const size_t num_files = m_options.m_filenames.GetSize();
if (num_files == 0)
{
@@ -561,7 +561,7 @@
// Then use the current stack frame's file.
if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
{
- StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
+ StackFrame *cur_frame = m_exe_ctx.GetFramePtr();
if (cur_frame == NULL)
{
result.AppendError ("No selected frame to use to find the default file.");
@@ -629,7 +629,10 @@
"The breakpoint stops only for threads in the queue whose name is given by this argument."},
{ LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
- "Specifies the source file in which to set this breakpoint."},
+ "Specifies the source file in which to set this breakpoint. "
+ "Note, by default lldb only looks for files that are #included if they use the standard include file extensions. "
+ "To set breakpoints on .c/.cpp/.m/.mm files that are #included, set target.inline-breakpoint-strategy"
+ " to \"always\"."},
{ LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
"Specifies the line number on which to set this breakpoint."},
@@ -639,7 +642,7 @@
// { 0, false, "column", 'C', required_argument, NULL, "<column>",
// "Set the breakpoint by source location at this particular column."},
- { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress,
+ { LLDB_OPT_SET_2, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression,
"Set the breakpoint by address, at the specified address."},
{ LLDB_OPT_SET_3, true, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
@@ -746,7 +749,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1253,7 +1256,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1441,7 +1444,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1794,7 +1797,7 @@
Breakpoint *breakpoint = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
if (breakpoint != NULL)
{
- int num_locations = breakpoint->GetNumLocations();
+ const size_t num_locations = breakpoint->GetNumLocations();
if (cur_bp_id.GetLocationID() > num_locations)
{
StreamString id_str;
Index: aze/lldb/source/Commands/CommandObjectCommands.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectCommands.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectCommands.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectCommands.h"
// C Includes
@@ -72,7 +74,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
switch (short_option)
@@ -186,7 +188,7 @@
return "";
}
- int
+ virtual int
HandleArgumentCompletion (Args &input,
int &cursor_index,
int &cursor_char_position,
@@ -234,7 +236,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
switch (short_option)
@@ -283,7 +285,7 @@
bool
DoExecute(Args& command, CommandReturnObject &result)
{
- const int argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
if (argc == 1)
{
const char *filename = command.GetArgumentAtIndex(0);
@@ -1082,7 +1084,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1287,7 +1289,7 @@
{
}
- int
+ virtual int
HandleArgumentCompletion (Args &input,
int &cursor_index,
int &cursor_char_position,
@@ -1335,7 +1337,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1478,7 +1480,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
Index: aze/lldb/source/Commands/CommandObjectCrossref.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectCrossref.cpp 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,88 +0,0 @@
-//===-- CommandObjectCrossref.cpp -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Interpreter/CommandObjectCrossref.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Interpreter/CommandReturnObject.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-//-------------------------------------------------------------------------
-// CommandObjectCrossref
-//-------------------------------------------------------------------------
-
-CommandObjectCrossref::CommandObjectCrossref
-(
- CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax
-) :
- CommandObjectParsed (interpreter, name, help, syntax),
- m_crossref_object_types()
-{
-}
-
-CommandObjectCrossref::~CommandObjectCrossref ()
-{
-}
-
-bool
-CommandObjectCrossref::DoExecute (Args& command, CommandReturnObject &result)
-{
- if (m_crossref_object_types.GetArgumentCount() == 0)
- {
- result.AppendErrorWithFormat ("There are no objects for which you can call '%s'.\n", GetCommandName());
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- GenerateHelpText (result);
- }
- return result.Succeeded();
-}
-
-void
-CommandObjectCrossref::AddObject (const char *obj_name)
-{
- m_crossref_object_types.AppendArgument (obj_name);
-}
-
-const char **
-CommandObjectCrossref::GetObjectTypes () const
-{
- return m_crossref_object_types.GetConstArgumentVector();
-}
-
-void
-CommandObjectCrossref::GenerateHelpText (CommandReturnObject &result)
-{
- result.AppendMessage ("This command can be called on the following types of objects:");
-
- const size_t count = m_crossref_object_types.GetArgumentCount();
- for (size_t i = 0; i < count; ++i)
- {
- const char *obj_name = m_crossref_object_types.GetArgumentAtIndex(i);
- result.AppendMessageWithFormat (" %s (e.g. '%s %s')\n", obj_name,
- obj_name, GetCommandName());
- }
-
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
-}
-
-bool
-CommandObjectCrossref::IsCrossRefObject ()
-{
- return true;
-}
Index: aze/lldb/source/Commands/CommandObjectDisassemble.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectDisassemble.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectDisassemble.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectDisassemble.h"
// C Includes
@@ -38,12 +40,13 @@
num_lines_context(0),
num_instructions (0),
func_name(),
- cur_function (false),
+ current_function (false),
start_addr(),
end_addr (),
at_pc (false),
frame_line (false),
plugin_name (),
+ flavor_string(),
arch(),
some_location_specified (false)
{
@@ -59,7 +62,7 @@
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
@@ -86,23 +89,21 @@
break;
case 's':
- start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
- if (start_addr == LLDB_INVALID_ADDRESS)
- start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
-
- if (start_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("invalid start address string '%s'", option_arg);
- some_location_specified = true;
+ {
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+ start_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+ if (start_addr != LLDB_INVALID_ADDRESS)
+ some_location_specified = true;
+ }
break;
case 'e':
- end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
- if (end_addr == LLDB_INVALID_ADDRESS)
- end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
-
- if (end_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat ("invalid end address string '%s'", option_arg);
+ {
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+ end_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+ if (end_addr != LLDB_INVALID_ADDRESS)
+ some_location_specified = true;
+ }
break;
- some_location_specified = true;
case 'n':
func_name.assign (option_arg);
some_location_specified = true;
@@ -125,12 +126,24 @@
plugin_name.assign (option_arg);
break;
+ case 'F':
+ {
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
+ || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ flavor_string.assign (option_arg);
+ }
+ else
+ error.SetErrorStringWithFormat("Disassembler flavors are currently only supported for x86 and x86_64 targets.");
+ break;
+ }
case 'r':
raw = true;
break;
case 'f':
- cur_function = true;
+ current_function = true;
some_location_specified = true;
break;
@@ -155,13 +168,33 @@
num_lines_context = 0;
num_instructions = 0;
func_name.clear();
- cur_function = false;
+ current_function = false;
at_pc = false;
frame_line = false;
start_addr = LLDB_INVALID_ADDRESS;
end_addr = LLDB_INVALID_ADDRESS;
raw = false;
plugin_name.clear();
+
+ Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+
+ // This is a hack till we get the ability to specify features based on architecture. For now GetDisassemblyFlavor
+ // is really only valid for x86 (and for the llvm assembler plugin, but I'm papering over that since that is the
+ // only disassembler plugin we have...
+ if (target)
+ {
+ if (target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86
+ || target->GetArchitecture().GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ flavor_string.assign(target->GetDisassemblyFlavor());
+ }
+ else
+ flavor_string.assign ("default");
+
+ }
+ else
+ flavor_string.assign("default");
+
arch.Clear();
some_location_specified = false;
}
@@ -170,7 +203,7 @@
CommandObjectDisassemble::CommandOptions::OptionParsingFinished ()
{
if (!some_location_specified)
- at_pc = true;
+ current_function = true;
return Error();
}
@@ -184,24 +217,28 @@
OptionDefinition
CommandObjectDisassemble::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL , false , "bytes", 'b', no_argument , NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
-{ LLDB_OPT_SET_ALL , false , "context", 'C', required_argument , NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."},
-{ LLDB_OPT_SET_ALL , false , "mixed", 'm', no_argument , NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."},
-{ LLDB_OPT_SET_ALL , false , "raw", 'r', no_argument , NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
-{ LLDB_OPT_SET_ALL , false , "plugin", 'P', required_argument , NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
-{ LLDB_OPT_SET_ALL , false , "arch", 'a', required_argument , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
-{ LLDB_OPT_SET_1 |
- LLDB_OPT_SET_2 , true , "start-address" , 's', required_argument , NULL, 0, eArgTypeStartAddress,"Address at which to start disassembling."},
-{ LLDB_OPT_SET_1 , false , "end-address" , 'e', required_argument , NULL, 0, eArgTypeEndAddress, "Address at which to end disassembling."},
-{ LLDB_OPT_SET_2 |
- LLDB_OPT_SET_3 |
- LLDB_OPT_SET_4 |
- LLDB_OPT_SET_5 , false , "count", 'c', required_argument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
-{ LLDB_OPT_SET_3 , false , "name", 'n', required_argument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name."},
-{ LLDB_OPT_SET_4 , false , "frame", 'f', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
-{ LLDB_OPT_SET_5 , false , "pc", 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble around the current pc."},
-{ LLDB_OPT_SET_6 , false , "line", 'l', no_argument , NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there debug line table information, else disasemble around the pc."},
-{ 0 , false , NULL, 0, 0 , NULL, 0, eArgTypeNone, NULL }
+{ LLDB_OPT_SET_ALL, false, "bytes" , 'b', no_argument , NULL, 0, eArgTypeNone, "Show opcode bytes when disassembling."},
+{ LLDB_OPT_SET_ALL, false, "context" , 'C', required_argument , NULL, 0, eArgTypeNumLines, "Number of context lines of source to show."},
+{ LLDB_OPT_SET_ALL, false, "mixed" , 'm', no_argument , NULL, 0, eArgTypeNone, "Enable mixed source and assembly display."},
+{ LLDB_OPT_SET_ALL, false, "raw" , 'r', no_argument , NULL, 0, eArgTypeNone, "Print raw disassembly with no symbol information."},
+{ LLDB_OPT_SET_ALL, false, "plugin" , 'P', required_argument , NULL, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use."},
+{ LLDB_OPT_SET_ALL, false, "flavor" , 'F', required_argument , NULL, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. "
+ "Currently the only valid options are default, and for Intel"
+ " architectures, att and intel."},
+{ LLDB_OPT_SET_ALL, false, "arch" , 'a', required_argument , NULL, 0, eArgTypeArchitecture,"Specify the architecture to use from cross disassembly."},
+{ LLDB_OPT_SET_1 |
+ LLDB_OPT_SET_2 , true , "start-address", 's', required_argument , NULL, 0, eArgTypeAddressOrExpression,"Address at which to start disassembling."},
+{ LLDB_OPT_SET_1 , false, "end-address" , 'e', required_argument , NULL, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling."},
+{ LLDB_OPT_SET_2 |
+ LLDB_OPT_SET_3 |
+ LLDB_OPT_SET_4 |
+ LLDB_OPT_SET_5 , false, "count" , 'c', required_argument , NULL, 0, eArgTypeNumLines, "Number of instructions to display."},
+{ LLDB_OPT_SET_3 , false, "name" , 'n', required_argument , NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
+ "Disassemble entire contents of the given function name."},
+{ LLDB_OPT_SET_4 , false, "frame" , 'f', no_argument , NULL, 0, eArgTypeNone, "Disassemble from the start of the current frame's function."},
+{ LLDB_OPT_SET_5 , false, "pc" , 'p', no_argument , NULL, 0, eArgTypeNone, "Disassemble around the current pc."},
+{ LLDB_OPT_SET_6 , false, "line" , 'l', no_argument , NULL, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there debug line table information, else disasemble around the pc."},
+{ 0 , false, NULL , 0, 0 , NULL, 0, eArgTypeNone, NULL }
};
@@ -244,20 +281,26 @@
}
const char *plugin_name = m_options.GetPluginName ();
- DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, plugin_name);
+ const char *flavor_string = m_options.GetFlavorString();
+
+ DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name);
if (!disassembler)
{
if (plugin_name)
- result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
+ {
+ result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
plugin_name,
m_options.arch.GetArchitectureName());
+ }
else
result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n",
m_options.arch.GetArchitectureName());
result.SetStatus (eReturnStatusFailed);
return false;
}
+ else if (flavor_string != NULL && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
+ result.AppendWarningWithFormat("invalid disassembler flavor \"%s\", using default.\n", flavor_string);
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -272,7 +315,6 @@
if (m_options.show_mixed && m_options.num_lines_context == 0)
m_options.num_lines_context = 1;
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
// Always show the PC in the disassembly
uint32_t options = Disassembler::eOptionMarkPCAddress;
@@ -293,7 +335,8 @@
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
m_options.arch,
plugin_name,
- exe_ctx,
+ flavor_string,
+ m_exe_ctx,
name,
NULL, // Module *
m_options.num_instructions,
@@ -312,7 +355,7 @@
else
{
AddressRange range;
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
if (m_options.frame_line)
{
if (frame == NULL)
@@ -332,7 +375,7 @@
m_options.show_mixed = false;
}
}
- else if (m_options.cur_function)
+ else if (m_options.current_function)
{
if (frame == NULL)
{
@@ -413,7 +456,8 @@
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
m_options.arch,
plugin_name,
- exe_ctx,
+ flavor_string,
+ m_exe_ctx,
range.GetBaseAddress(),
m_options.num_instructions,
m_options.show_mixed ? m_options.num_lines_context : 0,
@@ -424,7 +468,7 @@
}
else
{
- result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.start_addr);
+ result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
result.SetStatus (eReturnStatusFailed);
}
}
@@ -459,7 +503,8 @@
if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
m_options.arch,
plugin_name,
- exe_ctx,
+ flavor_string,
+ m_exe_ctx,
range,
m_options.num_instructions,
m_options.show_mixed ? m_options.num_lines_context : 0,
@@ -470,7 +515,7 @@
}
else
{
- result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8llx.\n", m_options.start_addr);
+ result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
result.SetStatus (eReturnStatusFailed);
}
}
Index: aze/lldb/source/Commands/CommandObjectDisassemble.h
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectDisassemble.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectDisassemble.h 2013-03-03 09:35:50.135457355 +0100
@@ -53,6 +53,14 @@
return plugin_name.c_str();
}
+ const char *
+ GetFlavorString ()
+ {
+ if (flavor_string.empty() || flavor_string == "default")
+ return NULL;
+ return flavor_string.c_str();
+ }
+
virtual Error
OptionParsingFinished ();
@@ -62,12 +70,13 @@
uint32_t num_instructions;
bool raw;
std::string func_name;
- bool cur_function;
+ bool current_function;
lldb::addr_t start_addr;
lldb::addr_t end_addr;
bool at_pc;
bool frame_line;
std::string plugin_name;
+ std::string flavor_string;
ArchSpec arch;
bool some_location_specified; // If no location was specified, we'll select "at_pc". This should be set
// in SetOptionValue if anything the selects a location is set.
Index: aze/lldb/source/Commands/CommandObjectExpression.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectExpression.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectExpression.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectExpression.h"
// C Includes
@@ -51,10 +53,9 @@
CommandObjectExpression::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', required_argument, NULL, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "dynamic-value", 'd', required_argument, NULL, 0, eArgTypeBoolean, "Upcast the value resulting from the expression to its dynamic type if available."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', required_argument, NULL, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"},
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Timeout value for running the expression."},
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."},
- { LLDB_OPT_SET_2 , false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."},
};
@@ -71,7 +72,7 @@
{
Error error;
- const char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
@@ -94,27 +95,16 @@
}
break;
- case 'd':
+ case 'i':
{
bool success;
- bool result;
- result = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
- error.SetErrorStringWithFormat("invalid dynamic value setting: \"%s\"", option_arg);
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ ignore_breakpoints = tmp_value;
else
- {
- if (result)
- use_dynamic = eLazyBoolYes;
- else
- use_dynamic = eLazyBoolNo;
- }
+ error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
+ break;
}
- break;
-
- case 'o':
- print_object = true;
- break;
-
case 't':
{
bool success;
@@ -130,8 +120,10 @@
case 'u':
{
bool success;
- unwind_on_error = Args::StringToBoolean(option_arg, true, &success);
- if (!success)
+ bool tmp_value = Args::StringToBoolean(option_arg, true, &success);
+ if (success)
+ unwind_on_error = tmp_value;
+ else
error.SetErrorStringWithFormat("could not convert \"%s\" to a boolean value.", option_arg);
break;
}
@@ -146,10 +138,18 @@
void
CommandObjectExpression::CommandOptions::OptionParsingStarting (CommandInterpreter &interpreter)
{
- use_dynamic = eLazyBoolCalculate;
- print_object = false;
- unwind_on_error = true;
- show_types = true;
+ Process *process = interpreter.GetExecutionContext().GetProcessPtr();
+ if (process != NULL)
+ {
+ ignore_breakpoints = process->GetIgnoreBreakpointsInExpressions();
+ unwind_on_error = process->GetUnwindOnErrorInExpressions();
+ }
+ else
+ {
+ ignore_breakpoints = false;
+ unwind_on_error = true;
+ }
+
show_summary = true;
try_all_threads = true;
timeout = 0;
@@ -166,7 +166,7 @@
"expression",
"Evaluate a C/ObjC/C++ expression in the current program context, using user defined variables and variables currently in scope.",
NULL,
- eFlagProcessMustBePaused),
+ eFlagProcessMustBePaused | eFlagTryTargetAPILock),
m_option_group (interpreter),
m_format_options (eFormatDefault),
m_command_options (),
@@ -210,6 +210,7 @@
// Add the "--format" and "--gdb-format"
m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
m_option_group.Append (&m_command_options);
+ m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
m_option_group.Finalize();
}
@@ -313,7 +314,12 @@
CommandReturnObject *result
)
{
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
+ // Don't use m_exe_ctx as this might be called asynchronously
+ // after the command object DoExecute has finished when doing
+ // multi-line expression that use an input reader...
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+
+ Target *target = exe_ctx.GetTargetPtr();
if (!target)
target = Host::GetDummyTarget(m_interpreter.GetDebugger()).get();
@@ -325,40 +331,28 @@
ExecutionResults exe_results;
bool keep_in_memory = true;
- lldb::DynamicValueType use_dynamic;
- // If use dynamic is not set, get it from the target:
- switch (m_command_options.use_dynamic)
- {
- case eLazyBoolCalculate:
- use_dynamic = target->GetPreferDynamicValue();
- break;
- case eLazyBoolYes:
- use_dynamic = lldb::eDynamicCanRunTarget;
- break;
- case eLazyBoolNo:
- use_dynamic = lldb::eNoDynamicValues;
- break;
- }
-
+
EvaluateExpressionOptions options;
- options.SetCoerceToId(m_command_options.print_object)
+ options.SetCoerceToId(m_varobj_options.use_objc)
.SetUnwindOnError(m_command_options.unwind_on_error)
+ .SetIgnoreBreakpoints (m_command_options.ignore_breakpoints)
.SetKeepInMemory(keep_in_memory)
- .SetUseDynamic(use_dynamic)
+ .SetUseDynamic(m_varobj_options.use_dynamic)
.SetRunOthers(m_command_options.try_all_threads)
.SetTimeoutUsec(m_command_options.timeout);
exe_results = target->EvaluateExpression (expr,
- m_interpreter.GetExecutionContext().GetFramePtr(),
+ exe_ctx.GetFramePtr(),
result_valobj_sp,
options);
- if (exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
+ if ((exe_results == eExecutionInterrupted && !m_command_options.unwind_on_error)
+ ||(exe_results == eExecutionHitBreakpoint && !m_command_options.ignore_breakpoints))
{
uint32_t start_frame = 0;
uint32_t num_frames = 1;
uint32_t num_frames_with_source = 0;
- Thread *thread = m_interpreter.GetExecutionContext().GetThreadPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
if (thread)
{
thread->GetStatus (result->GetOutputStream(),
@@ -368,7 +362,7 @@
}
else
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = exe_ctx.GetProcessPtr();
if (process)
{
bool only_threads_with_stop_reason = true;
@@ -393,21 +387,26 @@
result_valobj_sp->SetFormat (format);
ValueObject::DumpValueObjectOptions options;
- options.SetMaximumPointerDepth(0)
- .SetMaximumDepth(UINT32_MAX)
- .SetShowLocation(false)
- .SetShowTypes(m_command_options.show_types)
- .SetUseObjectiveC(m_command_options.print_object)
- .SetUseDynamicType(use_dynamic)
- .SetScopeChecked(true)
- .SetFlatOutput(false)
- .SetUseSyntheticValue(true)
- .SetIgnoreCap(false)
+ options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
+ .SetMaximumDepth(m_varobj_options.max_depth)
+ .SetShowTypes(m_varobj_options.show_types)
+ .SetShowLocation(m_varobj_options.show_location)
+ .SetUseObjectiveC(m_varobj_options.use_objc)
+ .SetUseDynamicType(m_varobj_options.use_dynamic)
+ .SetUseSyntheticValue(m_varobj_options.use_synth)
+ .SetFlatOutput(m_varobj_options.flat_output)
+ .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
+ .SetIgnoreCap(m_varobj_options.ignore_cap)
.SetFormat(format)
.SetSummary()
- .SetShowSummary(!m_command_options.print_object)
- .SetHideRootType(m_command_options.print_object);
+ .SetShowSummary(!m_varobj_options.use_objc)
+ .SetHideRootType(m_varobj_options.use_objc)
+ .SetHideName(m_varobj_options.use_objc)
+ .SetHideValue(m_varobj_options.use_objc);
+ if (m_varobj_options.be_raw)
+ options.SetRawDisplay(true);
+
ValueObject::DumpValueObject (*(output_stream),
result_valobj_sp.get(), // Variable object to dump
options);
@@ -432,7 +431,7 @@
const char *error_cstr = result_valobj_sp->GetError().AsCString();
if (error_cstr && error_cstr[0])
{
- int error_cstr_len = strlen (error_cstr);
+ const size_t error_cstr_len = strlen (error_cstr);
const bool ends_with_newline = error_cstr[error_cstr_len - 1] == '\n';
if (strstr(error_cstr, "error:") != error_cstr)
error_stream->PutCString ("error: ");
Index: aze/lldb/source/Commands/CommandObjectExpression.h
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectExpression.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectExpression.h 2013-03-03 09:35:50.135457355 +0100
@@ -16,6 +16,7 @@
// Project includes
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
#include "lldb/Target/ExecutionContext.h"
namespace lldb_private {
@@ -50,9 +51,8 @@
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
- bool print_object;
- LazyBool use_dynamic;
bool unwind_on_error;
+ bool ignore_breakpoints;
bool show_types;
bool show_summary;
uint32_t timeout;
@@ -88,6 +88,7 @@
OptionGroupOptions m_option_group;
OptionGroupFormat m_format_options;
+ OptionGroupValueObjectDisplay m_varobj_options;
CommandOptions m_command_options;
uint32_t m_expr_line_count;
std::string m_expr_lines; // Multi-line expression support
Index: aze/lldb/source/Commands/CommandObjectFrame.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectFrame.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectFrame.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectFrame.h"
// C Includes
@@ -14,7 +16,6 @@
#include <string>
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
@@ -23,6 +24,7 @@
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -61,7 +63,10 @@
"frame info",
"List information about the currently selected frame in the current thread.",
"frame info",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
}
@@ -71,21 +76,10 @@
protected:
bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
- {
- frame->DumpUsingSettingsFormat (&result.GetOutputStream());
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendError ("no current frame");
- result.SetStatus (eReturnStatusFailed);
- }
+ m_exe_ctx.GetFrameRef().DumpUsingSettingsFormat (&result.GetOutputStream());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
@@ -120,7 +114,7 @@
{
Error error;
bool success = false;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
case 'r':
@@ -160,7 +154,10 @@
"frame select",
"Select a frame by index from within the current thread and make it the current frame.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -191,113 +188,92 @@
protected:
bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- Thread *thread = exe_ctx.GetThreadPtr();
- if (thread)
+ // No need to check "thread" for validity as eFlagRequiresThread ensures it is valid
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+
+ uint32_t frame_idx = UINT32_MAX;
+ if (m_options.relative_frame_offset != INT32_MIN)
{
- uint32_t frame_idx = UINT32_MAX;
- if (m_options.relative_frame_offset != INT32_MIN)
+ // The one and only argument is a signed relative frame index
+ frame_idx = thread->GetSelectedFrameIndex ();
+ if (frame_idx == UINT32_MAX)
+ frame_idx = 0;
+
+ if (m_options.relative_frame_offset < 0)
{
- // The one and only argument is a signed relative frame index
- frame_idx = thread->GetSelectedFrameIndex ();
- if (frame_idx == UINT32_MAX)
- frame_idx = 0;
-
- if (m_options.relative_frame_offset < 0)
+ if (frame_idx >= -m_options.relative_frame_offset)
+ frame_idx += m_options.relative_frame_offset;
+ else
{
- if (frame_idx >= -m_options.relative_frame_offset)
- frame_idx += m_options.relative_frame_offset;
- else
+ if (frame_idx == 0)
{
- if (frame_idx == 0)
- {
- //If you are already at the bottom of the stack, then just warn and don't reset the frame.
- result.AppendError("Already at the bottom of the stack");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else
- frame_idx = 0;
+ //If you are already at the bottom of the stack, then just warn and don't reset the frame.
+ result.AppendError("Already at the bottom of the stack");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- }
- else if (m_options.relative_frame_offset > 0)
- {
- // I don't want "up 20" where "20" takes you past the top of the stack to produce
- // an error, but rather to just go to the top. So I have to count the stack here...
- const uint32_t num_frames = thread->GetStackFrameCount();
- if (num_frames - frame_idx > m_options.relative_frame_offset)
- frame_idx += m_options.relative_frame_offset;
else
- {
- if (frame_idx == num_frames - 1)
- {
- //If we are already at the top of the stack, just warn and don't reset the frame.
- result.AppendError("Already at the top of the stack");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
- else
- frame_idx = num_frames - 1;
- }
+ frame_idx = 0;
}
}
- else
+ else if (m_options.relative_frame_offset > 0)
{
- if (command.GetArgumentCount() == 1)
- {
- const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
- frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
- }
- else if (command.GetArgumentCount() == 0)
+ // I don't want "up 20" where "20" takes you past the top of the stack to produce
+ // an error, but rather to just go to the top. So I have to count the stack here...
+ const uint32_t num_frames = thread->GetStackFrameCount();
+ if (num_frames - frame_idx > m_options.relative_frame_offset)
+ frame_idx += m_options.relative_frame_offset;
+ else
{
- frame_idx = thread->GetSelectedFrameIndex ();
- if (frame_idx == UINT32_MAX)
+ if (frame_idx == num_frames - 1)
{
- frame_idx = 0;
+ //If we are already at the top of the stack, just warn and don't reset the frame.
+ result.AppendError("Already at the top of the stack");
+ result.SetStatus(eReturnStatusFailed);
+ return false;
}
- }
- else
- {
- result.AppendError ("invalid arguments.\n");
- m_options.GenerateOptionUsage (result.GetErrorStream(), this);
+ else
+ frame_idx = num_frames - 1;
}
}
-
- const bool broadcast = true;
- bool success = thread->SetSelectedFrameByIndex (frame_idx, broadcast);
- if (success)
+ }
+ else
+ {
+ if (command.GetArgumentCount() == 1)
+ {
+ const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
+ frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
+ }
+ else if (command.GetArgumentCount() == 0)
{
- exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
+ frame_idx = thread->GetSelectedFrameIndex ();
+ if (frame_idx == UINT32_MAX)
{
- bool already_shown = false;
- SymbolContext frame_sc(frame->GetSymbolContext(eSymbolContextLineEntry));
- if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
- {
- already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
- }
-
- bool show_frame_info = true;
- bool show_source = !already_shown;
- if (frame->GetStatus (result.GetOutputStream(), show_frame_info, show_source))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return result.Succeeded();
- }
+ frame_idx = 0;
}
}
- result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
+ else
+ {
+ result.AppendError ("invalid arguments.\n");
+ m_options.GenerateOptionUsage (result.GetErrorStream(), this);
+ }
+ }
+
+ bool success = thread->SetSelectedFrameByIndexNoisily (frame_idx, result.GetOutputStream());
+ if (success)
+ {
+ m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
{
- result.AppendError ("no current thread");
+ result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
+ result.SetStatus (eReturnStatusFailed);
}
- result.SetStatus (eReturnStatusFailed);
- return false;
+
+ return result.Succeeded();
}
protected:
@@ -329,7 +305,11 @@
"Children of aggregate variables can be specified such as "
"'var->child.x'.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused |
+ eFlagRequiresProcess),
m_option_group (interpreter),
m_option_variable(true), // Include the frame specific options by passing "true"
m_option_format (eFormatDefault),
@@ -370,14 +350,8 @@
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
- {
- result.AppendError ("you must be stopped in a valid stack frame to view frame variables.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ // No need to check "frame" for validity as eFlagRequiresFrame ensures it is valid
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
Stream &s = result.GetOutputStream();
@@ -432,7 +406,7 @@
{
if (m_option_variable.use_regex)
{
- const uint32_t regex_start_index = regex_var_list.GetSize();
+ const size_t regex_start_index = regex_var_list.GetSize();
RegularExpression regex (name_cstr);
if (regex.Compile(name_cstr))
{
@@ -442,7 +416,7 @@
num_matches);
if (num_new_regex_vars > 0)
{
- for (uint32_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize();
+ for (size_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize();
regex_idx < end_index;
++regex_idx)
{
@@ -525,10 +499,10 @@
}
else // No command arg specified. Use variable_list, instead.
{
- const uint32_t num_variables = variable_list->GetSize();
+ const size_t num_variables = variable_list->GetSize();
if (num_variables > 0)
{
- for (uint32_t i=0; i<num_variables; i++)
+ for (size_t i=0; i<num_variables; i++)
{
var_sp = variable_list->GetVariableAtIndex(i);
bool dump_variable = true;
Index: aze/lldb/source/Commands/CommandObjectHelp.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectHelp.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectHelp.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectHelp.h"
// C Includes
@@ -62,7 +64,7 @@
{
CommandObject::CommandMap::iterator pos;
CommandObject *cmd_obj;
- const int argc = command.GetArgumentCount ();
+ const size_t argc = command.GetArgumentCount ();
// 'help' doesn't take any arguments, other than command names. If argc is 0, we show the user
// all commands (aliases and user commands if asked for). Otherwise every argument must be the name of a command or a sub-command.
@@ -171,8 +173,9 @@
{
// Also emit a warning about using "--" in case you are using a command that takes options and arguments.
m_interpreter.OutputFormattedHelpText (output_strm, "", "",
- "\nThis command takes options and arguments, if your arguments look like option specifiers"
- " you must use '--' to terminate the options before starting to give the arguments.", 1);
+ "\nThis command takes options and free-form arguments. If your arguments resemble"
+ " option specifiers (i.e., they start with a - or --), you must use ' -- ' between"
+ " the end of the command options and the beginning of the arguments.", 1);
}
// Mark this help command with a success status.
@@ -221,8 +224,8 @@
{
Stream &output_strm = result.GetOutputStream();
output_strm.Printf("Help requested with ambiguous command name, possible completions:\n");
- const uint32_t match_count = matches.GetSize();
- for (uint32_t i = 0; i < match_count; i++)
+ const size_t match_count = matches.GetSize();
+ for (size_t i = 0; i < match_count; i++)
{
output_strm.Printf("\t%s\n", matches.GetStringAtIndex(i));
}
Index: aze/lldb/source/Commands/CommandObjectHelp.h
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectHelp.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectHelp.h 2013-03-03 09:35:50.135457355 +0100
@@ -57,7 +57,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
Index: aze/lldb/source/Commands/CommandObjectLog.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectLog.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectLog.cpp 2013-03-03 09:35:50.135457355 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectLog.h"
// C Includes
@@ -132,11 +134,11 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
- case 'f': log_file = option_arg; break;
+ case 'f': log_file.SetFile(option_arg, true); break;
case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; break;
case 'v': log_options |= LLDB_LOG_OPTION_VERBOSE; break;
case 'g': log_options |= LLDB_LOG_OPTION_DEBUG; break;
@@ -156,7 +158,7 @@
void
OptionParsingStarting ()
{
- log_file.clear();
+ log_file.Clear();
log_options = 0;
}
@@ -172,7 +174,7 @@
// Instance variables to hold the values for command options.
- std::string log_file;
+ FileSpec log_file;
uint32_t log_options;
};
@@ -189,9 +191,14 @@
{
std::string channel(args.GetArgumentAtIndex(0));
args.Shift (); // Shift off the channel
+ char log_file[PATH_MAX];
+ if (m_options.log_file)
+ m_options.log_file.GetPath(log_file, sizeof(log_file));
+ else
+ log_file[0] = '\0';
bool success = m_interpreter.GetDebugger().EnableLog (channel.c_str(),
args.GetConstArgumentVector(),
- m_options.log_file.c_str(),
+ log_file,
m_options.log_options,
result.GetErrorStream());
if (success)
Index: aze/lldb/source/Commands/CommandObjectMemory.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectMemory.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectMemory.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectMemory.h"
// C Includes
@@ -82,7 +84,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
@@ -190,7 +192,7 @@
if (byte_size_option_set)
{
if (byte_size_value > 1)
- error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %llu\n"
+ error.SetErrorStringWithFormat ("display format (bytes/bytes with ascii) conflicts with the specified byte size %" PRIu64 "\n"
"\tconsider using a different display format or don't specify the byte size",
byte_size_value.GetCurrentValue());
}
@@ -296,7 +298,7 @@
"memory read",
"Read from the memory of the process being debugged.",
NULL,
- eFlagProcessMustBePaused),
+ eFlagRequiresTarget | eFlagProcessMustBePaused),
m_option_group (interpreter),
m_format_options (eFormatBytesWithASCII, 1, 8),
m_memory_options (),
@@ -315,14 +317,14 @@
CommandArgumentData end_addr_arg;
// Define the first (and only) variant of this arg.
- start_addr_arg.arg_type = eArgTypeStartAddress;
+ start_addr_arg.arg_type = eArgTypeAddressOrExpression;
start_addr_arg.arg_repetition = eArgRepeatPlain;
// There is only one variant this argument could be; put it into the argument entry.
arg1.push_back (start_addr_arg);
// Define the first (and only) variant of this arg.
- end_addr_arg.arg_type = eArgTypeEndAddress;
+ end_addr_arg.arg_type = eArgTypeAddressOrExpression;
end_addr_arg.arg_repetition = eArgRepeatOptional;
// There is only one variant this argument could be; put it into the argument entry.
@@ -367,23 +369,17 @@
protected:
virtual bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- Target *target = exe_ctx.GetTargetPtr();
- if (target == NULL)
- {
- result.AppendError("need at least a target to read memory");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ // No need to check "target" for validity as eFlagRequiresTarget ensures it is valid
+ Target *target = m_exe_ctx.GetTargetPtr();
+
const size_t argc = command.GetArgumentCount();
-
if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
{
- result.AppendErrorWithFormat ("%s takes 1 or two args.\n", m_cmd_name.c_str());
+ result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str());
+ result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.\n");
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -391,11 +387,11 @@
ClangASTType clang_ast_type;
Error error;
- Format format = m_format_options.GetFormat();
const char *view_as_type_cstr = m_memory_options.m_view_as_type.GetCurrentValue();
if (view_as_type_cstr && view_as_type_cstr[0])
{
// We are viewing memory as a type
+
SymbolContext sc;
const bool exact_match = false;
TypeList type_list;
@@ -494,7 +490,7 @@
}
ConstString lookup_type_name(type_str.c_str());
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
if (frame)
{
sc = frame->GetSymbolContext (eSymbolContextModule);
@@ -563,7 +559,7 @@
// Look for invalid combinations of settings
if (error.Fail())
{
- result.AppendErrorWithFormat("%s", error.AsCString());
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -576,7 +572,8 @@
// if no options have been set
addr = m_next_addr;
total_byte_size = m_prev_byte_size;
- if (!m_format_options.AnyOptionWasSet() &&
+ clang_ast_type = m_prev_clang_ast_type;
+ if (!m_format_options.AnyOptionWasSet() &&
!m_memory_options.AnyOptionWasSet() &&
!m_outfile_options.AnyOptionWasSet() &&
!m_varobj_options.AnyOptionWasSet())
@@ -589,7 +586,7 @@
}
size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
- const size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+ size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
if (total_byte_size == 0)
@@ -600,33 +597,35 @@
}
if (argc > 0)
- addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
+ addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
if (addr == LLDB_INVALID_ADDRESS)
{
- result.AppendErrorWithFormat("invalid start address string '%s'.\n", command.GetArgumentAtIndex(0));
+ result.AppendError("invalid start address expression.");
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
if (argc == 2)
{
- lldb::addr_t end_addr = Args::StringToUInt64(command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
+ lldb::addr_t end_addr = Args::StringToAddress(&m_exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
if (end_addr == LLDB_INVALID_ADDRESS)
{
- result.AppendErrorWithFormat("invalid end address string '%s'.\n", command.GetArgumentAtIndex(1));
+ result.AppendError("invalid end address expression.");
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
else if (end_addr <= addr)
{
- result.AppendErrorWithFormat("end address (0x%llx) must be greater that the start address (0x%llx).\n", end_addr, addr);
+ result.AppendErrorWithFormat("end address (0x%" PRIx64 ") must be greater that the start address (0x%" PRIx64 ").\n", end_addr, addr);
result.SetStatus(eReturnStatusFailed);
return false;
}
else if (m_format_options.GetCountValue().OptionWasSet())
{
- result.AppendErrorWithFormat("specify either the end address (0x%llx) or the count (--count %lu), not both.\n", end_addr, item_count);
+ result.AppendErrorWithFormat("specify either the end address (0x%" PRIx64 ") or the count (--count %lu), not both.\n", end_addr, item_count);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -642,9 +641,19 @@
return false;
}
+
+
DataBufferSP data_sp;
size_t bytes_read = 0;
- if (!clang_ast_type.GetOpaqueQualType())
+ if (clang_ast_type.GetOpaqueQualType())
+ {
+ // Make sure we don't display our type as ASCII bytes like the default memory read
+ if (m_format_options.GetFormatValue().OptionWasSet() == false)
+ m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
+
+ bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
+ }
+ else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
{
data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Address address(addr, NULL);
@@ -658,24 +667,63 @@
}
else
{
- result.AppendErrorWithFormat("failed to read memory from 0x%llx.\n", addr);
+ result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
}
result.SetStatus(eReturnStatusFailed);
return false;
}
if (bytes_read < total_byte_size)
- result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%llx.\n", bytes_read, total_byte_size, addr);
- else
- {
- m_next_addr = addr + bytes_read;
- m_prev_byte_size = bytes_read;
- m_prev_format_options = m_format_options;
- m_prev_memory_options = m_memory_options;
- m_prev_outfile_options = m_outfile_options;
- m_prev_varobj_options = m_varobj_options;
- }
+ result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".\n", bytes_read, total_byte_size, addr);
}
+ else
+ {
+ // we treat c-strings as a special case because they do not have a fixed size
+ if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
+ item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+ else
+ item_byte_size = target->GetMaximumSizeOfStringSummary();
+ if (!m_format_options.GetCountValue().OptionWasSet())
+ item_count = 1;
+ data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
+ uint8_t *data_ptr = data_sp->GetBytes();
+ auto data_addr = addr;
+ auto count = item_count;
+ item_count = 0;
+ while (item_count < count)
+ {
+ std::string buffer;
+ buffer.resize(item_byte_size+1,0);
+ Error error;
+ size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
+ if (error.Fail())
+ {
+ result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (item_byte_size == read)
+ {
+ result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
+ break;
+ }
+ read+=1; // account for final NULL byte
+ memcpy(data_ptr, &buffer[0], read);
+ data_ptr += read;
+ data_addr += read;
+ bytes_read += read;
+ item_count++; // if we break early we know we only read item_count strings
+ }
+ data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
+ }
+
+ m_next_addr = addr + bytes_read;
+ m_prev_byte_size = bytes_read;
+ m_prev_format_options = m_format_options;
+ m_prev_memory_options = m_memory_options;
+ m_prev_outfile_options = m_outfile_options;
+ m_prev_varobj_options = m_varobj_options;
+ m_prev_clang_ast_type = clang_ast_type;
StreamFile outfile_stream;
Stream *output_stream = NULL;
@@ -694,10 +742,10 @@
{
if (m_memory_options.m_output_as_binary)
{
- int bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
+ const size_t bytes_written = outfile_stream.Write (data_sp->GetBytes(), bytes_read);
if (bytes_written > 0)
{
- result.GetOutputStream().Printf ("%i bytes %s to '%s'\n",
+ result.GetOutputStream().Printf ("%zi bytes %s to '%s'\n",
bytes_written,
append ? "appended" : "written",
path);
@@ -705,7 +753,7 @@
}
else
{
- result.AppendErrorWithFormat("Failed to write %llu bytes to '%s'.\n", (uint64_t)bytes_read, path);
+ result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", (uint64_t)bytes_read, path);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -730,7 +778,7 @@
}
- ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
+ ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
if (clang_ast_type.GetOpaqueQualType())
{
for (uint32_t i = 0; i<item_count; ++i)
@@ -738,13 +786,14 @@
addr_t item_addr = addr + (i * item_byte_size);
Address address (item_addr);
StreamString name_strm;
- name_strm.Printf ("0x%llx", item_addr);
+ name_strm.Printf ("0x%" PRIx64, item_addr);
ValueObjectSP valobj_sp (ValueObjectMemory::Create (exe_scope,
name_strm.GetString().c_str(),
address,
clang_ast_type));
if (valobj_sp)
{
+ Format format = m_format_options.GetFormat();
if (format != eFormatDefault)
valobj_sp->SetFormat (format);
@@ -786,16 +835,16 @@
assert (output_stream);
- uint32_t bytes_dumped = data.Dump (output_stream,
- 0,
- m_format_options.GetFormat(),
- item_byte_size,
- item_count,
- num_per_line,
- addr,
- 0,
- 0,
- exe_scope);
+ size_t bytes_dumped = data.Dump (output_stream,
+ 0,
+ m_format_options.GetFormat(),
+ item_byte_size,
+ item_count,
+ num_per_line,
+ addr,
+ 0,
+ 0,
+ exe_scope);
m_next_addr = addr + bytes_dumped;
output_stream->EOL();
return true;
@@ -812,6 +861,7 @@
OptionGroupReadMemory m_prev_memory_options;
OptionGroupOutputFile m_prev_outfile_options;
OptionGroupValueObjectDisplay m_prev_varobj_options;
+ ClangASTType m_prev_clang_ast_type;
};
@@ -861,7 +911,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_memory_write_option_table[option_idx].short_option;
+ const int short_option = g_memory_write_option_table[option_idx].short_option;
switch (short_option)
{
@@ -908,7 +958,7 @@
"memory write",
"Write to the memory of the process being debugged.",
NULL,
- eFlagProcessMustBeLaunched),
+ eFlagRequiresProcess | eFlagProcessMustBeLaunched),
m_option_group (interpreter),
m_format_options (eFormatBytes, 1, UINT64_MAX),
m_memory_options ()
@@ -985,13 +1035,8 @@
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError("need a process to read memory");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
+ // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+ Process *process = m_exe_ctx.GetProcessPtr();
const size_t argc = command.GetArgumentCount();
@@ -1018,11 +1063,16 @@
OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
size_t item_byte_size = byte_size_value.GetCurrentValue();
- lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
+ Error error;
+ lldb::addr_t addr = Args::StringToAddress (&m_exe_ctx,
+ command.GetArgumentAtIndex(0),
+ LLDB_INVALID_ADDRESS,
+ &error);
if (addr == LLDB_INVALID_ADDRESS)
{
- result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0));
+ result.AppendError("invalid address expression\n");
+ result.AppendError(error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1044,18 +1094,18 @@
if (bytes_written == length)
{
// All bytes written
- result.GetOutputStream().Printf("%llu bytes were written to 0x%llx\n", (uint64_t)bytes_written, addr);
+ result.GetOutputStream().Printf("%" PRIu64 " bytes were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, addr);
result.SetStatus(eReturnStatusSuccessFinishResult);
}
else if (bytes_written > 0)
{
// Some byte written
- result.GetOutputStream().Printf("%llu bytes of %llu requested were written to 0x%llx\n", (uint64_t)bytes_written, (uint64_t)length, addr);
+ result.GetOutputStream().Printf("%" PRIu64 " bytes of %" PRIu64 " requested were written to 0x%" PRIx64 "\n", (uint64_t)bytes_written, (uint64_t)length, addr);
result.SetStatus(eReturnStatusSuccessFinishResult);
}
else
{
- result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
+ result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
result.SetStatus(eReturnStatusFailed);
}
}
@@ -1079,9 +1129,8 @@
uint64_t uval64;
int64_t sval64;
bool success = false;
- const uint32_t num_value_args = command.GetArgumentCount();
- uint32_t i;
- for (i=0; i<num_value_args; ++i)
+ const size_t num_value_args = command.GetArgumentCount();
+ for (size_t i=0; i<num_value_args; ++i)
{
const char *value_str = command.GetArgumentAtIndex(i);
@@ -1133,7 +1182,7 @@
}
else if (!UIntValueIsValidForSize (uval64, item_byte_size))
{
- result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
+ result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1161,7 +1210,7 @@
}
else if (!UIntValueIsValidForSize (uval64, item_byte_size))
{
- result.AppendErrorWithFormat ("Value 0x%llx is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
+ result.AppendErrorWithFormat ("Value 0x%" PRIx64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1184,7 +1233,7 @@
}
else
{
- result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
+ result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1201,7 +1250,7 @@
}
else if (!SIntValueIsValidForSize (sval64, item_byte_size))
{
- result.AppendErrorWithFormat ("Value %lli is too large or small to fit in a %lu byte signed integer value.\n", sval64, item_byte_size);
+ result.AppendErrorWithFormat ("Value %" PRIi64 " is too large or small to fit in a %lu byte signed integer value.\n", sval64, item_byte_size);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1218,7 +1267,7 @@
}
else if (!UIntValueIsValidForSize (uval64, item_byte_size))
{
- result.AppendErrorWithFormat ("Value %llu is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
+ result.AppendErrorWithFormat ("Value %" PRIu64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1235,7 +1284,7 @@
}
else if (!UIntValueIsValidForSize (uval64, item_byte_size))
{
- result.AppendErrorWithFormat ("Value %llo is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
+ result.AppendErrorWithFormat ("Value %" PRIo64 " is too large to fit in a %lu byte unsigned integer value.\n", uval64, item_byte_size);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1251,7 +1300,7 @@
return true;
else
{
- result.AppendErrorWithFormat ("Memory write to 0x%llx failed: %s.\n", addr, error.AsCString());
+ result.AppendErrorWithFormat ("Memory write to 0x%" PRIx64 " failed: %s.\n", addr, error.AsCString());
result.SetStatus(eReturnStatusFailed);
return false;
}
Index: aze/lldb/source/Commands/CommandObjectMultiword.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectMultiword.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectMultiword.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/CommandObjectMultiword.h"
// C Includes
// C++ Includes
@@ -32,7 +34,8 @@
const char *syntax,
uint32_t flags
) :
- CommandObject (interpreter, name, help, syntax, flags)
+ CommandObject (interpreter, name, help, syntax, flags),
+ m_can_be_removed(false)
{
}
@@ -98,7 +101,6 @@
if (pos == m_subcommand_dict.end())
{
m_subcommand_dict[name] = cmd_obj;
- m_interpreter.CrossRegisterCommand (name, GetCommandName());
}
else
success = false;
@@ -141,7 +143,7 @@
else
{
std::string error_msg;
- int num_subcmd_matches = matches.GetSize();
+ const size_t num_subcmd_matches = matches.GetSize();
if (num_subcmd_matches > 0)
error_msg.assign ("ambiguous command ");
else
@@ -156,14 +158,14 @@
if (num_subcmd_matches > 0)
{
error_msg.append (" Possible completions:");
- for (int i = 0; i < num_subcmd_matches; i++)
+ for (size_t i = 0; i < num_subcmd_matches; i++)
{
error_msg.append ("\n\t");
error_msg.append (matches.GetStringAtIndex (i));
}
}
error_msg.append ("\n");
- result.AppendRawError (error_msg.c_str(), error_msg.size());
+ result.AppendRawError (error_msg.c_str());
result.SetStatus (eReturnStatusFailed);
}
}
@@ -362,23 +364,6 @@
return NULL;
}
-void
-CommandObjectProxy::AddObject (const char *obj_name)
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->AddObject (obj_name);
-}
-
-bool
-CommandObjectProxy::IsCrossRefObject ()
-{
- CommandObject *proxy_command = GetProxyCommandObject();
- if (proxy_command)
- return proxy_command->IsCrossRefObject();
- return false;
-}
-
bool
CommandObjectProxy::IsRemovable() const
{
Index: aze/lldb/source/Commands/CommandObjectPlatform.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectPlatform.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectPlatform.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectPlatform.h"
// C Includes
@@ -355,11 +357,11 @@
{
public:
CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) :
- CommandObjectParsed (interpreter,
+ CommandObjectParsed (interpreter,
"platform process launch",
"Launch a new process on a remote platform.",
"platform process launch program",
- 0),
+ eFlagRequiresTarget | eFlagTryTargetAPILock),
m_options (interpreter)
{
}
@@ -384,15 +386,8 @@
if (platform_sp)
{
Error error;
- const uint32_t argc = args.GetArgumentCount();
- Target *target = m_interpreter.GetExecutionContext().GetTargetPtr();
- if (target == NULL)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
+ const size_t argc = args.GetArgumentCount();
+ Target *target = m_exe_ctx.GetTargetPtr();
Module *exe_module = target->GetExecutableModulePointer();
if (exe_module)
{
@@ -519,7 +514,7 @@
}
else
{
- result.AppendErrorWithFormat ("no process found with pid = %llu\n", pid);
+ result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid);
result.SetStatus (eReturnStatusFailed);
}
}
@@ -606,7 +601,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success = false;
switch (short_option)
@@ -796,12 +791,12 @@
ProcessInstanceInfo proc_info;
if (platform_sp->GetProcessInfo (pid, proc_info))
{
- ostrm.Printf ("Process information for process %llu:\n", pid);
+ ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid);
proc_info.Dump (ostrm, platform_sp.get());
}
else
{
- ostrm.Printf ("error: no process information is available for process %llu\n", pid);
+ ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid);
}
ostrm.EOL();
}
Index: aze/lldb/source/Commands/CommandObjectPlugin.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectPlugin.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectPlugin.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectPlugin.h"
#include "lldb/API/SBDebugger.h"
Index: aze/lldb/source/Commands/CommandObjectProcess.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectProcess.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectProcess.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectProcess.h"
// C Includes
@@ -44,7 +46,8 @@
CommandObjectParsed (interpreter,
"process launch",
"Launch the executable in the debugger.",
- NULL),
+ NULL,
+ eFlagRequiresTarget),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -66,7 +69,7 @@
{
}
- int
+ virtual int
HandleArgumentCompletion (Args &input,
int &cursor_index,
int &cursor_char_position,
@@ -109,13 +112,6 @@
Debugger &debugger = m_interpreter.GetDebugger();
Target *target = debugger.GetSelectedTarget().get();
Error error;
-
- if (target == NULL)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
// If our listener is NULL, users aren't allows to launch
char filename[PATH_MAX];
const Module *exe_module = target->GetExecutableModulePointer();
@@ -128,7 +124,7 @@
}
StateType state = eStateInvalid;
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process)
{
state = process->GetState();
@@ -203,6 +199,11 @@
if (environment.GetArgumentCount() > 0)
m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
+ // Get the value of synchronous execution here. If you wait till after you have started to
+ // run, then you could have hit a breakpoint, whose command might switch the value, and
+ // then you'll pick up that incorrect value.
+ bool synchronous_execution = m_interpreter.GetSynchronous ();
+
// Finalize the file actions, and if none were given, default to opening
// up a pseudo terminal
const bool default_to_use_pty = true;
@@ -250,7 +251,7 @@
{
const char *archname = exe_module->GetArchitecture().GetArchitectureName();
- result.AppendMessageWithFormat ("Process %llu launched: '%s' (%s)\n", process->GetID(), filename, archname);
+ result.AppendMessageWithFormat ("Process %" PRIu64 " launched: '%s' (%s)\n", process->GetID(), filename, archname);
result.SetDidChangeProcessState (true);
if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
{
@@ -262,7 +263,6 @@
error = process->Resume();
if (error.Success())
{
- bool synchronous_execution = m_interpreter.GetSynchronous ();
if (synchronous_execution)
{
state = process->WaitForProcessToStop (NULL);
@@ -355,7 +355,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success = false;
switch (short_option)
{
@@ -450,10 +450,10 @@
match_info.SetNameMatchType(eNameMatchStartsWith);
}
platform_sp->FindProcesses (match_info, process_infos);
- const uint32_t num_matches = process_infos.GetSize();
+ const size_t num_matches = process_infos.GetSize();
if (num_matches > 0)
{
- for (uint32_t i=0; i<num_matches; ++i)
+ for (size_t i=0; i<num_matches; ++i)
{
matches.AppendString (process_infos.GetProcessNameAtIndex(i),
process_infos.GetProcessNameLengthAtIndex(i));
@@ -503,14 +503,14 @@
// and the target actually stopping. So even if the interpreter is set to be asynchronous, we wait for the stop
// ourselves here.
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
StateType state = eStateInvalid;
if (process)
{
state = process->GetState();
if (process->IsAlive() && state != eStateConnected)
{
- result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before attaching.\n",
+ result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before attaching.\n",
process->GetID());
result.SetStatus (eReturnStatusFailed);
return false;
@@ -597,7 +597,7 @@
if (state == eStateStopped)
{
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
+ result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -640,7 +640,7 @@
{
result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().GetTriple().getTriple().c_str());
}
- else if (old_arch_spec != target->GetArchitecture())
+ else if (!old_arch_spec.IsExactMatch(target->GetArchitecture()))
{
result.AppendWarningWithFormat("Architecture changed from %s to %s.\n",
old_arch_spec.GetTriple().getTriple().c_str(),
@@ -684,7 +684,10 @@
"process continue",
"Continue execution of all threads in the current process.",
"process continue",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_options(interpreter)
{
}
@@ -715,7 +718,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success = false;
switch (short_option)
{
@@ -752,19 +755,10 @@
};
bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
bool synchronous_execution = m_interpreter.GetSynchronous ();
-
- if (process == NULL)
- {
- result.AppendError ("no process to continue");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
StateType state = process->GetState();
if (state == eStateStopped)
{
@@ -783,12 +777,12 @@
StopInfoSP stop_info_sp = sel_thread_sp->GetStopInfo();
if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
{
- uint64_t bp_site_id = stop_info_sp->GetValue();
+ lldb::break_id_t bp_site_id = (lldb::break_id_t)stop_info_sp->GetValue();
BreakpointSiteSP bp_site_sp(process->GetBreakpointSiteList().FindByID(bp_site_id));
if (bp_site_sp)
{
- uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
- for (uint32_t i = 0; i < num_owners; i++)
+ const size_t num_owners = bp_site_sp->GetNumberOfOwners();
+ for (size_t i = 0; i < num_owners; i++)
{
Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
if (!bp_ref.IsInternal())
@@ -815,13 +809,13 @@
Error error(process->Resume());
if (error.Success())
{
- result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
+ result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
if (synchronous_execution)
{
state = process->WaitForProcessToStop (NULL);
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
+ result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -876,6 +870,8 @@
"process detach",
"Detach from the current process being debugged.",
"process detach",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
eFlagProcessMustBeLaunched)
{
}
@@ -886,18 +882,10 @@
protected:
bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("must have a valid process in order to detach");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- result.AppendMessageWithFormat ("Detaching from process %llu\n", process->GetID());
+ Process *process = m_exe_ctx.GetProcessPtr();
+ result.AppendMessageWithFormat ("Detaching from process %" PRIu64 "\n", process->GetID());
Error error (process->Detach());
if (error.Success())
{
@@ -941,7 +929,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1006,12 +994,12 @@
TargetSP target_sp (m_interpreter.GetDebugger().GetSelectedTarget());
Error error;
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process)
{
if (process->IsAlive())
{
- result.AppendErrorWithFormat ("Process %llu is currently being debugged, kill the process before connecting.\n",
+ result.AppendErrorWithFormat ("Process %" PRIu64 " is currently being debugged, kill the process before connecting.\n",
process->GetID());
result.SetStatus (eReturnStatusFailed);
return false;
@@ -1061,7 +1049,7 @@
else
{
result.AppendErrorWithFormat ("Unable to find process plug-in for remote URL '%s'.\nPlease specify a process plug-in name with the --plugin option, or specify an object file using the \"file\" command.\n",
- m_cmd_name.c_str());
+ remote_url);
result.SetStatus (eReturnStatusFailed);
}
}
@@ -1132,7 +1120,10 @@
"process load",
"Load a shared library into the current process.",
"process load <filename> [<filename> ...]",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
}
@@ -1145,15 +1136,9 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("must have a valid process in order to load a shared library");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
- const uint32_t argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
for (uint32_t i=0; i<argc; ++i)
{
@@ -1192,7 +1177,10 @@
"process unload",
"Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
"process unload <index>",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
}
@@ -1205,15 +1193,9 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("must have a valid process in order to load a shared library");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
- const uint32_t argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
for (uint32_t i=0; i<argc; ++i)
{
@@ -1258,7 +1240,8 @@
CommandObjectParsed (interpreter,
"process signal",
"Send a UNIX signal to the current process being debugged.",
- NULL)
+ NULL,
+ eFlagRequiresProcess | eFlagTryTargetAPILock)
{
CommandArgumentEntry arg;
CommandArgumentData signal_arg;
@@ -1283,13 +1266,7 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
- if (process == NULL)
- {
- result.AppendError ("no process to signal");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
if (command.GetArgumentCount() == 1)
{
@@ -1346,6 +1323,8 @@
"process interrupt",
"Interrupt the current process being debugged.",
"process interrupt",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
eFlagProcessMustBeLaunched)
{
}
@@ -1359,7 +1338,7 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("no process to halt");
@@ -1409,6 +1388,8 @@
"process kill",
"Terminate the current process being debugged.",
"process kill",
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
eFlagProcessMustBeLaunched)
{
}
@@ -1422,7 +1403,7 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("no process to kill");
@@ -1467,7 +1448,7 @@
"process status",
"Show the current status and location of executing process.",
"process status",
- 0)
+ eFlagRequiresProcess | eFlagTryTargetAPILock)
{
}
@@ -1481,27 +1462,18 @@
{
Stream &strm = result.GetOutputStream();
result.SetStatus (eReturnStatusSuccessFinishNoResult);
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- const bool only_threads_with_stop_reason = true;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 1;
- const uint32_t num_frames_with_source = 1;
- process->GetStatus(strm);
- process->GetThreadStatus (strm,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
-
- }
- else
- {
- result.AppendError ("No process.");
- result.SetStatus (eReturnStatusFailed);
- }
+ // No need to check "process" for validity as eFlagRequiresProcess ensures it is valid
+ Process *process = m_exe_ctx.GetProcessPtr();
+ const bool only_threads_with_stop_reason = true;
+ const uint32_t start_frame = 0;
+ const uint32_t num_frames = 1;
+ const uint32_t num_frames_with_source = 1;
+ process->GetStatus(strm);
+ process->GetThreadStatus (strm,
+ only_threads_with_stop_reason,
+ start_frame,
+ num_frames,
+ num_frames_with_source);
return result.Succeeded();
}
};
@@ -1533,7 +1505,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
Index: aze/lldb/source/Commands/CommandObjectQuit.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectQuit.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectQuit.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectQuit.h"
// C Includes
@@ -32,9 +34,63 @@
{
}
+// returns true if there is at least one alive process
+// is_a_detach will be true if all alive processes will be detached when you quit
+// and false if at least one process will be killed instead
+bool
+CommandObjectQuit::ShouldAskForConfirmation (bool& is_a_detach)
+{
+ if (m_interpreter.GetPromptOnQuit() == false)
+ return false;
+ bool should_prompt = false;
+ is_a_detach = true;
+ for (uint32_t debugger_idx = 0;
+ debugger_idx < Debugger::GetNumDebuggers();
+ debugger_idx++)
+ {
+ DebuggerSP debugger_sp(Debugger::GetDebuggerAtIndex(debugger_idx));
+ if (!debugger_sp)
+ continue;
+ const TargetList& target_list(debugger_sp->GetTargetList());
+ for (uint32_t target_idx = 0;
+ target_idx < target_list.GetNumTargets();
+ target_idx++)
+ {
+ TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
+ if (!target_sp)
+ continue;
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (process_sp &&
+ process_sp->IsValid() &&
+ process_sp->IsAlive())
+ {
+ should_prompt = true;
+ if (process_sp->GetShouldDetach() == false)
+ {
+ // if we need to kill at least one process, just say so and return
+ is_a_detach = false;
+ return should_prompt;
+ }
+ }
+ }
+ }
+ return should_prompt;
+}
+
bool
CommandObjectQuit::DoExecute (Args& command, CommandReturnObject &result)
{
+ bool is_a_detach = true;
+ if (ShouldAskForConfirmation (is_a_detach))
+ {
+ StreamString message;
+ message.Printf("Quitting LLDB will %s one or more processes. Do you really want to proceed", (is_a_detach ? "detach from" : "kill"));
+ if (!m_interpreter.Confirm(message.GetData(), true))
+ {
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ }
m_interpreter.BroadcastEvent (CommandInterpreter::eBroadcastBitQuitCommandReceived);
result.SetStatus (eReturnStatusQuit);
return true;
Index: aze/lldb/source/Commands/CommandObjectQuit.h
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectQuit.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectQuit.h 2013-03-03 09:35:50.139457354 +0100
@@ -35,6 +35,9 @@
virtual bool
DoExecute (Args& args,
CommandReturnObject &result);
+
+ bool
+ ShouldAskForConfirmation (bool& is_a_detach);
};
Index: aze/lldb/source/Commands/CommandObjectRegister.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectRegister.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectRegister.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectRegister.h"
// C Includes
@@ -43,7 +45,10 @@
"register read",
"Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresFrame |
+ eFlagRequiresRegContext |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_option_group (interpreter),
m_format_options (eFormatDefault),
m_command_options ()
@@ -124,7 +129,7 @@
DumpRegisterSet (const ExecutionContext &exe_ctx,
Stream &strm,
RegisterContext *reg_ctx,
- uint32_t set_idx,
+ size_t set_idx,
bool primitive_only=false)
{
uint32_t unavailable_count = 0;
@@ -134,8 +139,8 @@
{
strm.Printf ("%s:\n", reg_set->name);
strm.IndentMore ();
- const uint32_t num_registers = reg_set->num_registers;
- for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
+ const size_t num_registers = reg_set->num_registers;
+ for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
{
const uint32_t reg = reg_set->registers[reg_idx];
const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
@@ -163,89 +168,80 @@
DoExecute (Args& command, CommandReturnObject &result)
{
Stream &strm = result.GetOutputStream();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
+ RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
- if (reg_ctx)
+ const RegisterInfo *reg_info = NULL;
+ if (command.GetArgumentCount() == 0)
{
- const RegisterInfo *reg_info = NULL;
- if (command.GetArgumentCount() == 0)
+ size_t set_idx;
+
+ size_t num_register_sets = 1;
+ const size_t set_array_size = m_command_options.set_indexes.GetSize();
+ if (set_array_size > 0)
{
- uint32_t set_idx;
-
- uint32_t num_register_sets = 1;
- const uint32_t set_array_size = m_command_options.set_indexes.GetSize();
- if (set_array_size > 0)
+ for (size_t i=0; i<set_array_size; ++i)
{
- for (uint32_t i=0; i<set_array_size; ++i)
+ set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
+ if (set_idx != UINT32_MAX)
{
- set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
- if (set_idx != UINT32_MAX)
+ if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
{
- if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx))
- {
- result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx);
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- }
- else
- {
- result.AppendError ("invalid register set index\n");
+ result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx);
result.SetStatus (eReturnStatusFailed);
break;
}
}
- }
- else
- {
- if (m_command_options.dump_all_sets)
- num_register_sets = reg_ctx->GetRegisterSetCount();
-
- for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
+ else
{
- // When dump_all_sets option is set, dump primitive as well as derived registers.
- DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
+ result.AppendError ("invalid register set index\n");
+ result.SetStatus (eReturnStatusFailed);
+ break;
}
}
}
else
{
if (m_command_options.dump_all_sets)
+ num_register_sets = reg_ctx->GetRegisterSetCount();
+
+ for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
{
- result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
- result.SetStatus (eReturnStatusFailed);
- }
- else if (m_command_options.set_indexes.GetSize() > 0)
- {
- result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
- result.SetStatus (eReturnStatusFailed);
+ // When dump_all_sets option is set, dump primitive as well as derived registers.
+ DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
}
- else
+ }
+ }
+ else
+ {
+ if (m_command_options.dump_all_sets)
+ {
+ result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ else if (m_command_options.set_indexes.GetSize() > 0)
+ {
+ result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ else
+ {
+ const char *arg_cstr;
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
{
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
- {
- reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
+ reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
- if (reg_info)
- {
- if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
- strm.Printf("%-12s = error: unavailable\n", reg_info->name);
- }
- else
- {
- result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
- }
+ if (reg_info)
+ {
+ if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info))
+ strm.Printf("%-12s = error: unavailable\n", reg_info->name);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
}
}
}
}
- else
- {
- result.AppendError ("no current frame");
- result.SetStatus (eReturnStatusFailed);
- }
return result.Succeeded();
}
@@ -289,7 +285,7 @@
const char *option_value)
{
Error error;
- const char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 's':
@@ -364,7 +360,10 @@
"register write",
"Modify a single register value.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresFrame |
+ eFlagRequiresRegContext |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused)
{
CommandArgumentEntry arg1;
CommandArgumentEntry arg2;
@@ -400,64 +399,55 @@
DoExecute(Args& command, CommandReturnObject &result)
{
DataExtractor reg_data;
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
+ RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
- if (reg_ctx)
+ if (command.GetArgumentCount() != 2)
{
- if (command.GetArgumentCount() != 2)
- {
- result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
- result.SetStatus (eReturnStatusFailed);
- }
- else
- {
- const char *reg_name = command.GetArgumentAtIndex(0);
- const char *value_str = command.GetArgumentAtIndex(1);
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
+ result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ else
+ {
+ const char *reg_name = command.GetArgumentAtIndex(0);
+ const char *value_str = command.GetArgumentAtIndex(1);
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
- if (reg_info)
+ if (reg_info)
+ {
+ RegisterValue reg_value;
+
+ Error error (reg_value.SetValueFromCString (reg_info, value_str));
+ if (error.Success())
{
- RegisterValue reg_value;
-
- Error error (reg_value.SetValueFromCString (reg_info, value_str));
- if (error.Success())
+ if (reg_ctx->WriteRegister (reg_info, reg_value))
{
- if (reg_ctx->WriteRegister (reg_info, reg_value))
- {
- // Toss all frames and anything else in the thread
- // after a register has been written.
- exe_ctx.GetThreadRef().Flush();
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- return true;
- }
- }
- if (error.AsCString())
- {
- result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
- reg_name,
- value_str,
- error.AsCString());
+ // Toss all frames and anything else in the thread
+ // after a register has been written.
+ m_exe_ctx.GetThreadRef().Flush();
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ return true;
}
- else
- {
- result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
- reg_name,
- value_str);
- }
- result.SetStatus (eReturnStatusFailed);
+ }
+ if (error.AsCString())
+ {
+ result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
+ reg_name,
+ value_str,
+ error.AsCString());
}
else
{
- result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
- result.SetStatus (eReturnStatusFailed);
+ result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
+ reg_name,
+ value_str);
}
+ result.SetStatus (eReturnStatusFailed);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
+ result.SetStatus (eReturnStatusFailed);
}
- }
- else
- {
- result.AppendError ("no current frame");
- result.SetStatus (eReturnStatusFailed);
}
return result.Succeeded();
}
Index: aze/lldb/source/Commands/CommandObjectSettings.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectSettings.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectSettings.cpp 2013-03-03 09:35:50.139457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectSettings.h"
// C Includes
@@ -119,7 +121,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -200,12 +202,10 @@
}
else
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
-
// Complete setting value
const char *setting_var_name = input.GetArgumentAtIndex(setting_var_idx);
Error error;
- lldb::OptionValueSP value_sp (m_interpreter.GetDebugger().GetPropertyValue(&exe_ctx, setting_var_name, false, error));
+ lldb::OptionValueSP value_sp (m_interpreter.GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, false, error));
if (value_sp)
{
value_sp->AutoComplete (m_interpreter,
@@ -254,7 +254,6 @@
StripLeadingSpaces(var_value_str);
std::string var_value_string = var_value_str.str();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
Error error;
if (m_options.m_global)
{
@@ -266,7 +265,7 @@
if (error.Success())
{
- error = m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ error = m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationAssign,
var_name,
var_value_string.c_str());
@@ -355,7 +354,6 @@
virtual bool
DoExecute (Args& args, CommandReturnObject &result)
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
result.SetStatus (eReturnStatusSuccessFinishResult);
const size_t argc = args.GetArgumentCount ();
@@ -365,7 +363,7 @@
{
const char *property_path = args.GetArgumentAtIndex (i);
- Error error(m_interpreter.GetDebugger().DumpPropertyValue (&exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue));
+ Error error(m_interpreter.GetDebugger().DumpPropertyValue (&m_exe_ctx, result.GetOutputStream(), property_path, OptionValue::eDumpGroupValue));
if (error.Success())
{
result.GetOutputStream().EOL();
@@ -379,7 +377,7 @@
}
else
{
- m_interpreter.GetDebugger().DumpAllPropertyValues (& exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
+ m_interpreter.GetDebugger().DumpAllPropertyValues (&m_exe_ctx, result.GetOutputStream(), OptionValue::eDumpGroupValue);
}
return result.Succeeded();
@@ -448,7 +446,6 @@
virtual bool
DoExecute (Args& args, CommandReturnObject &result)
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
result.SetStatus (eReturnStatusSuccessFinishResult);
const bool will_modify = false;
@@ -461,7 +458,7 @@
{
const char *property_path = args.GetArgumentAtIndex (i);
- const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&exe_ctx, will_modify, property_path);
+ const Property *property = m_interpreter.GetDebugger().GetValueProperties()->GetPropertyAtPath (&m_exe_ctx, will_modify, property_path);
if (property)
{
@@ -590,8 +587,7 @@
StripLeadingSpaces(var_value_str);
std::string var_value_string = var_value_str.str();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Error error (m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationRemove,
var_name,
var_value_string.c_str()));
@@ -717,8 +713,7 @@
StripLeadingSpaces(var_value_str);
std::string var_value_string = var_value_str.str();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationReplace,
var_name,
var_value_string.c_str()));
@@ -851,8 +846,7 @@
StripLeadingSpaces(var_value_str);
std::string var_value_string = var_value_str.str();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationInsertBefore,
var_name,
var_value_string.c_str()));
@@ -980,8 +974,7 @@
StripLeadingSpaces(var_value_str);
std::string var_value_string = var_value_str.str();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationInsertAfter,
var_name,
var_value_string.c_str()));
@@ -1100,8 +1093,7 @@
StripLeadingSpaces(var_value_str);
std::string var_value_string = var_value_str.str();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Error error(m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ Error error(m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationAppend,
var_name,
var_value_string.c_str()));
@@ -1194,8 +1186,7 @@
return false;
}
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Error error (m_interpreter.GetDebugger().SetPropertyValue (&exe_ctx,
+ Error error (m_interpreter.GetDebugger().SetPropertyValue (&m_exe_ctx,
eVarSetOperationClear,
var_name,
NULL));
Index: aze/lldb/source/Commands/CommandObjectSource.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectSource.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectSource.cpp 2013-03-03 09:35:50.143457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectSource.h"
// C Includes
@@ -16,6 +18,7 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileLineResolver.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/SourceManager.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -54,7 +57,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- const char short_option = g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 'l':
@@ -162,7 +165,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- const char short_option = g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 'l':
@@ -185,6 +188,12 @@
symbol_name = option_arg;
break;
+ case 'a':
+ {
+ ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+ address = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+ }
+ break;
case 's':
modules.push_back (std::string (option_arg));
break;
@@ -192,6 +201,9 @@
case 'b':
show_bp_locs = true;
break;
+ case 'r':
+ reverse = true;
+ break;
default:
error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
break;
@@ -206,9 +218,11 @@
file_spec.Clear();
file_name.clear();
symbol_name.clear();
+ address = LLDB_INVALID_ADDRESS;
start_line = 0;
num_lines = 10;
show_bp_locs = false;
+ reverse = false;
modules.clear();
}
@@ -223,10 +237,12 @@
FileSpec file_spec;
std::string file_name;
std::string symbol_name;
+ lldb::addr_t address;
uint32_t start_line;
uint32_t num_lines;
STLStringArray modules;
bool show_bp_locs;
+ bool reverse;
};
public:
@@ -234,21 +250,10 @@
CommandObjectParsed (interpreter,
"source list",
"Display source code (as specified) based on the current executable's debug info.",
- NULL),
+ NULL,
+ eFlagRequiresTarget),
m_options (interpreter)
{
- CommandArgumentEntry arg;
- CommandArgumentData file_arg;
-
- // Define the first (and only) variant of this arg.
- file_arg.arg_type = eArgTypeFilename;
- file_arg.arg_repetition = eArgRepeatOptional;
-
- // There is only one variant this argument could be; put it into the argument entry.
- arg.push_back (file_arg);
-
- // Push the data for the first argument into the m_arguments vector.
- m_arguments.push_back (arg);
}
~CommandObjectSourceList ()
@@ -265,14 +270,36 @@
virtual const char *
GetRepeatCommand (Args &current_command_args, uint32_t index)
{
- return m_cmd_name.c_str();
+ // This is kind of gross, but the command hasn't been parsed yet so we can't look at the option
+ // values for this invocation... I have to scan the arguments directly.
+ size_t num_args = current_command_args.GetArgumentCount();
+ bool is_reverse = false;
+ for (size_t i = 0 ; i < num_args; i++)
+ {
+ const char *arg = current_command_args.GetArgumentAtIndex(i);
+ if (arg && (strcmp(arg, "-r") == 0 || strcmp(arg, "--reverse") == 0))
+ {
+ is_reverse = true;
+ }
+ }
+ if (is_reverse)
+ {
+ if (m_reverse_name.empty())
+ {
+ m_reverse_name = m_cmd_name;
+ m_reverse_name.append (" -r");
+ }
+ return m_reverse_name.c_str();
+ }
+ else
+ return m_cmd_name.c_str();
}
protected:
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- const int argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
if (argc != 0)
{
@@ -281,33 +308,23 @@
return false;
}
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Target *target = exe_ctx.GetTargetPtr();
-
- if (target == NULL)
- target = m_interpreter.GetDebugger().GetSelectedTarget().get();
-
- if (target == NULL)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ Target *target = m_exe_ctx.GetTargetPtr();
+ SymbolContextList sc_list;
if (!m_options.symbol_name.empty())
{
// Displaying the source for a symbol:
- SymbolContextList sc_list;
ConstString name(m_options.symbol_name.c_str());
bool include_symbols = false;
bool include_inlines = true;
bool append = true;
size_t num_matches = 0;
- if (m_options.modules.size() > 0)
+ const size_t num_modules = m_options.modules.size();
+ if (num_modules > 0)
{
ModuleList matching_modules;
- for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
+ for (size_t i = 0; i < num_modules; ++i)
{
FileSpec module_file_spec(m_options.modules[i].c_str(), false);
if (module_file_spec)
@@ -407,7 +424,7 @@
// This is a little hacky, but the first line table entry for a function points to the "{" that
// starts the function block. It would be nice to actually get the function
// declaration in there too. So back up a bit, but not further than what you're going to display.
- size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
+ uint32_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
uint32_t line_no;
if (start_line <= lines_to_back_up)
line_no = 1;
@@ -429,7 +446,7 @@
{
const bool show_inlines = true;
m_breakpoint_locations.Reset (start_file, 0, show_inlines);
- SearchFilter target_search_filter (exe_ctx.GetTargetSP());
+ SearchFilter target_search_filter (m_exe_ctx.GetTargetSP());
target_search_filter.Search (m_breakpoint_locations);
}
else
@@ -448,6 +465,108 @@
return true;
}
+ else if (m_options.address != LLDB_INVALID_ADDRESS)
+ {
+ SymbolContext sc;
+ Address so_addr;
+ StreamString error_strm;
+
+ if (target->GetSectionLoadList().IsEmpty())
+ {
+ // The target isn't loaded yet, we need to lookup the file address
+ // in all modules
+ const ModuleList &module_list = target->GetImages();
+ const size_t num_modules = module_list.GetSize();
+ for (size_t i=0; i<num_modules; ++i)
+ {
+ ModuleSP module_sp (module_list.GetModuleAtIndex(i));
+ if (module_sp && module_sp->ResolveFileAddress(m_options.address, so_addr))
+ {
+ sc.Clear(true);
+ if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
+ sc_list.Append(sc);
+ }
+ }
+
+ if (sc_list.GetSize() == 0)
+ {
+ result.AppendErrorWithFormat("no modules have source information for file address 0x%" PRIx64 ".\n",
+ m_options.address);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ else
+ {
+ // The target has some things loaded, resolve this address to a
+ // compile unit + file + line and display
+ if (target->GetSectionLoadList().ResolveLoadAddress (m_options.address, so_addr))
+ {
+ ModuleSP module_sp (so_addr.GetModule());
+ if (module_sp)
+ {
+ sc.Clear(true);
+ if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
+ {
+ sc_list.Append(sc);
+ }
+ else
+ {
+ so_addr.Dump(&error_strm, NULL, Address::DumpStyleModuleWithFileAddress);
+ result.AppendErrorWithFormat("address resolves to %s, but there is no line table information available for this address.\n",
+ error_strm.GetData());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
+
+ if (sc_list.GetSize() == 0)
+ {
+ result.AppendErrorWithFormat("no modules contain load address 0x%" PRIx64 ".\n", m_options.address);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ uint32_t num_matches = sc_list.GetSize();
+ for (uint32_t i=0; i<num_matches; ++i)
+ {
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.comp_unit)
+ {
+ if (m_options.show_bp_locs)
+ {
+ m_breakpoint_locations.Clear();
+ const bool show_inlines = true;
+ m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
+ SearchFilter target_search_filter (target->shared_from_this());
+ target_search_filter.Search (m_breakpoint_locations);
+ }
+
+ bool show_fullpaths = true;
+ bool show_module = true;
+ bool show_inlined_frames = true;
+ sc.DumpStopContext(&result.GetOutputStream(),
+ m_exe_ctx.GetBestExecutionContextScope(),
+ sc.line_entry.range.GetBaseAddress(),
+ show_fullpaths,
+ show_module,
+ show_inlined_frames);
+ result.GetOutputStream().EOL();
+
+ size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
+
+ target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
+ sc.line_entry.line,
+ lines_to_back_up,
+ m_options.num_lines - lines_to_back_up,
+ "->",
+ &result.GetOutputStream(),
+ GetBreakpointLocations ());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ }
+ }
else if (m_options.file_name.empty())
{
// Last valid source manager context, or the current frame if no
@@ -457,7 +576,8 @@
if (m_options.start_line == 0)
{
if (target->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(),
- GetBreakpointLocations ()))
+ GetBreakpointLocations (),
+ m_options.reverse))
{
result.SetStatus (eReturnStatusSuccessFinishResult);
}
@@ -502,7 +622,7 @@
if (m_options.modules.size() > 0)
{
ModuleList matching_modules;
- for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
+ for (size_t i = 0, e = m_options.modules.size(); i < e; ++i)
{
FileSpec module_file_spec(m_options.modules[i].c_str(), false);
if (module_file_spec)
@@ -611,18 +731,22 @@
}
CommandOptions m_options;
FileLineResolver m_breakpoint_locations;
+ std::string m_reverse_name;
};
OptionDefinition
CommandObjectSourceList::CommandOptions::g_option_table[] =
{
-{ LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "The number of source lines to display."},
-{ LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
+{ LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "The number of source lines to display."},
+{ LLDB_OPT_SET_1 |
+ LLDB_OPT_SET_2 , false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."},
{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', no_argument, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."},
-{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
-{ LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
-{ LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
+{ LLDB_OPT_SET_1 , false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."},
+{ LLDB_OPT_SET_1 , false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."},
+{ LLDB_OPT_SET_2 , false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."},
+{ LLDB_OPT_SET_3 , false, "address",'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line."},
+{ LLDB_OPT_SET_4, false, "reverse", 'r', no_argument, NULL, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
Index: aze/lldb/source/Commands/CommandObjectSyntax.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectSyntax.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectSyntax.cpp 2013-03-03 09:35:50.143457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectSyntax.h"
// C Includes
@@ -57,7 +59,7 @@
{
CommandObject::CommandMap::iterator pos;
CommandObject *cmd_obj;
- const int argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
if (argc > 0)
{
Index: aze/lldb/source/Commands/CommandObjectTarget.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectTarget.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectTarget.cpp 2013-03-03 09:35:50.143457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectTarget.h"
// C Includes
@@ -91,7 +93,7 @@
show_process_status = StateIsStoppedState(state, true);
const char *state_cstr = StateAsCString (state);
if (pid != LLDB_INVALID_PROCESS_ID)
- strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid);
+ strm.Printf ("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
}
if (properties > 0)
@@ -155,7 +157,9 @@
m_option_group (interpreter),
m_arch_option (),
m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
- m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target.")
+ m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."),
+ m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable."),
+ m_add_dependents (LLDB_OPT_SET_1, false, "no-dependents", 'd', "Don't load dependent files when creating the target, just add the specified executable.", true, true)
{
CommandArgumentEntry arg;
CommandArgumentData file_arg;
@@ -173,6 +177,8 @@
m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append (&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
m_option_group.Finalize();
}
@@ -186,7 +192,7 @@
return &m_option_group;
}
- int
+ virtual int
HandleArgumentCompletion (Args &input,
int &cursor_index,
int &cursor_char_position,
@@ -214,17 +220,30 @@
bool
DoExecute (Args& command, CommandReturnObject &result)
{
- const int argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
if (argc == 1 || core_file)
{
+ FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue());
+ if (symfile)
+ {
+ if (!symfile.Exists())
+ {
+ char symfile_path[PATH_MAX];
+ symfile.GetPath(symfile_path, sizeof(symfile_path));
+ result.AppendErrorWithFormat("invalid symbol file path '%s'", symfile_path);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+
const char *file_path = command.GetArgumentAtIndex(0);
Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
TargetSP target_sp;
Debugger &debugger = m_interpreter.GetDebugger();
const char *arch_cstr = m_arch_option.GetArchitectureName();
- const bool get_dependent_files = true;
+ const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue();
Error error (debugger.GetTargetList().CreateTarget (debugger,
file_path,
arch_cstr,
@@ -234,6 +253,13 @@
if (target_sp)
{
+ if (symfile)
+ {
+ ModuleSP module_sp (target_sp->GetExecutableModule());
+ if (module_sp)
+ module_sp->SetSymbolFileFileSpec(symfile);
+ }
+
debugger.GetTargetList().SetSelectedTarget(target_sp.get());
if (core_file)
{
@@ -303,7 +329,8 @@
OptionGroupArchitecture m_arch_option;
OptionGroupPlatform m_platform_options;
OptionGroupFile m_core_file;
-
+ OptionGroupFile m_symbol_file;
+ OptionGroupBoolean m_add_dependents;
};
#pragma mark CommandObjectTargetList
@@ -573,12 +600,12 @@
"target variable",
"Read global variable(s) prior to, or while running your binary.",
NULL,
- 0),
+ eFlagRequiresTarget),
m_option_group (interpreter),
m_option_variable (false), // Don't include frame options
m_option_format (eFormatDefault),
- m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeFilename, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
- m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'s', 0, eArgTypeFilename, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
+ m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'file', 0, eArgTypeFilename, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
+ m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'shlb', 0, eArgTypeFilename, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
m_varobj_options()
{
CommandArgumentEntry arg;
@@ -670,9 +697,9 @@
}
- static uint32_t GetVariableCallback (void *baton,
- const char *name,
- VariableList &variable_list)
+ static size_t GetVariableCallback (void *baton,
+ const char *name,
+ VariableList &variable_list)
{
Target *target = static_cast<Target *>(baton);
if (target)
@@ -694,109 +721,145 @@
}
protected:
+
+ void
+ DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s)
+ {
+ size_t count = variable_list.GetSize();
+ if (count > 0)
+ {
+ if (sc.module_sp)
+ {
+ if (sc.comp_unit)
+ {
+ s.Printf ("Global variables for %s/%s in %s/%s:\n",
+ sc.comp_unit->GetDirectory().GetCString(),
+ sc.comp_unit->GetFilename().GetCString(),
+ sc.module_sp->GetFileSpec().GetDirectory().GetCString(),
+ sc.module_sp->GetFileSpec().GetFilename().GetCString());
+ }
+ else
+ {
+ s.Printf ("Global variables for %s/%s\n",
+ sc.module_sp->GetFileSpec().GetDirectory().GetCString(),
+ sc.module_sp->GetFileSpec().GetFilename().GetCString());
+ }
+ }
+ else if (sc.comp_unit)
+ {
+ s.Printf ("Global variables for %s/%s\n",
+ sc.comp_unit->GetDirectory().GetCString(),
+ sc.comp_unit->GetFilename().GetCString());
+ }
+
+ for (uint32_t i=0; i<count; ++i)
+ {
+ VariableSP var_sp (variable_list.GetVariableAtIndex(i));
+ if (var_sp)
+ {
+ ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
+
+ if (valobj_sp)
+ DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
+ }
+ }
+ }
+
+ }
virtual bool
DoExecute (Args& args, CommandReturnObject &result)
{
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
+ Target *target = m_exe_ctx.GetTargetPtr();
+ const size_t argc = args.GetArgumentCount();
+ Stream &s = result.GetOutputStream();
+
+ if (argc > 0)
{
- const size_t argc = args.GetArgumentCount();
- Stream &s = result.GetOutputStream();
- if (argc > 0)
+
+ for (size_t idx = 0; idx < argc; ++idx)
{
+ VariableList variable_list;
+ ValueObjectList valobj_list;
- for (size_t idx = 0; idx < argc; ++idx)
+ const char *arg = args.GetArgumentAtIndex(idx);
+ size_t matches = 0;
+ bool use_var_name = false;
+ if (m_option_variable.use_regex)
{
- VariableList variable_list;
- ValueObjectList valobj_list;
-
- const char *arg = args.GetArgumentAtIndex(idx);
- uint32_t matches = 0;
- bool use_var_name = false;
- if (m_option_variable.use_regex)
- {
- RegularExpression regex(arg);
- if (!regex.IsValid ())
- {
- result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- use_var_name = true;
- matches = target->GetImages().FindGlobalVariables (regex,
- true,
- UINT32_MAX,
- variable_list);
- }
- else
+ RegularExpression regex(arg);
+ if (!regex.IsValid ())
{
- Error error (Variable::GetValuesForVariableExpressionPath (arg,
- exe_ctx.GetBestExecutionContextScope(),
- GetVariableCallback,
- target,
- variable_list,
- valobj_list));
- matches = variable_list.GetSize();
- }
-
- if (matches == 0)
- {
- result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
+ result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
result.SetStatus (eReturnStatusFailed);
return false;
}
- else
+ use_var_name = true;
+ matches = target->GetImages().FindGlobalVariables (regex,
+ true,
+ UINT32_MAX,
+ variable_list);
+ }
+ else
+ {
+ Error error (Variable::GetValuesForVariableExpressionPath (arg,
+ m_exe_ctx.GetBestExecutionContextScope(),
+ GetVariableCallback,
+ target,
+ variable_list,
+ valobj_list));
+ matches = variable_list.GetSize();
+ }
+
+ if (matches == 0)
+ {
+ result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ else
+ {
+ for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
{
- for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
+ VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
+ if (var_sp)
{
- VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
- if (var_sp)
- {
- ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
- if (!valobj_sp)
- valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
-
- if (valobj_sp)
- DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
- }
+ ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
+ if (!valobj_sp)
+ valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp);
+
+ if (valobj_sp)
+ DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
}
}
}
}
- else
+ }
+ else
+ {
+ const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue();
+ const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue();
+ SymbolContextList sc_list;
+ const size_t num_compile_units = compile_units.GetSize();
+ const size_t num_shlibs = shlibs.GetSize();
+ if (num_compile_units == 0 && num_shlibs == 0)
{
bool success = false;
- StackFrame *frame = exe_ctx.GetFramePtr();
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
CompileUnit *comp_unit = NULL;
if (frame)
{
- comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
- if (comp_unit)
+ SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit);
+ if (sc.comp_unit)
{
const bool can_create = true;
- VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create));
+ VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
if (comp_unit_varlist_sp)
{
size_t count = comp_unit_varlist_sp->GetSize();
if (count > 0)
{
- s.Printf ("Global variables for %s/%s:\n",
- comp_unit->GetDirectory().GetCString(),
- comp_unit->GetFilename().GetCString());
-
+ DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
success = true;
- for (uint32_t i=0; i<count; ++i)
- {
- VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i));
- if (var_sp)
- {
- ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
-
- if (valobj_sp)
- DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
- }
- }
}
}
}
@@ -810,21 +873,86 @@
comp_unit->GetDirectory().GetCString(),
comp_unit->GetFilename().GetCString());
else
- result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex());
+ result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex());
}
else
result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
result.SetStatus (eReturnStatusFailed);
}
}
+ else
+ {
+ SymbolContextList sc_list;
+ const bool append = true;
+ // We have one or more compile unit or shlib
+ if (num_shlibs > 0)
+ {
+ for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx)
+ {
+ const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
+ ModuleSpec module_spec (module_file);
+
+ ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
+ if (module_sp)
+ {
+ if (num_compile_units > 0)
+ {
+ for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
+ module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
+ }
+ else
+ {
+ SymbolContext sc;
+ sc.module_sp = module_sp;
+ sc_list.Append(sc);
+ }
+ }
+ else
+ {
+ // Didn't find matching shlib/module in target...
+ result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s%s%s\n",
+ module_file.GetDirectory().GetCString(),
+ module_file.GetDirectory() ? "/" : "",
+ module_file.GetFilename().GetCString());
+ }
+ }
+ }
+ else
+ {
+ // No shared libraries, we just want to find globals for the compile units files that were specified
+ for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx)
+ target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
+ }
+
+ const uint32_t num_scs = sc_list.GetSize();
+ if (num_scs > 0)
+ {
+ SymbolContext sc;
+ for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx)
+ {
+ if (sc_list.GetContextAtIndex(sc_idx, sc))
+ {
+ if (sc.comp_unit)
+ {
+ const bool can_create = true;
+ VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create));
+ if (comp_unit_varlist_sp)
+ DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
+ }
+ else if (sc.module_sp)
+ {
+ // Get all global variables for this module
+ lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character
+ VariableList variable_list;
+ sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list);
+ DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
+ }
+ }
+ }
+ }
+ }
}
- else
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
+
if (m_interpreter.TruncationWarningNecessary())
{
result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
@@ -891,7 +1019,7 @@
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
if (target)
{
- uint32_t argc = command.GetArgumentCount();
+ const size_t argc = command.GetArgumentCount();
if (argc & 1)
{
result.AppendError ("add requires an even number of arguments\n");
@@ -899,7 +1027,7 @@
}
else
{
- for (uint32_t i=0; i<argc; i+=2)
+ for (size_t i=0; i<argc; i+=2)
{
const char *from = command.GetArgumentAtIndex(i);
const char *to = command.GetArgumentAtIndex(i+1);
@@ -1028,7 +1156,7 @@
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
if (target)
{
- uint32_t argc = command.GetArgumentCount();
+ size_t argc = command.GetArgumentCount();
// check for at least 3 arguments and an odd nubmer of parameters
if (argc >= 3 && argc & 1)
{
@@ -1542,7 +1670,7 @@
strm.IndentLess ();
}
-static uint32_t
+static size_t
LookupFunctionInModule (CommandInterpreter &interpreter,
Stream &strm,
Module *module,
@@ -1556,7 +1684,7 @@
{
SymbolContextList sc_list;
const bool append = true;
- uint32_t num_matches = 0;
+ size_t num_matches = 0;
if (name_is_regex)
{
RegularExpression function_name_regex (name);
@@ -1581,7 +1709,7 @@
if (num_matches)
{
strm.Indent ();
- strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
+ strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : "");
DumpFullpath (strm, &module->GetFileSpec(), 0);
strm.PutCString(":\n");
DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
@@ -1591,7 +1719,7 @@
return 0;
}
-static uint32_t
+static size_t
LookupTypeInModule (CommandInterpreter &interpreter,
Stream &strm,
Module *module,
@@ -1602,7 +1730,7 @@
{
TypeList type_list;
const uint32_t max_num_matches = UINT32_MAX;
- uint32_t num_matches = 0;
+ size_t num_matches = 0;
bool name_is_fully_qualified = false;
SymbolContext sc;
@@ -1612,7 +1740,7 @@
if (num_matches)
{
strm.Indent ();
- strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
+ strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : "");
DumpFullpath (strm, &module->GetFileSpec(), 0);
strm.PutCString(":\n");
const uint32_t num_types = type_list.GetSize();
@@ -1646,7 +1774,7 @@
return 0;
}
-static uint32_t
+static size_t
LookupTypeHere (CommandInterpreter &interpreter,
Stream &strm,
const SymbolContext &sym_ctx,
@@ -1658,7 +1786,7 @@
TypeList type_list;
const uint32_t max_num_matches = UINT32_MAX;
- uint32_t num_matches = 1;
+ size_t num_matches = 1;
bool name_is_fully_qualified = false;
ConstString name(name_cstr);
@@ -1745,9 +1873,9 @@
{
// Check the global list
Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
- const uint32_t num_modules = Module::GetNumberAllocatedModules();
+ const size_t num_modules = Module::GetNumberAllocatedModules();
ModuleSP module_sp;
- for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
+ for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
{
Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
@@ -1859,10 +1987,11 @@
public:
CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
- const char *name,
- const char *help,
- const char *syntax) :
- CommandObjectParsed (interpreter, name, help, syntax)
+ const char *name,
+ const char *help,
+ const char *syntax,
+ uint32_t flags) :
+ CommandObjectParsed (interpreter, name, help, syntax, flags)
{
CommandArgumentEntry arg;
CommandArgumentData source_file_arg;
@@ -1955,7 +2084,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -2016,11 +2145,11 @@
{
// Dump all sections for all modules images
Mutex::Locker modules_locker(target->GetImages().GetMutex());
- const uint32_t num_modules = target->GetImages().GetSize();
+ const size_t num_modules = target->GetImages().GetSize();
if (num_modules > 0)
{
- result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
- for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
+ result.GetOutputStream().Printf("Dumping symbol table for %zu modules.\n", num_modules);
+ for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
{
if (num_dumped > 0)
{
@@ -2149,11 +2278,11 @@
if (command.GetArgumentCount() == 0)
{
// Dump all sections for all modules images
- const uint32_t num_modules = target->GetImages().GetSize();
+ const size_t num_modules = target->GetImages().GetSize();
if (num_modules > 0)
{
- result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
- for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
+ result.GetOutputStream().Printf("Dumping sections for %zu modules.\n", num_modules);
+ for (size_t image_idx = 0; image_idx<num_modules; ++image_idx)
{
num_dumped++;
DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
@@ -2257,10 +2386,10 @@
// Dump all sections for all modules images
const ModuleList &target_modules = target->GetImages();
Mutex::Locker modules_locker (target_modules.GetMutex());
- const uint32_t num_modules = target_modules.GetSize();
+ const size_t num_modules = target_modules.GetSize();
if (num_modules > 0)
{
- result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
+ result.GetOutputStream().Printf("Dumping debug symbols for %zu modules.\n", num_modules);
for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
{
if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
@@ -2323,9 +2452,10 @@
public:
CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
- "target modules dump line-table",
- "Dump the debug symbol file for one or more target modules.",
- NULL)
+ "target modules dump line-table",
+ "Dump the debug symbol file for one or more target modules.",
+ NULL,
+ eFlagRequiresTarget)
{
}
@@ -2339,65 +2469,55 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (target == NULL)
+ Target *target = m_exe_ctx.GetTargetPtr();
+ uint32_t total_num_dumped = 0;
+
+ uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
+ result.GetOutputStream().SetAddressByteSize(addr_byte_size);
+ result.GetErrorStream().SetAddressByteSize(addr_byte_size);
+
+ if (command.GetArgumentCount() == 0)
{
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
+ result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
result.SetStatus (eReturnStatusFailed);
- return false;
}
else
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- uint32_t total_num_dumped = 0;
-
- uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
- result.GetOutputStream().SetAddressByteSize(addr_byte_size);
- result.GetErrorStream().SetAddressByteSize(addr_byte_size);
-
- if (command.GetArgumentCount() == 0)
- {
- result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- else
+ // Dump specified images (by basename or fullpath)
+ const char *arg_cstr;
+ for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
{
- // Dump specified images (by basename or fullpath)
- const char *arg_cstr;
- for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
+ FileSpec file_spec(arg_cstr, false);
+
+ const ModuleList &target_modules = target->GetImages();
+ Mutex::Locker modules_locker(target_modules.GetMutex());
+ const size_t num_modules = target_modules.GetSize();
+ if (num_modules > 0)
{
- FileSpec file_spec(arg_cstr, false);
-
- const ModuleList &target_modules = target->GetImages();
- Mutex::Locker modules_locker(target_modules.GetMutex());
- const uint32_t num_modules = target_modules.GetSize();
- if (num_modules > 0)
+ uint32_t num_dumped = 0;
+ for (uint32_t i = 0; i<num_modules; ++i)
{
- uint32_t num_dumped = 0;
- for (uint32_t i = 0; i<num_modules; ++i)
- {
- if (DumpCompileUnitLineTable (m_interpreter,
- result.GetOutputStream(),
- target_modules.GetModulePointerAtIndexUnlocked(i),
- file_spec,
- exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
- num_dumped++;
- }
- if (num_dumped == 0)
- result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
- else
- total_num_dumped += num_dumped;
+ if (DumpCompileUnitLineTable (m_interpreter,
+ result.GetOutputStream(),
+ target_modules.GetModulePointerAtIndexUnlocked(i),
+ file_spec,
+ m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive()))
+ num_dumped++;
}
+ if (num_dumped == 0)
+ result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
+ else
+ total_num_dumped += num_dumped;
}
}
-
- if (total_num_dumped > 0)
- result.SetStatus (eReturnStatusSuccessFinishResult);
- else
- {
- result.AppendError ("no source filenames matched any command arguments");
- result.SetStatus (eReturnStatusFailed);
- }
+ }
+
+ if (total_num_dumped > 0)
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ else
+ {
+ result.AppendError ("no source filenames matched any command arguments");
+ result.SetStatus (eReturnStatusFailed);
}
return result.Succeeded();
}
@@ -2442,16 +2562,27 @@
CommandObjectParsed (interpreter,
"target modules add",
"Add a new module to the current target's modules.",
- "target modules add [<module>]")
+ "target modules add [<module>]"),
+ m_option_group (interpreter),
+ m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable.")
{
+ m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+ m_option_group.Finalize();
}
virtual
~CommandObjectTargetModulesAdd ()
{
}
+
+ virtual Options *
+ GetOptions ()
+ {
+ return &m_option_group;
+ }
- int
+ virtual int
HandleArgumentCompletion (Args &input,
int &cursor_index,
int &cursor_char_position,
@@ -2476,6 +2607,12 @@
}
protected:
+
+ OptionGroupOptions m_option_group;
+ OptionGroupUUID m_uuid_option_group;
+ OptionGroupFile m_symbol_file;
+
+
virtual bool
DoExecute (Args& args,
CommandReturnObject &result)
@@ -2489,12 +2626,75 @@
}
else
{
+ bool flush = false;
+
const size_t argc = args.GetArgumentCount();
if (argc == 0)
{
- result.AppendError ("one or more executable image paths must be specified");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
+ {
+ // We are given a UUID only, go locate the file
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
+ if (m_symbol_file.GetOptionValue().OptionWasSet())
+ module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
+ if (Symbols::DownloadObjectAndSymbolFile (module_spec))
+ {
+ ModuleSP module_sp (target->GetSharedModule (module_spec));
+ if (module_sp)
+ {
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ else
+ {
+ flush = true;
+
+ StreamString strm;
+ module_spec.GetUUID().Dump (&strm);
+ if (module_spec.GetFileSpec())
+ {
+ if (module_spec.GetSymbolFileSpec())
+ {
+ result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s/%s and symbol file %s/%s",
+ strm.GetString().c_str(),
+ module_spec.GetFileSpec().GetDirectory().GetCString(),
+ module_spec.GetFileSpec().GetFilename().GetCString(),
+ module_spec.GetSymbolFileSpec().GetDirectory().GetCString(),
+ module_spec.GetSymbolFileSpec().GetFilename().GetCString());
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s/%s",
+ strm.GetString().c_str(),
+ module_spec.GetFileSpec().GetDirectory().GetCString(),
+ module_spec.GetFileSpec().GetFilename().GetCString());
+ }
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s",
+ strm.GetString().c_str());
+ }
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ else
+ {
+ StreamString strm;
+ module_spec.GetUUID().Dump (&strm);
+ result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ else
+ {
+ result.AppendError ("one or more executable image paths must be specified");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
}
else
{
@@ -2507,13 +2707,26 @@
if (file_spec.Exists())
{
ModuleSpec module_spec (file_spec);
- ModuleSP module_sp (target->GetSharedModule (module_spec));
+ if (m_uuid_option_group.GetOptionValue ().OptionWasSet())
+ module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue();
+ if (m_symbol_file.GetOptionValue().OptionWasSet())
+ module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue();
+ Error error;
+ ModuleSP module_sp (target->GetSharedModule (module_spec, &error));
if (!module_sp)
{
- result.AppendError ("one or more executable image paths must be specified");
+ const char *error_cstr = error.AsCString();
+ if (error_cstr)
+ result.AppendError (error_cstr);
+ else
+ result.AppendErrorWithFormat ("unsupported module: %s", path);
result.SetStatus (eReturnStatusFailed);
return false;
}
+ else
+ {
+ flush = true;
+ }
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
@@ -2534,7 +2747,15 @@
}
}
}
+
+ if (flush)
+ {
+ ProcessSP process = target->GetProcessSP();
+ if (process)
+ process->Flush();
+ }
}
+
return result.Succeeded();
}
@@ -2664,7 +2885,7 @@
{
if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
changed = true;
- result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
+ result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr);
}
}
else
@@ -2694,7 +2915,12 @@
}
if (changed)
+ {
target->ModulesDidLoad (matching_modules);
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process)
+ process->Flush();
+ }
}
else
{
@@ -2803,29 +3029,24 @@
virtual Error
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
- char short_option = (char) m_getopt_table[option_idx].val;
+ Error error;
+
+ const int short_option = m_getopt_table[option_idx].val;
if (short_option == 'g')
{
m_use_global_module_list = true;
}
else if (short_option == 'a')
{
- bool success;
- m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
- if (!success)
- {
- Error error;
- error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
- }
+ m_module_addr = Args::StringToAddress(NULL, option_arg, LLDB_INVALID_ADDRESS, &error);
}
else
{
- uint32_t width = 0;
+ unsigned long width = 0;
if (option_arg)
width = strtoul (option_arg, NULL, 0);
m_format_array.push_back(std::make_pair(short_option, width));
}
- Error error;
return error;
}
@@ -2913,18 +3134,18 @@
ModuleSP module_sp (module_address.GetModule());
if (module_sp)
{
- PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm);
+ PrintModule (target, module_sp.get(), 0, strm);
result.SetStatus (eReturnStatusSuccessFinishResult);
}
else
{
- result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
+ result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr);
result.SetStatus (eReturnStatusFailed);
}
}
else
{
- result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
+ result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr);
result.SetStatus (eReturnStatusFailed);
}
}
@@ -2936,7 +3157,7 @@
return result.Succeeded();
}
- uint32_t num_modules = 0;
+ size_t num_modules = 0;
Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
// Otherwise it will lock the AllocationModuleCollectionMutex when accessing
// the global module list directly.
@@ -2998,8 +3219,8 @@
module_sp = module->shared_from_this();
}
- int indent = strm.Printf("[%3u] ", image_idx);
- PrintModule (target, module, image_idx, indent, strm);
+ const size_t indent = strm.Printf("[%3u] ", image_idx);
+ PrintModule (target, module, indent, strm);
}
result.SetStatus (eReturnStatusSuccessFinishResult);
@@ -3028,7 +3249,7 @@
}
void
- PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
+ PrintModule (Target *target, Module *module, int indent, Stream &strm)
{
if (module == NULL)
@@ -3102,12 +3323,12 @@
if (format_char == 'o')
{
// Show the offset of slide for the image
- strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
+ strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
}
else
{
// Show the load address of the image
- strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
+ strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr);
}
}
break;
@@ -3122,7 +3343,7 @@
break;
case 'r':
{
- uint32_t ref_count = 0;
+ size_t ref_count = 0;
ModuleSP module_sp (module->shared_from_this());
if (module_sp)
{
@@ -3130,9 +3351,9 @@
ref_count = module_sp.use_count() - 1;
}
if (width)
- strm.Printf("{%*u}", width, ref_count);
+ strm.Printf("{%*zu}", width, ref_count);
else
- strm.Printf("{%u}", ref_count);
+ strm.Printf("{%zu}", ref_count);
}
break;
@@ -3198,7 +3419,7 @@
OptionDefinition
CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
+ { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
{ LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
{ LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
{ LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
@@ -3241,10 +3462,10 @@
public:
CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter),
- m_type(eLookupTypeInvalid),
- m_str(),
- m_addr(LLDB_INVALID_ADDRESS)
+ Options(interpreter),
+ m_type(eLookupTypeInvalid),
+ m_str(),
+ m_addr(LLDB_INVALID_ADDRESS)
{
}
@@ -3258,7 +3479,7 @@
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -3307,7 +3528,11 @@
CommandObjectParsed (interpreter,
"target modules show-unwind",
"Show synthesized unwind instructions for a function.",
- NULL),
+ NULL,
+ eFlagRequiresTarget |
+ eFlagRequiresProcess |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_options (interpreter)
{
}
@@ -3329,16 +3554,8 @@
DoExecute (Args& command,
CommandReturnObject &result)
{
- Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- if (!target)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext();
- Process *process = exe_ctx.GetProcessPtr();
+ Target *target = m_exe_ctx.GetTargetPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
ABI *abi = NULL;
if (process)
abi = process->GetABI().get();
@@ -3369,7 +3586,7 @@
if (m_options.m_type == eLookupTypeFunctionOrSymbol)
{
SymbolContextList sc_list;
- uint32_t num_matches;
+ size_t num_matches;
ConstString function_name (m_options.m_str.c_str());
num_matches = target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
for (uint32_t idx = 0; idx < num_matches; idx++)
@@ -3399,14 +3616,14 @@
Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target));
if (first_non_prologue_insn.IsValid())
{
- result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%llx or offset %lld into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr);
+ result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%" PRIx64 " or offset %" PRId64 " into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr);
result.GetOutputStream().Printf ("\n");
}
UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get());
if (non_callsite_unwind_plan.get())
{
- result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
+ result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf ("\n");
}
@@ -3414,7 +3631,7 @@
UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1);
if (callsite_unwind_plan.get())
{
- result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
+ result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf ("\n");
}
@@ -3422,7 +3639,7 @@
UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get());
if (arch_default_unwind_plan.get())
{
- result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
+ result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf ("\n");
}
@@ -3430,7 +3647,7 @@
UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
if (fast_unwind_plan.get())
{
- result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
+ result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
result.GetOutputStream().Printf ("\n");
}
@@ -3491,7 +3708,7 @@
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -3603,7 +3820,8 @@
CommandObjectParsed (interpreter,
"target modules lookup",
"Look up information within executable and dependent shared library images.",
- NULL),
+ NULL,
+ eFlagRequiresTarget),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -3647,9 +3865,7 @@
break;
}
- ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext();
-
- StackFrameSP frame = exe_ctx.GetFrameSP();
+ StackFrameSP frame = m_exe_ctx.GetFrameSP();
if (!frame)
return false;
@@ -3827,7 +4043,7 @@
const ModuleList &target_modules = target->GetImages();
Mutex::Locker modules_locker(target_modules.GetMutex());
- const uint32_t num_modules = target_modules.GetSize();
+ const size_t num_modules = target_modules.GetSize();
if (num_modules > 0)
{
for (i = 0; i<num_modules && syntax_error == false; ++i)
@@ -3960,7 +4176,6 @@
{
LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
- //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
@@ -3989,7 +4204,7 @@
CommandObjectParsed (interpreter,
"target symbols add",
"Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
- "target symbols add [<symfile>]"),
+ "target symbols add [<symfile>]", eFlagRequiresTarget),
m_option_group (interpreter),
m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
@@ -4006,7 +4221,7 @@
{
}
- int
+ virtual int
HandleArgumentCompletion (Args &input,
int &cursor_index,
int &cursor_char_position,
@@ -4041,260 +4256,312 @@
bool
AddModuleSymbols (Target *target,
- const FileSpec &symfile_spec,
+ ModuleSpec &module_spec,
bool &flush,
CommandReturnObject &result)
{
- ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
- const UUID &symfile_uuid = symfile_module_sp->GetUUID();
- StreamString ss_symfile_uuid;
- symfile_uuid.Dump(&ss_symfile_uuid);
-
- if (symfile_module_sp)
+ const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
+ if (symbol_fspec)
{
char symfile_path[PATH_MAX];
- symfile_spec.GetPath (symfile_path, sizeof(symfile_path));
+ symbol_fspec.GetPath (symfile_path, sizeof(symfile_path));
+
+ if (!module_spec.GetUUID().IsValid())
+ {
+ if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
+ module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
+ }
// We now have a module that represents a symbol file
// that can be used for a module that might exist in the
// current target, so we need to find that module in the
// target
-
- ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
- if (old_module_sp)
+ ModuleList matching_module_list;
+ size_t num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
+ while (num_matches == 0)
+ {
+ ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension());
+ // Empty string returned, lets bail
+ if (!filename_no_extension)
+ break;
+
+ // Check if there was no extension to strip and the basename is the same
+ if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
+ break;
+
+ // Replace basename with one less extension
+ module_spec.GetFileSpec().GetFilename() = filename_no_extension;
+
+ num_matches = target->GetImages().FindModules (module_spec, matching_module_list);
+ }
+
+ if (num_matches > 1)
{
+ result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path);
+ }
+ else if (num_matches == 1)
+ {
+ ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0));
+
// The module has not yet created its symbol vendor, we can just
// give the existing target module the symfile path to use for
// when it decides to create it!
- old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
+ module_sp->SetSymbolFileFileSpec (symbol_fspec);
- // Provide feedback that the symfile has been successfully added.
- const FileSpec &module_fs = old_module_sp->GetFileSpec();
- result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
- symfile_path, ss_symfile_uuid.GetData(),
- module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
-
- // Let clients know something changed in the module
- // if it is currently loaded
- ModuleList module_list;
- module_list.Append (old_module_sp);
- target->ModulesDidLoad (module_list);
- flush = true;
+ SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream());
+ if (symbol_vendor)
+ {
+ SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
+
+ if (symbol_file)
+ {
+ ObjectFile *object_file = symbol_file->GetObjectFile();
+
+ if (object_file && object_file->GetFileSpec() == symbol_fspec)
+ {
+ // Provide feedback that the symfile has been successfully added.
+ const FileSpec &module_fs = module_sp->GetFileSpec();
+ result.AppendMessageWithFormat("symbol file '%s' has been added to '%s/%s'\n",
+ symfile_path,
+ module_fs.GetDirectory().AsCString(),
+ module_fs.GetFilename().AsCString());
+
+ // Let clients know something changed in the module
+ // if it is currently loaded
+ ModuleList module_list;
+ module_list.Append (module_sp);
+ target->ModulesDidLoad (module_list);
+
+ // Make sure we load any scripting resources that may be embedded
+ // in the debug info files in case the platform supports that.
+ Error error;
+ module_sp->LoadScriptingResourceInTarget (target, error);
+
+ flush = true;
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ return true;
+ }
+ }
+ }
+ // Clear the symbol file spec if anything went wrong
+ module_sp->SetSymbolFileFileSpec (FileSpec());
+ }
+
+ if (module_spec.GetUUID().IsValid())
+ {
+ StreamString ss_symfile_uuid;
+ module_spec.GetUUID().Dump(&ss_symfile_uuid);
+ result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n",
+ symfile_path,
+ ss_symfile_uuid.GetData(),
+ (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
+ ? "\n please specify the full path to the symbol file"
+ : "");
}
else
{
- result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
- symfile_path, ss_symfile_uuid.GetData(),
- (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
- ? "\n please specify the full path to the symbol file"
- : "");
- return false;
+ result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n",
+ symfile_path,
+ (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
+ ? "\n please specify the full path to the symbol file"
+ : "");
}
}
else
{
result.AppendError ("one or more executable image paths must be specified");
- result.SetStatus (eReturnStatusFailed);
- return false;
}
- result.SetStatus (eReturnStatusSuccessFinishResult);
- return true;
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
virtual bool
DoExecute (Args& args,
CommandReturnObject &result)
{
- ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
- Target *target = exe_ctx.GetTargetPtr();
+ Target *target = m_exe_ctx.GetTargetPtr();
result.SetStatus (eReturnStatusFailed);
- if (target == NULL)
- {
- result.AppendError ("invalid target, create a debug target using the 'target create' command");
- }
- else
- {
- bool flush = false;
- ModuleSpec sym_spec;
- const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
- const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
- const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
+ bool flush = false;
+ ModuleSpec module_spec;
+ const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
+ const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
+ const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
- const size_t argc = args.GetArgumentCount();
- if (argc == 0)
+ const size_t argc = args.GetArgumentCount();
+ if (argc == 0)
+ {
+ if (uuid_option_set || file_option_set || frame_option_set)
{
- if (uuid_option_set || file_option_set || frame_option_set)
+ bool success = false;
+ bool error_set = false;
+ if (frame_option_set)
{
- bool success = false;
- bool error_set = false;
- if (frame_option_set)
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process)
{
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
+ const StateType process_state = process->GetState();
+ if (StateIsStoppedState (process_state, true))
{
- const StateType process_state = process->GetState();
- if (StateIsStoppedState (process_state, true))
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
+ if (frame)
{
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
+ ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
+ if (frame_module_sp)
{
- ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
- if (frame_module_sp)
+ if (frame_module_sp->GetPlatformFileSpec().Exists())
{
- if (frame_module_sp->GetPlatformFileSpec().Exists())
- {
- sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
- sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
- }
- sym_spec.GetUUID() = frame_module_sp->GetUUID();
- success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec();
- }
- else
- {
- result.AppendError ("frame has no module");
- error_set = true;
+ module_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
+ module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
}
+ module_spec.GetUUID() = frame_module_sp->GetUUID();
+ success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec();
}
else
{
- result.AppendError ("invalid current frame");
+ result.AppendError ("frame has no module");
error_set = true;
}
}
else
{
- result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
+ result.AppendError ("invalid current frame");
error_set = true;
}
}
else
{
- result.AppendError ("a process must exist in order to use the --frame option");
+ result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
error_set = true;
}
}
else
{
- if (uuid_option_set)
- {
- sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
- success |= sym_spec.GetUUID().IsValid();
- }
- else if (file_option_set)
- {
- sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
- ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec));
- if (module_sp)
- {
- sym_spec.GetFileSpec() = module_sp->GetFileSpec();
- sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
- sym_spec.GetUUID() = module_sp->GetUUID();
- sym_spec.GetArchitecture() = module_sp->GetArchitecture();
- }
- else
- {
- sym_spec.GetArchitecture() = target->GetArchitecture();
- }
- success |= sym_spec.GetFileSpec().Exists();
- }
+ result.AppendError ("a process must exist in order to use the --frame option");
+ error_set = true;
}
-
- if (success)
+ }
+ else
+ {
+ if (uuid_option_set)
{
- if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
- {
- if (sym_spec.GetSymbolFileSpec())
- success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result);
- }
+ module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
+ success |= module_spec.GetUUID().IsValid();
}
-
- if (!success && !error_set)
+ else if (file_option_set)
{
- StreamString error_strm;
- if (uuid_option_set)
- {
- error_strm.PutCString("unable to find debug symbols for UUID ");
- sym_spec.GetUUID().Dump (&error_strm);
- }
- else if (file_option_set)
+ module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
+ ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec));
+ if (module_sp)
{
- error_strm.PutCString("unable to find debug symbols for the executable file ");
- error_strm << sym_spec.GetFileSpec();
+ module_spec.GetFileSpec() = module_sp->GetFileSpec();
+ module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
+ module_spec.GetUUID() = module_sp->GetUUID();
+ module_spec.GetArchitecture() = module_sp->GetArchitecture();
}
- else if (frame_option_set)
+ else
{
- error_strm.PutCString("unable to find debug symbols for the current frame");
+ module_spec.GetArchitecture() = target->GetArchitecture();
}
- result.AppendError (error_strm.GetData());
+ success |= module_spec.GetFileSpec().Exists();
}
}
- else
+
+ if (success)
{
- result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
+ if (Symbols::DownloadObjectAndSymbolFile (module_spec))
+ {
+ if (module_spec.GetSymbolFileSpec())
+ success = AddModuleSymbols (target, module_spec, flush, result);
+ }
+ }
+
+ if (!success && !error_set)
+ {
+ StreamString error_strm;
+ if (uuid_option_set)
+ {
+ error_strm.PutCString("unable to find debug symbols for UUID ");
+ module_spec.GetUUID().Dump (&error_strm);
+ }
+ else if (file_option_set)
+ {
+ error_strm.PutCString("unable to find debug symbols for the executable file ");
+ error_strm << module_spec.GetFileSpec();
+ }
+ else if (frame_option_set)
+ {
+ error_strm.PutCString("unable to find debug symbols for the current frame");
+ }
+ result.AppendError (error_strm.GetData());
}
}
else
{
- if (uuid_option_set)
- {
- result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
- }
- else if (file_option_set)
- {
- result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
- }
- else if (frame_option_set)
- {
- result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
- }
- else
- {
- PlatformSP platform_sp (target->GetPlatform());
+ result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
+ }
+ }
+ else
+ {
+ if (uuid_option_set)
+ {
+ result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
+ }
+ else if (file_option_set)
+ {
+ result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
+ }
+ else if (frame_option_set)
+ {
+ result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
+ }
+ else
+ {
+ PlatformSP platform_sp (target->GetPlatform());
- for (size_t i=0; i<argc; ++i)
+ for (size_t i=0; i<argc; ++i)
+ {
+ const char *symfile_path = args.GetArgumentAtIndex(i);
+ if (symfile_path)
{
- const char *symfile_path = args.GetArgumentAtIndex(i);
- if (symfile_path)
+ module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
+ if (platform_sp)
{
FileSpec symfile_spec;
- sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
- if (platform_sp)
- platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
- else
- symfile_spec.SetFile(symfile_path, true);
-
- ArchSpec arch;
- bool symfile_exists = symfile_spec.Exists();
+ if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success())
+ module_spec.GetSymbolFileSpec() = symfile_spec;
+ }
+
+ ArchSpec arch;
+ bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
- if (symfile_exists)
- {
- if (!AddModuleSymbols (target, symfile_spec, flush, result))
- break;
- }
- else
+ if (symfile_exists)
+ {
+ if (!AddModuleSymbols (target, module_spec, flush, result))
+ break;
+ }
+ else
+ {
+ char resolved_symfile_path[PATH_MAX];
+ if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
{
- char resolved_symfile_path[PATH_MAX];
- if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
+ if (strcmp (resolved_symfile_path, symfile_path) != 0)
{
- if (strcmp (resolved_symfile_path, symfile_path) != 0)
- {
- result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
- break;
- }
+ result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
+ break;
}
- result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
- break;
}
+ result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
+ break;
}
}
}
}
+ }
- if (flush)
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- process->Flush();
- }
+ if (flush)
+ {
+ Process *process = m_exe_ctx.GetProcessPtr();
+ if (process)
+ process->Flush();
}
return result.Succeeded();
}
@@ -4379,7 +4646,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
switch (short_option)
@@ -4604,7 +4871,7 @@
case eInputReaderDone:
if (!got_interrupted && !batch_mode)
{
- out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
+ out_stream->Printf ("Stop hook #%" PRIu64 " added.\n", new_stop_hook->GetID());
out_stream->Flush();
}
break;
@@ -4690,7 +4957,7 @@
{
// Use one-liner.
new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
- result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
+ result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID());
}
else
{
Index: aze/lldb/source/Commands/CommandObjectThread.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectThread.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectThread.cpp 2013-03-03 09:35:50.143457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectThread.h"
// C Includes
@@ -67,7 +69,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -123,10 +125,14 @@
CommandObjectThreadBacktrace (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
- "thread backtrace",
- "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.",
- NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ "thread backtrace",
+ "Show the stack for one or more threads. If no threads are specified, show the currently selected thread. Use the thread-index \"all\" to see all threads.",
+ NULL,
+ eFlagRequiresProcess |
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_options(interpreter)
{
CommandArgumentEntry arg;
@@ -164,28 +170,19 @@
const uint32_t num_frames_with_source = 0;
if (command.GetArgumentCount() == 0)
{
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Thread *thread = exe_ctx.GetThreadPtr();
- if (thread)
- {
- // Thread::GetStatus() returns the number of frames shown.
- if (thread->GetStatus (strm,
- m_options.m_start,
- m_options.m_count,
- num_frames_with_source))
- {
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- }
- else
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ // Thread::GetStatus() returns the number of frames shown.
+ if (thread->GetStatus (strm,
+ m_options.m_start,
+ m_options.m_count,
+ num_frames_with_source))
{
- result.AppendError ("invalid thread");
- result.SetStatus (eReturnStatusFailed);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
}
}
else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
Mutex::Locker locker (process->GetThreadList().GetMutex());
uint32_t num_threads = process->GetThreadList().GetSize();
for (uint32_t i = 0; i < num_threads; i++)
@@ -208,12 +205,12 @@
}
else
{
- uint32_t num_args = command.GetArgumentCount();
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ const size_t num_args = command.GetArgumentCount();
+ Process *process = m_exe_ctx.GetProcessPtr();
Mutex::Locker locker (process->GetThreadList().GetMutex());
std::vector<ThreadSP> thread_sps;
- for (uint32_t i = 0; i < num_args; i++)
+ for (size_t i = 0; i < num_args; i++)
{
bool success;
@@ -296,7 +293,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -323,6 +320,13 @@
}
break;
+ case 't':
+ {
+ m_step_in_target.clear();
+ m_step_in_target.assign(option_arg);
+
+ }
+ break;
default:
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
break;
@@ -337,6 +341,7 @@
m_avoid_no_debug = true;
m_run_mode = eOnlyDuringStepping;
m_avoid_regexp.clear();
+ m_step_in_target.clear();
}
const OptionDefinition*
@@ -353,16 +358,21 @@
bool m_avoid_no_debug;
RunMode m_run_mode;
std::string m_avoid_regexp;
+ std::string m_step_in_target;
};
CommandObjectThreadStepWithTypeAndScope (CommandInterpreter &interpreter,
const char *name,
const char *help,
const char *syntax,
- uint32_t flags,
StepType step_type,
StepScope step_scope) :
- CommandObjectParsed (interpreter, name, help, syntax, flags),
+ CommandObjectParsed (interpreter, name, help, syntax,
+ eFlagRequiresProcess |
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_step_type (step_type),
m_step_scope (step_scope),
m_options (interpreter)
@@ -397,171 +407,161 @@
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
bool synchronous_execution = m_interpreter.GetSynchronous();
- if (process == NULL)
- {
- result.AppendError ("need a valid process to step");
- result.SetStatus (eReturnStatusFailed);
+ const uint32_t num_threads = process->GetThreadList().GetSize();
+ Thread *thread = NULL;
+ if (command.GetArgumentCount() == 0)
+ {
+ thread = process->GetThreadList().GetSelectedThread().get();
+ if (thread == NULL)
+ {
+ result.AppendError ("no selected thread in process");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
}
else
{
- const uint32_t num_threads = process->GetThreadList().GetSize();
- Thread *thread = NULL;
-
- if (command.GetArgumentCount() == 0)
+ const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
+ uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
+ if (step_thread_idx == LLDB_INVALID_INDEX32)
{
- thread = process->GetThreadList().GetSelectedThread().get();
- if (thread == NULL)
- {
- result.AppendError ("no selected thread in process");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else
+ thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
+ if (thread == NULL)
{
- const char *thread_idx_cstr = command.GetArgumentAtIndex(0);
- uint32_t step_thread_idx = Args::StringToUInt32 (thread_idx_cstr, LLDB_INVALID_INDEX32);
- if (step_thread_idx == LLDB_INVALID_INDEX32)
- {
- result.AppendErrorWithFormat ("invalid thread index '%s'.\n", thread_idx_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- thread = process->GetThreadList().FindThreadByIndexID(step_thread_idx).get();
- if (thread == NULL)
- {
- result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
- step_thread_idx, num_threads);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ result.AppendErrorWithFormat ("Thread index %u is out of range (valid values are 0 - %u).\n",
+ step_thread_idx, num_threads);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
+ }
- const bool abort_other_plans = false;
- const lldb::RunMode stop_other_threads = m_options.m_run_mode;
-
- // This is a bit unfortunate, but not all the commands in this command object support
- // only while stepping, so I use the bool for them.
- bool bool_stop_other_threads;
- if (m_options.m_run_mode == eAllThreads)
+ const bool abort_other_plans = false;
+ const lldb::RunMode stop_other_threads = m_options.m_run_mode;
+
+ // This is a bit unfortunate, but not all the commands in this command object support
+ // only while stepping, so I use the bool for them.
+ bool bool_stop_other_threads;
+ if (m_options.m_run_mode == eAllThreads)
+ bool_stop_other_threads = false;
+ else if (m_options.m_run_mode == eOnlyDuringStepping)
+ {
+ if (m_step_type == eStepTypeOut)
bool_stop_other_threads = false;
- else if (m_options.m_run_mode == eOnlyDuringStepping)
- {
- if (m_step_type == eStepTypeOut)
- bool_stop_other_threads = false;
- else
- bool_stop_other_threads = true;
- }
else
bool_stop_other_threads = true;
+ }
+ else
+ bool_stop_other_threads = true;
- ThreadPlan *new_plan = NULL;
-
- if (m_step_type == eStepTypeInto)
- {
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ ThreadPlan *new_plan = NULL;
+
+ if (m_step_type == eStepTypeInto)
+ {
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame->HasDebugInformation ())
+ if (frame->HasDebugInformation ())
+ {
+ new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
+ frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
+ frame->GetSymbolContext(eSymbolContextEverything),
+ m_options.m_step_in_target.c_str(),
+ stop_other_threads,
+ m_options.m_avoid_no_debug);
+ if (new_plan && !m_options.m_avoid_regexp.empty())
{
- new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, m_step_type,
- frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
- frame->GetSymbolContext(eSymbolContextEverything),
- stop_other_threads,
- m_options.m_avoid_no_debug);
- if (new_plan && !m_options.m_avoid_regexp.empty())
- {
- ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
- step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
- }
+ ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (new_plan);
+ step_in_range_plan->SetAvoidRegexp(m_options.m_avoid_regexp.c_str());
}
- else
- new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
-
}
- else if (m_step_type == eStepTypeOver)
- {
- StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
+ else
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
+
+ }
+ else if (m_step_type == eStepTypeOver)
+ {
+ StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
- if (frame->HasDebugInformation())
- new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
- m_step_type,
+ if (frame->HasDebugInformation())
+ new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
frame->GetSymbolContext(eSymbolContextEverything).line_entry.range,
frame->GetSymbolContext(eSymbolContextEverything),
- stop_other_threads,
- false);
- else
- new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
- abort_other_plans,
- bool_stop_other_threads);
-
- }
- else if (m_step_type == eStepTypeTrace)
- {
- new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
- }
- else if (m_step_type == eStepTypeTraceOver)
- {
- new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
- }
- else if (m_step_type == eStepTypeOut)
- {
- new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
- NULL,
- false,
- bool_stop_other_threads,
- eVoteYes,
- eVoteNoOpinion,
- thread->GetSelectedFrameIndex());
- }
+ stop_other_threads);
else
- {
- result.AppendError ("step type is not supported");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
- // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
- // so that they can be interruptible). Then resume the process.
-
- if (new_plan != NULL)
- {
- new_plan->SetIsMasterPlan (true);
- new_plan->SetOkayToDiscard (false);
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
+ abort_other_plans,
+ bool_stop_other_threads);
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- process->Resume ();
-
+ }
+ else if (m_step_type == eStepTypeTrace)
+ {
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, abort_other_plans, bool_stop_other_threads);
+ }
+ else if (m_step_type == eStepTypeTraceOver)
+ {
+ new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, abort_other_plans, bool_stop_other_threads);
+ }
+ else if (m_step_type == eStepTypeOut)
+ {
+ new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
+ NULL,
+ false,
+ bool_stop_other_threads,
+ eVoteYes,
+ eVoteNoOpinion,
+ thread->GetSelectedFrameIndex());
+ }
+ else
+ {
+ result.AppendError ("step type is not supported");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ // If we got a new plan, then set it to be a master plan (User level Plans should be master plans
+ // so that they can be interruptible). Then resume the process.
+
+ if (new_plan != NULL)
+ {
+ new_plan->SetIsMasterPlan (true);
+ new_plan->SetOkayToDiscard (false);
- if (synchronous_execution)
- {
- StateType state = process->WaitForProcessToStop (NULL);
-
- //EventSP event_sp;
- //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
- //while (! StateIsStoppedState (state))
- // {
- // state = process->WaitForStateChangedEvents (NULL, event_sp);
- // }
- process->GetThreadList().SetSelectedThreadByID (thread->GetID());
- result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
- }
- else
- {
- result.SetStatus (eReturnStatusSuccessContinuingNoResult);
- }
+ process->GetThreadList().SetSelectedThreadByID (thread->GetID());
+ process->Resume ();
+
+
+ if (synchronous_execution)
+ {
+ StateType state = process->WaitForProcessToStop (NULL);
+
+ //EventSP event_sp;
+ //StateType state = process->WaitForStateChangedEvents (NULL, event_sp);
+ //while (! StateIsStoppedState (state))
+ // {
+ // state = process->WaitForStateChangedEvents (NULL, event_sp);
+ // }
+ process->GetThreadList().SetSelectedThreadByID (thread->GetID());
+ result.SetDidChangeProcessState (true);
+ result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
{
- result.AppendError ("Couldn't find thread plan to implement step type.");
- result.SetStatus (eReturnStatusFailed);
+ result.SetStatus (eReturnStatusSuccessContinuingNoResult);
}
}
+ else
+ {
+ result.AppendError ("Couldn't find thread plan to implement step type.");
+ result.SetStatus (eReturnStatusFailed);
+ }
return result.Succeeded();
}
@@ -593,7 +593,8 @@
{
{ LLDB_OPT_SET_1, false, "avoid-no-debug", 'a', required_argument, NULL, 0, eArgTypeBoolean, "A boolean value that sets whether step-in will step over functions with no debug information."},
{ LLDB_OPT_SET_1, false, "run-mode", 'm', required_argument, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread."},
-{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to step over."},
+{ LLDB_OPT_SET_1, false, "step-over-regexp",'r', required_argument, NULL, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in."},
+{ LLDB_OPT_SET_1, false, "step-in-target", 't', required_argument, NULL, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -611,7 +612,10 @@
"thread continue",
"Continue execution of one or more threads in an active process.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused)
{
CommandArgumentEntry arg;
CommandArgumentData thread_idx_arg;
@@ -645,7 +649,7 @@
return false;
}
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("no process exists. Cannot continue");
@@ -723,7 +727,7 @@
thread->SetResumeState (eStateSuspended);
}
}
- result.AppendMessageWithFormat ("in process %llu\n", process->GetID());
+ result.AppendMessageWithFormat ("in process %" PRIu64 "\n", process->GetID());
}
}
else
@@ -741,7 +745,7 @@
Thread *thread = process->GetThreadList().GetThreadAtIndex(idx).get();
if (thread == current_thread)
{
- result.AppendMessageWithFormat ("Resuming thread 0x%4.4llx in process %llu\n", thread->GetID(), process->GetID());
+ result.AppendMessageWithFormat ("Resuming thread 0x%4.4" PRIx64 " in process %" PRIu64 "\n", thread->GetID(), process->GetID());
thread->SetResumeState (eStateRunning);
}
else
@@ -754,13 +758,13 @@
Error error (process->Resume());
if (error.Success())
{
- result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
+ result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
if (synchronous_execution)
{
state = process->WaitForProcessToStop (NULL);
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
+ result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -818,7 +822,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -891,7 +895,10 @@
"thread until",
"Run the current or specified thread until it reaches a given line number or leaves the current function.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresThread |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_options (interpreter)
{
CommandArgumentEntry arg;
@@ -935,7 +942,7 @@
return false;
}
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("need a valid process to step");
@@ -1082,13 +1089,13 @@
Error error (process->Resume ());
if (error.Success())
{
- result.AppendMessageWithFormat ("Process %llu resuming\n", process->GetID());
+ result.AppendMessageWithFormat ("Process %" PRIu64 " resuming\n", process->GetID());
if (synchronous_execution)
{
StateType state = process->WaitForProcessToStop (NULL);
result.SetDidChangeProcessState (true);
- result.AppendMessageWithFormat ("Process %llu %s\n", process->GetID(), StateAsCString (state));
+ result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state));
result.SetStatus (eReturnStatusSuccessFinishNoResult);
}
else
@@ -1133,7 +1140,10 @@
"thread select",
"Select a thread as the currently active thread.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
CommandArgumentEntry arg;
CommandArgumentData thread_idx_arg;
@@ -1159,7 +1169,7 @@
virtual bool
DoExecute (Args& command, CommandReturnObject &result)
{
- Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+ Process *process = m_exe_ctx.GetProcessPtr();
if (process == NULL)
{
result.AppendError ("no process");
@@ -1183,17 +1193,9 @@
return false;
}
- process->GetThreadList().SetSelectedThreadByID(new_thread->GetID());
+ process->GetThreadList().SetSelectedThreadByID(new_thread->GetID(), true);
result.SetStatus (eReturnStatusSuccessFinishNoResult);
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 1;
- const uint32_t num_frames_with_source = 1;
- new_thread->GetStatus (result.GetOutputStream(),
- start_frame,
- num_frames,
- num_frames_with_source);
-
return result.Succeeded();
}
@@ -1214,7 +1216,10 @@
"thread list",
"Show a summary of all current threads in a process.",
"thread list",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresProcess |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused )
{
}
@@ -1228,46 +1233,119 @@
{
Stream &strm = result.GetOutputStream();
result.SetStatus (eReturnStatusSuccessFinishNoResult);
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- const bool only_threads_with_stop_reason = false;
- const uint32_t start_frame = 0;
- const uint32_t num_frames = 0;
- const uint32_t num_frames_with_source = 0;
- process->GetStatus(strm);
- process->GetThreadStatus (strm,
- only_threads_with_stop_reason,
- start_frame,
- num_frames,
- num_frames_with_source);
- }
- else
- {
- result.AppendError ("no current location or status available");
- result.SetStatus (eReturnStatusFailed);
- }
+ Process *process = m_exe_ctx.GetProcessPtr();
+ const bool only_threads_with_stop_reason = false;
+ const uint32_t start_frame = 0;
+ const uint32_t num_frames = 0;
+ const uint32_t num_frames_with_source = 0;
+ process->GetStatus(strm);
+ process->GetThreadStatus (strm,
+ only_threads_with_stop_reason,
+ start_frame,
+ num_frames,
+ num_frames_with_source);
return result.Succeeded();
}
};
+//-------------------------------------------------------------------------
+// CommandObjectThreadReturn
+//-------------------------------------------------------------------------
+
class CommandObjectThreadReturn : public CommandObjectRaw
{
public:
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions (CommandInterpreter &interpreter) :
+ Options (interpreter),
+ m_from_expression (false)
+ {
+ // Keep default values of all options in one place: OptionParsingStarting ()
+ OptionParsingStarting ();
+ }
+
+ virtual
+ ~CommandOptions ()
+ {
+ }
+
+ virtual Error
+ SetOptionValue (uint32_t option_idx, const char *option_arg)
+ {
+ Error error;
+ const int short_option = m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'x':
+ {
+ bool success;
+ bool tmp_value = Args::StringToBoolean (option_arg, false, &success);
+ if (success)
+ m_from_expression = tmp_value;
+ else
+ {
+ error.SetErrorStringWithFormat ("invalid boolean value '%s' for 'x' option", option_arg);
+ }
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+ break;
+
+ }
+ return error;
+ }
+
+ void
+ OptionParsingStarting ()
+ {
+ m_from_expression = false;
+ }
+
+ const OptionDefinition*
+ GetDefinitions ()
+ {
+ return g_option_table;
+ }
+
+ bool m_from_expression;
+
+ // Options table: Required for subclasses of Options.
+
+ static OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+ };
+
+ virtual
+ Options *
+ GetOptions ()
+ {
+ return &m_options;
+ }
+
CommandObjectThreadReturn (CommandInterpreter &interpreter) :
CommandObjectRaw (interpreter,
"thread return",
- "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value.",
+ "Return from the currently selected frame, short-circuiting execution of the frames below it, with an optional return value,"
+ " or with the -x option from the innermost function evaluation.",
"thread return",
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
+ m_options (interpreter)
{
CommandArgumentEntry arg;
CommandArgumentData expression_arg;
// Define the first (and only) variant of this arg.
expression_arg.arg_type = eArgTypeExpression;
- expression_arg.arg_repetition = eArgRepeatPlain;
+ expression_arg.arg_repetition = eArgRepeatOptional;
// There is only one variant this argument could be; put it into the argument entry.
arg.push_back (expression_arg);
@@ -1290,18 +1368,41 @@
CommandReturnObject &result
)
{
- // If there is a command string, pass it to the expression parser:
- ExecutionContext exe_ctx = m_interpreter.GetExecutionContext();
- if (!(exe_ctx.HasProcessScope() && exe_ctx.HasThreadScope() && exe_ctx.HasFrameScope()))
+ // I am going to handle this by hand, because I don't want you to have to say:
+ // "thread return -- -5".
+ if (command[0] == '-' && command[1] == 'x')
{
- result.AppendError("Must have selected process, thread and frame for thread return.");
- result.SetStatus (eReturnStatusFailed);
- return false;
+ if (command && command[2] != '\0')
+ result.AppendWarning("Return values ignored when returning from user called expressions");
+
+ Thread *thread = m_exe_ctx.GetThreadPtr();
+ Error error;
+ error = thread->UnwindInnermostExpression();
+ if (!error.Success())
+ {
+ result.AppendErrorWithFormat ("Unwinding expression failed - %s.", error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ }
+ else
+ {
+ bool success = thread->SetSelectedFrameByIndexNoisily (0, result.GetOutputStream());
+ if (success)
+ {
+ m_exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ }
+ else
+ {
+ result.AppendErrorWithFormat ("Could not select 0th frame after unwinding expression.");
+ result.SetStatus (eReturnStatusFailed);
+ }
+ }
+ return result.Succeeded();
}
ValueObjectSP return_valobj_sp;
- StackFrameSP frame_sp = exe_ctx.GetFrameSP();
+ StackFrameSP frame_sp = m_exe_ctx.GetFrameSP();
uint32_t frame_idx = frame_sp->GetFrameIndex();
if (frame_sp->IsInlined())
@@ -1313,7 +1414,7 @@
if (command && command[0] != '\0')
{
- Target *target = exe_ctx.GetTargetPtr();
+ Target *target = m_exe_ctx.GetTargetPtr();
EvaluateExpressionOptions options;
options.SetUnwindOnError(true);
@@ -1337,7 +1438,7 @@
}
Error error;
- ThreadSP thread_sp = exe_ctx.GetThreadSP();
+ ThreadSP thread_sp = m_exe_ctx.GetThreadSP();
const bool broadcast = true;
error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
if (!error.Success())
@@ -1350,8 +1451,16 @@
result.SetStatus (eReturnStatusSuccessFinishResult);
return true;
}
+
+ CommandOptions m_options;
};
+OptionDefinition
+CommandObjectThreadReturn::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_ALL, false, "from-expression", 'x', no_argument, NULL, 0, eArgTypeNone, "Return from the innermost expression evaluation."},
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
//-------------------------------------------------------------------------
// CommandObjectMultiwordThread
@@ -1374,7 +1483,6 @@
"thread step-in",
"Source level single step in specified thread (current thread, if none specified).",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
eStepTypeInto,
eStepScopeSource)));
@@ -1383,7 +1491,6 @@
"thread step-out",
"Finish executing the function of the currently selected frame and return to its call site in specified thread (current thread, if none specified).",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
eStepTypeOut,
eStepScopeSource)));
@@ -1392,7 +1499,6 @@
"thread step-over",
"Source level single step in specified thread (current thread, if none specified), stepping over calls.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
eStepTypeOver,
eStepScopeSource)));
@@ -1401,7 +1507,6 @@
"thread step-inst",
"Single step one instruction in specified thread (current thread, if none specified).",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
eStepTypeTrace,
eStepScopeInstruction)));
@@ -1410,7 +1515,6 @@
"thread step-inst-over",
"Single step one instruction in specified thread (current thread, if none specified), stepping over calls.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused,
eStepTypeTraceOver,
eStepScopeInstruction)));
}
Index: aze/lldb/source/Commands/CommandObjectType.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectType.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectType.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectType.h"
// C Includes
@@ -15,13 +17,13 @@
// C++ Includes
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/InputReaderEZ.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StringList.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandObject.h"
#include "lldb/Interpreter/CommandReturnObject.h"
@@ -209,7 +211,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
switch (short_option)
@@ -374,7 +376,7 @@
const char *option_value)
{
Error error;
- const char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
bool success;
switch (short_option)
@@ -816,7 +818,7 @@
ScriptAddOptions *options_ptr = ((ScriptAddOptions*)data.baton);
if (!options_ptr)
{
- out_stream->Printf ("Internal error #1: no script attached.\n");
+ out_stream->Printf ("internal synchronization information missing or invalid.\n");
out_stream->Flush();
return;
}
@@ -826,7 +828,7 @@
ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
if (!interpreter)
{
- out_stream->Printf ("Internal error #2: no script attached.\n");
+ out_stream->Printf ("no script interpreter.\n");
out_stream->Flush();
return;
}
@@ -834,13 +836,13 @@
if (!interpreter->GenerateTypeScriptFunction (options->m_user_source,
funct_name_str))
{
- out_stream->Printf ("Internal error #3: no script attached.\n");
+ out_stream->Printf ("unable to generate a function.\n");
out_stream->Flush();
return;
}
if (funct_name_str.empty())
{
- out_stream->Printf ("Internal error #4: no script attached.\n");
+ out_stream->Printf ("unable to obtain a valid function name from the script interpreter.\n");
out_stream->Flush();
return;
}
@@ -915,7 +917,7 @@
CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
switch (short_option)
@@ -1035,17 +1037,10 @@
if (!m_options.m_python_function.empty()) // we have a Python function ready to use
{
- ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
- if (!interpreter)
- {
- result.AppendError ("Internal error #1N: no script attached.\n");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
const char *funct_name = m_options.m_python_function.c_str();
if (!funct_name || !funct_name[0])
{
- result.AppendError ("Internal error #2N: no script attached.\n");
+ result.AppendError ("function name empty.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -1055,13 +1050,20 @@
script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
funct_name,
code.c_str()));
+
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+
+ if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
+ result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
+ "please define it before attempting to use this summary.\n",
+ funct_name);
}
else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
{
ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
if (!interpreter)
{
- result.AppendError ("Internal error #1Q: no script attached.\n");
+ result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -1071,13 +1073,13 @@
if (!interpreter->GenerateTypeScriptFunction (funct_sl,
funct_name_str))
{
- result.AppendError ("Internal error #2Q: no script attached.\n");
+ result.AppendError ("unable to generate function wrapper.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
if (funct_name_str.empty())
{
- result.AppendError ("Internal error #3Q: no script attached.\n");
+ result.AppendError ("script interpreter failed to generate a valid function name.\n");
result.SetStatus (eReturnStatusFailed);
return false;
}
@@ -1417,7 +1419,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1580,7 +1582,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1724,7 +1726,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -1959,7 +1961,7 @@
if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
{
// we want to make sure to enable "system" last and "default" first
- DataVisualization::Categories::Enable(ConstString("default"), CategoryMap::First);
+ DataVisualization::Categories::Enable(ConstString("default"), TypeCategoryMap::First);
uint32_t num_categories = DataVisualization::Categories::GetCount();
for (uint32_t i = 0; i < num_categories; i++)
{
@@ -1970,10 +1972,10 @@
::strcmp(category_sp->GetName(), "default") == 0 )
continue;
else
- DataVisualization::Categories::Enable(category_sp, CategoryMap::Default);
+ DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
}
}
- DataVisualization::Categories::Enable(ConstString("system"), CategoryMap::Last);
+ DataVisualization::Categories::Enable(ConstString("system"), TypeCategoryMap::Last);
}
else
{
@@ -2287,7 +2289,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -2501,7 +2503,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -2699,7 +2701,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -2865,7 +2867,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -3032,7 +3034,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -3161,7 +3163,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -3351,7 +3353,7 @@
SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton);
if (!options_ptr)
{
- out_stream->Printf ("Internal error #1: no script attached.\n");
+ out_stream->Printf ("internal synchronization data missing.\n");
out_stream->Flush();
return;
}
@@ -3361,7 +3363,7 @@
ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
if (!interpreter)
{
- out_stream->Printf ("Internal error #2: no script attached.\n");
+ out_stream->Printf ("no script interpreter.\n");
out_stream->Flush();
return;
}
@@ -3369,13 +3371,13 @@
if (!interpreter->GenerateTypeSynthClass (options->m_user_source,
class_name_str))
{
- out_stream->Printf ("Internal error #3: no script attached.\n");
+ out_stream->Printf ("unable to generate a class.\n");
out_stream->Flush();
return;
}
if (class_name_str.empty())
{
- out_stream->Printf ("Internal error #4: no script attached.\n");
+ out_stream->Printf ("unable to obtain a proper name for the class.\n");
out_stream->Flush();
return;
}
@@ -3383,10 +3385,10 @@
// everything should be fine now, let's add the synth provider class
SyntheticChildrenSP synth_provider;
- synth_provider.reset(new TypeSyntheticImpl(SyntheticChildren::Flags().SetCascades(options->m_cascade).
- SetSkipPointers(options->m_skip_pointers).
- SetSkipReferences(options->m_skip_references),
- class_name_str.c_str()));
+ synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
+ SetSkipPointers(options->m_skip_pointers).
+ SetSkipReferences(options->m_skip_references),
+ class_name_str.c_str()));
lldb::TypeCategoryImplSP category;
@@ -3413,7 +3415,7 @@
}
else
{
- out_stream->Printf ("Internal error #6: no script attached.\n");
+ out_stream->Printf ("invalid type name.\n");
out_stream->Flush();
return;
}
@@ -3502,14 +3504,19 @@
SyntheticChildrenSP entry;
- TypeSyntheticImpl* impl = new TypeSyntheticImpl(SyntheticChildren::Flags().
- SetCascades(m_options.m_cascade).
- SetSkipPointers(m_options.m_skip_pointers).
- SetSkipReferences(m_options.m_skip_references),
- m_options.m_class_name.c_str());
+ ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
+ SetCascades(m_options.m_cascade).
+ SetSkipPointers(m_options.m_skip_pointers).
+ SetSkipReferences(m_options.m_skip_references),
+ m_options.m_class_name.c_str());
entry.reset(impl);
+ ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
+
+ if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
+ result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
+
// now I have a valid provider, let's add it to every type
lldb::TypeCategoryImplSP category;
@@ -3658,7 +3665,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
bool success;
switch (short_option)
Index: aze/lldb/source/Commands/CommandObjectVersion.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectVersion.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectVersion.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectVersion.h"
// C Includes
Index: aze/lldb/source/Commands/CommandObjectWatchpointCommand.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectWatchpointCommand.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectWatchpointCommand.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
// C++ Includes
@@ -396,7 +398,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
Index: aze/lldb/source/Commands/CommandObjectWatchpoint.cpp
===================================================================
--- aze.orig/lldb/source/Commands/CommandObjectWatchpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/CommandObjectWatchpoint.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectWatchpoint.h"
#include "CommandObjectWatchpointCommand.h"
@@ -67,23 +69,6 @@
while (!Str.empty() && isspace(Str[0]))
Str = Str.substr(1);
}
-static inline llvm::StringRef StripOptionTerminator(llvm::StringRef &Str, bool with_dash_w, bool with_dash_x)
-{
- llvm::StringRef ExprStr = Str;
-
- // Get rid of the leading spaces first.
- StripLeadingSpaces(ExprStr);
-
- // If there's no '-w' and no '-x', we can just return.
- if (!with_dash_w && !with_dash_x)
- return ExprStr;
-
- // Otherwise, split on the "--" option terminator string, and return the rest of the string.
- ExprStr = ExprStr.split("--").second;
- StripLeadingSpaces(ExprStr);
- return ExprStr;
-}
-
// Equivalent class: {"-", "to", "To", "TO"} of range specifier array.
static const char* RSA[4] = { "-", "to", "To", "TO" };
@@ -213,7 +198,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -642,7 +627,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -799,7 +784,7 @@
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -932,7 +917,10 @@
"If watchpoint setting fails, consider disable/delete existing ones "
"to free up resources.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
@@ -970,9 +958,9 @@
}
protected:
- static uint32_t GetVariableCallback (void *baton,
- const char *name,
- VariableList &variable_list)
+ static size_t GetVariableCallback (void *baton,
+ const char *name,
+ VariableList &variable_list)
{
Target *target = static_cast<Target *>(baton);
if (target)
@@ -986,18 +974,10 @@
}
virtual bool
- DoExecute (Args& command,
- CommandReturnObject &result)
+ DoExecute (Args& command, CommandReturnObject &result)
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
- {
- result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
// If no argument is present, issue an error message. There's no way to set a watchpoint.
if (command.GetArgumentCount() <= 0)
@@ -1023,7 +1003,8 @@
Stream &output_stream = result.GetOutputStream();
// A simple watch variable gesture allows only one argument.
- if (command.GetArgumentCount() != 1) {
+ if (command.GetArgumentCount() != 1)
+ {
result.GetErrorStream().Printf("error: specify exactly one variable to watch for\n");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -1039,14 +1020,15 @@
var_sp,
error);
- if (!valobj_sp) {
+ if (!valobj_sp)
+ {
// Not in the frame; let's check the globals.
VariableList variable_list;
ValueObjectList valobj_list;
Error error (Variable::GetValuesForVariableExpressionPath (command.GetArgumentAtIndex(0),
- exe_ctx.GetBestExecutionContextScope(),
+ m_exe_ctx.GetBestExecutionContextScope(),
GetVariableCallback,
target,
variable_list,
@@ -1058,17 +1040,21 @@
ClangASTType type;
- if (valobj_sp) {
+ if (valobj_sp)
+ {
AddressType addr_type;
addr = valobj_sp->GetAddressOf(false, &addr_type);
- if (addr_type == eAddressTypeLoad) {
+ if (addr_type == eAddressTypeLoad)
+ {
// We're in business.
// Find out the size of this variable.
size = m_option_watchpoint.watch_size == 0 ? valobj_sp->GetByteSize()
: m_option_watchpoint.watch_size;
}
type.SetClangType(valobj_sp->GetClangAST(), valobj_sp->GetClangType());
- } else {
+ }
+ else
+ {
const char *error_cstr = error.AsCString(NULL);
if (error_cstr)
result.GetErrorStream().Printf("error: %s\n", error_cstr);
@@ -1082,10 +1068,12 @@
uint32_t watch_type = m_option_watchpoint.watch_type;
error.Clear();
Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
- if (wp) {
+ if (wp)
+ {
wp->SetWatchSpec(command.GetArgumentAtIndex(0));
wp->SetWatchVariable(true);
- if (var_sp && var_sp->GetDeclaration().GetFile()) {
+ if (var_sp && var_sp->GetDeclaration().GetFile())
+ {
StreamString ss;
// True to show fullpath for declaration file.
var_sp->GetDeclaration().DumpStopContext(&ss, true);
@@ -1095,8 +1083,10 @@
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu, variable expression='%s').\n",
+ }
+ else
+ {
+ result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu, variable expression='%s').\n",
addr, size, command.GetArgumentAtIndex(0));
if (error.AsCString(NULL))
result.AppendError(error.AsCString());
@@ -1133,7 +1123,10 @@
"If watchpoint setting fails, consider disable/delete existing ones "
"to free up resources.",
NULL,
- eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock |
+ eFlagProcessMustBeLaunched |
+ eFlagProcessMustBePaused ),
m_option_group (interpreter),
m_option_watchpoint ()
{
@@ -1180,23 +1173,53 @@
DoExecute (const char *raw_command, CommandReturnObject &result)
{
Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
- ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
- {
- result.AppendError ("you must be stopped in a valid stack frame to set a watchpoint.");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ StackFrame *frame = m_exe_ctx.GetFramePtr();
Args command(raw_command);
+ const char *expr = NULL;
+ if (raw_command[0] == '-')
+ {
+ // We have some options and these options MUST end with --.
+ const char *end_options = NULL;
+ const char *s = raw_command;
+ while (s && s[0])
+ {
+ end_options = ::strstr (s, "--");
+ if (end_options)
+ {
+ end_options += 2; // Get past the "--"
+ if (::isspace (end_options[0]))
+ {
+ expr = end_options;
+ while (::isspace (*expr))
+ ++expr;
+ break;
+ }
+ }
+ s = end_options;
+ }
+
+ if (end_options)
+ {
+ Args args (raw_command, end_options - raw_command);
+ if (!ParseOptions (args, result))
+ return false;
+
+ Error error (m_option_group.NotifyOptionParsingFinished());
+ if (error.Fail())
+ {
+ result.AppendError (error.AsCString());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ }
+ }
- // Process possible options.
- if (!ParseOptions (command, result))
- return false;
+ if (expr == NULL)
+ expr = raw_command;
// If no argument is present, issue an error message. There's no way to set a watchpoint.
- if (command.GetArgumentCount() <= 0)
+ if (command.GetArgumentCount() == 0)
{
result.GetErrorStream().Printf("error: required argument missing; specify an expression to evaulate into the addres to watch for\n");
result.SetStatus(eReturnStatusFailed);
@@ -1217,21 +1240,7 @@
lldb::addr_t addr = 0;
size_t size = 0;
- VariableSP var_sp;
ValueObjectSP valobj_sp;
- Stream &output_stream = result.GetOutputStream();
-
- // We will process the raw command string to rid of the '-w', '-x', or '--'
- llvm::StringRef raw_expr_str(raw_command);
- std::string expr_str = StripOptionTerminator(raw_expr_str, with_dash_w, with_dash_x).str();
-
- // Sanity check for when the user forgets to terminate the option strings with a '--'.
- if ((with_dash_w || with_dash_w) && expr_str.empty())
- {
- result.GetErrorStream().Printf("error: did you forget to enter the option terminator string \"--\"?\n");
- result.SetStatus(eReturnStatusFailed);
- return false;
- }
// Use expression evaluation to arrive at the address to watch.
EvaluateExpressionOptions options;
@@ -1241,13 +1250,14 @@
.SetRunOthers(true)
.SetTimeoutUsec(0);
- ExecutionResults expr_result = target->EvaluateExpression (expr_str.c_str(),
+ ExecutionResults expr_result = target->EvaluateExpression (expr,
frame,
valobj_sp,
options);
- if (expr_result != eExecutionCompleted) {
+ if (expr_result != eExecutionCompleted)
+ {
result.GetErrorStream().Printf("error: expression evaluation of address to watch failed\n");
- result.GetErrorStream().Printf("expression evaluated: %s\n", expr_str.c_str());
+ result.GetErrorStream().Printf("expression evaluated: %s\n", expr);
result.SetStatus(eReturnStatusFailed);
return false;
}
@@ -1255,7 +1265,8 @@
// Get the address to watch.
bool success = false;
addr = valobj_sp->GetValueAsUnsigned(0, &success);
- if (!success) {
+ if (!success)
+ {
result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
result.SetStatus(eReturnStatusFailed);
return false;
@@ -1274,19 +1285,17 @@
Error error;
Watchpoint *wp = target->CreateWatchpoint(addr, size, &type, watch_type, error).get();
- if (wp) {
- if (var_sp && var_sp->GetDeclaration().GetFile()) {
- StreamString ss;
- // True to show fullpath for declaration file.
- var_sp->GetDeclaration().DumpStopContext(&ss, true);
- wp->SetDeclInfo(ss.GetString());
- }
+ if (wp)
+ {
+ Stream &output_stream = result.GetOutputStream();
output_stream.Printf("Watchpoint created: ");
wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull);
output_stream.EOL();
result.SetStatus(eReturnStatusSuccessFinishResult);
- } else {
- result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%llx, size=%lu).\n",
+ }
+ else
+ {
+ result.AppendErrorWithFormat("Watchpoint creation failed (addr=0x%" PRIx64 ", size=%lu).\n",
addr, size);
if (error.AsCString(NULL))
result.AppendError(error.AsCString());
Index: aze/lldb/source/Commands/Makefile
===================================================================
--- aze.orig/lldb/source/Commands/Makefile 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Commands/Makefile 2013-03-03 09:35:50.147457352 +0100
@@ -12,3 +12,5 @@
BUILD_ARCHIVE = 1
include $(LLDB_LEVEL)/Makefile
+
+EXTRA_OPTIONS += -Wno-four-char-constants
\ No newline at end of file
Index: aze/lldb/source/Core/Address.cpp
===================================================================
--- aze.orig/lldb/source/Core/Address.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Address.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -86,7 +86,7 @@
if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
{
DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uval64 = data.GetU64(&offset);
}
else
@@ -311,8 +311,15 @@
}
addr_t
-Address::GetCallableLoadAddress (Target *target) const
+Address::GetCallableLoadAddress (Target *target, bool is_indirect) const
{
+ if (is_indirect && target) {
+ ProcessSP processSP = target->GetProcessSP();
+ Error error;
+ if (processSP.get())
+ return processSP->ResolveIndirectFunction(this, error);
+ }
+
addr_t code_addr = GetLoadAddress (target);
if (target)
@@ -384,7 +391,7 @@
if (section_sp)
{
section_sp->DumpName(s);
- s->Printf (" + %llu", m_offset);
+ s->Printf (" + %" PRIu64, m_offset);
}
else
{
@@ -465,7 +472,7 @@
s->PutCString(symbol_name);
addr_t delta = file_Addr - symbol->GetAddress().GetFileAddress();
if (delta)
- s->Printf(" + %llu", delta);
+ s->Printf(" + %" PRIu64, delta);
showed_info = true;
}
}
@@ -696,14 +703,14 @@
stop_if_block_is_inlined_function,
&variable_list);
- uint32_t num_variables = variable_list.GetSize();
- for (uint32_t var_idx = 0; var_idx < num_variables; ++var_idx)
+ const size_t num_variables = variable_list.GetSize();
+ for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
{
Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
if (var && var->LocationIsValidForAddress (*this))
{
s->Indent();
- s->Printf (" Variable: id = {0x%8.8llx}, name = \"%s\", type= \"%s\", location =",
+ s->Printf (" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\", type= \"%s\", location =",
var->GetID(),
var->GetName().GetCString(),
var->GetType()->GetName().GetCString());
@@ -762,7 +769,7 @@
uint32_t
Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const
{
- sc->Clear();
+ sc->Clear(false);
// Absolute addresses don't have enough information to reconstruct even their target.
SectionSP section_sp (GetSection());
Index: aze/lldb/source/Core/AddressRange.cpp
===================================================================
--- aze.orig/lldb/source/Core/AddressRange.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/AddressRange.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -196,7 +196,7 @@
void
AddressRange::DumpDebug (Stream *s) const
{
- s->Printf("%p: AddressRange section = %p, offset = 0x%16.16llx, byte_size = 0x%16.16llx\n", this, m_base_addr.GetSection().get(), m_base_addr.GetOffset(), GetByteSize());
+ s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 ", byte_size = 0x%16.16" PRIx64 "\n", this, m_base_addr.GetSection().get(), m_base_addr.GetOffset(), GetByteSize());
}
//
//bool
Index: aze/lldb/source/Core/AddressResolverFileLine.cpp
===================================================================
--- aze.orig/lldb/source/Core/AddressResolverFileLine.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/AddressResolverFileLine.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -77,7 +77,7 @@
else
{
if (log)
- log->Printf ("error: Unable to resolve address at file address 0x%llx for %s:%d\n",
+ log->Printf ("error: Unable to resolve address at file address 0x%" PRIx64 " for %s:%d\n",
line_start.GetFileAddress(),
m_file_spec.GetFilename().AsCString("<Unknown>"),
m_line_number);
Index: aze/lldb/source/Core/ArchSpec.cpp
===================================================================
--- aze.orig/lldb/source/Core/ArchSpec.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ArchSpec.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -118,7 +118,7 @@
};
-uint32_t
+size_t
ArchSpec::AutoComplete (const char *name, StringList &matches)
{
uint32_t i;
@@ -495,11 +495,11 @@
{
char *end = NULL;
errno = 0;
- uint32_t cpu = ::strtoul (triple_cstr, &end, 0);
+ uint32_t cpu = (uint32_t)::strtoul (triple_cstr, &end, 0);
if (errno == 0 && cpu != 0 && end && ((*end == '-') || (*end == '.')))
{
errno = 0;
- uint32_t sub = ::strtoul (end + 1, &end, 0);
+ uint32_t sub = (uint32_t)::strtoul (end + 1, &end, 0);
if (errno == 0 && end && ((*end == '-') || (*end == '.') || (*end == '\0')))
{
if (arch.SetArchitecture (eArchTypeMachO, cpu, sub))
@@ -513,7 +513,7 @@
llvm::StringRef vendor_str(vendor_os.substr(0, dash_pos));
arch.GetTriple().setVendorName(vendor_str);
const size_t vendor_start_pos = dash_pos+1;
- dash_pos = vendor_os.find(vendor_start_pos, '-');
+ dash_pos = vendor_os.find('-', vendor_start_pos);
if (dash_pos == llvm::StringRef::npos)
{
if (vendor_start_pos < vendor_os.size())
@@ -604,7 +604,7 @@
// architecture. If this is not available (might not be
// connected) use the first supported architecture.
ArchSpec compatible_arch;
- if (platform->IsCompatibleArchitecture (raw_arch, &compatible_arch))
+ if (platform->IsCompatibleArchitecture (raw_arch, false, &compatible_arch))
{
if (compatible_arch.IsValid())
{
@@ -717,17 +717,17 @@
bool
ArchSpec::IsExactMatch (const ArchSpec& rhs) const
{
- return Compare (rhs, true);
+ return IsEqualTo (rhs, true);
}
bool
ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const
{
- return Compare (rhs, false);
+ return IsEqualTo (rhs, false);
}
bool
-ArchSpec::Compare (const ArchSpec& rhs, bool exact_match) const
+ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
{
if (GetByteOrder() != rhs.GetByteOrder())
return false;
@@ -746,12 +746,15 @@
const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
if (lhs_triple_vendor != rhs_triple_vendor)
{
- const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
- const bool lhs_vendor_specified = TripleVendorWasSpecified();
- // Both architectures had the vendor specified, so if they aren't
- // equal then we return false
- if (rhs_vendor_specified && lhs_vendor_specified)
- return false;
+ if (exact_match)
+ {
+ const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
+ const bool lhs_vendor_specified = TripleVendorWasSpecified();
+ // Both architectures had the vendor specified, so if they aren't
+ // equal then we return false
+ if (rhs_vendor_specified && lhs_vendor_specified)
+ return false;
+ }
// Only fail if both vendor types are not unknown
if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
@@ -763,12 +766,15 @@
const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
if (lhs_triple_os != rhs_triple_os)
{
- const bool rhs_os_specified = rhs.TripleOSWasSpecified();
- const bool lhs_os_specified = TripleOSWasSpecified();
- // Both architectures had the OS specified, so if they aren't
- // equal then we return false
- if (rhs_os_specified && lhs_os_specified)
- return false;
+ if (exact_match)
+ {
+ const bool rhs_os_specified = rhs.TripleOSWasSpecified();
+ const bool lhs_os_specified = TripleOSWasSpecified();
+ // Both architectures had the OS specified, so if they aren't
+ // equal then we return false
+ if (rhs_os_specified && lhs_os_specified)
+ return false;
+ }
// Only fail if both os types are not unknown
if (lhs_triple_os != llvm::Triple::UnknownOS &&
rhs_triple_os != llvm::Triple::UnknownOS)
@@ -869,18 +875,6 @@
}
bool
-lldb_private::operator== (const ArchSpec& lhs, const ArchSpec& rhs)
-{
- return lhs.IsExactMatch (rhs);
-}
-
-bool
-lldb_private::operator!= (const ArchSpec& lhs, const ArchSpec& rhs)
-{
- return !(lhs == rhs);
-}
-
-bool
lldb_private::operator<(const ArchSpec& lhs, const ArchSpec& rhs)
{
const ArchSpec::Core lhs_core = lhs.GetCore ();
Index: aze/lldb/source/Core/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Core/CMakeLists.txt 2013-03-03 09:35:50.147457352 +0100
@@ -0,0 +1,85 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbCore
+ Address.cpp
+ AddressRange.cpp
+ AddressResolver.cpp
+ AddressResolverFileLine.cpp
+ AddressResolverName.cpp
+ ArchSpec.cpp
+ Baton.cpp
+ Broadcaster.cpp
+ Communication.cpp
+ Connection.cpp
+ ConnectionFileDescriptor.cpp
+ ConnectionMachPort.cpp
+ ConnectionSharedMemory.cpp
+ ConstString.cpp
+ cxa_demangle.cpp
+ DataBufferHeap.cpp
+ DataBufferMemoryMap.cpp
+ DataEncoder.cpp
+ DataExtractor.cpp
+ Debugger.cpp
+ Disassembler.cpp
+ DynamicLoader.cpp
+ EmulateInstruction.cpp
+ Error.cpp
+ Event.cpp
+ FileLineResolver.cpp
+ FileSpecList.cpp
+ History.cpp
+ InputReader.cpp
+ InputReaderEZ.cpp
+ InputReaderStack.cpp
+ Language.cpp
+ Listener.cpp
+ Log.cpp
+ Mangled.cpp
+ Module.cpp
+ ModuleChild.cpp
+ ModuleList.cpp
+ Opcode.cpp
+ PluginManager.cpp
+ RegisterValue.cpp
+ RegularExpression.cpp
+ Scalar.cpp
+ SearchFilter.cpp
+ Section.cpp
+ SourceManager.cpp
+ State.cpp
+ Stream.cpp
+ StreamAsynchronousIO.cpp
+ StreamCallback.cpp
+ StreamFile.cpp
+ StreamString.cpp
+ StringList.cpp
+ Timer.cpp
+ UserID.cpp
+ UserSettingsController.cpp
+ UUID.cpp
+ Value.cpp
+ ValueObject.cpp
+ ValueObjectCast.cpp
+ ValueObjectChild.cpp
+ ValueObjectConstResult.cpp
+ ValueObjectConstResultChild.cpp
+ ValueObjectConstResultImpl.cpp
+ ValueObjectDynamicValue.cpp
+ ValueObjectList.cpp
+ ValueObjectMemory.cpp
+ ValueObjectRegister.cpp
+ ValueObjectSyntheticFilter.cpp
+ ValueObjectVariable.cpp
+ VMRange.cpp
+ #Windows.cpp
+ )
+
+#FIXME: Below we append -frtti to cxa_demangle.cpp (and let the compiler choose to ignore the
+# -fno-rtti that is added due to LLVM_NO_RTTI at the top of this file.) It would be
+# better to replace -fno-rtti with -frtti rather than just appending the latter option.
+set_property(
+ SOURCE cxa_demangle.cpp
+ PROPERTY COMPILE_FLAGS -frtti
+ )
+
Index: aze/lldb/source/Core/Communication.cpp
===================================================================
--- aze.orig/lldb/source/Core/Communication.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Communication.cpp 2013-03-03 09:35:50.147457352 +0100
@@ -136,7 +136,7 @@
Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Read (dst = %p, dst_len = %llu, timeout = %u usec) connection = %p",
+ "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p",
this,
dst,
(uint64_t)dst_len,
@@ -210,7 +210,7 @@
Mutex::Locker locker(m_write_mutex);
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Write (src = %p, src_len = %llu) connection = %p",
+ "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p",
this,
src,
(uint64_t)src_len,
@@ -295,7 +295,7 @@
Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
{
lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::AppendBytesToCache (src = %p, src_len = %llu, broadcast = %i)",
+ "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
this, bytes, (uint64_t)len, broadcast);
if ((bytes == NULL || len == 0)
&& (status != lldb::eConnectionStatusEndOfFile))
@@ -374,7 +374,6 @@
case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
done = true;
// Fall through...
- default:
case eConnectionStatusError: // Check GetError() for details
case eConnectionStatusTimedOut: // Request timed out
if (log)
Index: aze/lldb/source/Core/ConnectionFileDescriptor.cpp
===================================================================
--- aze.orig/lldb/source/Core/ConnectionFileDescriptor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ConnectionFileDescriptor.cpp 2013-03-03 09:35:50.151457352 +0100
@@ -7,6 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#if defined(__APPLE__)
+// Enable this special support for Apple builds where we can have unlimited
+// select bounds. We tried switching to poll() and kqueue and we were panicing
+// the kernel, so we have to stick with select for now.
+#define _DARWIN_UNLIMITED_SELECT
+#endif
+
#include "lldb/Core/ConnectionFileDescriptor.h"
// C Includes
@@ -25,6 +32,9 @@
// C++ Includes
// Other libraries and framework includes
+#if defined(__APPLE__)
+#include "llvm/ADT/SmallVector.h"
+#endif
// Project includes
#include "lldb/lldb-private-log.h"
#include "lldb/Interpreter/Args.h"
@@ -362,7 +372,7 @@
{
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
if (log)
- log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %llu)...",
+ log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ")...",
this, m_fd_recv, dst, (uint64_t)dst_len);
Mutex::Locker locker;
@@ -411,7 +421,7 @@
}
if (log)
- log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %llu) => %lli, error = %s",
+ log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %" PRIu64 ") => %" PRIi64 ", error = %s",
this,
m_fd_recv,
dst,
@@ -464,7 +474,6 @@
return 0;
}
- //Disconnect (NULL);
return 0;
}
return bytes_read;
@@ -475,7 +484,7 @@
{
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
if (log)
- log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %llu)", this, src, (uint64_t)src_len);
+ log->Printf ("%p ConnectionFileDescriptor::Write (src = %p, src_len = %" PRIu64 ")", this, src, (uint64_t)src_len);
if (!IsConnected ())
{
@@ -530,7 +539,7 @@
switch (m_fd_send_type)
{
case eFDTypeFile: // Other FD requireing read/write
- log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %llu) => %lli (error = %s)",
+ log->Printf ("%p ConnectionFileDescriptor::Write() ::write (fd = %i, src = %p, src_len = %" PRIu64 ") => %" PRIi64 " (error = %s)",
this,
m_fd_send,
src,
@@ -540,7 +549,7 @@
break;
case eFDTypeSocket: // Socket requiring send/recv
- log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %llu, flags = 0) => %lli (error = %s)",
+ log->Printf ("%p ConnectionFileDescriptor::Write() ::send (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
this,
m_fd_send,
src,
@@ -550,7 +559,7 @@
break;
case eFDTypeSocketUDP: // Unconnected UDP socket requiring sendto/recvfrom
- log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %llu, flags = 0) => %lli (error = %s)",
+ log->Printf ("%p ConnectionFileDescriptor::Write() ::sendto (socket = %i, src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 " (error = %s)",
this,
m_fd_send,
src,
@@ -590,6 +599,21 @@
return bytes_sent;
}
+
+
+#if defined(__APPLE__)
+
+// This ConnectionFileDescriptor::BytesAvailable() uses select().
+//
+// PROS:
+// - select is consistent across most unix platforms
+// - this Apple specific version allows for unlimited fds in the fd_sets by
+// setting the _DARWIN_UNLIMITED_SELECT define prior to including the
+// required header files.
+
+// CONS:
+// - Darwin only
+
ConnectionStatus
ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
{
@@ -613,90 +637,423 @@
tv = time_value.GetAsTimeVal();
tv_ptr = &tv;
}
-
- while (m_fd_recv >= 0)
+
+ // Make a copy of the file descriptors to make sure we don't
+ // have another thread change these values out from under us
+ // and cause problems in the loop below where like in FS_SET()
+ const int data_fd = m_fd_recv;
+ const int pipe_fd = m_pipe_read;
+
+ if (data_fd >= 0)
{
- fd_set read_fds;
- FD_ZERO (&read_fds);
- FD_SET (m_fd_recv, &read_fds);
- if (m_pipe_read != -1)
- FD_SET (m_pipe_read, &read_fds);
- int nfds = std::max<int>(m_fd_recv, m_pipe_read) + 1;
+ const bool have_pipe_fd = pipe_fd >= 0;
- Error error;
+ while (data_fd == m_fd_recv)
+ {
+ const int nfds = std::max<int>(data_fd, pipe_fd) + 1;
+ llvm::SmallVector<fd_set, 1> read_fds;
+ read_fds.resize((nfds/FD_SETSIZE) + 1);
+ for (size_t i=0; i<read_fds.size(); ++i)
+ FD_ZERO (&read_fds[i]);
+ // FD_SET doesn't bounds check, it just happily walks off the end
+ // but we have taken care of making the extra storage with our
+ // SmallVector of fd_set objects
+ FD_SET (data_fd, read_fds.data());
+ if (have_pipe_fd)
+ FD_SET (pipe_fd, read_fds.data());
+
+ Error error;
+
+ if (log)
+ {
+ if (have_pipe_fd)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...",
+ this, nfds, data_fd, pipe_fd, tv_ptr);
+ else
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...",
+ this, nfds, data_fd, tv_ptr);
+ }
+
+ const int num_set_fds = ::select (nfds, read_fds.data(), NULL, NULL, tv_ptr);
+ if (num_set_fds < 0)
+ error.SetErrorToErrno();
+ else
+ error.Clear();
+
+ if (log)
+ {
+ if (have_pipe_fd)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s",
+ this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString());
+ else
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s",
+ this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString());
+ }
+
+ if (error_ptr)
+ *error_ptr = error;
+
+ if (error.Fail())
+ {
+ switch (error.GetError())
+ {
+ case EBADF: // One of the descriptor sets specified an invalid descriptor.
+ return eConnectionStatusLostConnection;
+
+ case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
+ default: // Other unknown error
+ return eConnectionStatusError;
+
+ case EAGAIN: // The kernel was (perhaps temporarily) unable to
+ // allocate the requested number of file descriptors,
+ // or we have non-blocking IO
+ case EINTR: // A signal was delivered before the time limit
+ // expired and before any of the selected events
+ // occurred.
+ break; // Lets keep reading to until we timeout
+ }
+ }
+ else if (num_set_fds == 0)
+ {
+ return eConnectionStatusTimedOut;
+ }
+ else if (num_set_fds > 0)
+ {
+ // FD_ISSET is happy to deal with a something larger than
+ // a single fd_set.
+ if (FD_ISSET(data_fd, read_fds.data()))
+ return eConnectionStatusSuccess;
+ if (have_pipe_fd && FD_ISSET(pipe_fd, read_fds.data()))
+ {
+ // We got a command to exit. Read the data from that pipe:
+ char buffer[16];
+ ssize_t bytes_read;
+
+ do
+ {
+ bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
+ } while (bytes_read < 0 && errno == EINTR);
+ assert (bytes_read == 1 && buffer[0] == 'q');
+
+ if (log)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
+ this, (int) bytes_read, buffer);
+
+ return eConnectionStatusEndOfFile;
+ }
+ }
+ }
+ }
+
+ if (error_ptr)
+ error_ptr->SetErrorString("not connected");
+ return eConnectionStatusLostConnection;
+}
+#else
- if (log)
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...",
- this, nfds, m_fd_recv, tv_ptr);
+// This ConnectionFileDescriptor::BytesAvailable() uses select().
+//
+// PROS:
+// - select is consistent across most unix platforms
+// CONS:
+// - only supports file descriptors up to FD_SETSIZE. This implementation
+// will assert if it runs into that hard limit to let users know that
+// another ConnectionFileDescriptor::BytesAvailable() should be used
+// or a new version of ConnectionFileDescriptor::BytesAvailable() should
+// be written for the system that is running into the limitations. MacOSX
+// uses kqueues, and there is a poll() based implementation below.
- const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
- if (num_set_fds < 0)
- error.SetErrorToErrno();
- else
- error.Clear();
+ConnectionStatus
+ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
+{
+ // Don't need to take the mutex here separately since we are only called from Read. If we
+ // ever get used more generally we will need to lock here as well.
+
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
+ struct timeval *tv_ptr;
+ struct timeval tv;
+ if (timeout_usec == UINT32_MAX)
+ {
+ // Infinite wait...
+ tv_ptr = NULL;
+ }
+ else
+ {
+ TimeValue time_value;
+ time_value.OffsetWithMicroSeconds (timeout_usec);
+ tv = time_value.GetAsTimeVal();
+ tv_ptr = &tv;
+ }
+
+ // Make a copy of the file descriptors to make sure we don't
+ // have another thread change these values out from under us
+ // and cause problems in the loop below where like in FS_SET()
+ const int data_fd = m_fd_recv;
+ const int pipe_fd = m_pipe_read;
+
+ if (data_fd >= 0)
+ {
+ // If this assert fires off on MacOSX, we will need to switch to using
+ // libdispatch to read from file descriptors because poll() is causing
+ // kernel panics and if we exceed FD_SETSIZE we will have no choice...
+ assert (data_fd < FD_SETSIZE);
+
+ const bool have_pipe_fd = pipe_fd >= 0;
+
+ if (have_pipe_fd)
+ {
+ assert (pipe_fd < FD_SETSIZE);
+ }
- if (log)
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s",
- this, nfds, m_fd_recv, tv_ptr, num_set_fds, error.AsCString());
+ while (data_fd == m_fd_recv)
+ {
+ fd_set read_fds;
+ FD_ZERO (&read_fds);
+ FD_SET (data_fd, &read_fds);
+ if (have_pipe_fd)
+ FD_SET (pipe_fd, &read_fds);
- if (error_ptr)
- *error_ptr = error;
+ const int nfds = std::max<int>(data_fd, pipe_fd) + 1;
- if (error.Fail())
- {
- switch (error.GetError())
+ Error error;
+
+ if (log)
{
- case EBADF: // One of the descriptor sets specified an invalid descriptor.
- return eConnectionStatusLostConnection;
-
- case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
- default: // Other unknown error
- return eConnectionStatusError;
+ if (have_pipe_fd)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p)...",
+ this, nfds, data_fd, pipe_fd, tv_ptr);
+ else
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p)...",
+ this, nfds, data_fd, tv_ptr);
+ }
+
+ const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
+ if (num_set_fds < 0)
+ error.SetErrorToErrno();
+ else
+ error.Clear();
+
+ if (log)
+ {
+ if (have_pipe_fd)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i, %i}, NULL, NULL, timeout=%p) => %d, error = %s",
+ this, nfds, data_fd, pipe_fd, tv_ptr, num_set_fds, error.AsCString());
+ else
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::select (nfds=%i, fds={%i}, NULL, NULL, timeout=%p) => %d, error = %s",
+ this, nfds, data_fd, tv_ptr, num_set_fds, error.AsCString());
+ }
- case EAGAIN: // The kernel was (perhaps temporarily) unable to
- // allocate the requested number of file descriptors,
- // or we have non-blocking IO
- case EINTR: // A signal was delivered before the time limit
- // expired and before any of the selected events
- // occurred.
- break; // Lets keep reading to until we timeout
+ if (error_ptr)
+ *error_ptr = error;
+
+ if (error.Fail())
+ {
+ switch (error.GetError())
+ {
+ case EBADF: // One of the descriptor sets specified an invalid descriptor.
+ return eConnectionStatusLostConnection;
+
+ case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
+ default: // Other unknown error
+ return eConnectionStatusError;
+
+ case EAGAIN: // The kernel was (perhaps temporarily) unable to
+ // allocate the requested number of file descriptors,
+ // or we have non-blocking IO
+ case EINTR: // A signal was delivered before the time limit
+ // expired and before any of the selected events
+ // occurred.
+ break; // Lets keep reading to until we timeout
+ }
+ }
+ else if (num_set_fds == 0)
+ {
+ return eConnectionStatusTimedOut;
+ }
+ else if (num_set_fds > 0)
+ {
+ if (FD_ISSET(data_fd, &read_fds))
+ return eConnectionStatusSuccess;
+ if (have_pipe_fd && FD_ISSET(pipe_fd, &read_fds))
+ {
+ // We got a command to exit. Read the data from that pipe:
+ char buffer[16];
+ ssize_t bytes_read;
+
+ do
+ {
+ bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
+ } while (bytes_read < 0 && errno == EINTR);
+ assert (bytes_read == 1 && buffer[0] == 'q');
+
+ if (log)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
+ this, (int) bytes_read, buffer);
+
+ return eConnectionStatusEndOfFile;
+ }
}
}
- else if (num_set_fds == 0)
+ }
+
+ if (error_ptr)
+ error_ptr->SetErrorString("not connected");
+ return eConnectionStatusLostConnection;
+}
+
+#endif
+
+#if 0
+#include <poll.h>
+
+// This ConnectionFileDescriptor::BytesAvailable() uses poll(). poll() should NOT
+// be used on MacOSX as it has all sorts of restrictions on the types of file descriptors
+// that it doesn't support.
+//
+// There may be some systems that properly support poll() that could use this
+// implementation. I will let each system opt into this on their own.
+//
+// PROS:
+// - no restrictions on the fd value that is used
+// CONS:
+// - varies wildly from platform to platform in its implementation restrictions
+
+ConnectionStatus
+ConnectionFileDescriptor::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
+{
+ // Don't need to take the mutex here separately since we are only called from Read. If we
+ // ever get used more generally we will need to lock here as well.
+
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+ if (log)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %u)", this, timeout_usec);
+ int timeout_msec = 0;
+ if (timeout_usec == UINT32_MAX)
+ {
+ // Infinite wait...
+ timeout_msec = -1;
+ }
+ else if (timeout_usec == 0)
+ {
+ // Return immediately, don't wait
+ timeout_msec = 0;
+ }
+ else
+ {
+ // Convert usec to msec
+ timeout_msec = (timeout_usec + 999) / 1000;
+ }
+
+ // Make a copy of the file descriptors to make sure we don't
+ // have another thread change these values out from under us
+ // and cause problems in the loop below where like in FS_SET()
+ const int data_fd = m_fd_recv;
+ const int pipe_fd = m_pipe_read;
+
+ // Make sure the file descriptor can be used with select as it
+ // must be in range
+ if (data_fd >= 0)
+ {
+ const bool have_pipe_fd = pipe_fd >= 0;
+ struct pollfd fds[2] =
{
- return eConnectionStatusTimedOut;
- }
- else if (num_set_fds > 0)
+ { data_fd, POLLIN, 0 },
+ { pipe_fd, POLLIN, 0 }
+ };
+ const int nfds = have_pipe_fd ? 2 : 1;
+ Error error;
+ while (data_fd == m_fd_recv)
{
- if (m_pipe_read != -1 && FD_ISSET(m_pipe_read, &read_fds))
+ const int num_set_fds = ::poll (fds, nfds, timeout_msec);
+
+ if (num_set_fds < 0)
+ error.SetErrorToErrno();
+ else
+ error.Clear();
+
+ if (error_ptr)
+ *error_ptr = error;
+
+ if (log)
{
- // We got a command to exit. Read the data from that pipe:
- char buffer[16];
- ssize_t bytes_read;
-
- do
+ if (have_pipe_fd)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN},{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n",
+ this,
+ data_fd,
+ pipe_fd,
+ nfds,
+ timeout_msec,
+ num_set_fds,
+ error.AsCString());
+ else
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() ::poll (fds={{%i,POLLIN}}, nfds=%i, timeout_ms=%i) => %d, error = %s\n",
+ this,
+ data_fd,
+ nfds,
+ timeout_msec,
+ num_set_fds,
+ error.AsCString());
+ }
+
+ if (error.Fail())
+ {
+ switch (error.GetError())
{
- bytes_read = ::read (m_pipe_read, buffer, sizeof(buffer));
- } while (bytes_read < 0 && errno == EINTR);
- assert (bytes_read == 1 && buffer[0] == 'q');
-
- if (log)
- log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
- this, (int) bytes_read, buffer);
-
- return eConnectionStatusEndOfFile;
+ case EBADF: // One of the descriptor sets specified an invalid descriptor.
+ return eConnectionStatusLostConnection;
+
+ case EINVAL: // The specified time limit is invalid. One of its components is negative or too large.
+ default: // Other unknown error
+ return eConnectionStatusError;
+
+ case EAGAIN: // The kernel was (perhaps temporarily) unable to
+ // allocate the requested number of file descriptors,
+ // or we have non-blocking IO
+ case EINTR: // A signal was delivered before the time limit
+ // expired and before any of the selected events
+ // occurred.
+ break; // Lets keep reading to until we timeout
+ }
+ }
+ else if (num_set_fds == 0)
+ {
+ return eConnectionStatusTimedOut;
+ }
+ else if (num_set_fds > 0)
+ {
+ if (fds[0].revents & POLLIN)
+ return eConnectionStatusSuccess;
+ if (fds[1].revents & POLLIN)
+ {
+ // We got a command to exit. Read the data from that pipe:
+ char buffer[16];
+ ssize_t bytes_read;
+
+ do
+ {
+ bytes_read = ::read (pipe_fd, buffer, sizeof(buffer));
+ } while (bytes_read < 0 && errno == EINTR);
+ assert (bytes_read == 1 && buffer[0] == 'q');
+
+ if (log)
+ log->Printf("%p ConnectionFileDescriptor::BytesAvailable() got data: %*s from the command channel.",
+ this, (int) bytes_read, buffer);
+
+ return eConnectionStatusEndOfFile;
+ }
}
- else
- return eConnectionStatusSuccess;
}
}
-
if (error_ptr)
error_ptr->SetErrorString("not connected");
return eConnectionStatusLostConnection;
}
+#endif
+
ConnectionStatus
ConnectionFileDescriptor::Close (int& fd, Error *error_ptr)
{
Index: aze/lldb/source/Core/ConstString.cpp
===================================================================
--- aze.orig/lldb/source/Core/ConstString.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ConstString.cpp 2013-03-03 09:35:50.151457352 +0100
@@ -87,7 +87,7 @@
}
const char *
- GetConstCStringWithLength (const char *cstr, int cstr_len)
+ GetConstCStringWithLength (const char *cstr, size_t cstr_len)
{
if (cstr)
{
@@ -132,11 +132,11 @@
}
const char *
- GetConstTrimmedCStringWithLength (const char *cstr, int cstr_len)
+ GetConstTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
{
if (cstr)
{
- int trimmed_len = std::min<int> (strlen (cstr), cstr_len);
+ const size_t trimmed_len = std::min<size_t> (strlen (cstr), cstr_len);
return GetConstCStringWithLength (cstr, trimmed_len);
}
return NULL;
@@ -294,7 +294,7 @@
size_t cstr_len = GetLength();
// Only print the parens if we have a non-NULL string
const char *parens = cstr ? "\"" : "";
- s->Printf("%*p: ConstString, string = %s%s%s, length = %llu", (int)sizeof(void*) * 2, this, parens, cstr, parens, (uint64_t)cstr_len);
+ s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64, (int)sizeof(void*) * 2, this, parens, cstr, parens, (uint64_t)cstr_len);
}
void
Index: aze/lldb/source/Core/cxa_demangle.cpp
===================================================================
--- aze.orig/lldb/source/Core/cxa_demangle.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/cxa_demangle.cpp 2013-03-03 09:35:50.151457352 +0100
@@ -133,9 +133,14 @@
{
for (int i = 0; i < 2*indent; ++i)
printf(" ");
- char* buf = (char*)malloc(x->size());
+ size_t sz = x->size();
+ char* buf = (char*)calloc(sz+10, 1);
x->get_demangled_name(buf);
- printf("%s %s, %p\n", typeid(*x).name(), buf, x);
+ printf("%s [%ld] %s, %p\n", typeid(*x).name(), sz, buf, x);
+ if (strlen(buf) != sz)
+ {
+ printf("strlen(buf) = %ld and size = %ld\n", strlen(buf), sz);
+ }
free(buf);
display(x->__left_, indent+1);
display(x->__right_, indent+1);
@@ -3822,10 +3827,14 @@
}
virtual bool ends_with_template(bool parsing = false) const
{
- if (__right_ != NULL)
+ if (__right_ && __right_->size() > 0)
+ {
return __right_->ends_with_template(parsing);
- if (__left_ != NULL)
+ }
+ else if (__left_ && __left_->size() > 0)
+ {
return __left_->ends_with_template(parsing);
+ }
return false;
}
virtual bool fix_forward_references(__node** t_begin, __node** t_end)
@@ -3932,11 +3941,11 @@
}
};
-class __lambda
+class ___lambda_node
: public __node
{
public:
- __lambda(__node* params, const char *number, size_t number_size)
+ ___lambda_node(__node* params, const char *number, size_t number_size)
{
__right_ = params;
__name_ = number;
@@ -6969,50 +6978,62 @@
{
case 't':
case 'l':
- first += 2;
-
+ {
+ const char* t = first + 2;
+ __node* params = 0;
if (type == 'l')
{
- __root_ = 0;
- if (first[0] == 'v')
+ if (*t == 'v')
{
// void lambda
- ++first;
- if (first[0] == 'E')
- ++first;
+ ++t;
+ if (t != last && *t == 'E')
+ ++t;
else
return first;
}
else
{
- while (first[0] && first[0] != 'E')
+ const char* t1 = __parse_type(t, last);
+ if (t1 == t || !__make<__list>(__root_))
+ return first;
+ params = __root_;
+ __node* prev = params;
+ t = t1;
+ while (true)
{
- const char *old = first;
- first = __parse_type(first, last);
- if (first == old)
+ t1 = __parse_type(t, last);
+ if (t1 == t)
break;
+ if (!__make<__list>(__root_))
+ return first;
+ t = t1;
+ prev->__right_ = __root_;
+ __root_->__size_ = prev->__size_ + 1;
+ prev = __root_;
}
- if (first[0] == 'E')
- ++first;
- else
+ if (t == last || *t != 'E')
return first;
+ ++t;
}
}
- const char *number_start = first;
- first = __parse_number(first, last);
- const char *number_end = first;
- if (first[0] == '_')
- {
- ++first;
- }
- else
+ const char* number_start = t;
+ const char* number_end = __parse_number(t, last);
+ if (number_end == last || *number_end != '_')
return first;
-
+ t = number_end + 1;
if (type == 'l')
- __make<__lambda>(__root_, number_start, static_cast<size_t>(number_end - number_start));
+ {
+ if (!__make<___lambda_node>(params, number_start, static_cast<size_t>(number_end - number_start)))
+ return first;
+ }
else
- __make<__unnamed>(number_start, static_cast<size_t>(number_end - number_start));
-
+ {
+ if (!__make<__unnamed>(number_start, static_cast<size_t>(number_end - number_start)))
+ return first;
+ }
+ first = t;
+ }
break;
}
}
Index: aze/lldb/source/Core/CXXFormatterFunctions.cpp
===================================================================
--- aze.orig/lldb/source/Core/CXXFormatterFunctions.cpp 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,1483 +0,0 @@
-//===-- CXXFormatterFunctions.cpp---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/CXXFormatterFunctions.h"
-
-// needed to get ConvertUTF16/32ToUTF8
-#define CLANG_NEEDS_THESE_ONE_DAY
-#include "clang/Basic/ConvertUTF.h"
-
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Stream.h"
-#include "lldb/Core/ValueObject.h"
-#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
-#include "lldb/Target/Target.h"
-
-using namespace lldb;
-using namespace lldb_private;
-using namespace lldb_private::formatters;
-
-bool
-lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
- const char* target_type,
- const char* selector,
- uint64_t &value)
-{
- if (!target_type || !*target_type)
- return false;
- if (!selector || !*selector)
- return false;
- StreamString expr_path_stream;
- valobj.GetExpressionPath(expr_path_stream, false);
- StreamString expr;
- expr.Printf("(%s)[%s %s]",target_type,expr_path_stream.GetData(),selector);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = exe_ctx.GetFramePtr();
- if (!target || !stack_frame)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false)
- .SetUnwindOnError(true)
- .SetKeepInMemory(true)
- .SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- result_sp,
- options);
- if (!result_sp)
- return false;
- value = result_sp->GetValueAsUnsigned(0);
- return true;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- uint64_t index)
-{
- lldb::ValueObjectSP valobj_sp;
- if (!return_type || !*return_type)
- return valobj_sp;
- if (!selector || !*selector)
- return valobj_sp;
- StreamString expr_path_stream;
- valobj.GetExpressionPath(expr_path_stream, false);
- StreamString expr;
- expr.Printf("(%s)[%s %s:%lld]",return_type,expr_path_stream.GetData(),selector,index);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = exe_ctx.GetFramePtr();
- if (!target || !stack_frame)
- return valobj_sp;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false)
- .SetUnwindOnError(true)
- .SetKeepInMemory(true)
- .SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- valobj_sp,
- options);
- return valobj_sp;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
- const char* return_type,
- const char* selector,
- const char* key)
-{
- lldb::ValueObjectSP valobj_sp;
- if (!return_type || !*return_type)
- return valobj_sp;
- if (!selector || !*selector)
- return valobj_sp;
- if (!key || !*key)
- return valobj_sp;
- StreamString expr_path_stream;
- valobj.GetExpressionPath(expr_path_stream, false);
- StreamString expr;
- expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = exe_ctx.GetFramePtr();
- if (!target || !stack_frame)
- return valobj_sp;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false)
- .SetUnwindOnError(true)
- .SetKeepInMemory(true)
- .SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- valobj_sp,
- options);
- return valobj_sp;
-}
-
-template<bool name_entries>
-bool
-lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
- bool is_64bit = (ptr_size == 8);
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"__NSDictionaryI"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- }
- else if (!strcmp(class_name,"__NSDictionaryM"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
- }
- else if (!strcmp(class_name,"__NSCFDictionary"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), ptr_size, 0, error);
- if (error.Fail())
- return false;
- if (is_64bit)
- value &= ~0x0f1f000000000000UL;
- }
- else
- {
- if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
- return false;
- }
-
- stream.Printf("%s%llu %s%s",
- (name_entries ? "@\"" : ""),
- value,
- (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
- (name_entries ? "\"" : ""));
- return true;
-}
-
-bool
-lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"__NSArrayI"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else if (!strcmp(class_name,"__NSArrayM"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else if (!strcmp(class_name,"__NSCFArray"))
- {
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
- if (error.Fail())
- return false;
- }
- else
- {
- if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
- return false;
- }
-
- stream.Printf("@\"%llu object%s\"",
- value,
- value == 1 ? "" : "s");
- return true;
-}
-
-template<bool needs_at>
-bool
-lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- bool is_64bit = (process_sp->GetAddressByteSize() == 8);
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- uint64_t value = 0;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSConcreteData") ||
- !strcmp(class_name,"NSConcreteMutableData") ||
- !strcmp(class_name,"__NSCFData"))
- {
- uint32_t offset = (is_64bit ? 16 : 8);
- Error error;
- value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
- if (error.Fail())
- return false;
- }
- else
- {
- if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
- return false;
- }
-
- stream.Printf("%s%llu byte%s%s",
- (needs_at ? "@\"" : ""),
- value,
- (value > 1 ? "s" : ""),
- (needs_at ? "\"" : ""));
-
- return true;
-}
-
-bool
-lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
- {
- if (descriptor->IsTagged())
- {
- // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
- int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
- uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
-
- switch (i_bits)
- {
- case 0:
- stream.Printf("(char)%hhd",(char)value);
- break;
- case 4:
- stream.Printf("(short)%hd",(short)value);
- break;
- case 8:
- stream.Printf("(int)%d",(int)value);
- break;
- case 12:
- stream.Printf("(long)%lld",value);
- break;
- default:
- stream.Printf("absurd value:(info=%llu, value=%llu",i_bits,value);
- break;
- }
- return true;
- }
- else
- {
- Error error;
- uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
- uint64_t data_location = valobj_addr + 2*ptr_size;
- uint64_t value = 0;
- if (error.Fail())
- return false;
- switch (data_type)
- {
- case 1: // 0B00001
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(char)%hhd",(char)value);
- break;
- case 2: // 0B0010
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(short)%hd",(short)value);
- break;
- case 3: // 0B0011
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(int)%d",(int)value);
- break;
- case 17: // 0B10001
- data_location += 8;
- case 4: // 0B0100
- value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
- if (error.Fail())
- return false;
- stream.Printf("(long)%lld",value);
- break;
- case 5: // 0B0101
- {
- uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
- if (error.Fail())
- return false;
- float flt_value = *((float*)&flt_as_int);
- stream.Printf("(float)%f",flt_value);
- break;
- }
- case 6: // 0B0110
- {
- uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
- if (error.Fail())
- return false;
- double dbl_value = *((double*)&dbl_as_lng);
- stream.Printf("(double)%g",dbl_value);
- break;
- }
- default:
- stream.Printf("absurd: dt=%d",data_type);
- break;
- }
- return true;
- }
- }
- else
- {
- // similar to ExtractValueFromObjCExpression but uses summary instead of value
- StreamString expr_path_stream;
- valobj.GetExpressionPath(expr_path_stream, false);
- StreamString expr;
- expr.Printf("(NSString*)[%s stringValue]",expr_path_stream.GetData());
- ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
- lldb::ValueObjectSP result_sp;
- Target* target = exe_ctx.GetTargetPtr();
- StackFrame* stack_frame = exe_ctx.GetFramePtr();
- if (!target || !stack_frame)
- return false;
-
- EvaluateExpressionOptions options;
- options.SetCoerceToId(false)
- .SetUnwindOnError(true)
- .SetKeepInMemory(true)
- .SetUseDynamic(lldb::eDynamicCanRunTarget);
-
- target->EvaluateExpression(expr.GetData(),
- stack_frame,
- result_sp,
- options);
- if (!result_sp)
- return false;
- stream.Printf("%s",result_sp->GetSummaryAsCString());
- return true;
- }
-}
-
-static bool
-ReadUTFBufferAndDumpToStream (uint64_t location,
- const ProcessSP& process_sp,
- Stream& stream)
-{
- Error error;
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
- size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), 1024, error);
- if (error.Fail())
- {
- stream.Printf("unable to read data");
- return true;
- }
- else
- stream.Printf("@\"");
- if (data_read)
- {
- UTF16 *data_ptr = (UTF16*)buffer_sp->GetBytes();
- UTF16 *data_end_ptr = data_ptr + 256;
-
- while (data_ptr < data_end_ptr)
- {
- if (!*data_ptr)
- {
- data_end_ptr = data_ptr;
- break;
- }
- data_ptr++;
- }
-
- *data_ptr = 0;
- data_ptr = (UTF16*)buffer_sp->GetBytes();
-
- lldb::DataBufferSP utf8_data_buffer_sp(new DataBufferHeap(1024,0));
- UTF8* utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
- UTF8* utf8_data_end_ptr = utf8_data_ptr + 1024;
-
- ConvertUTF16toUTF8 ( (const UTF16**)&data_ptr,
- data_end_ptr,
- &utf8_data_ptr,
- utf8_data_end_ptr,
- lenientConversion);
- utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
- for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++)
- {
- if (!*utf8_data_ptr)
- break;
- stream.Printf("%c",*utf8_data_ptr);
- }
- stream.Printf("\"");
- return true;
- }
- stream.Printf("\"");
- return true;
-}
-
-bool
-lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- ProcessSP process_sp = valobj.GetProcessSP();
- if (!process_sp)
- return false;
-
- ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
-
- if (!runtime)
- return false;
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return false;
-
- uint32_t ptr_size = process_sp->GetAddressByteSize();
-
- lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
-
- if (!valobj_addr)
- return false;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return false;
-
- uint64_t info_bits_location = valobj_addr + ptr_size;
- if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
- info_bits_location += 3;
-
- Error error;
-
- uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
- if (error.Fail())
- return false;
-
- bool is_mutable = (info_bits & 1) == 1;
- bool is_inline = (info_bits & 0x60) == 0;
- bool has_explicit_length = (info_bits & (1 | 4)) != 4;
- bool is_unicode = (info_bits & 0x10) == 0x10;
- bool is_special = strcmp(class_name,"NSPathStore2") == 0;
-
- if (strcmp(class_name,"NSString") &&
- strcmp(class_name,"CFStringRef") &&
- strcmp(class_name,"CFMutableStringRef") &&
- strcmp(class_name,"__NSCFConstantString") &&
- strcmp(class_name,"__NSCFString") &&
- strcmp(class_name,"NSCFConstantString") &&
- strcmp(class_name,"NSCFString") &&
- strcmp(class_name,"NSPathStore2"))
- {
- // probably not one of us - bail out
- return false;
- }
-
- if (is_mutable)
- {
- uint64_t location = 2 * ptr_size + valobj_addr;
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- if (has_explicit_length and is_unicode)
- return ReadUTFBufferAndDumpToStream (location, process_sp, stream);
- else
- {
- location++;
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
- size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
- if (error.Fail())
- return false;
- if (data_read)
- stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
- return true;
- }
- }
- else if (is_inline && has_explicit_length && !is_unicode && !is_special && !is_mutable)
- {
- uint64_t location = 3 * ptr_size + valobj_addr;
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
- size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
- if (error.Fail())
- return false;
- if (data_read)
- stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
- return true;
- }
- else if (is_unicode)
- {
- uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
- if (is_inline)
- {
- if (!has_explicit_length)
- {
- stream.Printf("found new combo");
- return true;
- }
- else
- location += ptr_size;
- }
- else
- {
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- }
- return ReadUTFBufferAndDumpToStream (location, process_sp, stream);
- }
- else if (is_special)
- {
- uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8);
- return ReadUTFBufferAndDumpToStream (location, process_sp, stream);
- }
- else if (is_inline)
- {
- uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
- if (!has_explicit_length)
- location++;
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
- size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
- if (error.Fail())
- return false;
- if (data_read)
- stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
- return true;
- }
- else
- {
- uint64_t location = valobj_addr + ptr_size + 4 + (ptr_size == 8 ? 4 : 0);
- location = process_sp->ReadPointerFromMemory(location, error);
- if (error.Fail())
- return false;
- lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024,0));
- size_t data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), 1024, error);
- if (error.Fail())
- return false;
- if (data_read)
- stream.Printf("@\"%s\"",(char*)buffer_sp->GetBytes());
- return true;
- }
-
- stream.Printf("class name = %s",class_name);
- return true;
-
-}
-
-bool
-lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- stream.Printf("%s",valobj.GetObjectDescription());
- return true;
-}
-
-bool
-lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
- valobj.GetClangAST(),
- NULL);
-
- ValueObjectSP real_guy_sp = valobj.GetSP();
-
- if (type_info & ClangASTContext::eTypeIsPointer)
- {
- Error err;
- real_guy_sp = valobj.Dereference(err);
- if (err.Fail() || !real_guy_sp)
- return false;
- }
- else if (type_info & ClangASTContext::eTypeIsReference)
- {
- real_guy_sp = valobj.GetChildAtIndex(0, true);
- if (!real_guy_sp)
- return false;
- }
- uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
- if (value == 0)
- {
- stream.Printf("NO");
- return true;
- }
- stream.Printf("YES");
- return true;
-}
-
-template <bool is_sel_ptr>
-bool
-lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream)
-{
- lldb::addr_t data_address = LLDB_INVALID_ADDRESS;
-
- if (is_sel_ptr)
- data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- else
- data_address = valobj.GetAddressOf();
-
- if (data_address == LLDB_INVALID_ADDRESS)
- return false;
-
- ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
-
- void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr();
- ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type));
-
- ValueObjectSP valobj_sp(ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar));
-
- stream.Printf("%s",valobj_sp->GetSummaryAsCString());
- return true;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_data_32(NULL),
-m_data_64(NULL)
-{
- if (valobj_sp)
- {
- m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
- Update();
- }
-}
-
-uint32_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (m_data_32)
- return m_data_32->_used;
- if (m_data_64)
- return m_data_64->_used;
- return 0;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
-{
- if (!m_data_32 && !m_data_64)
- return lldb::ValueObjectSP();
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = (m_data_32 ? m_data_32->_data : m_data_64->_data);
- object_at_idx += (idx * m_ptr_size);
- StreamString idx_name;
- idx_name.Printf("[%d]",idx);
- lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
- object_at_idx,
- m_exe_ctx_ref,
- m_id_type);
- m_children.push_back(retval_sp);
- return retval_sp;
-}
-
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::Update()
-{
- m_children.clear();
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = NULL;
- delete m_data_64;
- m_data_64 = NULL;
- if (valobj_sp->IsDynamic())
- valobj_sp = valobj_sp->GetStaticValue();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- if (valobj_sp->IsPointerType())
- {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
- return false;
-}
-
-bool
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
-{
- if (!m_data_32 && !m_data_64)
- Update ();
- return CalculateNumChildren();
-}
-
-static uint32_t
-ExtractIndexFromString (const char* item_name)
-{
- if (!item_name || !*item_name)
- return UINT32_MAX;
- if (*item_name != '[')
- return UINT32_MAX;
- item_name++;
- uint32_t idx = 0;
- while(*item_name)
- {
- char x = *item_name;
- if (x == ']')
- break;
- if (x < '0' || x > '9')
- return UINT32_MAX;
- idx = 10*idx + (x-'0');
- item_name++;
- }
- return idx;
-}
-
-uint32_t
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- if (!m_data_32 && !m_data_64)
- return UINT32_MAX;
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
-lldb_private::formatters::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = NULL;
- delete m_data_64;
- m_data_64 = NULL;
-}
-
-lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get()),
-m_exe_ctx_ref(),
-m_ptr_size(8),
-m_items(0),
-m_data_ptr(0)
-{
- if (valobj_sp)
- {
- m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
- Update();
- }
-}
-
-lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
-{
-}
-
-uint32_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
-uint32_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
-{
- return m_items;
-}
-
-bool
-lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
-{
- m_ptr_size = 0;
- m_items = 0;
- m_data_ptr = 0;
- m_children.clear();
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (valobj_sp->IsDynamic())
- valobj_sp = valobj_sp->GetStaticValue();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- if (valobj_sp->IsPointerType())
- {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
- m_items = process_sp->ReadPointerFromMemory(data_location, error);
- if (error.Fail())
- return false;
- m_data_ptr = data_location+m_ptr_size;
- return false;
-}
-
-bool
-lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
-{
- if (!m_data_ptr)
- Update ();
- return CalculateNumChildren();
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
-{
- if (idx >= CalculateNumChildren())
- return lldb::ValueObjectSP();
- lldb::addr_t object_at_idx = m_data_ptr;
- object_at_idx += (idx * m_ptr_size);
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- object_at_idx = process_sp->ReadPointerFromMemory(object_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
- StreamString expr;
- expr.Printf("(id)%llu",object_at_idx);
- StreamString idx_name;
- idx_name.Printf("[%d]",idx);
- lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
- m_children.push_back(retval_sp);
- return retval_sp;
-}
-
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return NULL;
- ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
- if (!runtime)
- return NULL;
-
- if (!valobj_sp->IsPointerType())
- {
- Error error;
- valobj_sp = valobj_sp->AddressOf(error);
- if (error.Fail() || !valobj_sp)
- return NULL;
- }
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return NULL;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return NULL;
-
- if (!strcmp(class_name,"__NSArrayI"))
- {
- return (new NSArrayISyntheticFrontEnd(valobj_sp));
- }
- else if (!strcmp(class_name,"__NSArrayM"))
- {
- return (new NSArrayMSyntheticFrontEnd(valobj_sp));
- }
- else
- {
- return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
- }
-}
-
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get())
-{}
-
-uint32_t
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
-{
- uint64_t count = 0;
- if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
- return count;
- return 0;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
-{
- StreamString idx_name;
- idx_name.Printf("[%d]",idx);
- lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
- if (valobj_sp)
- valobj_sp->SetName(ConstString(idx_name.GetData()));
- return valobj_sp;
-}
-
-bool
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
-{
- return false;
-}
-
-bool
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
-{
- return CalculateNumChildren() > 0;
-}
-
-uint32_t
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return 0;
-}
-
-lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
-{}
-
-SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
-{
-
- lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
- if (!process_sp)
- return NULL;
- ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
- if (!runtime)
- return NULL;
-
- if (!valobj_sp->IsPointerType())
- {
- Error error;
- valobj_sp = valobj_sp->AddressOf(error);
- if (error.Fail() || !valobj_sp)
- return NULL;
- }
-
- ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
-
- if (!descriptor.get() || !descriptor->IsValid())
- return NULL;
-
- const char* class_name = descriptor->GetClassName().GetCString();
-
- if (!class_name || !*class_name)
- return NULL;
-
- if (!strcmp(class_name,"__NSDictionaryI"))
- {
- return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
- }
- else if (!strcmp(class_name,"__NSDictionaryM"))
- {
- return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
- }
- else
- {
- return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
- }
-}
-
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
-SyntheticChildrenFrontEnd(*valobj_sp.get())
-{}
-
-uint32_t
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
-{
- uint64_t count = 0;
- if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
- return count;
- return 0;
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
-{
- StreamString idx_name;
- idx_name.Printf("[%d]",idx);
- StreamString valobj_expr_path;
- m_backend.GetExpressionPath(valobj_expr_path, false);
- StreamString key_fetcher_expr;
- key_fetcher_expr.Printf("(id)[(NSArray*)[%s allKeys] objectAtIndex:%d]",valobj_expr_path.GetData(),idx);
- StreamString value_fetcher_expr;
- value_fetcher_expr.Printf("(id)[%s objectForKey:%s]",valobj_expr_path.GetData(),key_fetcher_expr.GetData());
- StreamString object_fetcher_expr;
- object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
- lldb::ValueObjectSP child_sp;
- m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
- EvaluateExpressionOptions().SetKeepInMemory(true));
- if (child_sp)
- child_sp->SetName(ConstString(idx_name.GetData()));
- return child_sp;
-}
-
-bool
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
-{
- return false;
-}
-
-bool
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
-{
- return CalculateNumChildren() > 0;
-}
-
-uint32_t
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- return 0;
-}
-
-lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
-{}
-
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp.get()),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_data_32(NULL),
- m_data_64(NULL)
-{
- if (valobj_sp)
- Update();
-}
-
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = NULL;
- delete m_data_64;
- m_data_64 = NULL;
-}
-
-uint32_t
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
-uint32_t
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return (m_data_32 ? m_data_32->_used : m_data_64->_used);
-}
-
-bool
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
-{
- m_children.clear();
- delete m_data_32;
- m_data_32 = NULL;
- delete m_data_64;
- m_data_64 = NULL;
- m_ptr_size = 0;
- ValueObjectSP valobj_sp = m_backend.GetSP();
- if (!valobj_sp)
- return false;
- if (valobj_sp->IsDynamic())
- valobj_sp = valobj_sp->GetStaticValue();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- if (valobj_sp->IsPointerType())
- {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
- m_data_ptr = data_location + m_ptr_size;
- return false;
-}
-
-bool
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
-{
- if (!m_data_32 && !m_data_64)
- Update ();
- return CalculateNumChildren();
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
-{
- uint32_t num_children = CalculateNumChildren();
-
- if (idx >= num_children)
- return lldb::ValueObjectSP();
-
- if (m_children.empty())
- {
- // do the scan phase
- lldb::addr_t key_at_idx = 0, val_at_idx = 0;
-
- uint32_t tries = 0;
- uint32_t test_idx = 0;
-
- while(tries < num_children)
- {
- key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
- val_at_idx = key_at_idx + m_ptr_size;
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
- val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- test_idx++;
-
- if (!key_at_idx || !val_at_idx)
- continue;
- tries++;
-
- DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
-
- m_children.push_back(descriptor);
- }
- }
-
- if (idx >= m_children.size()) // should never happen
- return lldb::ValueObjectSP();
-
- DictionaryItemDescriptor &dict_item = m_children[idx];
- if (!dict_item.valobj_sp)
- {
- // make the new ValueObject
- StreamString expr;
- expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%llu ; _lldb_valgen_item.value = (id)%llu; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
- StreamString idx_name;
- idx_name.Printf("[%d]",idx);
- dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
- }
- return dict_item.valobj_sp;
-}
-
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
- SyntheticChildrenFrontEnd(*valobj_sp.get()),
- m_exe_ctx_ref(),
- m_ptr_size(8),
- m_data_32(NULL),
- m_data_64(NULL)
-{
- if (valobj_sp)
- Update ();
-}
-
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
-{
- delete m_data_32;
- m_data_32 = NULL;
- delete m_data_64;
- m_data_64 = NULL;
-}
-
-uint32_t
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
-{
- const char* item_name = name.GetCString();
- uint32_t idx = ExtractIndexFromString(item_name);
- if (idx < UINT32_MAX && idx >= CalculateNumChildren())
- return UINT32_MAX;
- return idx;
-}
-
-uint32_t
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
-{
- if (!m_data_32 && !m_data_64)
- return 0;
- return (m_data_32 ? m_data_32->_used : m_data_64->_used);
-}
-
-bool
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
-{
- m_children.clear();
- ValueObjectSP valobj_sp = m_backend.GetSP();
- m_ptr_size = 0;
- delete m_data_32;
- m_data_32 = NULL;
- delete m_data_64;
- m_data_64 = NULL;
- if (!valobj_sp)
- return false;
- if (valobj_sp->IsDynamic())
- valobj_sp = valobj_sp->GetStaticValue();
- if (!valobj_sp)
- return false;
- m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
- Error error;
- if (valobj_sp->IsPointerType())
- {
- valobj_sp = valobj_sp->Dereference(error);
- if (error.Fail() || !valobj_sp)
- return false;
- }
- error.Clear();
- lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
- if (!process_sp)
- return false;
- m_ptr_size = process_sp->GetAddressByteSize();
- uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
- if (m_ptr_size == 4)
- {
- m_data_32 = new DataDescriptor_32();
- process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
- }
- else
- {
- m_data_64 = new DataDescriptor_64();
- process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
- }
- if (error.Fail())
- return false;
- return false;
-}
-
-bool
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
-{
- if (!m_data_32 && !m_data_64)
- Update ();
- return CalculateNumChildren();
-}
-
-lldb::ValueObjectSP
-lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (uint32_t idx)
-{
- lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
- lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
-
- uint32_t num_children = CalculateNumChildren();
-
- if (idx >= num_children)
- return lldb::ValueObjectSP();
-
- if (m_children.empty())
- {
- // do the scan phase
- lldb::addr_t key_at_idx = 0, val_at_idx = 0;
-
- uint32_t tries = 0;
- uint32_t test_idx = 0;
-
- while(tries < num_children)
- {
- key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
- val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
- ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
- if (!process_sp)
- return lldb::ValueObjectSP();
- Error error;
- key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
- val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
- if (error.Fail())
- return lldb::ValueObjectSP();
-
- test_idx++;
-
- if (!key_at_idx || !val_at_idx)
- continue;
- tries++;
-
- DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
-
- m_children.push_back(descriptor);
- }
- }
-
- if (idx >= m_children.size()) // should never happen
- return lldb::ValueObjectSP();
-
- DictionaryItemDescriptor &dict_item = m_children[idx];
- if (!dict_item.valobj_sp)
- {
- // make the new ValueObject
- StreamString expr;
- expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%llu ; _lldb_valgen_item.value = (id)%llu; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
- StreamString idx_name;
- idx_name.Printf("[%d]",idx);
- dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
- }
- return dict_item.valobj_sp;
-}
-
-template bool
-lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
-
-template bool
-lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
-
-template bool
-lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
-
-template bool
-lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
-
-template bool
-lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&) ;
-
-template bool
-lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&) ;
Index: aze/lldb/source/Core/DataBufferMemoryMap.cpp
===================================================================
--- aze.orig/lldb/source/Core/DataBufferMemoryMap.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/DataBufferMemoryMap.cpp 2013-03-03 09:35:50.151457352 +0100
@@ -19,7 +19,10 @@
#include "lldb/Host/File.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
+#include "lldb/Core/Log.h"
+#include "lldb/lldb-private-log.h"
+using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
@@ -80,6 +83,9 @@
{
if (m_mmap_addr != NULL)
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
+ if (log)
+ log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %zu", m_mmap_addr, m_mmap_size);
::munmap((void *)m_mmap_addr, m_mmap_size);
m_mmap_addr = NULL;
m_mmap_size = 0;
@@ -104,6 +110,16 @@
{
if (filespec != NULL)
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
+ if (log)
+ {
+ log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s/%s\", offset=0x%" PRIx64 ", length=0x%zx, writeable=%i",
+ filespec->GetDirectory().GetCString(),
+ filespec->GetFilename().GetCString(),
+ offset,
+ length,
+ writeable);
+ }
char path[PATH_MAX];
if (filespec->GetPath(path, sizeof(path)))
{
@@ -116,8 +132,7 @@
if (error.Success())
{
const bool fd_is_file = true;
- MemoryMapFromFileDescriptor (file.GetDescriptor(), offset, length, writeable, fd_is_file);
- return GetByteSize();
+ return MemoryMapFromFileDescriptor (file.GetDescriptor(), offset, length, writeable, fd_is_file);
}
}
}
@@ -149,6 +164,16 @@
Clear();
if (fd >= 0)
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE));
+ if (log)
+ {
+ log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(fd=%i, offset=0x%" PRIx64 ", length=0x%zx, writeable=%i, fd_is_file=%i)",
+ fd,
+ offset,
+ length,
+ writeable,
+ fd_is_file);
+ }
struct stat stat;
if (::fstat(fd, &stat) == 0)
{
@@ -176,10 +201,10 @@
flags |= MAP_FILE;
m_mmap_addr = (uint8_t *)::mmap(NULL, length, prot, flags, fd, offset);
+ Error error;
if (m_mmap_addr == (void*)-1)
{
- Error error;
error.SetErrorToErrno ();
if (error.GetError() == EINVAL)
{
@@ -209,7 +234,7 @@
}
if (error.GetError() == ENOMEM)
{
- error.SetErrorStringWithFormat("could not allocate %lld bytes of memory to mmap in file", (uint64_t) length);
+ error.SetErrorStringWithFormat("could not allocate %" PRId64 " bytes of memory to mmap in file", (uint64_t) length);
}
}
else
@@ -220,6 +245,12 @@
m_data = m_mmap_addr;
m_size = length;
}
+
+ if (log)
+ {
+ log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %zu, error = %s",
+ m_mmap_addr, m_mmap_size, error.AsCString());
+ }
}
}
}
Index: aze/lldb/source/Core/DataExtractor.cpp
===================================================================
--- aze.orig/lldb/source/Core/DataExtractor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/DataExtractor.cpp 2013-03-03 09:35:50.155457353 +0100
@@ -38,39 +38,73 @@
using namespace lldb_private;
static inline uint16_t
-ReadInt16(const unsigned char* ptr, unsigned offset)
+ReadInt16(const unsigned char* ptr, offset_t offset)
{
return *(uint16_t *)(ptr + offset);
}
static inline uint32_t
-ReadInt32 (const unsigned char* ptr, unsigned offset)
+ReadInt32 (const unsigned char* ptr, offset_t offset)
{
return *(uint32_t *)(ptr + offset);
}
static inline uint64_t
-ReadInt64(const unsigned char* ptr, unsigned offset)
+ReadInt64(const unsigned char* ptr, offset_t offset)
{
return *(uint64_t *)(ptr + offset);
}
static inline uint16_t
-ReadSwapInt16(const unsigned char* ptr, unsigned offset)
+ReadInt16(const void* ptr)
+{
+ return *(uint16_t *)(ptr);
+}
+static inline uint32_t
+ReadInt32 (const void* ptr)
+{
+ return *(uint32_t *)(ptr);
+}
+
+static inline uint64_t
+ReadInt64(const void* ptr)
+{
+ return *(uint64_t *)(ptr);
+}
+
+static inline uint16_t
+ReadSwapInt16(const unsigned char* ptr, offset_t offset)
{
return llvm::ByteSwap_16(*(uint16_t *)(ptr + offset));
}
static inline uint32_t
-ReadSwapInt32 (const unsigned char* ptr, unsigned offset)
+ReadSwapInt32 (const unsigned char* ptr, offset_t offset)
{
return llvm::ByteSwap_32(*(uint32_t *)(ptr + offset));
}
static inline uint64_t
-ReadSwapInt64(const unsigned char* ptr, unsigned offset)
+ReadSwapInt64(const unsigned char* ptr, offset_t offset)
{
return llvm::ByteSwap_64(*(uint64_t *)(ptr + offset));
}
+static inline uint16_t
+ReadSwapInt16(const void* ptr)
+{
+ return llvm::ByteSwap_16(*(uint16_t *)(ptr));
+}
+
+static inline uint32_t
+ReadSwapInt32 (const void* ptr)
+{
+ return llvm::ByteSwap_32(*(uint32_t *)(ptr));
+}
+static inline uint64_t
+ReadSwapInt64(const void* ptr)
+{
+ return llvm::ByteSwap_64(*(uint64_t *)(ptr));
+}
+
#define NON_PRINTABLE_CHAR '.'
//----------------------------------------------------------------------
// Default constructor.
@@ -88,7 +122,7 @@
// This constructor allows us to use data that is owned by someone else.
// The data must stay around as long as this object is valid.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const void* data, uint32_t length, ByteOrder endian, uint8_t addr_size) :
+DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endian, uint32_t addr_size) :
m_start ((uint8_t*)data),
m_end ((uint8_t*)data + length),
m_byte_order(endian),
@@ -104,7 +138,7 @@
// as long as any DataExtractor objects exist that have a reference to
// this data.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint8_t addr_size) :
+DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint32_t addr_size) :
m_start (NULL),
m_end (NULL),
m_byte_order(endian),
@@ -121,7 +155,7 @@
// as any object contains a reference to that data. The endian
// swap and address size settings are copied from "data".
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataExtractor& data, uint32_t offset, uint32_t length) :
+DataExtractor::DataExtractor (const DataExtractor& data, offset_t offset, offset_t length) :
m_start(NULL),
m_end(NULL),
m_byte_order(data.m_byte_order),
@@ -130,7 +164,7 @@
{
if (data.ValidOffset(offset))
{
- uint32_t bytes_available = data.GetByteSize() - offset;
+ offset_t bytes_available = data.GetByteSize() - offset;
if (length > bytes_available)
length = bytes_available;
SetData(data, offset, length);
@@ -208,32 +242,6 @@
return 0;
}
-//------------------------------------------------------------------
-// Returns true if there are LENGTH bytes availabe starting OFFSET
-// into the data that is in this object.
-//------------------------------------------------------------------
-bool
-DataExtractor::ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const
-{
- size_t size = GetByteSize();
- if (offset >= size)
- return false; // offset isn't valid
-
- if (length == 0)
- return true; // No bytes requested at this offset, return true
-
- // If we flip the bits in offset we can figure out how
- // many bytes we have left before "offset + length"
- // could overflow when doing unsigned arithmetic.
- if (length > ~offset)
- return false; // unsigned overflow
-
- // Make sure "offset + length" is a valid offset as well.
- // length must be greater than zero for this to be a
- // valid expression, and we have already checked for this.
- return ((offset + length) <= size);
-}
-
//----------------------------------------------------------------------
// Set the data with which this object will extract from to data
// starting at BYTES and set the length of the data to LENGTH bytes
@@ -244,8 +252,8 @@
// reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::SetData (const void *bytes, uint32_t length, ByteOrder endian)
+lldb::offset_t
+DataExtractor::SetData (const void *bytes, offset_t length, ByteOrder endian)
{
m_byte_order = endian;
m_data_sp.reset();
@@ -276,8 +284,8 @@
// refers to those bytes. The address size and endian swap settings
// are copied from the current values in "data".
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::SetData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
+lldb::offset_t
+DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_t data_length)
{
m_addr_size = data.m_addr_size;
// If "data" contains shared pointer to data, then we can use that
@@ -311,8 +319,8 @@
// around as long as it is needed. The address size and endian swap
// settings will remain unchanged from their current settings.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::SetData (const DataBufferSP& data_sp, uint32_t data_offset, uint32_t data_length)
+lldb::offset_t
+DataExtractor::SetData (const DataBufferSP& data_sp, offset_t data_offset, offset_t data_length)
{
m_start = m_end = NULL;
@@ -335,7 +343,7 @@
}
}
- uint32_t new_size = GetByteSize();
+ size_t new_size = GetByteSize();
// Don't hold a shared pointer to the data buffer if we don't share
// any valid bytes in the shared buffer.
@@ -352,15 +360,12 @@
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
uint8_t
-DataExtractor::GetU8 (uint32_t *offset_ptr) const
+DataExtractor::GetU8 (offset_t *offset_ptr) const
{
- uint8_t val = 0;
- if ( m_start < m_end )
- {
- val = m_start[*offset_ptr];
- *offset_ptr += sizeof(val);
- }
- return val;
+ const uint8_t *data = (const uint8_t *)GetData (offset_ptr, 1);
+ if (data)
+ return *data;
+ return 0;
}
//----------------------------------------------------------------------
@@ -373,16 +378,13 @@
// the buffer due to being out of bounds, or unsufficient data.
//----------------------------------------------------------------------
void *
-DataExtractor::GetU8 (uint32_t *offset_ptr, void *dst, uint32_t count) const
+DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
{
- register uint32_t offset = *offset_ptr;
-
- if ((count > 0) && ValidOffsetForDataOfSize(offset, count) )
+ const uint8_t *data = (const uint8_t *)GetData (offset_ptr, count);
+ if (data)
{
// Copy the data into the buffer
- memcpy (dst, m_start + offset, count);
- // Advance the offset
- *offset_ptr += count;
+ memcpy (dst, data, count);
// Return a non-NULL pointer to the converted data as an indicator of success
return dst;
}
@@ -396,49 +398,52 @@
// RETURNS the uint16_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
uint16_t
-DataExtractor::GetU16 (uint32_t *offset_ptr) const
+DataExtractor::GetU16 (offset_t *offset_ptr) const
{
uint16_t val = 0;
- register uint32_t offset = *offset_ptr;
- if ( ValidOffsetForDataOfSize(offset, sizeof(val)) )
+ const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
+ if (data)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
- val = ReadSwapInt16(m_start, offset);
+ val = ReadSwapInt16(data);
else
- val = ReadInt16 (m_start, offset);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
+ val = ReadInt16 (data);
}
return val;
}
uint16_t
-DataExtractor::GetU16_unchecked (uint32_t *offset_ptr) const
+DataExtractor::GetU16_unchecked (offset_t *offset_ptr) const
{
- uint16_t val = (m_byte_order == lldb::endian::InlHostByteOrder()) ?
- ReadInt16 (m_start, *offset_ptr) :
- ReadSwapInt16(m_start, *offset_ptr);
+ uint16_t val;
+ if (m_byte_order == lldb::endian::InlHostByteOrder())
+ val = ReadInt16 (m_start, *offset_ptr);
+ else
+ val = ReadSwapInt16(m_start, *offset_ptr);
*offset_ptr += sizeof(val);
return val;
}
uint32_t
-DataExtractor::GetU32_unchecked (uint32_t *offset_ptr) const
+DataExtractor::GetU32_unchecked (offset_t *offset_ptr) const
{
- uint32_t val = (m_byte_order == lldb::endian::InlHostByteOrder()) ?
- ReadInt32 (m_start, *offset_ptr) :
- ReadSwapInt32 (m_start, *offset_ptr);
+ uint32_t val;
+ if (m_byte_order == lldb::endian::InlHostByteOrder())
+ val = ReadInt32 (m_start, *offset_ptr);
+ else
+ val = ReadSwapInt32 (m_start, *offset_ptr);
*offset_ptr += sizeof(val);
return val;
}
uint64_t
-DataExtractor::GetU64_unchecked (uint32_t *offset_ptr) const
+DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
{
- uint64_t val = (m_byte_order == lldb::endian::InlHostByteOrder()) ?
- ReadInt64 (m_start, *offset_ptr) :
- ReadSwapInt64 (m_start, *offset_ptr);
+ uint64_t val;
+ if (m_byte_order == lldb::endian::InlHostByteOrder())
+ val = ReadInt64 (m_start, *offset_ptr);
+ else
+ val = ReadSwapInt64 (m_start, *offset_ptr);
*offset_ptr += sizeof(val);
return val;
}
@@ -454,31 +459,30 @@
// in the buffer due to being out of bounds, or unsufficient data.
//----------------------------------------------------------------------
void *
-DataExtractor::GetU16 (uint32_t *offset_ptr, void *void_dst, uint32_t count) const
+DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
{
- uint16_t *dst = (uint16_t *)void_dst;
- const size_t value_size = sizeof(*dst);
- register uint32_t offset = *offset_ptr;
-
- if ((count > 0) && ValidOffsetForDataOfSize(offset, value_size * count) )
+ const size_t src_size = sizeof(uint16_t) * count;
+ const uint16_t *src = (const uint16_t *)GetData (offset_ptr, src_size);
+ if (src)
{
- uint16_t *value_ptr;
- uint16_t *end = dst + count;
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
- for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
- *value_ptr = ReadSwapInt16 (m_start, offset);
+ uint16_t *dst_pos = (uint16_t *)void_dst;
+ uint16_t *dst_end = dst_pos + count;
+ const uint16_t *src_pos = src;
+ while (dst_pos < dst_end)
+ {
+ *dst_pos = ReadSwapInt16 (src_pos);
+ ++dst_pos;
+ ++src_pos;
+ }
}
else
{
- for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
- *value_ptr = ReadInt16 (m_start, offset);
+ memcpy (void_dst, src, src_size);
}
-
- // Advance the offset
- *offset_ptr = offset;
// Return a non-NULL pointer to the converted data as an indicator of success
- return dst;
+ return void_dst;
}
return NULL;
}
@@ -490,20 +494,16 @@
// RETURNS the uint32_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
uint32_t
-DataExtractor::GetU32 (uint32_t *offset_ptr) const
+DataExtractor::GetU32 (offset_t *offset_ptr) const
{
uint32_t val = 0;
- register uint32_t offset = *offset_ptr;
-
- if ( ValidOffsetForDataOfSize(offset, sizeof(val)) )
+ const uint32_t *data = (const uint32_t *)GetData (offset_ptr, sizeof(val));
+ if (data)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
- val = ReadSwapInt32 (m_start, offset);
+ val = ReadSwapInt32 (data);
else
- val = ReadInt32 (m_start, offset);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
+ val = *data;
}
return val;
}
@@ -518,32 +518,30 @@
// in the buffer due to being out of bounds, or unsufficient data.
//----------------------------------------------------------------------
void *
-DataExtractor::GetU32 (uint32_t *offset_ptr, void *void_dst, uint32_t count) const
+DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
{
- uint32_t *dst = (uint32_t *)void_dst;
- const size_t value_size = sizeof(*dst);
- register uint32_t offset = *offset_ptr;
-
- if ((count > 0) && ValidOffsetForDataOfSize(offset, value_size * count))
+ const size_t src_size = sizeof(uint32_t) * count;
+ const uint32_t *src = (const uint32_t *)GetData (offset_ptr, src_size);
+ if (src)
{
- uint32_t *value_ptr;
- uint32_t *end = dst + count;
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
- for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
- *value_ptr = ReadSwapInt32 (m_start, offset);
-
+ uint32_t *dst_pos = (uint32_t *)void_dst;
+ uint32_t *dst_end = dst_pos + count;
+ const uint32_t *src_pos = src;
+ while (dst_pos < dst_end)
+ {
+ *dst_pos = ReadSwapInt32 (src_pos);
+ ++dst_pos;
+ ++src_pos;
+ }
}
else
{
- for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
- *value_ptr = ReadInt32 (m_start, offset);
+ memcpy (void_dst, src, src_size);
}
-
- // Advance the offset
- *offset_ptr = offset;
// Return a non-NULL pointer to the converted data as an indicator of success
- return dst;
+ return void_dst;
}
return NULL;
}
@@ -555,19 +553,16 @@
// RETURNS the uint64_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
uint64_t
-DataExtractor::GetU64 (uint32_t *offset_ptr) const
+DataExtractor::GetU64 (offset_t *offset_ptr) const
{
uint64_t val = 0;
- register uint32_t offset = *offset_ptr;
- if ( ValidOffsetForDataOfSize(offset, sizeof(val)) )
+ const uint64_t *data = (const uint64_t *)GetData (offset_ptr, sizeof(val));
+ if (data)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
- val = ReadSwapInt64 (m_start, offset);
+ val = ReadSwapInt64 (data);
else
- val = ReadInt64 (m_start, offset);
-
- // Advance the offset
- *offset_ptr += sizeof(val);
+ val = *data;
}
return val;
}
@@ -580,32 +575,30 @@
// return false and leave the offset pointed to by offset_ptr unchanged.
//----------------------------------------------------------------------
void *
-DataExtractor::GetU64 (uint32_t *offset_ptr, void *void_dst, uint32_t count) const
+DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
{
- uint64_t *dst = (uint64_t *)void_dst;
- const size_t value_size = sizeof(uint64_t);
- register uint32_t offset = *offset_ptr;
-
- if ((count > 0) && ValidOffsetForDataOfSize(offset, value_size * count))
+ const size_t src_size = sizeof(uint64_t) * count;
+ const uint64_t *src = (const uint64_t *)GetData (offset_ptr, src_size);
+ if (src)
{
- uint64_t *value_ptr;
- uint64_t *end = dst + count;
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
- for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
- *value_ptr = ReadSwapInt64 (m_start, offset);
-
+ uint64_t *dst_pos = (uint64_t *)void_dst;
+ uint64_t *dst_end = dst_pos + count;
+ const uint64_t *src_pos = src;
+ while (dst_pos < dst_end)
+ {
+ *dst_pos = ReadSwapInt64 (src_pos);
+ ++dst_pos;
+ ++src_pos;
+ }
}
else
{
- for (value_ptr = dst; value_ptr < end; ++value_ptr, offset += value_size)
- *value_ptr = ReadInt64 (m_start, offset);
+ memcpy (void_dst, src, src_size);
}
-
- // Advance the offset
- *offset_ptr = offset;
// Return a non-NULL pointer to the converted data as an indicator of success
- return dst;
+ return void_dst;
}
return NULL;
}
@@ -621,7 +614,7 @@
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
uint32_t
-DataExtractor::GetMaxU32 (uint32_t *offset_ptr, uint32_t byte_size) const
+DataExtractor::GetMaxU32 (offset_t *offset_ptr, size_t byte_size) const
{
switch (byte_size)
{
@@ -629,7 +622,7 @@
case 2: return GetU16(offset_ptr); break;
case 4: return GetU32(offset_ptr); break;
default:
- assert(!"GetMaxU32 unhandled case!");
+ assert("GetMaxU32 unhandled case!" == NULL);
break;
}
return 0;
@@ -646,7 +639,7 @@
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
uint64_t
-DataExtractor::GetMaxU64 (uint32_t *offset_ptr, uint32_t size) const
+DataExtractor::GetMaxU64 (offset_t *offset_ptr, size_t size) const
{
switch (size)
{
@@ -655,14 +648,14 @@
case 4: return GetU32(offset_ptr); break;
case 8: return GetU64(offset_ptr); break;
default:
- assert(!"GetMax64 unhandled case!");
+ assert("GetMax64 unhandled case!" == NULL);
break;
}
return 0;
}
uint64_t
-DataExtractor::GetMaxU64_unchecked (uint32_t *offset_ptr, uint32_t size) const
+DataExtractor::GetMaxU64_unchecked (offset_t *offset_ptr, size_t size) const
{
switch (size)
{
@@ -671,14 +664,14 @@
case 4: return GetU32_unchecked (offset_ptr); break;
case 8: return GetU64_unchecked (offset_ptr); break;
default:
- assert(!"GetMax64 unhandled case!");
+ assert("GetMax64 unhandled case!" == NULL);
break;
}
return 0;
}
int64_t
-DataExtractor::GetMaxS64 (uint32_t *offset_ptr, uint32_t size) const
+DataExtractor::GetMaxS64 (offset_t *offset_ptr, size_t size) const
{
switch (size)
{
@@ -687,14 +680,14 @@
case 4: return (int32_t)GetU32(offset_ptr); break;
case 8: return (int64_t)GetU64(offset_ptr); break;
default:
- assert(!"GetMax64 unhandled case!");
+ assert("GetMax64 unhandled case!" == NULL);
break;
}
return 0;
}
uint64_t
-DataExtractor::GetMaxU64Bitfield (uint32_t *offset_ptr, uint32_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
+DataExtractor::GetMaxU64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
{
uint64_t uval64 = GetMaxU64 (offset_ptr, size);
if (bitfield_bit_size > 0)
@@ -710,7 +703,7 @@
}
int64_t
-DataExtractor::GetMaxS64Bitfield (uint32_t *offset_ptr, uint32_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
+DataExtractor::GetMaxS64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
{
int64_t sval64 = GetMaxS64 (offset_ptr, size);
if (bitfield_bit_size > 0)
@@ -728,23 +721,24 @@
float
-DataExtractor::GetFloat (uint32_t *offset_ptr) const
+DataExtractor::GetFloat (offset_t *offset_ptr) const
{
typedef float float_type;
float_type val = 0.0;
- const uint8_t *src_data = PeekData (*offset_ptr, sizeof(float_type));
-
- if (src_data)
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
+ if (src)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
+ const uint8_t *src_data = (const uint8_t *)src;
uint8_t *dst_data = (uint8_t *)&val;
for (int i=0; i<sizeof(float_type); ++i)
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
}
else
{
- ::memcpy (&val, src_data, sizeof (float_type));
+ val = *src;
}
// Advance the offset
@@ -754,25 +748,26 @@
}
double
-DataExtractor::GetDouble (uint32_t *offset_ptr) const
+DataExtractor::GetDouble (offset_t *offset_ptr) const
{
typedef double float_type;
float_type val = 0.0;
- const uint8_t *src_data = PeekData (*offset_ptr, sizeof(float_type));
-
- if (src_data)
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
+ if (src)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
+ const uint8_t *src_data = (const uint8_t *)src;
uint8_t *dst_data = (uint8_t *)&val;
for (int i=0; i<sizeof(float_type); ++i)
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
}
else
{
- ::memcpy (&val, src_data, sizeof (float_type));
+ val = *src;
}
-
+
// Advance the offset
*offset_ptr += sizeof(val);
}
@@ -781,25 +776,26 @@
long double
-DataExtractor::GetLongDouble (uint32_t *offset_ptr) const
+DataExtractor::GetLongDouble (offset_t *offset_ptr) const
{
typedef long double float_type;
float_type val = 0.0;
- const uint8_t *src_data = PeekData (*offset_ptr, sizeof(float_type));
-
- if (src_data)
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
+ if (src)
{
if (m_byte_order != lldb::endian::InlHostByteOrder())
{
+ const uint8_t *src_data = (const uint8_t *)src;
uint8_t *dst_data = (uint8_t *)&val;
for (int i=0; i<sizeof(float_type); ++i)
dst_data[sizeof(float_type) - 1 - i] = src_data[i];
}
else
{
- ::memcpy (&val, src_data, sizeof (float_type));
+ val = *src;
}
-
+
// Advance the offset
*offset_ptr += sizeof(val);
}
@@ -816,13 +812,13 @@
// RETURNS the address that was extracted, or zero on failure.
//------------------------------------------------------------------
uint64_t
-DataExtractor::GetAddress (uint32_t *offset_ptr) const
+DataExtractor::GetAddress (offset_t *offset_ptr) const
{
return GetMaxU64 (offset_ptr, m_addr_size);
}
uint64_t
-DataExtractor::GetAddress_unchecked (uint32_t *offset_ptr) const
+DataExtractor::GetAddress_unchecked (offset_t *offset_ptr) const
{
return GetMaxU64_unchecked (offset_ptr, m_addr_size);
}
@@ -836,7 +832,7 @@
// RETURNS the pointer that was extracted, or zero on failure.
//------------------------------------------------------------------
uint64_t
-DataExtractor::GetPointer (uint32_t *offset_ptr) const
+DataExtractor::GetPointer (offset_t *offset_ptr) const
{
return GetMaxU64 (offset_ptr, m_addr_size);
}
@@ -849,7 +845,7 @@
//----------------------------------------------------------------------
uint64_t
-DataExtractor::GetGNUEHPointer (uint32_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr, lldb::addr_t text_addr, lldb::addr_t data_addr)//, BSDRelocs *data_relocs) const
+DataExtractor::GetGNUEHPointer (offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr, lldb::addr_t text_addr, lldb::addr_t data_addr)//, BSDRelocs *data_relocs) const
{
if (eh_ptr_enc == DW_EH_PE_omit)
return ULLONG_MAX; // Value isn't in the buffer...
@@ -948,7 +944,7 @@
}
size_t
-DataExtractor::ExtractBytes (uint32_t offset, uint32_t length, ByteOrder dst_byte_order, void *dst) const
+DataExtractor::ExtractBytes (offset_t offset, offset_t length, ByteOrder dst_byte_order, void *dst) const
{
const uint8_t *src = PeekData (offset, length);
if (src)
@@ -964,52 +960,18 @@
}
return 0;
}
-//----------------------------------------------------------------------
-// Peeks at bytes in the contained data.
-//
-// Returns a valid pointer to bytes if "offset" is a valid offset in
-// and there are "length" bytes available, else NULL is returned.
-//----------------------------------------------------------------------
-const uint8_t*
-DataExtractor::PeekData (uint32_t offset, uint32_t length) const
-{
- if ( length > 0 && ValidOffsetForDataOfSize(offset, length) )
- return m_start + offset;
- return NULL;
-}
-
-//----------------------------------------------------------------------
-// Returns a pointer to a bytes in this object's data at the offset
-// pointed to by "offset_ptr". If "length" is zero or too large,
-// then the offset pointed to by "offset_ptr" will not be updated
-// and NULL will be returned.
-//
-// Returns a pointer to the data if the offset and length are valid,
-// or NULL otherwise.
-//----------------------------------------------------------------------
-const void*
-DataExtractor::GetData (uint32_t *offset_ptr, uint32_t length) const
-{
- const uint8_t* bytes = NULL;
- register uint32_t offset = *offset_ptr;
- if ( length > 0 && ValidOffsetForDataOfSize(offset, length) )
- {
- bytes = m_start + offset;
- *offset_ptr = offset + length;
- }
- return bytes;
-}
// Extract data and swap if needed when doing the copy
-uint32_t
-DataExtractor::CopyByteOrderedData (uint32_t src_offset,
- uint32_t src_len,
+lldb::offset_t
+DataExtractor::CopyByteOrderedData (offset_t src_offset,
+ offset_t src_len,
void *dst_void_ptr,
- uint32_t dst_len,
+ offset_t dst_len,
ByteOrder dst_byte_order) const
{
// Validate the source info
- assert (ValidOffsetForDataOfSize(src_offset, src_len));
+ if (!ValidOffsetForDataOfSize(src_offset, src_len))
+ assert (ValidOffsetForDataOfSize(src_offset, src_len));
assert (src_len > 0);
assert (m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
@@ -1033,7 +995,7 @@
// We are copying the entire value from src into dst.
// Calculate how many, if any, zeroes we need for the most
// significant bytes if "dst_len" is greater than "src_len"...
- const uint32_t num_zeroes = dst_len - src_len;
+ const size_t num_zeroes = dst_len - src_len;
if (dst_byte_order == eByteOrderBig)
{
// Big endian, so we lead with zeroes...
@@ -1126,22 +1088,31 @@
// updated.
//----------------------------------------------------------------------
const char*
-DataExtractor::GetCStr (uint32_t *offset_ptr) const
+DataExtractor::GetCStr (offset_t *offset_ptr) const
{
- const char *s = NULL;
- if ( m_start < m_end )
+ const char *cstr = (const char *)PeekData (*offset_ptr, 1);
+ if (cstr)
{
- s = (char*)m_start + *offset_ptr;
-
- size_t length = strlen(s) + 1;
-
- if (!ValidOffsetForDataOfSize(*offset_ptr, length))
- return NULL;
-
- // Advance the offset
- *offset_ptr += length;
+ const char *cstr_end = cstr;
+ const char *end = (const char *)m_end;
+ while (cstr_end < end && *cstr_end)
+ ++cstr_end;
+
+ // Now we are either at the end of the data or we point to the
+ // NULL C string terminator with cstr_end...
+ if (*cstr_end == '\0')
+ {
+ // Advance the offset with one extra byte for the NULL terminator
+ *offset_ptr += (cstr_end - cstr + 1);
+ return cstr;
+ }
+
+ // We reached the end of the data without finding a NULL C string
+ // terminator. Fall through and return NULL otherwise anyone that
+ // would have used the result as a C string can wonder into
+ // unknown memory...
}
- return s;
+ return NULL;
}
//------------------------------------------------------------------
@@ -1153,11 +1124,9 @@
// this object's data, else NULL is returned.
//------------------------------------------------------------------
const char *
-DataExtractor::PeekCStr (uint32_t offset) const
+DataExtractor::PeekCStr (offset_t offset) const
{
- if (ValidOffset (offset))
- return (const char*)m_start + offset;
- return NULL;
+ return (const char *)PeekData (offset, 1);
}
//----------------------------------------------------------------------
@@ -1169,9 +1138,9 @@
// Returned the extracted integer value.
//----------------------------------------------------------------------
uint64_t
-DataExtractor::GetULEB128 (uint32_t *offset_ptr) const
+DataExtractor::GetULEB128 (offset_t *offset_ptr) const
{
- const uint8_t *src = m_start + *offset_ptr;
+ const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
const uint8_t *end = m_end;
if (src < end)
@@ -1190,7 +1159,7 @@
shift += 7;
}
}
- *offset_ptr = (uint32_t)(src - m_start);
+ *offset_ptr = src - m_start;
return result;
}
@@ -1206,20 +1175,21 @@
// Returned the extracted integer value.
//----------------------------------------------------------------------
int64_t
-DataExtractor::GetSLEB128 (uint32_t *offset_ptr) const
+DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
{
- int64_t result = 0;
-
- if ( m_start < m_end )
+ const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
+ const uint8_t *end = m_end;
+
+ if (src < end)
{
+ int64_t result = 0;
int shift = 0;
- int size = sizeof (uint32_t) * 8;
- const uint8_t *src = m_start + *offset_ptr;
+ int size = sizeof (int64_t) * 8;
uint8_t byte = 0;
int bytecount = 0;
- while (src < m_end)
+ while (src < end)
{
bytecount++;
byte = *src++;
@@ -1234,8 +1204,9 @@
result |= - (1 << shift);
*offset_ptr += bytecount;
+ return result;
}
- return result;
+ return 0;
}
//----------------------------------------------------------------------
@@ -1247,27 +1218,27 @@
// Returns the number of bytes consumed during the extraction.
//----------------------------------------------------------------------
uint32_t
-DataExtractor::Skip_LEB128 (uint32_t *offset_ptr) const
+DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
{
uint32_t bytes_consumed = 0;
- if ( m_start < m_end )
+ const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
+ const uint8_t *end = m_end;
+
+ if (src < end)
{
- const uint8_t *start = m_start + *offset_ptr;
- const uint8_t *src = start;
-
- while ((src < m_end) && (*src++ & 0x80))
+ const uint8_t *src_pos = src;
+ while ((src_pos < end) && (*src_pos++ & 0x80))
++bytes_consumed;
-
- *offset_ptr += src - start;
+ *offset_ptr += src_pos - src;
}
return bytes_consumed;
}
-static uint32_t
-DumpAPInt (Stream *s, const DataExtractor &data, uint32_t offset, uint32_t byte_size, bool is_signed, unsigned radix)
+static lldb::offset_t
+DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix)
{
llvm::SmallVector<uint64_t, 2> uint64_array;
- uint32_t bytes_left = byte_size;
+ lldb::offset_t bytes_left = byte_size;
uint64_t u64;
const lldb::ByteOrder byte_order = data.GetByteOrder();
if (byte_order == lldb::eByteOrderLittle)
@@ -1281,7 +1252,7 @@
}
else
{
- u64 = data.GetMaxU64(&offset, bytes_left);
+ u64 = data.GetMaxU64(&offset, (uint32_t)bytes_left);
bytes_left = 0;
}
uint64_array.push_back(u64);
@@ -1289,8 +1260,8 @@
}
else if (byte_order == lldb::eByteOrderBig)
{
- uint32_t be_offset = offset + byte_size;
- uint32_t temp_offset;
+ lldb::offset_t be_offset = offset + byte_size;
+ lldb::offset_t temp_offset;
while (bytes_left > 0)
{
if (bytes_left >= 8)
@@ -1304,7 +1275,7 @@
{
be_offset -= bytes_left;
temp_offset = be_offset;
- u64 = data.GetMaxU64(&temp_offset, bytes_left);
+ u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
bytes_left = 0;
}
uint64_array.push_back(u64);
@@ -1331,13 +1302,13 @@
return offset;
}
-uint32_t
+lldb::offset_t
DataExtractor::Dump (Stream *s,
- uint32_t start_offset,
+ offset_t start_offset,
lldb::Format item_format,
- uint32_t item_byte_size,
- uint32_t item_count,
- uint32_t num_per_line,
+ size_t item_byte_size,
+ size_t item_count,
+ size_t num_per_line,
uint64_t base_addr,
uint32_t item_bit_size, // If zero, this is not a bitfield value, if non-zero, the value is a bitfield
uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the shift amount to apply to a bitfield
@@ -1352,7 +1323,7 @@
item_byte_size = s->GetAddressByteSize();
}
- uint32_t offset = start_offset;
+ offset_t offset = start_offset;
if (item_format == eFormatInstruction)
{
@@ -1361,14 +1332,15 @@
target_sp = exe_scope->CalculateTarget();
if (target_sp)
{
- DisassemblerSP disassembler_sp (Disassembler::FindPlugin(target_sp->GetArchitecture(), NULL));
+ DisassemblerSP disassembler_sp (Disassembler::FindPlugin(target_sp->GetArchitecture(), NULL, NULL));
if (disassembler_sp)
{
lldb::addr_t addr = base_addr + start_offset;
lldb_private::Address so_addr;
if (!target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
{
- so_addr.SetRawAddress(addr);
+ if (target_sp->GetSectionLoadList().IsEmpty() || !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
+ so_addr.SetRawAddress(addr);
}
size_t bytes_consumed = disassembler_sp->DecodeInstructions (so_addr, *this, start_offset, item_count, false);
@@ -1393,7 +1365,7 @@
if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8)
item_format = eFormatHex;
- uint32_t line_start_offset = start_offset;
+ lldb::offset_t line_start_offset = start_offset;
for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count)
{
if ((count % num_per_line) == 0)
@@ -1402,13 +1374,13 @@
{
if (item_format == eFormatBytesWithASCII && offset > line_start_offset)
{
- s->Printf("%*s", (num_per_line - (offset - line_start_offset)) * 3 + 2, "");
- Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+ s->Printf("%*s", static_cast<int>((num_per_line - (offset - line_start_offset)) * 3 + 2), "");
+ Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, LLDB_INVALID_OFFSET, LLDB_INVALID_ADDRESS, 0, 0);
}
s->EOL();
}
if (base_addr != LLDB_INVALID_ADDRESS)
- s->Printf ("0x%8.8llx: ", (uint64_t)(base_addr + (offset - start_offset)));
+ s->Printf ("0x%8.8" PRIx64 ": ", (uint64_t)(base_addr + (offset - start_offset)));
line_start_offset = offset;
}
else
@@ -1428,7 +1400,7 @@
s->Printf ("%s", GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset) ? "true" : "false");
else
{
- s->Printf("error: unsupported byte size (%u) for boolean format", item_byte_size);
+ s->Printf("error: unsupported byte size (%zu) for boolean format", item_byte_size);
return offset;
}
break;
@@ -1498,7 +1470,7 @@
if (item_byte_size == 1)
s->Printf ("\\x%2.2x", (uint8_t)ch);
else
- s->Printf ("%llu", ch);
+ s->Printf ("%" PRIu64, ch);
break;
}
}
@@ -1516,7 +1488,7 @@
case eFormatEnum: // Print enum value as a signed integer when we don't get the enum type
case eFormatDecimal:
if (item_byte_size <= 8)
- s->Printf ("%lld", GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
+ s->Printf ("%" PRId64, GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
else
{
const bool is_signed = true;
@@ -1527,7 +1499,7 @@
case eFormatUnsigned:
if (item_byte_size <= 8)
- s->Printf ("%llu", GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
+ s->Printf ("%" PRIu64, GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
else
{
const bool is_signed = false;
@@ -1538,7 +1510,7 @@
case eFormatOctal:
if (item_byte_size <= 8)
- s->Printf ("0%llo", GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
+ s->Printf ("0%" PRIo64, GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
else
{
const bool is_signed = false;
@@ -1584,7 +1556,7 @@
if (!cstr)
{
s->Printf("NULL");
- offset = UINT32_MAX;
+ offset = LLDB_INVALID_OFFSET;
}
else
{
@@ -1628,16 +1600,16 @@
case eFormatComplexInteger:
{
- uint32_t complex_int_byte_size = item_byte_size / 2;
+ size_t complex_int_byte_size = item_byte_size / 2;
if (complex_int_byte_size <= 8)
{
- s->Printf("%llu", GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
- s->Printf(" + %llui", GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
+ s->Printf("%" PRIu64, GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
+ s->Printf(" + %" PRIu64 "i", GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
}
else
{
- s->Printf("error: unsupported byte size (%u) for complex integer format", item_byte_size);
+ s->Printf("error: unsupported byte size (%zu) for complex integer format", item_byte_size);
return offset;
}
}
@@ -1669,7 +1641,7 @@
}
else
{
- s->Printf("error: unsupported byte size (%u) for complex float format", item_byte_size);
+ s->Printf("error: unsupported byte size (%zu) for complex float format", item_byte_size);
return offset;
}
break;
@@ -1682,7 +1654,7 @@
bool wantsuppercase = (item_format == eFormatHexUppercase);
if (item_byte_size <= 8)
{
- s->Printf(wantsuppercase ? "0x%*.*llX" : "0x%*.*llx", 2 * item_byte_size, 2 * item_byte_size, GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
+ s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, (int)(2 * item_byte_size), (int)(2 * item_byte_size), GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
}
else
{
@@ -1727,7 +1699,7 @@
}
else
{
- s->Printf("error: unsupported byte size (%u) for float format", item_byte_size);
+ s->Printf("error: unsupported byte size (%zu) for float format", item_byte_size);
return offset;
}
ss.flush();
@@ -1746,7 +1718,7 @@
case eFormatAddressInfo:
{
addr_t addr = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- s->Printf("0x%*.*llx", 2 * item_byte_size, 2 * item_byte_size, addr);
+ s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), (int)(2 * item_byte_size), addr);
if (exe_scope)
{
TargetSP target_sp (exe_scope->CalculateTarget());
@@ -1790,7 +1762,7 @@
}
else
{
- s->Printf("error: unsupported byte size (%u) for hex float format", item_byte_size);
+ s->Printf("error: unsupported byte size (%zu) for hex float format", item_byte_size);
return offset;
}
break;
@@ -1874,8 +1846,8 @@
if (item_format == eFormatBytesWithASCII && offset > line_start_offset)
{
- s->Printf("%*s", (num_per_line - (offset - line_start_offset)) * 3 + 2, "");
- Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+ s->Printf("%*s", static_cast<int>((num_per_line - (offset - line_start_offset)) * 3 + 2), "");
+ Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, LLDB_INVALID_OFFSET, LLDB_INVALID_ADDRESS, 0, 0);
}
return offset; // Return the offset at which we ended up
}
@@ -1892,12 +1864,12 @@
// string will be used for the supplied "type". If the stream "s"
// is NULL, then the output will be send to Log().
//----------------------------------------------------------------------
-uint32_t
+lldb::offset_t
DataExtractor::PutToLog
(
Log *log,
- uint32_t start_offset,
- uint32_t length,
+ offset_t start_offset,
+ offset_t length,
uint64_t base_addr,
uint32_t num_per_line,
DataExtractor::Type type,
@@ -1907,8 +1879,8 @@
if (log == NULL)
return start_offset;
- uint32_t offset;
- uint32_t end_offset;
+ offset_t offset;
+ offset_t end_offset;
uint32_t count;
StreamString sstr;
for (offset = start_offset, end_offset = offset + length, count = 0; ValidOffset(offset) && offset < end_offset; ++count)
@@ -1923,12 +1895,11 @@
}
// Reset string offset and fill the current line string with address:
if (base_addr != LLDB_INVALID_ADDRESS)
- sstr.Printf("0x%8.8llx:", (uint64_t)(base_addr + (offset - start_offset)));
+ sstr.Printf("0x%8.8" PRIx64 ":", (uint64_t)(base_addr + (offset - start_offset)));
}
switch (type)
{
- default:
case TypeUInt8: sstr.Printf (format ? format : " %2.2x", GetU8(&offset)); break;
case TypeChar:
{
@@ -1938,10 +1909,10 @@
break;
case TypeUInt16: sstr.Printf (format ? format : " %4.4x", GetU16(&offset)); break;
case TypeUInt32: sstr.Printf (format ? format : " %8.8x", GetU32(&offset)); break;
- case TypeUInt64: sstr.Printf (format ? format : " %16.16llx", GetU64(&offset)); break;
- case TypePointer: sstr.Printf (format ? format : " 0x%llx", GetAddress(&offset)); break;
- case TypeULEB128: sstr.Printf (format ? format : " 0x%llx", GetULEB128(&offset)); break;
- case TypeSLEB128: sstr.Printf (format ? format : " %lld", GetSLEB128(&offset)); break;
+ case TypeUInt64: sstr.Printf (format ? format : " %16.16" PRIx64, GetU64(&offset)); break;
+ case TypePointer: sstr.Printf (format ? format : " 0x%" PRIx64, GetAddress(&offset)); break;
+ case TypeULEB128: sstr.Printf (format ? format : " 0x%" PRIx64, GetULEB128(&offset)); break;
+ case TypeSLEB128: sstr.Printf (format ? format : " %" PRId64, GetSLEB128(&offset)); break;
}
}
@@ -1957,7 +1928,7 @@
// Dump out a UUID starting at 'offset' bytes into the buffer
//----------------------------------------------------------------------
void
-DataExtractor::DumpUUID (Stream *s, uint32_t offset) const
+DataExtractor::DumpUUID (Stream *s, offset_t offset) const
{
if (s)
{
@@ -1969,7 +1940,7 @@
}
else
{
- s->Printf("<not enough data for UUID at offset 0x%8.8x>", offset);
+ s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">", offset);
}
}
}
@@ -2040,7 +2011,7 @@
}
bool
-DataExtractor::Append(void* buf, uint32_t length)
+DataExtractor::Append(void* buf, offset_t length)
{
if (buf == NULL)
return false;
Index: aze/lldb/source/Core/DataVisualization.cpp
===================================================================
--- aze.orig/lldb/source/Core/DataVisualization.cpp 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,277 +0,0 @@
-//===-- DataVisualization.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/DataVisualization.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-
-#include "lldb/Core/Debugger.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-static FormatManager&
-GetFormatManager()
-{
- static FormatManager g_format_manager;
- return g_format_manager;
-}
-
-void
-DataVisualization::ForceUpdate ()
-{
- GetFormatManager().Changed();
-}
-
-uint32_t
-DataVisualization::GetCurrentRevision ()
-{
- return GetFormatManager().GetCurrentRevision();
-}
-
-lldb::TypeFormatImplSP
-DataVisualization::ValueFormats::GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
-{
- lldb::TypeFormatImplSP entry;
- GetFormatManager().GetValueNavigator().Get(valobj, entry, use_dynamic);
- return entry;
-}
-
-lldb::TypeFormatImplSP
-DataVisualization::ValueFormats::GetFormat (const ConstString &type)
-{
- lldb::TypeFormatImplSP entry;
- GetFormatManager().GetValueNavigator().Get(type, entry);
- return entry;
-}
-
-void
-DataVisualization::ValueFormats::Add (const ConstString &type, const lldb::TypeFormatImplSP &entry)
-{
- GetFormatManager().GetValueNavigator().Add(FormatManager::GetValidTypeName(type),entry);
-}
-
-bool
-DataVisualization::ValueFormats::Delete (const ConstString &type)
-{
- return GetFormatManager().GetValueNavigator().Delete(type);
-}
-
-void
-DataVisualization::ValueFormats::Clear ()
-{
- GetFormatManager().GetValueNavigator().Clear();
-}
-
-void
-DataVisualization::ValueFormats::LoopThrough (TypeFormatImpl::ValueCallback callback, void* callback_baton)
-{
- GetFormatManager().GetValueNavigator().LoopThrough(callback, callback_baton);
-}
-
-uint32_t
-DataVisualization::ValueFormats::GetCount ()
-{
- return GetFormatManager().GetValueNavigator().GetCount();
-}
-
-lldb::TypeNameSpecifierImplSP
-DataVisualization::ValueFormats::GetTypeNameSpecifierForFormatAtIndex (uint32_t index)
-{
- return GetFormatManager().GetValueNavigator().GetTypeNameSpecifierAtIndex(index);
-}
-
-lldb::TypeFormatImplSP
-DataVisualization::ValueFormats::GetFormatAtIndex (uint32_t index)
-{
- return GetFormatManager().GetValueNavigator().GetAtIndex(index);
-}
-
-lldb::TypeSummaryImplSP
-DataVisualization::GetSummaryFormat (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic)
-{
- return GetFormatManager().GetSummaryFormat(valobj, use_dynamic);
-}
-
-lldb::TypeSummaryImplSP
-DataVisualization::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- return GetFormatManager().GetSummaryForType(type_sp);
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-lldb::SyntheticChildrenSP
-DataVisualization::GetSyntheticChildren (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic)
-{
- return GetFormatManager().GetSyntheticChildren(valobj, use_dynamic);
-}
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
-lldb::SyntheticChildrenSP
-DataVisualization::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- return GetFormatManager().GetSyntheticChildrenForType(type_sp);
-}
-#endif
-
-lldb::TypeFilterImplSP
-DataVisualization::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- return GetFormatManager().GetFilterForType(type_sp);
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-lldb::TypeSyntheticImplSP
-DataVisualization::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- return GetFormatManager().GetSyntheticForType(type_sp);
-}
-#endif
-
-bool
-DataVisualization::AnyMatches (ConstString type_name,
- TypeCategoryImpl::FormatCategoryItems items,
- bool only_enabled,
- const char** matching_category,
- TypeCategoryImpl::FormatCategoryItems* matching_type)
-{
- return GetFormatManager().AnyMatches(type_name,
- items,
- only_enabled,
- matching_category,
- matching_type);
-}
-
-bool
-DataVisualization::Categories::GetCategory (const ConstString &category, lldb::TypeCategoryImplSP &entry,
- bool allow_create)
-{
- entry = GetFormatManager().GetCategory(category, allow_create);
- return (entry.get() != NULL);
-}
-
-void
-DataVisualization::Categories::Add (const ConstString &category)
-{
- GetFormatManager().GetCategory(category);
-}
-
-bool
-DataVisualization::Categories::Delete (const ConstString &category)
-{
- GetFormatManager().DisableCategory(category);
- return GetFormatManager().DeleteCategory(category);
-}
-
-void
-DataVisualization::Categories::Clear ()
-{
- GetFormatManager().ClearCategories();
-}
-
-void
-DataVisualization::Categories::Clear (const ConstString &category)
-{
- GetFormatManager().GetCategory(category)->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
-}
-
-void
-DataVisualization::Categories::Enable (const ConstString& category,
- CategoryMap::Position pos)
-{
- if (GetFormatManager().GetCategory(category)->IsEnabled())
- GetFormatManager().DisableCategory(category);
- GetFormatManager().EnableCategory(category, pos);
-}
-
-void
-DataVisualization::Categories::Disable (const ConstString& category)
-{
- if (GetFormatManager().GetCategory(category)->IsEnabled() == true)
- GetFormatManager().DisableCategory(category);
-}
-
-void
-DataVisualization::Categories::Enable (const lldb::TypeCategoryImplSP& category,
- CategoryMap::Position pos)
-{
- if (category.get())
- {
- if (category->IsEnabled())
- GetFormatManager().DisableCategory(category);
- GetFormatManager().EnableCategory(category, pos);
- }
-}
-
-void
-DataVisualization::Categories::Disable (const lldb::TypeCategoryImplSP& category)
-{
- if (category.get() && category->IsEnabled() == true)
- GetFormatManager().DisableCategory(category);
-}
-
-void
-DataVisualization::Categories::LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton)
-{
- GetFormatManager().LoopThroughCategories(callback, callback_baton);
-}
-
-uint32_t
-DataVisualization::Categories::GetCount ()
-{
- return GetFormatManager().GetCategoriesCount();
-}
-
-lldb::TypeCategoryImplSP
-DataVisualization::Categories::GetCategoryAtIndex (uint32_t index)
-{
- return GetFormatManager().GetCategoryAtIndex(index);
-}
-
-bool
-DataVisualization::NamedSummaryFormats::GetSummaryFormat (const ConstString &type, lldb::TypeSummaryImplSP &entry)
-{
- return GetFormatManager().GetNamedSummaryNavigator().Get(type,entry);
-}
-
-void
-DataVisualization::NamedSummaryFormats::Add (const ConstString &type, const lldb::TypeSummaryImplSP &entry)
-{
- GetFormatManager().GetNamedSummaryNavigator().Add(FormatManager::GetValidTypeName(type),entry);
-}
-
-bool
-DataVisualization::NamedSummaryFormats::Delete (const ConstString &type)
-{
- return GetFormatManager().GetNamedSummaryNavigator().Delete(type);
-}
-
-void
-DataVisualization::NamedSummaryFormats::Clear ()
-{
- GetFormatManager().GetNamedSummaryNavigator().Clear();
-}
-
-void
-DataVisualization::NamedSummaryFormats::LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton)
-{
- GetFormatManager().GetNamedSummaryNavigator().LoopThrough(callback, callback_baton);
-}
-
-uint32_t
-DataVisualization::NamedSummaryFormats::GetCount ()
-{
- return GetFormatManager().GetNamedSummaryNavigator().GetCount();
-}
Index: aze/lldb/source/Core/Debugger.cpp
===================================================================
--- aze.orig/lldb/source/Core/Debugger.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Debugger.cpp 2013-03-03 09:35:50.155457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/API/SBDebugger.h"
#include "lldb/Core/Debugger.h"
@@ -18,8 +20,6 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/ConnectionFileDescriptor.h"
-#include "lldb/Core/DataVisualization.h"
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/InputReader.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
@@ -31,6 +31,8 @@
#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Host/DynamicLibrary.h"
#include "lldb/Host/Terminal.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -548,6 +550,7 @@
m_input_file (),
m_output_file (),
m_error_file (),
+ m_terminal_state (),
m_target_list (*this),
m_platform_list (),
m_listener ("lldb.Debugger"),
@@ -604,10 +607,7 @@
{
ProcessSP process_sp (target_sp->GetProcessSP());
if (process_sp)
- {
- if (process_sp->GetShouldDetach())
- process_sp->Detach();
- }
+ process_sp->Finalize();
target_sp->Destroy();
}
}
@@ -615,6 +615,7 @@
// Close the input file _before_ we close the input read communications class
// as it does NOT own the input file, our m_input_file does.
+ m_terminal_state.Clear();
GetInputFile().Close ();
// Now that we have closed m_input_file, we can now tell our input communication
// class to close down. Its read thread should quickly exit after we close
@@ -662,7 +663,10 @@
// want to objects trying to own and close a file descriptor.
m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), false));
m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
-
+
+ // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
+ SaveInputTerminalState ();
+
Error error;
if (m_input_comm.StartReadThread (&error) == false)
{
@@ -698,6 +702,20 @@
err_file.SetStream (stderr, false);
}
+void
+Debugger::SaveInputTerminalState ()
+{
+ File &in_file = GetInputFile();
+ if (in_file.GetDescriptor() != File::kInvalidDescriptor)
+ m_terminal_state.Save(in_file.GetDescriptor(), true);
+}
+
+void
+Debugger::RestoreInputTerminalState ()
+{
+ m_terminal_state.Restore();
+}
+
ExecutionContext
Debugger::GetSelectedExecutionContext ()
{
@@ -978,7 +996,7 @@
CommandInterpreter::eBroadcastBitAsynchronousErrorData));
}
-uint32_t
+size_t
Debugger::GetNumDebuggers()
{
if (g_shared_debugger_refcount > 0)
@@ -990,7 +1008,7 @@
}
lldb::DebuggerSP
-Debugger::GetDebuggerAtIndex (uint32_t index)
+Debugger::GetDebuggerAtIndex (size_t index)
{
DebuggerSP debugger_sp;
@@ -1187,7 +1205,7 @@
*index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
*index_higher = *index_lower;
if (log)
- log->Printf("[ScanBracketedRange] [%lld] detected, high index is same", *index_lower);
+ log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", *index_lower);
}
else if (*close_bracket_position && *close_bracket_position < var_name_end)
{
@@ -1195,7 +1213,7 @@
*index_lower = ::strtoul (*open_bracket_position+1, &end, 0);
*index_higher = ::strtoul (*separator_position+1, &end, 0);
if (log)
- log->Printf("[ScanBracketedRange] [%lld-%lld] detected", *index_lower, *index_higher);
+ log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", *index_lower, *index_higher);
}
else
{
@@ -1207,7 +1225,7 @@
{
if (log)
log->Printf("[ScanBracketedRange] swapping indices");
- int temp = *index_lower;
+ int64_t temp = *index_lower;
*index_lower = *index_higher;
*index_higher = temp;
}
@@ -1219,22 +1237,22 @@
static ValueObjectSP
ExpandIndexedExpression (ValueObject* valobj,
- uint32_t index,
+ size_t index,
StackFrame* frame,
bool deref_pointer)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
const char* ptr_deref_format = "[%d]";
- std::auto_ptr<char> ptr_deref_buffer(new char[10]);
- ::sprintf(ptr_deref_buffer.get(), ptr_deref_format, index);
+ std::string ptr_deref_buffer(10,0);
+ ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index);
if (log)
- log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.get());
+ log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
const char* first_unparsed;
ValueObject::GetValueForExpressionPathOptions options;
ValueObject::ExpressionPathEndResultType final_value_type;
ValueObject::ExpressionPathScanEndReason reason_to_stop;
ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
- ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.get(),
+ ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
&first_unparsed,
&reason_to_stop,
&final_value_type,
@@ -1460,15 +1478,14 @@
&index_higher);
Error error;
-
- std::auto_ptr<char> expr_path(new char[var_name_final-var_name_begin-1]);
- ::memset(expr_path.get(), 0, var_name_final-var_name_begin-1);
- memcpy(expr_path.get(), var_name_begin+3,var_name_final-var_name_begin-3);
-
+
+ std::string expr_path(var_name_final-var_name_begin-1,0);
+ memcpy(&expr_path[0], var_name_begin+3,var_name_final-var_name_begin-3);
+
if (log)
- log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.get());
+ log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
- target = valobj->GetValueForExpressionPath(expr_path.get(),
+ target = valobj->GetValueForExpressionPath(expr_path.c_str(),
&first_unparsed,
&reason_to_stop,
&final_value_type,
@@ -1530,7 +1547,7 @@
}
// TODO use flags for these
- bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
+ bool is_array = ClangASTContext::IsArrayType(target->GetClangType(), NULL, NULL, NULL);
bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
bool is_aggregate = ClangASTContext::IsAggregateType(target->GetClangType());
@@ -1642,7 +1659,7 @@
if (!item)
{
if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %lld", index_lower);
+ log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index_lower);
}
else
{
@@ -1898,7 +1915,7 @@
var_name_begin += ::strlen ("process.");
if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
{
- s.Printf("%llu", process->GetID());
+ s.Printf("%" PRIu64, process->GetID());
var_success = true;
}
else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
@@ -1936,7 +1953,7 @@
var_name_begin += ::strlen ("thread.");
if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
{
- s.Printf("0x%4.4llx", thread->GetID());
+ s.Printf("0x%4.4" PRIx64, thread->GetID());
var_success = true;
}
else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
@@ -2144,7 +2161,7 @@
if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
{
if (sc->function)
- s.Printf("function{0x%8.8llx}", sc->function->GetID());
+ s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
else
s.Printf("symbol[%u]", sc->symbol->GetID());
@@ -2248,12 +2265,12 @@
ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
const char *var_name = var_value_sp->GetName().GetCString();
const char *var_value = var_value_sp->GetValueAsCString();
+ if (arg_idx > 0)
+ s.PutCString (", ");
if (var_value_sp->GetError().Success())
- {
- if (arg_idx > 0)
- s.PutCString (", ");
s.Printf ("%s=%s", var_name, var_value);
- }
+ else
+ s.Printf ("%s=<unavailable>", var_name);
}
if (close_paren)
@@ -2430,9 +2447,9 @@
addr_t func_file_addr = func_addr.GetFileAddress();
addr_t addr_file_addr = format_addr.GetFileAddress();
if (addr_file_addr > func_file_addr)
- s.Printf(" + %llu", addr_file_addr - func_file_addr);
+ s.Printf(" + %" PRIu64, addr_file_addr - func_file_addr);
else if (addr_file_addr < func_file_addr)
- s.Printf(" - %llu", func_file_addr - addr_file_addr);
+ s.Printf(" - %" PRIu64, func_file_addr - addr_file_addr);
var_success = true;
}
else
@@ -2443,9 +2460,9 @@
addr_t func_load_addr = func_addr.GetLoadAddress (target);
addr_t addr_load_addr = format_addr.GetLoadAddress (target);
if (addr_load_addr > func_load_addr)
- s.Printf(" + %llu", addr_load_addr - func_load_addr);
+ s.Printf(" + %" PRIu64, addr_load_addr - func_load_addr);
else if (addr_load_addr < func_load_addr)
- s.Printf(" - %llu", func_load_addr - addr_load_addr);
+ s.Printf(" - %" PRIu64, func_load_addr - addr_load_addr);
var_success = true;
}
}
@@ -2465,7 +2482,7 @@
int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
if (addr_width == 0)
addr_width = 16;
- s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
+ s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
var_success = true;
}
}
@@ -2518,8 +2535,7 @@
unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
if (octal_value <= UINT8_MAX)
{
- char octal_char = octal_value;
- s.Write (&octal_char, 1);
+ s.PutChar((char)octal_value);
}
}
break;
@@ -2542,7 +2558,7 @@
unsigned long hex_value = strtoul (hex_str, NULL, 16);
if (hex_value <= UINT8_MAX)
- s.PutChar (hex_value);
+ s.PutChar ((char)hex_value);
}
else
{
@@ -2593,13 +2609,13 @@
else
{
LogStreamMap::iterator pos = m_log_streams.find(log_file);
- if (pos == m_log_streams.end())
+ if (pos != m_log_streams.end())
+ log_stream_sp = pos->second.lock();
+ if (!log_stream_sp)
{
log_stream_sp.reset (new StreamFile (log_file));
m_log_streams[log_file] = log_stream_sp;
}
- else
- log_stream_sp = pos->second;
}
assert (log_stream_sp.get());
Index: aze/lldb/source/Core/Disassembler.cpp
===================================================================
--- aze.orig/lldb/source/Core/Disassembler.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Disassembler.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Core/Disassembler.h"
// C Includes
@@ -43,7 +45,7 @@
DisassemblerSP
-Disassembler::FindPlugin (const ArchSpec &arch, const char *plugin_name)
+Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
@@ -57,7 +59,7 @@
create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (plugin_name);
if (create_callback)
{
- DisassemblerSP disassembler_sp(create_callback(arch));
+ DisassemblerSP disassembler_sp(create_callback(arch, flavor));
if (disassembler_sp.get())
return disassembler_sp;
@@ -67,7 +69,7 @@
{
for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- DisassemblerSP disassembler_sp(create_callback(arch));
+ DisassemblerSP disassembler_sp(create_callback(arch, flavor));
if (disassembler_sp.get())
return disassembler_sp;
@@ -76,6 +78,20 @@
return DisassemblerSP();
}
+DisassemblerSP
+Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
+{
+ if (target_sp && flavor == NULL)
+ {
+ // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
+ // we only support flavors on x86 & x86_64,
+ if (arch.GetTriple().getArch() == llvm::Triple::x86
+ || arch.GetTriple().getArch() == llvm::Triple::x86_64)
+ flavor = target_sp->GetDisassemblyFlavor();
+ }
+ return FindPlugin(arch, flavor, plugin_name);
+}
+
static void
ResolveAddress (const ExecutionContext &exe_ctx,
@@ -112,6 +128,7 @@
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
SymbolContextList &sc_list,
uint32_t num_instructions,
@@ -135,6 +152,7 @@
if (Disassemble (debugger,
arch,
plugin_name,
+ flavor,
exe_ctx,
range,
num_instructions,
@@ -156,6 +174,7 @@
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const ConstString &name,
Module *module,
@@ -202,6 +221,7 @@
return Disassemble (debugger,
arch,
plugin_name,
+ flavor,
exe_ctx,
sc_list,
num_instructions,
@@ -218,6 +238,7 @@
(
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &range
)
@@ -225,7 +246,7 @@
lldb::DisassemblerSP disasm_sp;
if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
{
- disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
+ disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
if (disasm_sp)
{
@@ -242,6 +263,7 @@
(
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const Address &start,
const void *bytes,
size_t length,
@@ -252,7 +274,7 @@
if (bytes)
{
- disasm_sp = Disassembler::FindPlugin(arch, plugin_name);
+ disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
if (disasm_sp)
{
@@ -276,6 +298,7 @@
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const AddressRange &disasm_range,
uint32_t num_instructions,
@@ -286,7 +309,7 @@
{
if (disasm_range.GetByteSize())
{
- lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
+ lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
if (disasm_sp.get())
{
@@ -317,6 +340,7 @@
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
const Address &start_address,
uint32_t num_instructions,
@@ -327,7 +351,7 @@
{
if (num_instructions > 0)
{
- lldb::DisassemblerSP disasm_sp (Disassembler::FindPlugin(arch, plugin_name));
+ lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
if (disasm_sp.get())
{
Address addr;
@@ -443,7 +467,7 @@
}
else
{
- sc.Clear();
+ sc.Clear(true);
}
}
@@ -471,6 +495,7 @@
Debugger &debugger,
const ArchSpec &arch,
const char *plugin_name,
+ const char *flavor,
const ExecutionContext &exe_ctx,
uint32_t num_instructions,
uint32_t num_mixed_context_lines,
@@ -504,6 +529,7 @@
return Disassemble (debugger,
arch,
plugin_name,
+ flavor,
exe_ctx,
range,
num_instructions,
@@ -539,7 +565,7 @@
bool show_bytes,
const ExecutionContext* exe_ctx)
{
- const size_t opcode_column_width = 7;
+ size_t opcode_column_width = 7;
const size_t operand_column_width = 25;
CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
@@ -582,9 +608,17 @@
const size_t opcode_pos = ss.GetSize();
+ // The default opcode size of 7 characters is plenty for most architectures
+ // but some like arm can pull out the occasional vqrshrun.s16. We won't get
+ // consistent column spacing in these cases, unfortunately.
+ if (m_opcode_name.length() >= opcode_column_width)
+ {
+ opcode_column_width = m_opcode_name.length() + 1;
+ }
+
ss.PutCString (m_opcode_name.c_str());
ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
- ss.PutCString (m_mnemocics.c_str());
+ ss.PutCString (m_mnemonics.c_str());
if (!m_comment.empty())
{
@@ -628,7 +662,7 @@
std::string line (buffer);
- int len = line.size();
+ size_t len = line.size();
if (line[len-1] == '\n')
{
line[len-1] = '\0';
@@ -696,7 +730,7 @@
// Check to see if the line contains the end-of-dictionary marker ("}")
std::string line (buffer);
- int len = line.size();
+ size_t len = line.size();
if (line[len-1] == '\n')
{
line[len-1] = '\0';
@@ -766,7 +800,7 @@
}
else
{
- int len = value.size();
+ size_t len = value.size();
if ((value[0] == '"') && (value[len-1] == '"'))
value = value.substr (1, len-2);
value_sp.reset (new OptionValueString (value.c_str(), ""));
@@ -935,7 +969,7 @@
InstructionSP
-InstructionList::GetInstructionAtIndex (uint32_t idx) const
+InstructionList::GetInstructionAtIndex (size_t idx) const
{
InstructionSP inst_sp;
if (idx < m_instructions.size())
@@ -997,9 +1031,9 @@
{
Address address;
address.SetLoadAddress(load_addr, &target);
- uint32_t num_instructions = m_instructions.size();
+ size_t num_instructions = m_instructions.size();
uint32_t index = UINT32_MAX;
- for (int i = 0; i < num_instructions; i++)
+ for (size_t i = 0; i < num_instructions; i++)
{
if (m_instructions[i]->GetAddress() == address)
{
@@ -1111,12 +1145,16 @@
//----------------------------------------------------------------------
// Disassembler copy constructor
//----------------------------------------------------------------------
-Disassembler::Disassembler(const ArchSpec& arch) :
+Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
m_arch (arch),
m_instruction_list(),
- m_base_addr(LLDB_INVALID_ADDRESS)
+ m_base_addr(LLDB_INVALID_ADDRESS),
+ m_flavor ()
{
-
+ if (flavor == NULL)
+ m_flavor.assign("default");
+ else
+ m_flavor.assign(flavor);
}
//----------------------------------------------------------------------
@@ -1161,7 +1199,7 @@
size_t
PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
const lldb_private::DataExtractor &data,
- uint32_t data_offset)
+ lldb::offset_t data_offset)
{
return m_opcode.GetByteSize();
}
Index: aze/lldb/source/Core/DynamicLoader.cpp
===================================================================
--- aze.orig/lldb/source/Core/DynamicLoader.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/DynamicLoader.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -9,6 +9,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/Process.h"
#include "lldb/Core/PluginManager.h"
using namespace lldb;
@@ -45,8 +46,7 @@
// DynamicLoader constructor
//----------------------------------------------------------------------
DynamicLoader::DynamicLoader(Process *process) :
- m_process (process),
- m_stop_when_images_change(false) // Stop the process by default when a process' images change
+ m_process (process)
{
}
@@ -64,12 +64,12 @@
bool
DynamicLoader::GetStopWhenImagesChange () const
{
- return m_stop_when_images_change;
+ return m_process->GetStopOnSharedLibraryEvents();
}
void
DynamicLoader::SetStopWhenImagesChange (bool stop)
{
- m_stop_when_images_change = stop;
+ m_process->SetStopOnSharedLibraryEvents (stop);
}
Index: aze/lldb/source/Core/EmulateInstruction.cpp
===================================================================
--- aze.orig/lldb/source/Core/EmulateInstruction.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/EmulateInstruction.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -186,7 +186,7 @@
size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
if (bytes_read == byte_size)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
uval64 = data.GetMaxU64 (&offset, byte_size);
success = true;
@@ -361,7 +361,7 @@
size_t length)
{
StreamFile strm (stdout, false);
- strm.Printf (" Read from Memory (address = 0x%llx, length = %llu, context = ", addr, (uint64_t)length);
+ strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
context.Dump (strm, instruction);
strm.EOL();
*((uint64_t *) dst) = 0xdeadbeef;
@@ -377,7 +377,7 @@
size_t length)
{
StreamFile strm (stdout, false);
- strm.Printf (" Write to Memory (address = 0x%llx, length = %llu, context = ", addr, (uint64_t)length);
+ strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
context.Dump (strm, instruction);
strm.EOL();
return length;
@@ -503,7 +503,7 @@
{
case eInfoTypeRegisterPlusOffset:
{
- strm.Printf (" (reg_plus_offset = %s%+lld)",
+ strm.Printf (" (reg_plus_offset = %s%+" PRId64 ")",
info.RegisterPlusOffset.reg.name,
info.RegisterPlusOffset.signed_offset);
}
@@ -519,7 +519,7 @@
case eInfoTypeRegisterToRegisterPlusOffset:
{
- strm.Printf (" (base_and_imm_offset = %s%+lld, data_reg = %s)",
+ strm.Printf (" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
info.RegisterToRegisterPlusOffset.base_reg.name,
info.RegisterToRegisterPlusOffset.offset,
info.RegisterToRegisterPlusOffset.data_reg.name);
@@ -544,7 +544,7 @@
break;
case eInfoTypeOffset:
- strm.Printf (" (signed_offset = %+lld)", info.signed_offset);
+ strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
break;
case eInfoTypeRegister:
@@ -552,19 +552,19 @@
break;
case eInfoTypeImmediate:
- strm.Printf (" (unsigned_immediate = %llu (0x%16.16llx))",
+ strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
info.unsigned_immediate,
info.unsigned_immediate);
break;
case eInfoTypeImmediateSigned:
- strm.Printf (" (signed_immediate = %+lld (0x%16.16llx))",
+ strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
info.signed_immediate,
info.signed_immediate);
break;
case eInfoTypeAddress:
- strm.Printf (" (address = 0x%llx)", info.address);
+ strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
break;
case eInfoTypeISAAndImmediate:
@@ -587,10 +587,6 @@
case eInfoTypeNoArgs:
break;
-
- default:
- strm.Printf (" (unknown <info_type>)");
- break;
}
}
Index: aze/lldb/source/Core/Error.cpp
===================================================================
--- aze.orig/lldb/source/Core/Error.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Error.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -356,7 +356,7 @@
// allocated buffer above
va_list copy_args;
va_copy (copy_args, args);
- size_t length = ::vsnprintf (buf.data(), buf.size(), format, args);
+ unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args);
if (length >= buf.size())
{
// The error formatted string didn't fit into our buffer, resize it
Index: aze/lldb/source/Core/FileSpecList.cpp
===================================================================
--- aze.orig/lldb/source/Core/FileSpecList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/FileSpecList.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -106,17 +106,16 @@
// Returns the valid index of the file that matches "file_spec" if
// it is found, else UINT32_MAX is returned.
//------------------------------------------------------------------
-uint32_t
-FileSpecList::FindFileIndex (uint32_t start_idx, const FileSpec &file_spec, bool full) const
+size_t
+FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full) const
{
- const uint32_t num_files = m_files.size();
- uint32_t idx;
+ const size_t num_files = m_files.size();
// When looking for files, we will compare only the filename if the
// FILE_SPEC argument is empty
bool compare_filename_only = file_spec.GetDirectory().IsEmpty();
- for (idx = start_idx; idx < num_files; ++idx)
+ for (size_t idx = start_idx; idx < num_files; ++idx)
{
if (compare_filename_only)
{
@@ -139,7 +138,7 @@
// range, then an empty FileSpec object will be returned.
//------------------------------------------------------------------
const FileSpec &
-FileSpecList::GetFileSpecAtIndex(uint32_t idx) const
+FileSpecList::GetFileSpecAtIndex(size_t idx) const
{
if (idx < m_files.size())
@@ -149,7 +148,7 @@
}
const FileSpec *
-FileSpecList::GetFileSpecPointerAtIndex(uint32_t idx) const
+FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const
{
if (idx < m_files.size())
return &m_files[idx];
@@ -179,7 +178,7 @@
//------------------------------------------------------------------
// Return the number of files in the file spec list.
//------------------------------------------------------------------
-uint32_t
+size_t
FileSpecList::GetSize() const
{
return m_files.size();
Index: aze/lldb/source/Core/FormatClasses.cpp
===================================================================
--- aze.orig/lldb/source/Core/FormatClasses.cpp 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,407 +0,0 @@
-//===-- FormatClasses.cpp ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-
-// C++ Includes
-
-// Other libraries and framework includes
-
-// Project includes
-#include "lldb/lldb-public.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/FormatClasses.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Core/Timer.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Target/StackFrame.h"
-#include "lldb/Target/Target.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-TypeFormatImpl::TypeFormatImpl (lldb::Format f,
- const Flags& flags) :
- m_flags(flags),
- m_format (f)
-{
-}
-
-std::string
-TypeFormatImpl::GetDescription()
-{
- StreamString sstr;
- sstr.Printf ("%s%s%s%s\n",
- FormatManager::GetFormatAsCString (GetFormat()),
- Cascades() ? "" : " (not cascading)",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "");
- return sstr.GetString();
-}
-
-TypeSummaryImpl::TypeSummaryImpl(const TypeSummaryImpl::Flags& flags) :
- m_flags(flags)
-{
-}
-
-
-StringSummaryFormat::StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
- const char *format_cstr) :
- TypeSummaryImpl(flags),
- m_format()
-{
- if (format_cstr)
- m_format.assign(format_cstr);
-}
-
-bool
-StringSummaryFormat::FormatObject(ValueObject *valobj,
- std::string& retval)
-{
- if (!valobj)
- {
- retval.assign("NULL ValueObject");
- return false;
- }
-
- StreamString s;
- ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
- SymbolContext sc;
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
- sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
-
- if (IsOneliner())
- {
- ValueObject* object;
-
- ValueObjectSP synth_valobj = valobj->GetSyntheticValue();
- if (synth_valobj)
- object = synth_valobj.get();
- else
- object = valobj;
-
- const uint32_t num_children = object->GetNumChildren();
- if (num_children)
- {
- s.PutChar('(');
-
- for (uint32_t idx=0; idx<num_children; ++idx)
- {
- lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
- if (child_sp.get())
- {
- if (idx)
- s.PutCString(", ");
- if (!HideNames())
- {
- s.PutCString(child_sp.get()->GetName().AsCString());
- s.PutCString(" = ");
- }
- child_sp.get()->DumpPrintableRepresentation(s,
- ValueObject::eValueObjectRepresentationStyleSummary,
- lldb::eFormatInvalid,
- ValueObject::ePrintableRepresentationSpecialCasesDisable);
- }
- }
-
- s.PutChar(')');
-
- retval.assign(s.GetString());
- return true;
- }
- else
- {
- retval.assign("error: oneliner for no children");
- return false;
- }
-
- }
- else
- {
- if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, valobj))
- {
- retval.assign(s.GetString());
- return true;
- }
- else
- {
- retval.assign("error: summary string parsing error");
- return false;
- }
- }
-}
-
-std::string
-StringSummaryFormat::GetDescription()
-{
- StreamString sstr;
-
- sstr.Printf ("`%s`%s%s%s%s%s%s%s", m_format.c_str(),
- Cascades() ? "" : " (not cascading)",
- !DoesPrintChildren() ? "" : " (show children)",
- !DoesPrintValue() ? " (hide value)" : "",
- IsOneliner() ? " (one-line printout)" : "",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "",
- HideNames() ? " (hide member names)" : "");
- return sstr.GetString();
-}
-
-CXXFunctionSummaryFormat::CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
- Callback impl,
- const char* description) :
- TypeSummaryImpl(flags),
- m_impl(impl),
- m_description(description ? description : "")
-{
-}
-
-bool
-CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj,
- std::string& dest)
-{
- dest.clear();
- StreamString stream;
- if (!m_impl || m_impl(*valobj,stream) == false)
- return false;
- dest.assign(stream.GetData());
- return true;
-}
-
-std::string
-CXXFunctionSummaryFormat::GetDescription()
-{
- StreamString sstr;
- sstr.Printf ("`%s (%p) `%s%s%s%s%s%s%s", m_description.c_str(),m_impl,
- Cascades() ? "" : " (not cascading)",
- !DoesPrintChildren() ? "" : " (show children)",
- !DoesPrintValue() ? " (hide value)" : "",
- IsOneliner() ? " (one-line printout)" : "",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "",
- HideNames() ? " (hide member names)" : "");
- return sstr.GetString();
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-
-
-ScriptSummaryFormat::ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
- const char * function_name,
- const char * python_script) :
- TypeSummaryImpl(flags),
- m_function_name(),
- m_python_script(),
- m_script_function_sp()
-{
- if (function_name)
- m_function_name.assign(function_name);
- if (python_script)
- m_python_script.assign(python_script);
-}
-
-bool
-ScriptSummaryFormat::FormatObject(ValueObject *valobj,
- std::string& retval)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
-
- TargetSP target_sp(valobj->GetTargetSP());
-
- if (!target_sp)
- {
- retval.assign("error: no target");
- return false;
- }
-
- ScriptInterpreter *script_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
-
- if (!script_interpreter)
- {
- retval.assign("error: no ScriptInterpreter");
- return false;
- }
-
- return script_interpreter->GetScriptedSummary(m_function_name.c_str(),
- valobj->GetSP(),
- m_script_function_sp,
- retval);
-
-}
-
-std::string
-ScriptSummaryFormat::GetDescription()
-{
- StreamString sstr;
- sstr.Printf ("%s%s%s%s%s%s%s\n%s", Cascades() ? "" : " (not cascading)",
- !DoesPrintChildren() ? "" : " (show children)",
- !DoesPrintValue() ? " (hide value)" : "",
- IsOneliner() ? " (one-line printout)" : "",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "",
- HideNames() ? " (hide member names)" : "",
- m_python_script.c_str());
- return sstr.GetString();
-
-}
-
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
-std::string
-TypeFilterImpl::GetDescription()
-{
- StreamString sstr;
- sstr.Printf("%s%s%s {\n",
- Cascades() ? "" : " (not cascading)",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "");
-
- for (int i = 0; i < GetCount(); i++)
- {
- sstr.Printf(" %s\n",
- GetExpressionPathAtIndex(i));
- }
-
- sstr.Printf("}");
- return sstr.GetString();
-}
-
-std::string
-CXXSyntheticChildren::GetDescription()
-{
- StreamString sstr;
- sstr.Printf("%s%s%s Generator at %p - %s\n",
- Cascades() ? "" : " (not cascading)",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "",
- m_create_callback,
- m_description.c_str());
-
- return sstr.GetString();
-}
-
-std::string
-SyntheticArrayView::GetDescription()
-{
- StreamString sstr;
- sstr.Printf("%s%s%s {\n",
- Cascades() ? "" : " (not cascading)",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "");
-
- SyntheticArrayRange* ptr = &m_head;
- while (ptr && ptr != m_tail)
- {
- if (ptr->GetLow() == ptr->GetHigh())
- sstr.Printf(" [%d]\n",
- ptr->GetLow());
- else
- sstr.Printf(" [%d-%d]\n",
- ptr->GetLow(),
- ptr->GetHigh());
- ptr = ptr->GetNext();
- }
-
- sstr.Printf("}");
- return sstr.GetString();
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-
-TypeSyntheticImpl::FrontEnd::FrontEnd(std::string pclass, ValueObject &backend) :
- SyntheticChildrenFrontEnd(backend),
- m_python_class(pclass),
- m_wrapper_sp(),
- m_interpreter(NULL)
-{
- if (backend == LLDB_INVALID_UID)
- return;
-
- TargetSP target_sp = backend.GetTargetSP();
-
- if (!target_sp)
- return;
-
- m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
-
- if (m_interpreter != NULL)
- m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(m_python_class, backend.GetSP());
-}
-
-TypeSyntheticImpl::FrontEnd::~FrontEnd()
-{
-}
-
-lldb::ValueObjectSP
-TypeSyntheticImpl::FrontEnd::GetChildAtIndex (uint32_t idx)
-{
- if (!m_wrapper_sp || !m_interpreter)
- return lldb::ValueObjectSP();
-
- return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx);
-}
-
-std::string
-TypeSyntheticImpl::GetDescription()
-{
- StreamString sstr;
- sstr.Printf("%s%s%s Python class %s",
- Cascades() ? "" : " (not cascading)",
- SkipsPointers() ? " (skip pointers)" : "",
- SkipsReferences() ? " (skip references)" : "",
- m_python_class.c_str());
-
- return sstr.GetString();
-}
-
-#endif // #ifndef LLDB_DISABLE_PYTHON
-
-int
-SyntheticArrayView::GetRealIndexForIndex(int i)
-{
- if (i >= GetCount())
- return -1;
-
- SyntheticArrayRange* ptr = &m_head;
-
- int residual = i;
-
- while(ptr && ptr != m_tail)
- {
- if (residual >= ptr->GetSelfCount())
- {
- residual -= ptr->GetSelfCount();
- ptr = ptr->GetNext();
- }
-
- return ptr->GetLow() + residual;
- }
-
- return -1;
-}
-
-uint32_t
-SyntheticArrayView::FrontEnd::GetIndexOfChildWithName (const ConstString &name_cs)
-{
- const char* name_cstr = name_cs.GetCString();
- if (*name_cstr != '[')
- return UINT32_MAX;
- std::string name(name_cstr+1);
- if (name[name.size()-1] != ']')
- return UINT32_MAX;
- name = name.erase(name.size()-1,1);
- int index = Args::StringToSInt32 (name.c_str(), -1);
- if (index < 0)
- return UINT32_MAX;
- return index;
-}
Index: aze/lldb/source/Core/FormatManager.cpp
===================================================================
--- aze.orig/lldb/source/Core/FormatManager.cpp 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,1247 +0,0 @@
-//===-- FormatManager.cpp -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/FormatManager.h"
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-
-#include "lldb/Core/CXXFormatterFunctions.h"
-#include "lldb/Core/Debugger.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-
-struct FormatInfo
-{
- Format format;
- const char format_char; // One or more format characters that can be used for this format.
- const char *format_name; // Long format name that can be used to specify the current format
-};
-
-static FormatInfo
-g_format_infos[] =
-{
- { eFormatDefault , '\0' , "default" },
- { eFormatBoolean , 'B' , "boolean" },
- { eFormatBinary , 'b' , "binary" },
- { eFormatBytes , 'y' , "bytes" },
- { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
- { eFormatChar , 'c' , "character" },
- { eFormatCharPrintable , 'C' , "printable character" },
- { eFormatComplexFloat , 'F' , "complex float" },
- { eFormatCString , 's' , "c-string" },
- { eFormatDecimal , 'd' , "decimal" },
- { eFormatEnum , 'E' , "enumeration" },
- { eFormatHex , 'x' , "hex" },
- { eFormatHexUppercase , 'X' , "uppercase hex" },
- { eFormatFloat , 'f' , "float" },
- { eFormatOctal , 'o' , "octal" },
- { eFormatOSType , 'O' , "OSType" },
- { eFormatUnicode16 , 'U' , "unicode16" },
- { eFormatUnicode32 , '\0' , "unicode32" },
- { eFormatUnsigned , 'u' , "unsigned decimal" },
- { eFormatPointer , 'p' , "pointer" },
- { eFormatVectorOfChar , '\0' , "char[]" },
- { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
- { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
- { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
- { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
- { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
- { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
- { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
- { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
- { eFormatVectorOfFloat32, '\0' , "float32[]" },
- { eFormatVectorOfFloat64, '\0' , "float64[]" },
- { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
- { eFormatComplexInteger , 'I' , "complex integer" },
- { eFormatCharArray , 'a' , "character array" },
- { eFormatAddressInfo , 'A' , "address" },
- { eFormatHexFloat , '\0' , "hex float" },
- { eFormatInstruction , 'i' , "instruction" },
- { eFormatVoid , 'v' , "void" }
-};
-
-static uint32_t
-g_num_format_infos = sizeof(g_format_infos)/sizeof(FormatInfo);
-
-static bool
-GetFormatFromFormatChar (char format_char, Format &format)
-{
- for (uint32_t i=0; i<g_num_format_infos; ++i)
- {
- if (g_format_infos[i].format_char == format_char)
- {
- format = g_format_infos[i].format;
- return true;
- }
- }
- format = eFormatInvalid;
- return false;
-}
-
-static bool
-GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
-{
- uint32_t i;
- for (i=0; i<g_num_format_infos; ++i)
- {
- if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
- {
- format = g_format_infos[i].format;
- return true;
- }
- }
-
- if (partial_match_ok)
- {
- for (i=0; i<g_num_format_infos; ++i)
- {
- if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
- {
- format = g_format_infos[i].format;
- return true;
- }
- }
- }
- format = eFormatInvalid;
- return false;
-}
-
-bool
-FormatManager::GetFormatFromCString (const char *format_cstr,
- bool partial_match_ok,
- lldb::Format &format)
-{
- bool success = false;
- if (format_cstr && format_cstr[0])
- {
- if (format_cstr[1] == '\0')
- {
- success = GetFormatFromFormatChar (format_cstr[0], format);
- if (success)
- return true;
- }
-
- success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
- }
- if (!success)
- format = eFormatInvalid;
- return success;
-}
-
-char
-FormatManager::GetFormatAsFormatChar (lldb::Format format)
-{
- for (uint32_t i=0; i<g_num_format_infos; ++i)
- {
- if (g_format_infos[i].format == format)
- return g_format_infos[i].format_char;
- }
- return '\0';
-}
-
-
-
-const char *
-FormatManager::GetFormatAsCString (Format format)
-{
- if (format >= eFormatDefault && format < kNumFormats)
- return g_format_infos[format].format_name;
- return NULL;
-}
-
-TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
- ConstString name) :
- m_summary_nav(new SummaryNavigator("summary",clist)),
- m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
- m_filter_nav(new FilterNavigator("filter",clist)),
- m_regex_filter_nav(new RegexFilterNavigator("regex-filter",clist)),
-#ifndef LLDB_DISABLE_PYTHON
- m_synth_nav(new SynthNavigator("synth",clist)),
- m_regex_synth_nav(new RegexSynthNavigator("regex-synth",clist)),
-#endif
- m_enabled(false),
- m_change_listener(clist),
- m_mutex(Mutex::eMutexTypeRecursive),
- m_name(name)
-{}
-
-bool
-TypeCategoryImpl::Get (ValueObject& valobj,
- lldb::TypeSummaryImplSP& entry,
- lldb::DynamicValueType use_dynamic,
- uint32_t* reason)
-{
- if (!IsEnabled())
- return false;
- if (GetSummaryNavigator()->Get(valobj, entry, use_dynamic, reason))
- return true;
- bool regex = GetRegexSummaryNavigator()->Get(valobj, entry, use_dynamic, reason);
- if (regex && reason)
- *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
- return regex;
-}
-
-bool
-TypeCategoryImpl::Get(ValueObject& valobj,
- lldb::SyntheticChildrenSP& entry_sp,
- lldb::DynamicValueType use_dynamic,
- uint32_t* reason)
-{
- if (!IsEnabled())
- return false;
- TypeFilterImpl::SharedPointer filter_sp;
- uint32_t reason_filter = 0;
- bool regex_filter = false;
- // first find both Filter and Synth, and then check which is most recent
-
- if (!GetFilterNavigator()->Get(valobj, filter_sp, use_dynamic, &reason_filter))
- regex_filter = GetRegexFilterNavigator()->Get (valobj, filter_sp, use_dynamic, &reason_filter);
-
-#ifndef LLDB_DISABLE_PYTHON
- bool regex_synth = false;
- uint32_t reason_synth = 0;
- bool pick_synth = false;
- TypeSyntheticImpl::SharedPointer synth;
- if (!GetSyntheticNavigator()->Get(valobj, synth, use_dynamic, &reason_synth))
- regex_synth = GetRegexSyntheticNavigator()->Get (valobj, synth, use_dynamic, &reason_synth);
- if (!filter_sp.get() && !synth.get())
- return false;
- else if (!filter_sp.get() && synth.get())
- pick_synth = true;
-
- else if (filter_sp.get() && !synth.get())
- pick_synth = false;
-
- else /*if (filter_sp.get() && synth.get())*/
- {
- if (filter_sp->GetRevision() > synth->GetRevision())
- pick_synth = false;
- else
- pick_synth = true;
- }
- if (pick_synth)
- {
- if (regex_synth && reason)
- *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
- entry_sp = synth;
- return true;
- }
- else
- {
- if (regex_filter && reason)
- *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
- entry_sp = filter_sp;
- return true;
- }
-
-#else
- if (filter_sp)
- {
- entry_sp = filter_sp;
- return true;
- }
-#endif
-
- return false;
-
-}
-
-void
-TypeCategoryImpl::Clear (FormatCategoryItems items)
-{
- if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
- m_summary_nav->Clear();
- if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
- m_regex_summary_nav->Clear();
- if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
- m_filter_nav->Clear();
- if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
- m_regex_filter_nav->Clear();
-#ifndef LLDB_DISABLE_PYTHON
- if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
- m_synth_nav->Clear();
- if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
- m_regex_synth_nav->Clear();
-#endif
-}
-
-bool
-TypeCategoryImpl::Delete (ConstString name,
- FormatCategoryItems items)
-{
- bool success = false;
- if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
- success = m_summary_nav->Delete(name) || success;
- if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
- success = m_regex_summary_nav->Delete(name) || success;
- if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
- success = m_filter_nav->Delete(name) || success;
- if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
- success = m_regex_filter_nav->Delete(name) || success;
-#ifndef LLDB_DISABLE_PYTHON
- if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
- success = m_synth_nav->Delete(name) || success;
- if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
- success = m_regex_synth_nav->Delete(name) || success;
-#endif
- return success;
-}
-
-uint32_t
-TypeCategoryImpl::GetCount (FormatCategoryItems items)
-{
- uint32_t count = 0;
- if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
- count += m_summary_nav->GetCount();
- if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
- count += m_regex_summary_nav->GetCount();
- if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
- count += m_filter_nav->GetCount();
- if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
- count += m_regex_filter_nav->GetCount();
-#ifndef LLDB_DISABLE_PYTHON
- if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
- count += m_synth_nav->GetCount();
- if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
- count += m_regex_synth_nav->GetCount();
-#endif
- return count;
-}
-
-bool
-TypeCategoryImpl::AnyMatches(ConstString type_name,
- FormatCategoryItems items,
- bool only_enabled,
- const char** matching_category,
- FormatCategoryItems* matching_type)
-{
- if (!IsEnabled() && only_enabled)
- return false;
-
- lldb::TypeSummaryImplSP summary;
- TypeFilterImpl::SharedPointer filter;
-#ifndef LLDB_DISABLE_PYTHON
- TypeSyntheticImpl::SharedPointer synth;
-#endif
-
- if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
- {
- if (m_summary_nav->Get(type_name, summary))
- {
- if (matching_category)
- *matching_category = m_name.GetCString();
- if (matching_type)
- *matching_type = eFormatCategoryItemSummary;
- return true;
- }
- }
- if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
- {
- if (m_regex_summary_nav->Get(type_name, summary))
- {
- if (matching_category)
- *matching_category = m_name.GetCString();
- if (matching_type)
- *matching_type = eFormatCategoryItemRegexSummary;
- return true;
- }
- }
- if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
- {
- if (m_filter_nav->Get(type_name, filter))
- {
- if (matching_category)
- *matching_category = m_name.GetCString();
- if (matching_type)
- *matching_type = eFormatCategoryItemFilter;
- return true;
- }
- }
- if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
- {
- if (m_regex_filter_nav->Get(type_name, filter))
- {
- if (matching_category)
- *matching_category = m_name.GetCString();
- if (matching_type)
- *matching_type = eFormatCategoryItemRegexFilter;
- return true;
- }
- }
-#ifndef LLDB_DISABLE_PYTHON
- if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
- {
- if (m_synth_nav->Get(type_name, synth))
- {
- if (matching_category)
- *matching_category = m_name.GetCString();
- if (matching_type)
- *matching_type = eFormatCategoryItemSynth;
- return true;
- }
- }
- if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
- {
- if (m_regex_synth_nav->Get(type_name, synth))
- {
- if (matching_category)
- *matching_category = m_name.GetCString();
- if (matching_type)
- *matching_type = eFormatCategoryItemRegexSynth;
- return true;
- }
- }
-#endif
- return false;
-}
-
-bool
-CategoryMap::AnyMatches (ConstString type_name,
- TypeCategoryImpl::FormatCategoryItems items,
- bool only_enabled,
- const char** matching_category,
- TypeCategoryImpl::FormatCategoryItems* matching_type)
-{
- Mutex::Locker locker(m_map_mutex);
-
- MapIterator pos, end = m_map.end();
- for (pos = m_map.begin(); pos != end; pos++)
- {
- if (pos->second->AnyMatches(type_name,
- items,
- only_enabled,
- matching_category,
- matching_type))
- return true;
- }
- return false;
-}
-
-lldb::TypeSummaryImplSP
-CategoryMap::GetSummaryFormat (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic)
-{
- Mutex::Locker locker(m_map_mutex);
-
- uint32_t reason_why;
- ActiveCategoriesIterator begin, end = m_active_categories.end();
-
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
-
- for (begin = m_active_categories.begin(); begin != end; begin++)
- {
- lldb::TypeCategoryImplSP category_sp = *begin;
- lldb::TypeSummaryImplSP current_format;
- if (log)
- log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s\n", category_sp->GetName());
- if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
- continue;
- return current_format;
- }
- if (log)
- log->Printf("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP\n");
- return lldb::TypeSummaryImplSP();
-}
-
-lldb::TypeSummaryImplSP
-FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- if (!type_sp)
- return lldb::TypeSummaryImplSP();
- lldb::TypeSummaryImplSP summary_chosen_sp;
- uint32_t num_categories = m_categories_map.GetCount();
- lldb::TypeCategoryImplSP category_sp;
- uint32_t prio_category = UINT32_MAX;
- for (uint32_t category_id = 0;
- category_id < num_categories;
- category_id++)
- {
- category_sp = GetCategoryAtIndex(category_id);
- if (category_sp->IsEnabled() == false)
- continue;
- lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
- if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
- {
- prio_category = category_sp->GetEnabledPosition();
- summary_chosen_sp = summary_current_sp;
- }
- }
- return summary_chosen_sp;
-}
-
-lldb::TypeFilterImplSP
-FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- if (!type_sp)
- return lldb::TypeFilterImplSP();
- lldb::TypeFilterImplSP filter_chosen_sp;
- uint32_t num_categories = m_categories_map.GetCount();
- lldb::TypeCategoryImplSP category_sp;
- uint32_t prio_category = UINT32_MAX;
- for (uint32_t category_id = 0;
- category_id < num_categories;
- category_id++)
- {
- category_sp = GetCategoryAtIndex(category_id);
- if (category_sp->IsEnabled() == false)
- continue;
- lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
- if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
- {
- prio_category = category_sp->GetEnabledPosition();
- filter_chosen_sp = filter_current_sp;
- }
- }
- return filter_chosen_sp;
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-lldb::TypeSyntheticImplSP
-FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- if (!type_sp)
- return lldb::TypeSyntheticImplSP();
- lldb::TypeSyntheticImplSP synth_chosen_sp;
- uint32_t num_categories = m_categories_map.GetCount();
- lldb::TypeCategoryImplSP category_sp;
- uint32_t prio_category = UINT32_MAX;
- for (uint32_t category_id = 0;
- category_id < num_categories;
- category_id++)
- {
- category_sp = GetCategoryAtIndex(category_id);
- if (category_sp->IsEnabled() == false)
- continue;
- lldb::TypeSyntheticImplSP synth_current_sp((TypeSyntheticImpl*)category_sp->GetSyntheticForType(type_sp).get());
- if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
- {
- prio_category = category_sp->GetEnabledPosition();
- synth_chosen_sp = synth_current_sp;
- }
- }
- return synth_chosen_sp;
-}
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
-lldb::SyntheticChildrenSP
-FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
-{
- if (!type_sp)
- return lldb::SyntheticChildrenSP();
- lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
- lldb::TypeSyntheticImplSP synth_sp = GetSyntheticForType(type_sp);
- if (filter_sp->GetRevision() > synth_sp->GetRevision())
- return lldb::SyntheticChildrenSP(filter_sp.get());
- else
- return lldb::SyntheticChildrenSP(synth_sp.get());
-}
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
-lldb::SyntheticChildrenSP
-CategoryMap::GetSyntheticChildren (ValueObject& valobj,
- lldb::DynamicValueType use_dynamic)
-{
- Mutex::Locker locker(m_map_mutex);
-
- uint32_t reason_why;
-
- ActiveCategoriesIterator begin, end = m_active_categories.end();
-
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
-
- for (begin = m_active_categories.begin(); begin != end; begin++)
- {
- lldb::TypeCategoryImplSP category_sp = *begin;
- lldb::SyntheticChildrenSP current_format;
- if (log)
- log->Printf("[CategoryMap::GetSyntheticChildren] Trying to use category %s\n", category_sp->GetName());
- if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
- continue;
- return current_format;
- }
- if (log)
- log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP\n");
- return lldb::SyntheticChildrenSP();
-}
-#endif
-
-void
-CategoryMap::LoopThrough(CallbackType callback, void* param)
-{
- if (callback)
- {
- Mutex::Locker locker(m_map_mutex);
-
- // loop through enabled categories in respective order
- {
- ActiveCategoriesIterator begin, end = m_active_categories.end();
- for (begin = m_active_categories.begin(); begin != end; begin++)
- {
- lldb::TypeCategoryImplSP category = *begin;
- ConstString type = ConstString(category->GetName());
- if (!callback(param, category))
- break;
- }
- }
-
- // loop through disabled categories in just any order
- {
- MapIterator pos, end = m_map.end();
- for (pos = m_map.begin(); pos != end; pos++)
- {
- if (pos->second->IsEnabled())
- continue;
- KeyType type = pos->first;
- if (!callback(param, pos->second))
- break;
- }
- }
- }
-}
-
-TypeCategoryImplSP
-CategoryMap::GetAtIndex (uint32_t index)
-{
- Mutex::Locker locker(m_map_mutex);
-
- if (index < m_map.size())
- {
- MapIterator pos, end = m_map.end();
- for (pos = m_map.begin(); pos != end; pos++)
- {
- if (index == 0)
- return pos->second;
- index--;
- }
- }
-
- return TypeCategoryImplSP();
-}
-
-lldb::TypeCategoryImplSP
-FormatManager::GetCategory (const ConstString& category_name,
- bool can_create)
-{
- if (!category_name)
- return GetCategory(m_default_category_name);
- lldb::TypeCategoryImplSP category;
- if (m_categories_map.Get(category_name, category))
- return category;
-
- if (!can_create)
- return lldb::TypeCategoryImplSP();
-
- m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
- return GetCategory(category_name);
-}
-
-lldb::Format
-FormatManager::GetSingleItemFormat(lldb::Format vector_format)
-{
- switch(vector_format)
- {
- case eFormatVectorOfChar:
- return eFormatCharArray;
-
- case eFormatVectorOfSInt8:
- case eFormatVectorOfSInt16:
- case eFormatVectorOfSInt32:
- case eFormatVectorOfSInt64:
- return eFormatDecimal;
-
- case eFormatVectorOfUInt8:
- case eFormatVectorOfUInt16:
- case eFormatVectorOfUInt32:
- case eFormatVectorOfUInt64:
- case eFormatVectorOfUInt128:
- return eFormatHex;
-
- case eFormatVectorOfFloat32:
- case eFormatVectorOfFloat64:
- return eFormatFloat;
-
- default:
- return lldb::eFormatInvalid;
- }
-}
-
-ConstString
-FormatManager::GetValidTypeName (const ConstString& type)
-{
- return ::GetValidTypeName_Impl(type);
-}
-
-FormatManager::FormatManager() :
- m_value_nav("format",this),
- m_named_summaries_map(this),
- m_last_revision(0),
- m_categories_map(this),
- m_default_category_name(ConstString("default")),
- m_system_category_name(ConstString("system")),
- m_gnu_cpp_category_name(ConstString("gnu-libstdc++")),
- m_libcxx_category_name(ConstString("libcxx")),
- m_objc_category_name(ConstString("objc")),
- m_corefoundation_category_name(ConstString("CoreFoundation")),
- m_coregraphics_category_name(ConstString("CoreGraphics")),
- m_coreservices_category_name(ConstString("CoreServices")),
- m_vectortypes_category_name(ConstString("VectorTypes")),
- m_appkit_category_name(ConstString("AppKit"))
-{
-
- LoadSystemFormatters();
- LoadSTLFormatters();
- LoadLibcxxFormatters();
- LoadObjCFormatters();
-
- EnableCategory(m_objc_category_name,CategoryMap::Last);
- EnableCategory(m_corefoundation_category_name,CategoryMap::Last);
- EnableCategory(m_appkit_category_name,CategoryMap::Last);
- EnableCategory(m_coreservices_category_name,CategoryMap::Last);
- EnableCategory(m_coregraphics_category_name,CategoryMap::Last);
- EnableCategory(m_gnu_cpp_category_name,CategoryMap::Last);
- EnableCategory(m_libcxx_category_name,CategoryMap::Last);
- EnableCategory(m_vectortypes_category_name,CategoryMap::Last);
- EnableCategory(m_system_category_name,CategoryMap::Last);
-}
-
-void
-FormatManager::LoadSTLFormatters()
-{
- TypeSummaryImpl::Flags stl_summary_flags;
- stl_summary_flags.SetCascades(true)
- .SetSkipPointers(false)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags,
- "${var._M_dataplus._M_p}"));
-
- TypeCategoryImpl::SharedPointer gnu_category_sp = GetCategory(m_gnu_cpp_category_name);
-
- gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::string"),
- std_string_summary_sp);
- gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char>"),
- std_string_summary_sp);
- gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
- std_string_summary_sp);
- gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
- std_string_summary_sp);
-
-
-#ifndef LLDB_DISABLE_PYTHON
-
- SyntheticChildren::Flags stl_synth_flags;
- stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
-
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
- gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
-
- stl_summary_flags.SetDontShowChildren(false);
- gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
- "size=${svar%#}")));
- gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
- "size=${svar%#}")));
- gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
- "size=${svar%#}")));
-#endif
-}
-
-void
-FormatManager::LoadLibcxxFormatters()
-{
- TypeSummaryImpl::Flags stl_summary_flags;
- stl_summary_flags.SetCascades(true)
- .SetSkipPointers(false)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
-#ifndef LLDB_DISABLE_PYTHON
- std::string code(" lldb.formatters.cpp.libcxx.stdstring_SummaryProvider(valobj,internal_dict)");
- lldb::TypeSummaryImplSP std_string_summary_sp(new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.libcxx.stdstring_SummaryProvider",code.c_str()));
-
- TypeCategoryImpl::SharedPointer libcxx_category_sp = GetCategory(m_libcxx_category_name);
-
- libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::string"),
- std_string_summary_sp);
- libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"),
- std_string_summary_sp);
-
- SyntheticChildren::Flags stl_synth_flags;
- stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
-
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdvector_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdlist_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdmap_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)shared_ptr<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
- libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)weak_ptr<.+>(( )?&)?$")),
- SyntheticChildrenSP(new TypeSyntheticImpl(stl_synth_flags,
- "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
-
- stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::deque<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::shared_ptr<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "{${var.__ptr_%S}} (strong=${var.count} weak=${var.weak_count})")));
- libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::weak_ptr<.+>(( )?&)?$")),
- TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "{${var.__ptr_%S}} (strong=${var.count} weak=${var.weak_count})")));
-
-#endif
-}
-
-void
-FormatManager::LoadSystemFormatters()
-{
- lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
- .SetSkipPointers(true)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(false)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false),
- "${var%s}"));
-
-
- lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
- .SetSkipPointers(true)
- .SetSkipReferences(false)
- .SetDontShowChildren(false)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false),
- "${var%s}"));
-
- lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
-
- TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
-
- sys_category_sp->GetSummaryNavigator()->Add(ConstString("char *"), string_format);
- sys_category_sp->GetSummaryNavigator()->Add(ConstString("const char *"), string_format);
- sys_category_sp->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format);
-
- lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
- .SetSkipPointers(true)
- .SetSkipReferences(true)
- .SetDontShowChildren(true)
- .SetDontShowValue(false)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false),
- "${var%O}"));
-
- sys_category_sp->GetSummaryNavigator()->Add(ConstString("OSType"), ostype_summary);
-}
-
-static void
-AddSummary(TypeCategoryImpl::SharedPointer category_sp,
- const char* string,
- ConstString type_name,
- TypeSummaryImpl::Flags flags)
-{
- lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags,
- string));
- category_sp->GetSummaryNavigator()->Add(type_name,
- summary_sp);
-}
-
-#ifndef LLDB_DISABLE_PYTHON
-static void
-AddScriptSummary(TypeCategoryImpl::SharedPointer category_sp,
- const char* funct_name,
- ConstString type_name,
- TypeSummaryImpl::Flags flags)
-{
-
- std::string code(" ");
- code.append(funct_name).append("(valobj,internal_dict)");
-
- lldb::TypeSummaryImplSP summary_sp(new ScriptSummaryFormat(flags,
- funct_name,
- code.c_str()));
- category_sp->GetSummaryNavigator()->Add(type_name,
- summary_sp);
-}
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
-static void
-AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp,
- CXXFunctionSummaryFormat::Callback funct,
- const char* description,
- ConstString type_name,
- TypeSummaryImpl::Flags flags)
-{
- lldb::TypeSummaryImplSP summary_sp(new CXXFunctionSummaryFormat(flags,funct,description));
- category_sp->GetSummaryNavigator()->Add(type_name,
- summary_sp);
-}
-#endif
-
-#ifndef LLDB_DISABLE_PYTHON
-static void AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp,
- CXXSyntheticChildren::CreateFrontEndCallback generator,
- const char* description,
- ConstString type_name,
- TypeSyntheticImpl::Flags flags)
-{
- lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator));
- category_sp->GetSyntheticNavigator()->Add(type_name,synth_sp);
-}
-#endif
-
-void
-FormatManager::LoadObjCFormatters()
-{
- TypeSummaryImpl::Flags objc_flags;
- objc_flags.SetCascades(false)
- .SetSkipPointers(true)
- .SetSkipReferences(true)
- .SetDontShowChildren(true)
- .SetDontShowValue(true)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- TypeCategoryImpl::SharedPointer objc_category_sp = GetCategory(m_objc_category_name);
-
- lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider,""));
- objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL"),
- ObjC_BOOL_summary);
- objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL &"),
- ObjC_BOOL_summary);
- objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL *"),
- ObjC_BOOL_summary);
-
-#ifndef LLDB_DISABLE_PYTHON
- // we need to skip pointers here since we are special casing a SEL* when retrieving its value
- objc_flags.SetSkipPointers(true);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("SEL"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("struct objc_selector"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary", ConstString("objc_selector"), objc_flags);
- AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary", ConstString("objc_selector *"), objc_flags);
-
- AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Class.Class_Summary", ConstString("Class"), objc_flags);
-#endif // LLDB_DISABLE_PYTHON
-
- objc_flags.SetSkipPointers(false);
-
- TypeCategoryImpl::SharedPointer corefoundation_category_sp = GetCategory(m_corefoundation_category_name);
-
- AddSummary(corefoundation_category_sp,
- "${var.years} years, ${var.months} months, ${var.days} days, ${var.hours} hours, ${var.minutes} minutes ${var.seconds} seconds",
- ConstString("CFGregorianUnits"),
- objc_flags);
- AddSummary(corefoundation_category_sp,
- "location=${var.location} length=${var.length}",
- ConstString("CFRange"),
- objc_flags);
- AddSummary(corefoundation_category_sp,
- "(x=${var.x}, y=${var.y})",
- ConstString("NSPoint"),
- objc_flags);
- AddSummary(corefoundation_category_sp,
- "location=${var.location}, length=${var.length}",
- ConstString("NSRange"),
- objc_flags);
- AddSummary(corefoundation_category_sp,
- "${var.origin}, ${var.size}",
- ConstString("NSRect"),
- objc_flags);
- AddSummary(corefoundation_category_sp,
- "(${var.origin}, ${var.size}), ...",
- ConstString("NSRectArray"),
- objc_flags);
- AddSummary(objc_category_sp,
- "(width=${var.width}, height=${var.height})",
- ConstString("NSSize"),
- objc_flags);
-
- TypeCategoryImpl::SharedPointer coregraphics_category_sp = GetCategory(m_coregraphics_category_name);
-
- AddSummary(coregraphics_category_sp,
- "(width=${var.width}, height=${var.height})",
- ConstString("CGSize"),
- objc_flags);
- AddSummary(coregraphics_category_sp,
- "(x=${var.x}, y=${var.y})",
- ConstString("CGPoint"),
- objc_flags);
- AddSummary(coregraphics_category_sp,
- "origin=${var.origin} size=${var.size}",
- ConstString("CGRect"),
- objc_flags);
-
- TypeCategoryImpl::SharedPointer coreservices_category_sp = GetCategory(m_coreservices_category_name);
-
- AddSummary(coreservices_category_sp,
- "red=${var.red} green=${var.green} blue=${var.blue}",
- ConstString("RGBColor"),
- objc_flags);
- AddSummary(coreservices_category_sp,
- "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
- ConstString("Rect"),
- objc_flags);
- AddSummary(coreservices_category_sp,
- "(v=${var.v}, h=${var.h})",
- ConstString("Point"),
- objc_flags);
- AddSummary(coreservices_category_sp,
- "${var.month}/${var.day}/${var.year} ${var.hour} :${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
- ConstString("DateTimeRect *"),
- objc_flags);
- AddSummary(coreservices_category_sp,
- "${var.ld.month}/${var.ld.day}/${var.ld.year} ${var.ld.hour} :${var.ld.minute} :${var.ld.second} dayOfWeek:${var.ld.dayOfWeek}",
- ConstString("LongDateRect"),
- objc_flags);
- AddSummary(coreservices_category_sp,
- "(x=${var.x}, y=${var.y})",
- ConstString("HIPoint"),
- objc_flags);
- AddSummary(coreservices_category_sp,
- "origin=${var.origin} size=${var.size}",
- ConstString("HIRect"),
- objc_flags);
-
- TypeCategoryImpl::SharedPointer appkit_category_sp = GetCategory(m_appkit_category_name);
-
- TypeSummaryImpl::Flags appkit_flags;
- appkit_flags.SetCascades(true)
- .SetSkipPointers(false)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(false)
- .SetShowMembersOneLiner(false)
- .SetHideItemNames(false);
-
- appkit_flags.SetDontShowChildren(false);
-
-
-#ifndef LLDB_DISABLE_PYTHON
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
-
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
-
- // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
-
- appkit_flags.SetDontShowChildren(true);
-
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), TypeSyntheticImpl::Flags());
-
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), TypeSyntheticImpl::Flags());
- AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), TypeSyntheticImpl::Flags());
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("__CFBag"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("const struct __CFBag"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFMutableBagRef"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("CFBinaryHeapRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags);
-
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFString.CFAttributedString_SummaryProvider", ConstString("NSAttributedString"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSBundle.NSBundle_SummaryProvider", ConstString("NSBundle"), appkit_flags);
-
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSException.NSException_SummaryProvider", ConstString("NSException"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSMachPort.NSMachPort_SummaryProvider", ConstString("NSMachPort"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSNotification"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags);
-
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
-
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSDecimalNumber summary provider", ConstString("NSDecimalNumber"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSHost summary provider", ConstString("NSHost"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSTask summary provider", ConstString("NSTask"), appkit_flags);
- AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSValue summary provider", ConstString("NSValue"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("NSSet"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider2", ConstString("CFSetRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider2", ConstString("CFMutableSetRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("__NSCFSet"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("__NSSetI"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("__NSSetM"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSSet.NSSet_SummaryProvider", ConstString("NSCountedSet"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSURL.NSURL_SummaryProvider", ConstString("NSURL"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSURL.NSURL_SummaryProvider", ConstString("CFURLRef"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("NSDate"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("__NSDate"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("__NSTaggedDate"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("NSCalendarDate"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSTimeZone_SummaryProvider", ConstString("NSTimeZone"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSTimeZone_SummaryProvider", ConstString("CFTimeZoneRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSTimeZone_SummaryProvider", ConstString("__NSTimeZone"), appkit_flags);
-
- // CFAbsoluteTime is actually a double rather than a pointer to an object
- // we do not care about the numeric value, since it is probably meaningless to users
- appkit_flags.SetDontShowValue(true);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.CFAbsoluteTime_SummaryProvider", ConstString("CFAbsoluteTime"), appkit_flags);
- appkit_flags.SetDontShowValue(false);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSIndexSet.NSIndexSet_SummaryProvider", ConstString("NSIndexSet"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSIndexSet.NSIndexSet_SummaryProvider", ConstString("NSMutableIndexSet"), appkit_flags);
-
- AddSummary(appkit_category_sp, "@\"${var.month%d}/${var.day%d}/${var.year%d} ${var.hour%d}:${var.minute%d}:${var.second}\"", ConstString("CFGregorianDate"), appkit_flags);
-
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("CFBitVectorRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("CFMutableBitVectorRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("__CFBitVector"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("__CFMutableBitVector"), appkit_flags);
-#endif // LLDB_DISABLE_PYTHON
-
- TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
-
- TypeSummaryImpl::Flags vector_flags;
- vector_flags.SetCascades(true)
- .SetSkipPointers(true)
- .SetSkipReferences(false)
- .SetDontShowChildren(true)
- .SetDontShowValue(false)
- .SetShowMembersOneLiner(true)
- .SetHideItemNames(true);
-
- AddSummary(vectors_category_sp,
- "${var.uint128}",
- ConstString("builtin_type_vec128"),
- objc_flags);
-
- AddSummary(vectors_category_sp,
- "",
- ConstString("float [4]"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("int32_t [4]"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("int16_t [8]"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vDouble"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vFloat"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vSInt8"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vSInt16"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vSInt32"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vUInt16"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vUInt8"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vUInt16"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vUInt32"),
- vector_flags);
- AddSummary(vectors_category_sp,
- "",
- ConstString("vBool32"),
- vector_flags);
-}
Index: aze/lldb/source/Core/History.cpp
===================================================================
--- aze.orig/lldb/source/Core/History.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/History.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -10,6 +10,7 @@
#include "lldb/Core/History.h"
// C Includes
+#include <inttypes.h>
// C++ Includes
// Other libraries and framework includes
// Project includes
@@ -21,5 +22,5 @@
void
HistorySourceUInt::DumpHistoryEvent (Stream &strm, HistoryEvent event)
{
- strm.Printf ("%s %llu", m_name.c_str(), (uint64_t)((uintptr_t)event));
+ strm.Printf ("%s %" PRIu64, m_name.c_str(), (uint64_t)((uintptr_t)event));
}
Index: aze/lldb/source/Core/InputReader.cpp
===================================================================
--- aze.orig/lldb/source/Core/InputReader.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/InputReader.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include <string>
#include "lldb/Core/InputReader.h"
Index: aze/lldb/source/Core/Listener.cpp
===================================================================
--- aze.orig/lldb/source/Core/Listener.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Listener.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -411,12 +411,24 @@
while (1)
{
+ // Note, we don't want to lock the m_events_mutex in the call to GetNextEventInternal, since the DoOnRemoval
+ // code might require that new events be serviced. For instance, the Breakpoint Command's
if (GetNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp))
- return true;
+ return true;
- // Reset condition value to false, so we can wait for new events to be
- // added that might meet our current filter
- m_cond_wait.SetValue (false, eBroadcastNever);
+ {
+ // Reset condition value to false, so we can wait for new events to be
+ // added that might meet our current filter
+ // But first poll for any new event that might satisfy our condition, and if so consume it,
+ // otherwise wait.
+
+ Mutex::Locker event_locker(m_events_mutex);
+ const bool remove = false;
+ if (FindNextEventInternal (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, remove))
+ continue;
+ else
+ m_cond_wait.SetValue (false, eBroadcastNever);
+ }
if (m_cond_wait.WaitForValueEqualTo (true, timeout, &timed_out))
continue;
Index: aze/lldb/source/Core/Log.cpp
===================================================================
--- aze.orig/lldb/source/Core/Log.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Log.cpp 2013-03-03 09:35:50.159457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <pthread.h>
#include <stdio.h>
@@ -100,20 +102,19 @@
if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
{
struct timeval tv = TimeValue::Now().GetAsTimeVal();
- header.Printf ("%9ld.%6.6d ", tv.tv_sec, tv.tv_usec);
+ header.Printf ("%9ld.%6.6d ", tv.tv_sec, (int32_t)tv.tv_usec);
}
// Add the process and thread if requested
if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
- header.Printf ("[%4.4x/%4.4llx]: ", getpid(), Host::GetCurrentThreadID());
+ header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
// Add the process and thread if requested
if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
{
- const char *thread_name_str = Host::GetThreadName (getpid(), Host::GetCurrentThreadID());
- if (thread_name_str)
- header.Printf ("%s ", thread_name_str);
-
+ std::string thread_name (Host::GetThreadName (getpid(), Host::GetCurrentThreadID()));
+ if (!thread_name.empty())
+ header.Printf ("%s ", thread_name.c_str());
}
header.PrintfVarArg (format, args);
Index: aze/lldb/source/Core/Makefile
===================================================================
--- aze.orig/lldb/source/Core/Makefile 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Makefile 2013-03-03 09:35:50.159457354 +0100
@@ -12,3 +12,15 @@
BUILD_ARCHIVE = 1
include $(LLDB_LEVEL)/Makefile
+
+# Enable RTTI on GCC builds because one source file in this directory
+# (cxa_demangle.cpp) uses dynamic_cast<> and GCC (at least 4.6 and 4.7)
+# complain if we try to compile it with -fno-rtti.
+$(info shell basename CXX is $(shell basename $(CXX)))
+ifeq (g++,$(shell basename $(CXX)))
+$(ObjDir)/cxa_demangle.o: Compile.CXX := $(filter-out -fno-rtti,$(Compile.CXX)) -frtti
+endif
+
+ifeq (Darwin,$(shell uname -s))
+$(ObjDir)/cxa_demangle.o: Compile.CXX := $(filter-out -fno-rtti,$(Compile.CXX)) -frtti
+endif
Index: aze/lldb/source/Core/Module.cpp
===================================================================
--- aze.orig/lldb/source/Core/Module.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Module.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Core/Error.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/DataBuffer.h"
@@ -103,7 +105,7 @@
Mutex::Locker locker (Module::GetAllocationModuleCollectionMutex());
ModuleCollection &modules = GetModuleCollection();
const size_t count = modules.size();
- printf ("%s: %llu modules:\n", __PRETTY_FUNCTION__, (uint64_t)count);
+ printf ("%s: %" PRIu64 " modules:\n", __PRETTY_FUNCTION__, (uint64_t)count);
for (size_t i=0; i<count; ++i)
{
@@ -263,7 +265,7 @@
if (m_objfile_sp)
{
StreamString s;
- s.Printf("0x%16.16llx", header_addr);
+ s.Printf("0x%16.16" PRIx64, header_addr);
m_object_name.SetCString (s.GetData());
// Once we get the object file, update our module with the object file's
@@ -344,16 +346,15 @@
Module::ParseAllDebugSymbols()
{
Mutex::Locker locker (m_mutex);
- uint32_t num_comp_units = GetNumCompileUnits();
+ size_t num_comp_units = GetNumCompileUnits();
if (num_comp_units == 0)
return;
SymbolContext sc;
sc.module_sp = shared_from_this();
- uint32_t cu_idx;
SymbolVendor *symbols = GetSymbolVendor ();
- for (cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
+ for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
{
sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
if (sc.comp_unit)
@@ -363,8 +364,7 @@
symbols->ParseCompileUnitFunctions(sc);
- uint32_t func_idx;
- for (func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
+ for (size_t func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != NULL; ++func_idx)
{
symbols->ParseFunctionBlocks(sc);
@@ -398,7 +398,7 @@
s->Printf(", Module{%p}", this);
}
-uint32_t
+size_t
Module::GetNumCompileUnits()
{
Mutex::Locker locker (m_mutex);
@@ -410,10 +410,10 @@
}
CompUnitSP
-Module::GetCompileUnitAtIndex (uint32_t index)
+Module::GetCompileUnitAtIndex (size_t index)
{
Mutex::Locker locker (m_mutex);
- uint32_t num_comp_units = GetNumCompileUnits ();
+ size_t num_comp_units = GetNumCompileUnits ();
CompUnitSP cu_sp;
if (index < num_comp_units)
@@ -429,7 +429,7 @@
Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
{
Mutex::Locker locker (m_mutex);
- Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%llx)", vm_addr);
+ Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")", vm_addr);
ObjectFile* ofile = GetObjectFile();
if (ofile)
return so_addr.ResolveAddressUsingFileSections(vm_addr, ofile->GetSectionList());
@@ -442,8 +442,8 @@
Mutex::Locker locker (m_mutex);
uint32_t resolved_flags = 0;
- // Clear the result symbol context in case we don't find anything
- sc.Clear();
+ // Clear the result symbol context in case we don't find anything, but don't clear the target
+ sc.Clear(false);
// Get the section from the section/offset address.
SectionSP section_sp (so_addr.GetSection());
@@ -527,16 +527,24 @@
}
-uint32_t
-Module::FindGlobalVariables(const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
+size_t
+Module::FindGlobalVariables (const ConstString &name,
+ const ClangNamespaceDecl *namespace_decl,
+ bool append,
+ size_t max_matches,
+ VariableList& variables)
{
SymbolVendor *symbols = GetSymbolVendor ();
if (symbols)
return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables);
return 0;
}
-uint32_t
-Module::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+
+size_t
+Module::FindGlobalVariables (const RegularExpression& regex,
+ bool append,
+ size_t max_matches,
+ VariableList& variables)
{
SymbolVendor *symbols = GetSymbolVendor ();
if (symbols)
@@ -544,7 +552,7 @@
return 0;
}
-uint32_t
+size_t
Module::FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list)
@@ -552,12 +560,12 @@
if (!append)
sc_list.Clear();
- const uint32_t start_size = sc_list.GetSize();
- const uint32_t num_compile_units = GetNumCompileUnits();
+ const size_t start_size = sc_list.GetSize();
+ const size_t num_compile_units = GetNumCompileUnits();
SymbolContext sc;
sc.module_sp = shared_from_this();
const bool compare_directory = path.GetDirectory();
- for (uint32_t i=0; i<num_compile_units; ++i)
+ for (size_t i=0; i<num_compile_units; ++i)
{
sc.comp_unit = GetCompileUnitAtIndex(i).get();
if (sc.comp_unit)
@@ -569,10 +577,10 @@
return sc_list.GetSize() - start_size;
}
-uint32_t
+size_t
Module::FindFunctions (const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
- uint32_t name_type_mask,
+ uint32_t name_type_mask,
bool include_symbols,
bool include_inlines,
bool append,
@@ -581,7 +589,7 @@
if (!append)
sc_list.Clear();
- const uint32_t start_size = sc_list.GetSize();
+ const size_t start_size = sc_list.GetSize();
// Find all the functions (not symbols, but debug information functions...
SymbolVendor *symbols = GetSymbolVendor ();
@@ -598,16 +606,19 @@
if (symtab)
{
std::vector<uint32_t> symbol_indexes;
- symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
- const uint32_t num_matches = symbol_indexes.size();
+ symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
+ const size_t num_matches = symbol_indexes.size();
if (num_matches)
{
const bool merge_symbol_into_function = true;
SymbolContext sc(this);
- for (uint32_t i=0; i<num_matches; i++)
+ for (size_t i=0; i<num_matches; i++)
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- sc_list.AppendIfUnique (sc, merge_symbol_into_function);
+ SymbolType sym_type = sc.symbol->GetType();
+ if (sc.symbol && (sym_type == eSymbolTypeCode ||
+ sym_type == eSymbolTypeResolver))
+ sc_list.AppendIfUnique (sc, merge_symbol_into_function);
}
}
}
@@ -616,7 +627,7 @@
return sc_list.GetSize() - start_size;
}
-uint32_t
+size_t
Module::FindFunctions (const RegularExpression& regex,
bool include_symbols,
bool include_inlines,
@@ -626,7 +637,7 @@
if (!append)
sc_list.Clear();
- const uint32_t start_size = sc_list.GetSize();
+ const size_t start_size = sc_list.GetSize();
SymbolVendor *symbols = GetSymbolVendor ();
if (symbols)
@@ -641,16 +652,19 @@
if (symtab)
{
std::vector<uint32_t> symbol_indexes;
- symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeCode, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
- const uint32_t num_matches = symbol_indexes.size();
+ symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
+ const size_t num_matches = symbol_indexes.size();
if (num_matches)
{
const bool merge_symbol_into_function = true;
SymbolContext sc(this);
- for (uint32_t i=0; i<num_matches; i++)
+ for (size_t i=0; i<num_matches; i++)
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- sc_list.AppendIfUnique (sc, merge_symbol_into_function);
+ SymbolType sym_type = sc.symbol->GetType();
+ if (sc.symbol && (sym_type == eSymbolTypeCode ||
+ sym_type == eSymbolTypeResolver))
+ sc_list.AppendIfUnique (sc, merge_symbol_into_function);
}
}
}
@@ -659,12 +673,12 @@
return sc_list.GetSize() - start_size;
}
-uint32_t
+size_t
Module::FindTypes_Impl (const SymbolContext& sc,
const ConstString &name,
const ClangNamespaceDecl *namespace_decl,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& types)
{
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
@@ -677,25 +691,38 @@
return 0;
}
-uint32_t
+size_t
Module::FindTypesInNamespace (const SymbolContext& sc,
const ConstString &type_name,
const ClangNamespaceDecl *namespace_decl,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& type_list)
{
const bool append = true;
return FindTypes_Impl(sc, type_name, namespace_decl, append, max_matches, type_list);
}
-uint32_t
+lldb::TypeSP
+Module::FindFirstType (const SymbolContext& sc,
+ const ConstString &name,
+ bool exact_match)
+{
+ TypeList type_list;
+ const size_t num_matches = FindTypes (sc, name, exact_match, 1, type_list);
+ if (num_matches)
+ return type_list.GetTypeAtIndex(0);
+ return TypeSP();
+}
+
+
+size_t
Module::FindTypes (const SymbolContext& sc,
const ConstString &name,
bool exact_match,
- uint32_t max_matches,
+ size_t max_matches,
TypeList& types)
{
- uint32_t num_matches = 0;
+ size_t num_matches = 0;
const char *type_name_cstr = name.GetCString();
std::string type_scope;
std::string type_basename;
@@ -741,19 +768,8 @@
}
-//uint32_t
-//Module::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, const char *udt_name, TypeList& types)
-//{
-// Timer scoped_timer(__PRETTY_FUNCTION__);
-// SymbolVendor *symbols = GetSymbolVendor ();
-// if (symbols)
-// return symbols->FindTypes(sc, regex, append, max_matches, encoding, udt_name, types);
-// return 0;
-//
-//}
-
SymbolVendor*
-Module::GetSymbolVendor (bool can_create)
+Module::GetSymbolVendor (bool can_create, lldb_private::Stream *feedback_strm)
{
Mutex::Locker locker (m_mutex);
if (m_did_load_symbol_vendor == false && can_create)
@@ -762,7 +778,7 @@
if (obj_file != NULL)
{
Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this()));
+ m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
m_did_load_symbol_vendor = true;
}
}
@@ -994,12 +1010,14 @@
m_did_load_objfile = true;
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString(""));
- DataBufferSP file_data_sp;
- m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(),
+ DataBufferSP data_sp;
+ lldb::offset_t data_offset = 0;
+ m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(),
&m_file,
m_object_offset,
m_file.GetByteSize(),
- file_data_sp);
+ data_sp,
+ data_offset);
if (m_objfile_sp)
{
// Once we get the object file, update our module with the object file's
@@ -1049,6 +1067,25 @@
}
size_t
+Module::FindFunctionSymbols (const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList& sc_list)
+{
+ Timer scoped_timer(__PRETTY_FUNCTION__,
+ "Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
+ name.AsCString(),
+ name_type_mask);
+ ObjectFile *objfile = GetObjectFile ();
+ if (objfile)
+ {
+ Symtab *symtab = objfile->GetSymtab();
+ if (symtab)
+ return symtab->FindFunctionSymbols (name, name_type_mask, sc_list);
+ }
+ return 0;
+}
+
+size_t
Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
{
// No need to protect this call using m_mutex all other method calls are
@@ -1146,27 +1183,45 @@
return false;
}
- PlatformSP platform_sp(target->GetPlatform());
-
- if (!platform_sp)
+ Debugger &debugger = target->GetDebugger();
+ const ScriptLanguage script_language = debugger.GetScriptLanguage();
+ if (script_language != eScriptLanguageNone)
{
- error.SetErrorString("invalid Platform");
- return false;
- }
+
+ PlatformSP platform_sp(target->GetPlatform());
+
+ if (!platform_sp)
+ {
+ error.SetErrorString("invalid Platform");
+ return false;
+ }
- ModuleSpec module_spec(GetFileSpec());
- FileSpec scripting_fspec = platform_sp->LocateExecutableScriptingResource(module_spec);
- Debugger &debugger(target->GetDebugger());
- if (scripting_fspec && scripting_fspec.Exists())
- {
ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
if (script_interpreter)
{
- StreamString scripting_stream;
- scripting_fspec.Dump(&scripting_stream);
- bool did_load = script_interpreter->LoadScriptingModule(scripting_stream.GetData(), false, true, error);
- if (!did_load)
- return false;
+ FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources (target,
+ *this);
+
+
+ const uint32_t num_specs = file_specs.GetSize();
+ if (num_specs)
+ {
+ for (uint32_t i=0; i<num_specs; ++i)
+ {
+ FileSpec scripting_fspec (file_specs.GetFileSpecAtIndex(i));
+ if (scripting_fspec && scripting_fspec.Exists())
+ {
+
+ StreamString scripting_stream;
+ scripting_fspec.Dump(&scripting_stream);
+ const bool can_reload = false;
+ const bool init_lldb_globals = false;
+ bool did_load = script_interpreter->LoadScriptingModule(scripting_stream.GetData(), can_reload, init_lldb_globals, error);
+ if (!did_load)
+ return false;
+ }
+ }
+ }
}
else
{
@@ -1185,7 +1240,7 @@
m_arch = new_arch;
return true;
}
- return m_arch == new_arch;
+ return m_arch.IsExactMatch(new_arch);
}
bool
@@ -1251,7 +1306,7 @@
const ArchSpec &arch = module_ref.GetArchitecture();
if (arch.IsValid())
{
- if (m_arch != arch)
+ if (!m_arch.IsCompatibleMatch(arch))
return false;
}
Index: aze/lldb/source/Core/ModuleList.cpp
===================================================================
--- aze.orig/lldb/source/Core/ModuleList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ModuleList.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -296,14 +296,14 @@
}
Module*
-ModuleList::GetModulePointerAtIndex (uint32_t idx) const
+ModuleList::GetModulePointerAtIndex (size_t idx) const
{
Mutex::Locker locker(m_modules_mutex);
return GetModulePointerAtIndexUnlocked(idx);
}
Module*
-ModuleList::GetModulePointerAtIndexUnlocked (uint32_t idx) const
+ModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
{
if (idx < m_modules.size())
return m_modules[idx].get();
@@ -311,14 +311,14 @@
}
ModuleSP
-ModuleList::GetModuleAtIndex(uint32_t idx) const
+ModuleList::GetModuleAtIndex(size_t idx) const
{
Mutex::Locker locker(m_modules_mutex);
return GetModuleAtIndexUnlocked(idx);
}
ModuleSP
-ModuleList::GetModuleAtIndexUnlocked(uint32_t idx) const
+ModuleList::GetModuleAtIndexUnlocked(size_t idx) const
{
ModuleSP module_sp;
if (idx < m_modules.size())
@@ -326,7 +326,7 @@
return module_sp;
}
-uint32_t
+size_t
ModuleList::FindFunctions (const ConstString &name,
uint32_t name_type_mask,
bool include_symbols,
@@ -347,7 +347,7 @@
return sc_list.GetSize();
}
-uint32_t
+size_t
ModuleList::FindCompileUnits (const FileSpec &path,
bool append,
SymbolContextList &sc_list) const
@@ -365,10 +365,10 @@
return sc_list.GetSize();
}
-uint32_t
+size_t
ModuleList::FindGlobalVariables (const ConstString &name,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variable_list) const
{
size_t initial_size = variable_list.GetSize();
@@ -382,10 +382,10 @@
}
-uint32_t
+size_t
ModuleList::FindGlobalVariables (const RegularExpression& regex,
bool append,
- uint32_t max_matches,
+ size_t max_matches,
VariableList& variable_list) const
{
size_t initial_size = variable_list.GetSize();
@@ -495,12 +495,12 @@
}
-uint32_t
-ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, uint32_t max_matches, TypeList& types) const
+size_t
+ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, TypeList& types) const
{
Mutex::Locker locker(m_modules_mutex);
- uint32_t total_matches = 0;
+ size_t total_matches = 0;
collection::const_iterator pos, end = m_modules.end();
if (sc.module_sp)
{
@@ -689,7 +689,7 @@
return sc_list.GetSize();
}
-uint32_t
+size_t
ModuleList::GetIndexForModule (const Module *module) const
{
if (module)
@@ -737,7 +737,7 @@
return GetSharedModuleList ().FindModules (module_spec, matching_module_list);
}
-uint32_t
+size_t
ModuleList::RemoveOrphanSharedModules (bool mandatory)
{
return GetSharedModuleList ().RemoveOrphans(mandatory);
@@ -781,7 +781,7 @@
const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
if (num_matching_modules > 0)
{
- for (uint32_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
+ for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
{
module_sp = matching_module_list.GetModuleAtIndex(module_idx);
Index: aze/lldb/source/Core/Opcode.cpp
===================================================================
--- aze.orig/lldb/source/Core/Opcode.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Opcode.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -46,7 +46,7 @@
break;
case Opcode::eType64:
- bytes_written = s->Printf ("0x%16.16llx", m_data.inst64);
+ bytes_written = s->Printf ("0x%16.16" PRIx64, m_data.inst64);
break;
case Opcode::eTypeBytes:
Index: aze/lldb/source/Core/PluginManager.cpp
===================================================================
--- aze.orig/lldb/source/Core/PluginManager.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/PluginManager.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Core/PluginManager.h"
#include <limits.h>
@@ -1344,7 +1346,7 @@
return NULL;
}
-uint32_t
+size_t
PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
{
if (name && name[0])
Index: aze/lldb/source/Core/RegisterValue.cpp
===================================================================
--- aze.orig/lldb/source/Core/RegisterValue.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/RegisterValue.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -301,7 +301,7 @@
}
Error
-RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, uint32_t src_offset, bool partial_data_ok)
+RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_t src_offset, bool partial_data_ok)
{
Error error;
@@ -450,7 +450,6 @@
const uint32_t byte_size = reg_info->byte_size;
switch (reg_info->encoding)
{
- default:
case eEncodingInvalid:
error.SetErrorString ("Invalid encoding.");
break;
@@ -462,7 +461,7 @@
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
else if (!Args::UInt64ValueIsValidForByteSize (uval64, byte_size))
- error.SetErrorStringWithFormat ("value 0x%llx is too large to fit in a %u byte unsigned integer value", uval64, byte_size);
+ error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %u byte unsigned integer value", uval64, byte_size);
else
{
if (!SetUInt (uval64, reg_info->byte_size))
@@ -483,7 +482,7 @@
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
else if (!Args::SInt64ValueIsValidForByteSize (sval64, byte_size))
- error.SetErrorStringWithFormat ("value 0x%llx is too large to fit in a %u byte signed integer value", sval64, byte_size);
+ error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %u byte signed integer value", sval64, byte_size);
else
{
if (!SetUInt (sval64, reg_info->byte_size))
@@ -637,7 +636,6 @@
m_type = rhs.m_type;
switch (m_type)
{
- default:
case eTypeInvalid:
return false;
case eTypeUInt8: m_data.uint8 = rhs.m_data.uint8; break;
Index: aze/lldb/source/Core/RegularExpression.cpp
===================================================================
--- aze.orig/lldb/source/Core/RegularExpression.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/RegularExpression.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/RegularExpression.h"
+#include "llvm/ADT/StringRef.h"
#include <string.h>
using namespace lldb_private;
@@ -146,6 +147,34 @@
}
bool
+RegularExpression::ExecuteThreadSafe (const char* s, llvm::StringRef *match_srefs, size_t count, int execute_flags) const
+{
+ bool success = false;
+ if (m_comp_err == 0)
+ {
+ std::vector<regmatch_t> matches;
+
+ if (match_srefs && count > 0)
+ matches.resize(count + 1);
+
+ success = ::regexec (&m_preg,
+ s,
+ matches.size(),
+ matches.data(),
+ execute_flags) == 0;
+ for (size_t i=0; i<count; ++i)
+ {
+ size_t match_idx = i+1;
+ if (success && matches[match_idx].rm_so < matches[match_idx].rm_eo)
+ match_srefs[i] = llvm::StringRef(s + matches[match_idx].rm_so, matches[match_idx].rm_eo - matches[match_idx].rm_so);
+ else
+ match_srefs[i] = llvm::StringRef();
+ }
+ }
+ return success;
+}
+
+bool
RegularExpression::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
{
if (idx <= m_preg.re_nsub && idx < m_matches.size())
@@ -163,6 +192,46 @@
return true;
}
}
+ return false;
+}
+
+bool
+RegularExpression::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
+{
+ if (idx <= m_preg.re_nsub && idx < m_matches.size())
+ {
+ if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
+ {
+ // Matched the empty string...
+ match_str = llvm::StringRef();
+ return true;
+ }
+ else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
+ {
+ match_str = llvm::StringRef (s + m_matches[idx].rm_so, m_matches[idx].rm_eo - m_matches[idx].rm_so);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+RegularExpression::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
+{
+ if (idx1 <= m_preg.re_nsub && idx1 < m_matches.size() && idx2 <= m_preg.re_nsub && idx2 < m_matches.size())
+ {
+ if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo)
+ {
+ // Matched the empty string...
+ match_str = llvm::StringRef();
+ return true;
+ }
+ else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo)
+ {
+ match_str = llvm::StringRef (s + m_matches[idx1].rm_so, m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
+ return true;
+ }
+ }
return false;
}
Index: aze/lldb/source/Core/Scalar.cpp
===================================================================
--- aze.orig/lldb/source/Core/Scalar.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Scalar.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -10,6 +10,7 @@
#include "lldb/Core/Scalar.h"
#include <math.h>
+#include <inttypes.h>
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Error.h"
@@ -168,7 +169,6 @@
{
switch (m_type)
{
- default:
case e_void:
break;
case e_sint: return sizeof(m_data.sint);
@@ -189,7 +189,6 @@
{
switch (m_type)
{
- default:
case e_void:
break;
case e_sint: return m_data.sint == 0;
@@ -214,7 +213,6 @@
switch (m_type)
{
case e_void:
- default:
break;
case e_sint: s->Printf("%i", m_data.sint); break;
case e_uint: s->Printf("0x%8.8x", m_data.uint); break;
@@ -233,8 +231,6 @@
{
switch (m_type)
{
- default:
- break;
case e_void: return "void";
case e_sint: return "int";
case e_uint: return "unsigned int";
@@ -357,7 +353,6 @@
case e_sint:
switch (type)
{
- default:
case e_void: break;
case e_sint: success = true; break;
case e_uint: m_data.uint = m_data.sint; success = true; break;
@@ -374,7 +369,6 @@
case e_uint:
switch (type)
{
- default:
case e_void:
case e_sint: break;
case e_uint: success = true; break;
@@ -391,7 +385,6 @@
case e_slong:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint: break;
@@ -408,7 +401,6 @@
case e_ulong:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint:
@@ -425,7 +417,6 @@
case e_slonglong:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint:
@@ -442,7 +433,6 @@
case e_ulonglong:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint:
@@ -459,7 +449,6 @@
case e_float:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint:
@@ -476,7 +465,6 @@
case e_double:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint:
@@ -493,7 +481,6 @@
case e_long_double:
switch (type)
{
- default:
case e_void:
case e_sint:
case e_uint:
@@ -518,7 +505,6 @@
{
switch (type)
{
- default: break;
case e_void: return "void";
case e_sint: return "int";
case e_uint: return "unsigned int";
@@ -537,11 +523,11 @@
Scalar::Type
Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
{
- if (byte_size <= sizeof(int))
+ if (byte_size <= sizeof(sint_t))
return e_sint;
- if (byte_size <= sizeof(long))
+ if (byte_size <= sizeof(slong_t))
return e_slong;
- if (byte_size <= sizeof(long long))
+ if (byte_size <= sizeof(slonglong_t))
return e_slonglong;
return e_void;
}
@@ -549,11 +535,11 @@
Scalar::Type
Scalar::GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size)
{
- if (byte_size <= sizeof(unsigned int))
+ if (byte_size <= sizeof(uint_t))
return e_uint;
- if (byte_size <= sizeof(unsigned long))
+ if (byte_size <= sizeof(ulong_t))
return e_ulong;
- if (byte_size <= sizeof(unsigned long long))
+ if (byte_size <= sizeof(ulonglong_t))
return e_ulonglong;
return e_void;
}
@@ -561,11 +547,11 @@
Scalar::Type
Scalar::GetValueTypeForFloatWithByteSize (size_t byte_size)
{
- if (byte_size == sizeof(float))
+ if (byte_size == sizeof(float_t))
return e_float;
- if (byte_size == sizeof(double))
+ if (byte_size == sizeof(double_t))
return e_double;
- if (byte_size == sizeof(long double))
+ if (byte_size == sizeof(long_double_t))
return e_long_double;
return e_void;
}
@@ -582,7 +568,6 @@
case e_sint:
switch (type)
{
- default:
case e_void: break;
case e_sint: success = true; break;
case e_uint: m_data.uint = m_data.sint; success = true; break;
@@ -599,7 +584,6 @@
case e_uint:
switch (type)
{
- default:
case e_void:
case e_sint: m_data.sint = m_data.uint; success = true; break;
case e_uint: success = true; break;
@@ -616,10 +600,9 @@
case e_slong:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.slong; success = true; break;
- case e_uint: m_data.uint = m_data.slong; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.slong; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.slong; success = true; break;
case e_slong: success = true; break;
case e_ulong: m_data.ulong = m_data.slong; success = true; break;
case e_slonglong: m_data.slonglong = m_data.slong; success = true; break;
@@ -633,10 +616,9 @@
case e_ulong:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.ulong; success = true; break;
- case e_uint: m_data.uint = m_data.ulong; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.ulong; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.ulong; success = true; break;
case e_slong: m_data.slong = m_data.ulong; success = true; break;
case e_ulong: success = true; break;
case e_slonglong: m_data.slonglong = m_data.ulong; success = true; break;
@@ -650,10 +632,9 @@
case e_slonglong:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.slonglong; success = true; break;
- case e_uint: m_data.uint = m_data.slonglong; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.slonglong; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.slonglong; success = true; break;
case e_slong: m_data.slong = m_data.slonglong; success = true; break;
case e_ulong: m_data.ulong = m_data.slonglong; success = true; break;
case e_slonglong: success = true; break;
@@ -667,10 +648,9 @@
case e_ulonglong:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.ulonglong; success = true; break;
- case e_uint: m_data.uint = m_data.ulonglong; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.ulonglong; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.ulonglong; success = true; break;
case e_slong: m_data.slong = m_data.ulonglong; success = true; break;
case e_ulong: m_data.ulong = m_data.ulonglong; success = true; break;
case e_slonglong: m_data.slonglong = m_data.ulonglong; success = true; break;
@@ -684,50 +664,47 @@
case e_float:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.flt; success = true; break;
- case e_uint: m_data.uint = m_data.flt; success = true; break;
- case e_slong: m_data.slong = m_data.flt; success = true; break;
- case e_ulong: m_data.ulong = m_data.flt; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.flt; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.flt; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.flt; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.flt; success = true; break;
+ case e_slong: m_data.slong = (slong_t)m_data.flt; success = true; break;
+ case e_ulong: m_data.ulong = (ulong_t)m_data.flt; success = true; break;
+ case e_slonglong: m_data.slonglong = (slonglong_t)m_data.flt; success = true; break;
+ case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.flt; success = true; break;
case e_float: success = true; break;
- case e_double: m_data.dbl = m_data.flt; success = true; break;
- case e_long_double: m_data.ldbl = m_data.flt; success = true; break;
+ case e_double: m_data.dbl = m_data.flt; success = true; break;
+ case e_long_double: m_data.ldbl = m_data.flt; success = true; break;
}
break;
case e_double:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.dbl; success = true; break;
- case e_uint: m_data.uint = m_data.dbl; success = true; break;
- case e_slong: m_data.slong = m_data.dbl; success = true; break;
- case e_ulong: m_data.ulong = m_data.dbl; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.dbl; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.dbl; success = true; break;
- case e_float: m_data.flt = m_data.dbl; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.dbl; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.dbl; success = true; break;
+ case e_slong: m_data.slong = (slong_t)m_data.dbl; success = true; break;
+ case e_ulong: m_data.ulong = (ulong_t)m_data.dbl; success = true; break;
+ case e_slonglong: m_data.slonglong = (slonglong_t)m_data.dbl; success = true; break;
+ case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.dbl; success = true; break;
+ case e_float: m_data.flt = (float_t)m_data.dbl; success = true; break;
case e_double: success = true; break;
- case e_long_double: m_data.ldbl = m_data.dbl; success = true; break;
+ case e_long_double: m_data.ldbl = m_data.dbl; success = true; break;
}
break;
case e_long_double:
switch (type)
{
- default:
case e_void:
- case e_sint: m_data.sint = m_data.ldbl; success = true; break;
- case e_uint: m_data.uint = m_data.ldbl; success = true; break;
- case e_slong: m_data.slong = m_data.ldbl; success = true; break;
- case e_ulong: m_data.ulong = m_data.ldbl; success = true; break;
- case e_slonglong: m_data.slonglong = m_data.ldbl; success = true; break;
- case e_ulonglong: m_data.ulonglong = m_data.ldbl; success = true; break;
- case e_float: m_data.flt = m_data.ldbl; success = true; break;
- case e_double: m_data.dbl = m_data.ldbl; success = true; break;
+ case e_sint: m_data.sint = (sint_t)m_data.ldbl; success = true; break;
+ case e_uint: m_data.uint = (uint_t)m_data.ldbl; success = true; break;
+ case e_slong: m_data.slong = (slong_t)m_data.ldbl; success = true; break;
+ case e_ulong: m_data.ulong = (ulong_t)m_data.ldbl; success = true; break;
+ case e_slonglong: m_data.slonglong = (slonglong_t)m_data.ldbl; success = true; break;
+ case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.ldbl; success = true; break;
+ case e_float: m_data.flt = (float_t)m_data.ldbl; success = true; break;
+ case e_double: m_data.dbl = (double_t)m_data.ldbl; success = true; break;
case e_long_double: success = true; break;
}
break;
@@ -743,7 +720,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return m_data.sint;
case e_uint: return (int)m_data.uint;
@@ -763,7 +739,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (unsigned int)m_data.sint;
case e_uint: return (unsigned int)m_data.uint;
@@ -784,7 +759,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (long)m_data.sint;
case e_uint: return (long)m_data.uint;
@@ -806,7 +780,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (unsigned long)m_data.sint;
case e_uint: return (unsigned long)m_data.uint;
@@ -826,7 +799,6 @@
{
switch (m_type)
{
- default:
case e_void:
break;
@@ -843,29 +815,29 @@
return m_data.ulonglong;
case e_float:
- if (sizeof(m_data.flt) == sizeof(int))
+ if (sizeof(m_data.flt) == sizeof(m_data.uint))
return m_data.uint;
- else if (sizeof(m_data.flt) == sizeof(unsigned long))
+ else if (sizeof(m_data.flt) == sizeof(m_data.ulong))
return m_data.ulong;
- else if (sizeof(m_data.flt) == sizeof(unsigned long long))
+ else if (sizeof(m_data.flt) == sizeof(m_data.ulonglong))
return m_data.ulonglong;
break;
case e_double:
- if (sizeof(m_data.dbl) == sizeof(int))
+ if (sizeof(m_data.dbl) == sizeof(m_data.uint))
return m_data.uint;
- else if (sizeof(m_data.dbl) == sizeof(unsigned long))
+ else if (sizeof(m_data.dbl) == sizeof(m_data.ulong))
return m_data.ulong;
- else if (sizeof(m_data.dbl) == sizeof(unsigned long long))
+ else if (sizeof(m_data.dbl) == sizeof(m_data.ulonglong))
return m_data.ulonglong;
break;
case e_long_double:
- if (sizeof(m_data.ldbl) == sizeof(int))
+ if (sizeof(m_data.ldbl) == sizeof(m_data.uint))
return m_data.uint;
- else if (sizeof(m_data.ldbl) == sizeof(unsigned long))
+ else if (sizeof(m_data.ldbl) == sizeof(m_data.ulong))
return m_data.ulong;
- else if (sizeof(m_data.ldbl) == sizeof(unsigned long long))
+ else if (sizeof(m_data.ldbl) == sizeof(m_data.ulonglong))
return m_data.ulonglong;
break;
}
@@ -879,7 +851,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (long long)m_data.sint;
case e_uint: return (long long)m_data.uint;
@@ -900,7 +871,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (unsigned long long)m_data.sint;
case e_uint: return (unsigned long long)m_data.uint;
@@ -921,7 +891,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (float)m_data.sint;
case e_uint: return (float)m_data.uint;
@@ -942,7 +911,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (double)m_data.sint;
case e_uint: return (double)m_data.uint;
@@ -963,7 +931,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: return (long double)m_data.sint;
case e_uint: return (long double)m_data.uint;
@@ -989,7 +956,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: m_data.sint = a->m_data.sint + b->m_data.sint; break;
case e_uint: m_data.uint = a->m_data.uint + b->m_data.uint; break;
@@ -1010,7 +976,6 @@
{
switch (m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1021,7 +986,6 @@
case e_sint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1040,7 +1004,6 @@
case e_uint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1059,7 +1022,6 @@
case e_slong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1078,7 +1040,6 @@
case e_ulong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1096,7 +1057,6 @@
case e_slonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1115,7 +1075,6 @@
case e_ulonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1139,7 +1098,6 @@
{
switch (m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1151,7 +1109,6 @@
case e_uint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1171,7 +1128,6 @@
case e_ulong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1191,7 +1147,6 @@
case e_ulonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1216,7 +1171,6 @@
{
switch (m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1227,7 +1181,6 @@
case e_sint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1246,7 +1199,6 @@
case e_uint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1265,7 +1217,6 @@
case e_slong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1284,7 +1235,6 @@
case e_ulong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1302,7 +1252,6 @@
case e_slonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1321,7 +1270,6 @@
case e_ulonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1346,7 +1294,6 @@
{
switch (m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1357,7 +1304,6 @@
case e_sint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1376,7 +1322,6 @@
case e_uint:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1395,7 +1340,6 @@
case e_slong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1414,7 +1358,6 @@
case e_ulong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1432,7 +1375,6 @@
case e_slonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1451,7 +1393,6 @@
case e_ulonglong:
switch (rhs.m_type)
{
- default:
case e_void:
case e_float:
case e_double:
@@ -1477,7 +1418,6 @@
{
switch (m_type)
{
- default:
case e_void:
break;
@@ -1512,7 +1452,6 @@
{
switch (m_type)
{
- default:
case e_void: break;
case e_sint: m_data.sint = -m_data.sint; return true;
case e_uint: m_data.uint = -m_data.uint; return true;
@@ -1539,7 +1478,6 @@
case e_slonglong: m_data.slonglong = ~m_data.slonglong; return true;
case e_ulonglong: m_data.ulonglong = ~m_data.ulonglong; return true;
- default:
case e_void:
case e_float:
case e_double:
@@ -1561,7 +1499,6 @@
{
switch (result.m_type)
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: result.m_data.sint = a->m_data.sint + b->m_data.sint; break;
case Scalar::e_uint: result.m_data.uint = a->m_data.uint + b->m_data.uint; break;
@@ -1589,7 +1526,6 @@
{
switch (result.m_type)
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: result.m_data.sint = a->m_data.sint - b->m_data.sint; break;
case Scalar::e_uint: result.m_data.uint = a->m_data.uint - b->m_data.uint; break;
@@ -1616,7 +1552,6 @@
{
switch (result.m_type)
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: if (b->m_data.sint != 0) { result.m_data.sint = a->m_data.sint/ b->m_data.sint; return result; } break;
@@ -1647,7 +1582,6 @@
{
switch (result.m_type)
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: result.m_data.sint = a->m_data.sint * b->m_data.sint; break;
case Scalar::e_uint: result.m_data.uint = a->m_data.uint * b->m_data.uint; break;
@@ -1681,7 +1615,6 @@
case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong & b->m_data.slonglong; break;
case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong & b->m_data.ulonglong; break;
- default:
case Scalar::e_void:
case Scalar::e_float:
case Scalar::e_double:
@@ -1712,7 +1645,6 @@
case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong | b->m_data.slonglong; break;
case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong | b->m_data.ulonglong; break;
- default:
case Scalar::e_void:
case Scalar::e_float:
case Scalar::e_double:
@@ -1743,7 +1675,6 @@
case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong % b->m_data.slonglong; break;
case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong % b->m_data.ulonglong; break;
- default:
case Scalar::e_void:
case Scalar::e_float:
case Scalar::e_double:
@@ -1774,7 +1705,6 @@
case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong ^ b->m_data.slonglong; break;
case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong ^ b->m_data.ulonglong; break;
- default:
case Scalar::e_void:
case Scalar::e_float:
case Scalar::e_double:
@@ -1787,6 +1717,22 @@
return result;
}
+const Scalar
+lldb_private::operator<< (const Scalar& lhs, const Scalar &rhs)
+{
+ Scalar result = lhs;
+ result <<= rhs;
+ return result;
+}
+
+const Scalar
+lldb_private::operator>> (const Scalar& lhs, const Scalar &rhs)
+{
+ Scalar result = lhs;
+ result >>= rhs;
+ return result;
+}
+
// Return the raw unsigned integer without any casting or conversion
unsigned int
Scalar::RawUInt () const
@@ -1810,7 +1756,7 @@
Error
-Scalar::SetValueFromCString (const char *value_str, Encoding encoding, uint32_t byte_size)
+Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t byte_size)
{
Error error;
if (value_str == NULL || value_str[0] == '\0')
@@ -1821,7 +1767,6 @@
bool success = false;
switch (encoding)
{
- default:
case eEncodingInvalid:
error.SetErrorString ("Invalid encoding.");
break;
@@ -1833,24 +1778,24 @@
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
else if (!UIntValueIsValidForSize (uval64, byte_size))
- error.SetErrorStringWithFormat ("value 0x%llx is too large to fit in a %u byte unsigned integer value", uval64, byte_size);
+ error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %zu byte unsigned integer value", uval64, byte_size);
else
{
m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize (byte_size);
switch (m_type)
{
- case e_uint: m_data.uint = uval64; break;
- case e_ulong: m_data.ulong = uval64; break;
- case e_ulonglong: m_data.ulonglong = uval64; break;
+ case e_uint: m_data.uint = (uint_t)uval64; break;
+ case e_ulong: m_data.ulong = (ulong_t)uval64; break;
+ case e_ulonglong: m_data.ulonglong = (ulonglong_t)uval64; break;
default:
- error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %u", byte_size);
+ error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %zu", byte_size);
break;
}
}
}
else
{
- error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %u", byte_size);
+ error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %zu", byte_size);
return error;
}
break;
@@ -1862,24 +1807,24 @@
if (!success)
error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
else if (!SIntValueIsValidForSize (sval64, byte_size))
- error.SetErrorStringWithFormat ("value 0x%llx is too large to fit in a %u byte signed integer value", sval64, byte_size);
+ error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %zu byte signed integer value", sval64, byte_size);
else
{
m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize (byte_size);
switch (m_type)
{
- case e_sint: m_data.sint = sval64; break;
- case e_slong: m_data.slong = sval64; break;
- case e_slonglong: m_data.slonglong = sval64; break;
+ case e_sint: m_data.sint = (sint_t)sval64; break;
+ case e_slong: m_data.slong = (slong_t)sval64; break;
+ case e_slonglong: m_data.slonglong = (slonglong_t)sval64; break;
default:
- error.SetErrorStringWithFormat ("unsupported signed integer byte size: %u", byte_size);
+ error.SetErrorStringWithFormat ("unsupported signed integer byte size: %zu", byte_size);
break;
}
}
}
else
{
- error.SetErrorStringWithFormat ("unsupported signed integer byte size: %u", byte_size);
+ error.SetErrorStringWithFormat ("unsupported signed integer byte size: %zu", byte_size);
return error;
}
break;
@@ -1908,7 +1853,7 @@
}
else
{
- error.SetErrorStringWithFormat ("unsupported float byte size: %u", byte_size);
+ error.SetErrorStringWithFormat ("unsupported float byte size: %zu", byte_size);
return error;
}
break;
@@ -1932,7 +1877,6 @@
{
switch (m_type)
{
- default:
case Scalar::e_void:
case Scalar::e_float:
case Scalar::e_double:
@@ -1991,9 +1935,9 @@
return false;
}
-uint32_t
+size_t
Scalar::GetAsMemoryData (void *dst,
- uint32_t dst_len,
+ size_t dst_len,
lldb::ByteOrder dst_byte_order,
Error &error) const
{
@@ -2008,7 +1952,7 @@
const size_t src_len = data.GetByteSize();
// Prepare a memory buffer that contains some or all of the register value
- const uint32_t bytes_copied = data.CopyByteOrderedData (0, // src offset
+ const size_t bytes_copied = data.CopyByteOrderedData (0, // src offset
src_len, // src length
dst, // dst buffer
dst_len, // dst length
@@ -2030,65 +1974,64 @@
uint32_t lsbit = bit_offset;
switch (m_type)
{
- default:
case Scalar::e_void:
break;
case e_float:
- if (sizeof(m_data.flt) == sizeof(int))
- m_data.sint = SignedBits (m_data.sint, msbit, lsbit);
- else if (sizeof(m_data.flt) == sizeof(unsigned long))
- m_data.slong = SignedBits (m_data.slong, msbit, lsbit);
- else if (sizeof(m_data.flt) == sizeof(unsigned long long))
- m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit);
+ if (sizeof(m_data.flt) == sizeof(sint_t))
+ m_data.sint = (sint_t)SignedBits (m_data.sint, msbit, lsbit);
+ else if (sizeof(m_data.flt) == sizeof(ulong_t))
+ m_data.slong = (slong_t)SignedBits (m_data.slong, msbit, lsbit);
+ else if (sizeof(m_data.flt) == sizeof(ulonglong_t))
+ m_data.slonglong = (slonglong_t)SignedBits (m_data.slonglong, msbit, lsbit);
else
return false;
return true;
case e_double:
- if (sizeof(m_data.dbl) == sizeof(int))
+ if (sizeof(m_data.dbl) == sizeof(sint_t))
m_data.sint = SignedBits (m_data.sint, msbit, lsbit);
- else if (sizeof(m_data.dbl) == sizeof(unsigned long))
+ else if (sizeof(m_data.dbl) == sizeof(ulong_t))
m_data.slong = SignedBits (m_data.slong, msbit, lsbit);
- else if (sizeof(m_data.dbl) == sizeof(unsigned long long))
+ else if (sizeof(m_data.dbl) == sizeof(ulonglong_t))
m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit);
else
return false;
return true;
case e_long_double:
- if (sizeof(m_data.ldbl) == sizeof(int))
+ if (sizeof(m_data.ldbl) == sizeof(sint_t))
m_data.sint = SignedBits (m_data.sint, msbit, lsbit);
- else if (sizeof(m_data.ldbl) == sizeof(unsigned long))
+ else if (sizeof(m_data.ldbl) == sizeof(ulong_t))
m_data.slong = SignedBits (m_data.slong, msbit, lsbit);
- else if (sizeof(m_data.ldbl) == sizeof(unsigned long long))
+ else if (sizeof(m_data.ldbl) == sizeof(ulonglong_t))
m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit);
else
return false;
return true;
case Scalar::e_sint:
- m_data.sint = SignedBits (m_data.sint, msbit, lsbit);
+ m_data.sint = (sint_t)SignedBits (m_data.sint, msbit, lsbit);
return true;
case Scalar::e_uint:
- m_data.uint = UnsignedBits (m_data.uint, msbit, lsbit);
+ m_data.uint = (uint_t)UnsignedBits (m_data.uint, msbit, lsbit);
return true;
case Scalar::e_slong:
- m_data.slong = SignedBits (m_data.slong, msbit, lsbit);
+ m_data.slong = (slong_t)SignedBits (m_data.slong, msbit, lsbit);
return true;
case Scalar::e_ulong:
- m_data.ulong = SignedBits (m_data.ulong, msbit, lsbit);
+ m_data.ulong = (ulong_t)UnsignedBits (m_data.ulong, msbit, lsbit);
return true;
case Scalar::e_slonglong:
- m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit);
+ m_data.slonglong = (slonglong_t)SignedBits (m_data.slonglong, msbit, lsbit);
return true;
case Scalar::e_ulonglong:
- m_data.ulonglong = SignedBits (m_data.ulonglong, msbit, lsbit);
+ m_data.ulonglong = (ulonglong_t)UnsignedBits (m_data.ulonglong, msbit, lsbit);
return true;
}
return false;
@@ -2110,7 +2053,6 @@
const Scalar* b;
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: return a->m_data.sint == b->m_data.sint;
case Scalar::e_uint: return a->m_data.uint == b->m_data.uint;
@@ -2137,7 +2079,6 @@
const Scalar* b;
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: return a->m_data.sint != b->m_data.sint;
case Scalar::e_uint: return a->m_data.uint != b->m_data.uint;
@@ -2163,7 +2104,6 @@
const Scalar* b;
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: return a->m_data.sint < b->m_data.sint;
case Scalar::e_uint: return a->m_data.uint < b->m_data.uint;
@@ -2189,7 +2129,6 @@
const Scalar* b;
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: return a->m_data.sint <= b->m_data.sint;
case Scalar::e_uint: return a->m_data.uint <= b->m_data.uint;
@@ -2216,7 +2155,6 @@
const Scalar* b;
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: return a->m_data.sint > b->m_data.sint;
case Scalar::e_uint: return a->m_data.uint > b->m_data.uint;
@@ -2242,7 +2180,6 @@
const Scalar* b;
switch (PromoteToMaxType(lhs, rhs, temp_value, a, b))
{
- default:
case Scalar::e_void: break;
case Scalar::e_sint: return a->m_data.sint >= b->m_data.sint;
case Scalar::e_uint: return a->m_data.uint >= b->m_data.uint;
Index: aze/lldb/source/Core/SearchFilter.cpp
===================================================================
--- aze.orig/lldb/source/Core/SearchFilter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/SearchFilter.cpp 2013-03-03 09:35:50.163457354 +0100
@@ -245,8 +245,8 @@
Searcher::CallbackReturn shouldContinue;
if (context.comp_unit == NULL)
{
- uint32_t num_comp_units = module_sp->GetNumCompileUnits();
- for (uint32_t i = 0; i < num_comp_units; i++)
+ const size_t num_comp_units = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_comp_units; i++)
{
CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i));
if (cu_sp)
@@ -617,7 +617,7 @@
void
SearchFilterByModuleList::GetDescription (Stream *s)
{
- uint32_t num_modules = m_module_spec_list.GetSize();
+ size_t num_modules = m_module_spec_list.GetSize();
if (num_modules == 1)
{
s->Printf (", module = ");
@@ -634,8 +634,8 @@
}
else
{
- s->Printf (", modules(%u) = ", num_modules);
- for (uint32_t i = 0; i < num_modules; i++)
+ s->Printf (", modules(%zu) = ", num_modules);
+ for (size_t i = 0; i < num_modules; i++)
{
if (s->GetVerbose())
{
@@ -812,7 +812,7 @@
void
SearchFilterByModuleListAndCU::GetDescription (Stream *s)
{
- uint32_t num_modules = m_module_spec_list.GetSize();
+ size_t num_modules = m_module_spec_list.GetSize();
if (num_modules == 1)
{
s->Printf (", module = ");
@@ -829,8 +829,8 @@
}
else if (num_modules > 0)
{
- s->Printf (", modules(%d) = ", num_modules);
- for (uint32_t i = 0; i < num_modules; i++)
+ s->Printf (", modules(%zd) = ", num_modules);
+ for (size_t i = 0; i < num_modules; i++)
{
if (s->GetVerbose())
{
Index: aze/lldb/source/Core/Section.cpp
===================================================================
--- aze.orig/lldb/source/Core/Section.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Section.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -41,7 +41,7 @@
m_linked_section_wp(),
m_linked_offset (0)
{
-// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16llx, addr=[0x%16.16llx - 0x%16.16llx), file [0x%16.16llx - 0x%16.16llx), flags = 0x%8.8x, name = %s\n",
+// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
}
@@ -72,7 +72,7 @@
m_linked_section_wp(),
m_linked_offset (0)
{
-// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16llx, addr=[0x%16.16llx - 0x%16.16llx), file [0x%16.16llx - 0x%16.16llx), flags = 0x%8.8x, name = %s.%s\n",
+// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
if (parent_section_sp)
m_parent_wp = parent_section_sp;
@@ -162,10 +162,10 @@
bool
Section::ResolveContainedAddress (addr_t offset, Address &so_addr) const
{
- const uint32_t num_children = m_children.GetSize();
+ const size_t num_children = m_children.GetSize();
if (num_children > 0)
{
- for (uint32_t i=0; i<num_children; i++)
+ for (size_t i=0; i<num_children; i++)
{
Section* child_section = m_children.GetSectionAtIndex (i).get();
@@ -257,7 +257,7 @@
{
// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
s->Indent();
- s->Printf("0x%8.8llx %-16s ", GetID(), GetSectionTypeAsCString (m_type));
+ s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetSectionTypeAsCString (m_type));
bool resolved = true;
addr_t addr = LLDB_INVALID_ADDRESS;
@@ -280,7 +280,7 @@
range.Dump (s, 0);
}
- s->Printf("%c 0x%8.8llx 0x%8.8llx 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get());
+ s->Printf("%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get());
DumpName (s);
@@ -312,7 +312,7 @@
s->Printf("%c%*.*s", resolved ? ' ' : '*', indent, indent, "");
linked_section_sp->DumpName(s);
- s->Printf(" + 0x%llx\n", m_linked_offset);
+ s->Printf(" + 0x%" PRIx64 "\n", m_linked_offset);
}
if (depth > 0)
@@ -395,17 +395,17 @@
{
}
-uint32_t
+size_t
SectionList::AddSection (const lldb::SectionSP& section_sp)
{
assert (section_sp.get());
- uint32_t section_index = m_sections.size();
+ size_t section_index = m_sections.size();
m_sections.push_back(section_sp);
InvalidateRangeCache();
return section_index;
}
-uint32_t
+size_t
SectionList::FindSectionIndex (const Section* sect)
{
iterator sect_iter;
@@ -422,10 +422,10 @@
return UINT32_MAX;
}
-uint32_t
+size_t
SectionList::AddUniqueSection (const lldb::SectionSP& sect_sp)
{
- uint32_t sect_idx = FindSectionIndex (sect_sp.get());
+ size_t sect_idx = FindSectionIndex (sect_sp.get());
if (sect_idx == UINT32_MAX)
sect_idx = AddSection (sect_sp);
return sect_idx;
@@ -470,7 +470,7 @@
}
SectionSP
-SectionList::GetSectionAtIndex (uint32_t idx) const
+SectionList::GetSectionAtIndex (size_t idx) const
{
SectionSP sect_sp;
if (idx < m_sections.size())
@@ -530,11 +530,11 @@
SectionSP
-SectionList::FindSectionByType (SectionType sect_type, bool check_children, uint32_t start_idx) const
+SectionList::FindSectionByType (SectionType sect_type, bool check_children, size_t start_idx) const
{
SectionSP sect_sp;
- uint32_t num_sections = m_sections.size();
- for (uint32_t idx = start_idx; idx < num_sections; ++idx)
+ size_t num_sections = m_sections.size();
+ for (size_t idx = start_idx; idx < num_sections; ++idx)
{
if (m_sections[idx]->GetType() == sect_type)
{
Index: aze/lldb/source/Core/SourceManager.cpp
===================================================================
--- aze.orig/lldb/source/Core/SourceManager.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/SourceManager.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Core/SourceManager.h"
// C Includes
@@ -40,6 +42,7 @@
m_last_file_context_before (0),
m_last_file_context_after (10),
m_default_set(false),
+ m_first_reverse(true),
m_target (&target),
m_debugger(NULL)
{
@@ -52,6 +55,7 @@
m_last_file_context_before (0),
m_last_file_context_after (10),
m_default_set(false),
+ m_first_reverse (true),
m_target (NULL),
m_debugger (&debugger)
{
@@ -64,26 +68,6 @@
{
}
-size_t
-SourceManager::DisplaySourceLines
-(
- const FileSpec &file_spec,
- uint32_t line,
- uint32_t context_before,
- uint32_t context_after,
- Stream *s
-)
-{
- m_last_file_sp = GetFile (file_spec);
- m_last_file_line = line + context_after + 1;
- m_last_file_context_before = context_before;
- m_last_file_context_after = context_after;
- if (m_last_file_sp.get())
- return m_last_file_sp->DisplaySourceLines (line, context_before, context_after, s);
-
- return 0;
-}
-
SourceManager::FileSP
SourceManager::GetFile (const FileSpec &file_spec)
{
@@ -110,6 +94,7 @@
const SymbolContextList *bp_locs
)
{
+ m_first_reverse = true;
size_t return_value = 0;
if (line == 0)
{
@@ -197,13 +182,67 @@
}
size_t
-SourceManager::DisplayMoreWithLineNumbers (Stream *s, const SymbolContextList *bp_locs)
+SourceManager::DisplayMoreWithLineNumbers (Stream *s, const SymbolContextList *bp_locs, bool reverse)
{
+ // If we get called before anybody has set a default file and line, then try to figure it out here.
+ if (!m_default_set)
+ {
+ FileSpec tmp_spec;
+ uint32_t tmp_line;
+ GetDefaultFileAndLine(tmp_spec, tmp_line);
+ }
+
if (m_last_file_sp)
{
if (m_last_file_line == UINT32_MAX)
return 0;
- return DisplaySourceLinesWithLineNumbersUsingLastFile (0, m_last_file_context_before, m_last_file_context_after, "", s, bp_locs);
+
+ if (reverse && m_last_file_line == 1)
+ return 0;
+
+ uint32_t line;
+ uint32_t new_last_file_line = 0;
+
+ if (m_last_file_line != 0
+ && m_last_file_line != UINT32_MAX)
+ {
+ if (reverse)
+ {
+ // If this is the first time we've done a reverse, then back up one more time so we end
+ // up showing the chunk before the last one we've shown:
+ if (m_first_reverse)
+ {
+ if (m_last_file_line > m_last_file_context_after)
+ m_last_file_line -= m_last_file_context_after + 1;
+ }
+
+ if (m_last_file_line > m_last_file_context_after)
+ {
+ line = m_last_file_line - m_last_file_context_after;
+ if (line > m_last_file_context_before)
+ new_last_file_line = line - m_last_file_context_before - 1;
+ else
+ new_last_file_line = 1;
+ }
+ else
+ {
+ line = 1;
+ new_last_file_line = 1;
+ }
+ }
+ else
+ line = m_last_file_line + m_last_file_context_before;
+ }
+ else
+ line = 1;
+
+ size_t num_chars_shown = DisplaySourceLinesWithLineNumbersUsingLastFile (line, m_last_file_context_before, m_last_file_context_after, "", s, bp_locs);
+ if (new_last_file_line != 0)
+ m_last_file_line = new_last_file_line;
+ if (reverse)
+ m_first_reverse = false;
+
+ return num_chars_shown;
}
return 0;
}
@@ -245,13 +284,18 @@
if (executable_ptr)
{
SymbolContextList sc_list;
- uint32_t num_matches;
ConstString main_name("main");
bool symbols_okay = false; // Force it to be a debug symbol.
bool inlines_okay = true;
bool append = false;
- num_matches = executable_ptr->FindFunctions (main_name, NULL, lldb::eFunctionNameTypeBase, inlines_okay, symbols_okay, append, sc_list);
- for (uint32_t idx = 0; idx < num_matches; idx++)
+ size_t num_matches = executable_ptr->FindFunctions (main_name,
+ NULL,
+ lldb::eFunctionNameTypeBase,
+ inlines_okay,
+ symbols_okay,
+ append,
+ sc_list);
+ for (size_t idx = 0; idx < num_matches; idx++)
{
SymbolContext sc;
sc_list.GetContextAtIndex(idx, sc);
@@ -525,11 +569,14 @@
register char curr_ch = *s;
if (is_newline_char (curr_ch))
{
- register char next_ch = s[1];
- if (is_newline_char (next_ch))
+ if (s + 1 < end)
{
- if (curr_ch != next_ch)
- ++s;
+ register char next_ch = s[1];
+ if (is_newline_char (next_ch))
+ {
+ if (curr_ch != next_ch)
+ ++s;
+ }
}
m_offsets.push_back(s + 1 - start);
}
@@ -545,14 +592,14 @@
else
{
// Some lines have been populated, start where we last left off
- assert(!"Not implemented yet");
+ assert("Not implemented yet" == NULL);
}
}
else
{
// Calculate all line offsets up to "line"
- assert(!"Not implemented yet");
+ assert("Not implemented yet" == NULL);
}
return false;
}
@@ -563,8 +610,8 @@
if (!LineIsValid(line_no))
return false;
- uint32_t start_offset = GetLineOffset (line_no);
- uint32_t end_offset = GetLineOffset (line_no + 1);
+ size_t start_offset = GetLineOffset (line_no);
+ size_t end_offset = GetLineOffset (line_no + 1);
if (end_offset == UINT32_MAX)
{
end_offset = m_data_sp->GetByteSize();
Index: aze/lldb/source/Core/State.cpp
===================================================================
--- aze.orig/lldb/source/Core/State.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/State.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -83,7 +83,6 @@
case eStateCrashed:
case eStateExited:
case eStateSuspended:
- default:
break;
}
return false;
@@ -101,7 +100,6 @@
case eStateRunning:
case eStateStepping:
case eStateDetached:
- default:
break;
case eStateUnloaded:
Index: aze/lldb/source/Core/StreamAsynchronousIO.cpp
===================================================================
--- aze.orig/lldb/source/Core/StreamAsynchronousIO.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/StreamAsynchronousIO.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -44,7 +44,7 @@
}
}
-int
+size_t
StreamAsynchronousIO::Write (const void *s, size_t length)
{
m_accumulated_data.Write (s, length);
Index: aze/lldb/source/Core/StreamCallback.cpp
===================================================================
--- aze.orig/lldb/source/Core/StreamCallback.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/StreamCallback.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -55,7 +55,7 @@
out_stream.Clear();
}
-int
+size_t
StreamCallback::Write (const void *s, size_t length)
{
lldb::tid_t cur_tid = Host::GetCurrentThreadID();
Index: aze/lldb/source/Core/Stream.cpp
===================================================================
--- aze.orig/lldb/source/Core/Stream.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Stream.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -14,6 +14,8 @@
#include <string.h>
#include <stdlib.h>
+#include <inttypes.h>
+
using namespace lldb;
using namespace lldb_private;
@@ -62,10 +64,10 @@
// Put an SLEB128 "uval" out to the stream using the printf format
// in "format".
//------------------------------------------------------------------
-int
+size_t
Stream::PutSLEB128 (int64_t sval)
{
- int bytes_written = 0;
+ size_t bytes_written = 0;
if (m_flags.Test(eBinary))
{
bool more = true;
@@ -85,7 +87,7 @@
}
else
{
- bytes_written = Printf ("0x%lli", sval);
+ bytes_written = Printf ("0x%" PRIi64, sval);
}
return bytes_written;
@@ -96,10 +98,10 @@
// Put an ULEB128 "uval" out to the stream using the printf format
// in "format".
//------------------------------------------------------------------
-int
+size_t
Stream::PutULEB128 (uint64_t uval)
{
- int bytes_written = 0;
+ size_t bytes_written = 0;
if (m_flags.Test(eBinary))
{
do
@@ -117,7 +119,7 @@
}
else
{
- bytes_written = Printf ("0x%llx", uval);
+ bytes_written = Printf ("0x%" PRIx64, uval);
}
return bytes_written;
}
@@ -125,10 +127,10 @@
//------------------------------------------------------------------
// Print a raw NULL terminated C string to the stream.
//------------------------------------------------------------------
-int
+size_t
Stream::PutCString (const char *cstr)
{
- int cstr_len = strlen(cstr);
+ size_t cstr_len = strlen(cstr);
// when in binary mode, emit the NULL terminator
if (m_flags.Test(eBinary))
++cstr_len;
@@ -150,15 +152,15 @@
// and suffix strings.
//------------------------------------------------------------------
void
-Stream::Address (uint64_t addr, int addr_size, const char *prefix, const char *suffix)
+Stream::Address (uint64_t addr, uint32_t addr_size, const char *prefix, const char *suffix)
{
if (prefix == NULL)
prefix = "";
if (suffix == NULL)
suffix = "";
// int addr_width = m_addr_size << 1;
-// Printf ("%s0x%0*llx%s", prefix, addr_width, addr, suffix);
- Printf ("%s0x%0*llx%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
+// Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
+ Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
}
//------------------------------------------------------------------
@@ -166,7 +168,7 @@
// and suffix strings.
//------------------------------------------------------------------
void
-Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr, int addr_size, const char *prefix, const char *suffix)
+Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix, const char *suffix)
{
if (prefix && prefix[0])
PutCString (prefix);
@@ -177,7 +179,7 @@
}
-int
+size_t
Stream::PutChar (char ch)
{
return Write (&ch, 1);
@@ -187,7 +189,7 @@
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-int
+size_t
Stream::Printf (const char *format, ...)
{
va_list args;
@@ -200,7 +202,7 @@
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-int
+size_t
Stream::PrintfVarArg (const char *format, va_list args)
{
char str[1024];
@@ -208,7 +210,7 @@
va_copy (args_copy, args);
- int bytes_written = 0;
+ size_t bytes_written = 0;
// Try and format our string into a fixed buffer first and see if it fits
size_t length = ::vsnprintf (str, sizeof(str), format, args);
if (length < sizeof(str))
@@ -242,7 +244,7 @@
//------------------------------------------------------------------
// Print and End of Line character to the stream
//------------------------------------------------------------------
-int
+size_t
Stream::EOL()
{
return PutChar ('\n');
@@ -252,7 +254,7 @@
// Indent the current line using the current indentation level and
// print an optional string following the idenatation spaces.
//------------------------------------------------------------------
-int
+size_t
Stream::Indent(const char *s)
{
return Printf ("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
@@ -364,7 +366,7 @@
Stream&
Stream::operator<< (int64_t sval)
{
- Printf ("%lli", sval);
+ Printf ("%" PRIi64, sval);
return *this;
}
@@ -410,7 +412,7 @@
//------------------------------------------------------------------
// Get the address size in bytes
//------------------------------------------------------------------
-uint8_t
+uint32_t
Stream::GetAddressByteSize() const
{
return m_addr_size;
@@ -420,7 +422,7 @@
// Set the address size in bytes
//------------------------------------------------------------------
void
-Stream::SetAddressByteSize(uint8_t addr_size)
+Stream::SetAddressByteSize(uint32_t addr_size)
{
m_addr_size = addr_size;
}
@@ -471,7 +473,7 @@
return m_byte_order;
}
-int
+size_t
Stream::PrintfAsRawHex8 (const char *format, ...)
{
va_list args;
@@ -480,7 +482,7 @@
va_copy (args, args_copy); // Copy this so we
char str[1024];
- int bytes_written = 0;
+ size_t bytes_written = 0;
// Try and format our string into a fixed buffer first and see if it fits
size_t length = ::vsnprintf (str, sizeof(str), format, args);
if (length < sizeof(str))
@@ -509,19 +511,19 @@
return bytes_written;
}
-int
+size_t
Stream::PutNHex8 (size_t n, uint8_t uvalue)
{
- int bytes_written = 0;
+ size_t bytes_written = 0;
for (size_t i=0; i<n; ++i)
bytes_written += _PutHex8 (uvalue, m_flags.Test(eAddPrefix));
return bytes_written;
}
-int
+size_t
Stream::_PutHex8 (uint8_t uvalue, bool add_prefix)
{
- int bytes_written = 0;
+ size_t bytes_written = 0;
if (m_flags.Test(eBinary))
{
bytes_written = Write (&uvalue, 1);
@@ -540,76 +542,76 @@
return bytes_written;
}
-int
+size_t
Stream::PutHex8 (uint8_t uvalue)
{
return _PutHex8 (uvalue, m_flags.Test(eAddPrefix));
}
-int
+size_t
Stream::PutHex16 (uint16_t uvalue, ByteOrder byte_order)
{
if (byte_order == eByteOrderInvalid)
byte_order = m_byte_order;
bool add_prefix = m_flags.Test(eAddPrefix);
- int bytes_written = 0;
+ size_t bytes_written = 0;
if (byte_order == eByteOrderLittle)
{
for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
- bytes_written += _PutHex8 (uvalue >> (byte * 8), add_prefix);
+ bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
}
else
{
for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
- bytes_written += _PutHex8 (uvalue >> (byte * 8), add_prefix);
+ bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
}
return bytes_written;
}
-int
+size_t
Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order)
{
if (byte_order == eByteOrderInvalid)
byte_order = m_byte_order;
bool add_prefix = m_flags.Test(eAddPrefix);
- int bytes_written = 0;
+ size_t bytes_written = 0;
if (byte_order == eByteOrderLittle)
{
for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
- bytes_written += _PutHex8 (uvalue >> (byte * 8), add_prefix);
+ bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
}
else
{
for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
- bytes_written += _PutHex8 (uvalue >> (byte * 8), add_prefix);
+ bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
}
return bytes_written;
}
-int
+size_t
Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order)
{
if (byte_order == eByteOrderInvalid)
byte_order = m_byte_order;
bool add_prefix = m_flags.Test(eAddPrefix);
- int bytes_written = 0;
+ size_t bytes_written = 0;
if (byte_order == eByteOrderLittle)
{
for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
- bytes_written += _PutHex8 (uvalue >> (byte * 8), add_prefix);
+ bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
}
else
{
for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
- bytes_written += _PutHex8 (uvalue >> (byte * 8), add_prefix);
+ bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
}
return bytes_written;
}
-int
+size_t
Stream::PutMaxHex64
(
uint64_t uvalue,
@@ -619,21 +621,21 @@
{
switch (byte_size)
{
- case 1: return PutHex8 (uvalue);
- case 2: return PutHex16 (uvalue);
- case 4: return PutHex32 (uvalue);
+ case 1: return PutHex8 ((uint8_t)uvalue);
+ case 2: return PutHex16 ((uint16_t)uvalue);
+ case 4: return PutHex32 ((uint32_t)uvalue);
case 8: return PutHex64 (uvalue);
}
return 0;
}
-int
+size_t
Stream::PutPointer (void *ptr)
{
return PutRawBytes (&ptr, sizeof(ptr), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
}
-int
+size_t
Stream::PutFloat(float f, ByteOrder byte_order)
{
if (byte_order == eByteOrderInvalid)
@@ -642,7 +644,7 @@
return PutRawBytes (&f, sizeof(f), lldb::endian::InlHostByteOrder(), byte_order);
}
-int
+size_t
Stream::PutDouble(double d, ByteOrder byte_order)
{
if (byte_order == eByteOrderInvalid)
@@ -651,7 +653,7 @@
return PutRawBytes (&d, sizeof(d), lldb::endian::InlHostByteOrder(), byte_order);
}
-int
+size_t
Stream::PutLongDouble(long double ld, ByteOrder byte_order)
{
if (byte_order == eByteOrderInvalid)
@@ -660,7 +662,7 @@
return PutRawBytes (&ld, sizeof(ld), lldb::endian::InlHostByteOrder(), byte_order);
}
-int
+size_t
Stream::PutRawBytes (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order)
{
if (src_byte_order == eByteOrderInvalid)
@@ -669,7 +671,7 @@
if (dst_byte_order == eByteOrderInvalid)
dst_byte_order = m_byte_order;
- int bytes_written = 0;
+ size_t bytes_written = 0;
const uint8_t *src = (const uint8_t *)s;
bool binary_was_set = m_flags.Test (eBinary);
if (!binary_was_set)
@@ -690,7 +692,7 @@
return bytes_written;
}
-int
+size_t
Stream::PutBytesAsRawHex8 (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order)
{
if (src_byte_order == eByteOrderInvalid)
@@ -699,7 +701,7 @@
if (dst_byte_order == eByteOrderInvalid)
dst_byte_order = m_byte_order;
- int bytes_written = 0;
+ size_t bytes_written = 0;
const uint8_t *src = (const uint8_t *)s;
bool binary_is_set = m_flags.Test(eBinary);
m_flags.Clear(eBinary);
@@ -719,10 +721,10 @@
return bytes_written;
}
-int
+size_t
Stream::PutCStringAsRawHex8 (const char *s)
{
- int bytes_written = 0;
+ size_t bytes_written = 0;
bool binary_is_set = m_flags.Test(eBinary);
m_flags.Clear(eBinary);
do
Index: aze/lldb/source/Core/StreamFile.cpp
===================================================================
--- aze.orig/lldb/source/Core/StreamFile.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/StreamFile.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -64,7 +64,7 @@
m_file.Flush();
}
-int
+size_t
StreamFile::Write (const void *s, size_t length)
{
m_file.Write (s, length);
Index: aze/lldb/source/Core/StreamString.cpp
===================================================================
--- aze.orig/lldb/source/Core/StreamString.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/StreamString.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -34,7 +34,7 @@
// Nothing to do when flushing a buffer based stream...
}
-int
+size_t
StreamString::Write (const void *s, size_t length)
{
m_packet.append ((char *)s, length);
Index: aze/lldb/source/Core/StringList.cpp
===================================================================
--- aze.orig/lldb/source/Core/StringList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/StringList.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -75,9 +75,9 @@
void
StringList::AppendList (StringList strings)
{
- uint32_t len = strings.GetSize();
+ size_t len = strings.GetSize();
- for (uint32_t i = 0; i < len; ++i)
+ for (size_t i = 0; i < len; ++i)
m_strings.push_back (strings.GetStringAtIndex(i));
}
@@ -87,7 +87,7 @@
return input_file.ReadFileLines (m_strings);
}
-uint32_t
+size_t
StringList::GetSize () const
{
return m_strings.size();
@@ -104,7 +104,7 @@
void
StringList::Join (const char *separator, Stream &strm)
{
- uint32_t size = GetSize();
+ size_t size = GetSize();
if (size == 0)
return;
@@ -127,8 +127,8 @@
StringList::LongestCommonPrefix (std::string &common_prefix)
{
//arg_sstr_collection::iterator pos, end = m_args.end();
- int pos = 0;
- int end = m_strings.size();
+ size_t pos = 0;
+ size_t end = m_strings.size();
if (pos == end)
common_prefix.clear();
Index: aze/lldb/source/Core/Timer.cpp
===================================================================
--- aze.orig/lldb/source/Core/Timer.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Timer.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -25,7 +25,7 @@
uint32_t Timer::g_display_depth = 0;
FILE * Timer::g_file = NULL;
typedef std::vector<Timer *> TimerStack;
-typedef std::map<const char *, uint64_t> CategoryMap;
+typedef std::map<const char *, uint64_t> TimerCategoryMap;
static pthread_key_t g_key;
static Mutex &
@@ -35,10 +35,10 @@
return g_category_mutex;
}
-static CategoryMap &
+static TimerCategoryMap &
GetCategoryMap()
{
- static CategoryMap g_category_map;
+ static TimerCategoryMap g_category_map;
return g_category_map;
}
@@ -153,7 +153,7 @@
// Keep total results for each category so we can dump results.
Mutex::Locker locker (GetCategoryMutex());
- CategoryMap &category_map = GetCategoryMap();
+ TimerCategoryMap &category_map = GetCategoryMap();
category_map[m_category] += timer_nsec_uint;
}
if (g_depth > 0)
@@ -214,7 +214,7 @@
* - returns whether a person is less than another person
*/
static bool
-CategoryMapIteratorSortCriterion (const CategoryMap::const_iterator& lhs, const CategoryMap::const_iterator& rhs)
+CategoryMapIteratorSortCriterion (const TimerCategoryMap::const_iterator& lhs, const TimerCategoryMap::const_iterator& rhs)
{
return lhs->second > rhs->second;
}
@@ -224,7 +224,7 @@
Timer::ResetCategoryTimes ()
{
Mutex::Locker locker (GetCategoryMutex());
- CategoryMap &category_map = GetCategoryMap();
+ TimerCategoryMap &category_map = GetCategoryMap();
category_map.clear();
}
@@ -232,9 +232,9 @@
Timer::DumpCategoryTimes (Stream *s)
{
Mutex::Locker locker (GetCategoryMutex());
- CategoryMap &category_map = GetCategoryMap();
- std::vector<CategoryMap::const_iterator> sorted_iterators;
- CategoryMap::const_iterator pos, end = category_map.end();
+ TimerCategoryMap &category_map = GetCategoryMap();
+ std::vector<TimerCategoryMap::const_iterator> sorted_iterators;
+ TimerCategoryMap::const_iterator pos, end = category_map.end();
for (pos = category_map.begin(); pos != end; ++pos)
{
sorted_iterators.push_back (pos);
Index: aze/lldb/source/Core/UserID.cpp
===================================================================
--- aze.orig/lldb/source/Core/UserID.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/UserID.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -10,6 +10,8 @@
#include "lldb/Core/UserID.h"
#include "lldb/Core/Stream.h"
+#include <inttypes.h>
+
using namespace lldb;
using namespace lldb_private;
@@ -20,6 +22,6 @@
Stream&
lldb_private::operator << (Stream& strm, const UserID& uid)
{
- strm.Printf("{0x%8.8llx}", uid.GetID());
+ strm.Printf("{0x%8.8" PRIx64 "}", uid.GetID());
return strm;
}
Index: aze/lldb/source/Core/UserSettingsController.cpp
===================================================================
--- aze.orig/lldb/source/Core/UserSettingsController.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/UserSettingsController.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include <string.h>
#include <algorithm>
Index: aze/lldb/source/Core/UUID.cpp
===================================================================
--- aze.orig/lldb/source/Core/UUID.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/UUID.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -178,7 +178,7 @@
while (isspace(*p))
++p;
- const uint32_t uuid_byte_idx = UUID::DecodeUUIDBytesFromCString (p, m_uuid, &p);
+ const size_t uuid_byte_idx = UUID::DecodeUUIDBytesFromCString (p, m_uuid, &p);
// If we successfully decoded a UUID, return the amount of characters that
// were consumed
Index: aze/lldb/source/Core/Value.cpp
===================================================================
--- aze.orig/lldb/source/Core/Value.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/Value.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -144,7 +144,7 @@
}
void
-Value::ResizeData(int len)
+Value::ResizeData(size_t len)
{
m_value_type = eValueTypeHostAddress;
m_data_buffer.SetByteSize(len);
@@ -156,7 +156,6 @@
{
switch (m_context_type)
{
- default:
case eContextTypeInvalid:
case eContextTypeClangType: // clang::Type *
case eContextTypeRegisterInfo: // RegisterInfo *
@@ -177,7 +176,6 @@
switch (m_context_type)
{
- default:
case eContextTypeInvalid:
// If we have no context, there is no way to know how much memory to read
if (error_ptr)
@@ -201,8 +199,7 @@
if (GetRegisterInfo())
byte_size = GetRegisterInfo()->byte_size;
else if (error_ptr)
- error_ptr->SetErrorString ("Can't determine byte size with NULL RegisterInfo *.");
-
+ error_ptr->SetErrorString ("Can't determine byte size with NULL RegisterInfo *.");
break;
case eContextTypeLLDBType: // Type *
@@ -245,7 +242,6 @@
{
switch (m_context_type)
{
- default:
case eContextTypeInvalid:
break;
@@ -274,7 +270,6 @@
{
switch (m_context_type)
{
- default:
case eContextTypeInvalid:
break;
@@ -331,7 +326,7 @@
}
Error
-Value::GetValueAsData (ExecutionContext *exe_ctx,
+Value::GetValueAsData (ExecutionContext *exe_ctx,
clang::ASTContext *ast_context,
DataExtractor &data,
uint32_t data_offset,
@@ -373,9 +368,54 @@
else
{
Process *process = exe_ctx->GetProcessPtr();
- if (process == NULL)
+ if (process == NULL || !process->IsAlive())
{
- error.SetErrorString ("can't read load address (invalid process)");
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
+ {
+ // Allow expressions to run and evaluate things when the target
+ // has memory sections loaded. This allows you to use "target modules load"
+ // to load your executable and any shared libraries, then execute
+ // commands where you can look at types in data sections.
+ const SectionLoadList &target_sections = target->GetSectionLoadList();
+ if (!target_sections.IsEmpty())
+ {
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if (target_sections.ResolveLoadAddress(address, file_so_addr))
+ {
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
+ else
+ address = LLDB_INVALID_ADDRESS;
+ }
+// else
+// {
+// ModuleSP exe_module_sp (target->GetExecutableModule());
+// if (exe_module_sp)
+// {
+// address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+// if (address != LLDB_INVALID_ADDRESS)
+// {
+// if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
+// {
+// data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+// data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+// address_type = eAddressTypeFile;
+// }
+// else
+// {
+// address = LLDB_INVALID_ADDRESS;
+// }
+// }
+// }
+// }
+ }
+ else
+ {
+ error.SetErrorString ("can't read load address (invalid process)");
+ }
}
else
{
@@ -456,14 +496,14 @@
if (module)
{
if (variable)
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s%s%s",
address,
variable->GetName().AsCString(""),
module->GetFileSpec().GetDirectory().GetCString(),
module->GetFileSpec().GetDirectory() ? "/" : "",
module->GetFileSpec().GetFilename().GetCString());
else
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx in %s%s%s",
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s%s%s",
address,
module->GetFileSpec().GetDirectory().GetCString(),
module->GetFileSpec().GetDirectory() ? "/" : "",
@@ -472,11 +512,11 @@
else
{
if (variable)
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'",
address,
variable->GetName().AsCString(""));
else
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx", address);
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address);
}
}
}
@@ -520,7 +560,7 @@
}
// If we got here, we need to read the value from memory
- uint32_t byte_size = GetValueByteSize (ast_context, &error);
+ size_t byte_size = GetValueByteSize (ast_context, &error);
// Bail if we encountered any errors getting the byte size
if (error.Fail())
@@ -555,7 +595,7 @@
const bool prefer_file_cache = false;
if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
{
- error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
+ error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address);
}
}
else
@@ -570,14 +610,14 @@
{
const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
if (bytes_read != byte_size)
- error.SetErrorStringWithFormat("read memory from 0x%llx failed (%u of %u bytes read)",
+ error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
(uint64_t)address,
(uint32_t)bytes_read,
(uint32_t)byte_size);
}
else
{
- error.SetErrorStringWithFormat("read memory from 0x%llx failed (invalid process)", (uint64_t)address);
+ error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address);
}
}
}
@@ -607,16 +647,13 @@
default:
case eValueTypeFileAddress:
- m_value.Clear();
- break;
-
case eValueTypeLoadAddress: // load address value
case eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb)
{
- AddressType address_type = m_value_type == eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost;
- lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
DataExtractor data;
- if (ClangASTType::ReadFromMemory (ast_context, opaque_clang_qual_type, exe_ctx, addr, address_type, data))
+ lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ Error error (GetValueAsData (exe_ctx, ast_context, data, 0, NULL));
+ if (error.Success())
{
Scalar scalar;
if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))
Index: aze/lldb/source/Core/ValueObjectCast.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectCast.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectCast.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -67,7 +67,7 @@
return m_cast_type.GetOpaqueQualType();
}
-uint32_t
+size_t
ValueObjectCast::CalculateNumChildren()
{
return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
Index: aze/lldb/source/Core/ValueObjectChild.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectChild.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectChild.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -62,7 +62,7 @@
return m_parent->GetValueType();
}
-uint32_t
+size_t
ValueObjectChild::CalculateNumChildren()
{
return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
@@ -164,7 +164,6 @@
m_value.SetValueType(Value::eValueTypeHostAddress);
break;
case eAddressTypeInvalid:
- default:
// TODO: does this make sense?
m_value.SetValueType(Value::eValueTypeScalar);
break;
Index: aze/lldb/source/Core/ValueObjectConstResultChild.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectConstResultChild.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectConstResultChild.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -68,7 +68,7 @@
}
ValueObject *
-ValueObjectConstResultChild::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+ValueObjectConstResultChild::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
}
Index: aze/lldb/source/Core/ValueObjectConstResult.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectConstResult.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectConstResult.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -124,7 +124,7 @@
const ConstString &name,
const lldb::DataBufferSP &data_sp,
lldb::ByteOrder data_byte_order,
- uint8_t data_addr_size,
+ uint32_t data_addr_size,
lldb::addr_t address
)
{
@@ -155,7 +155,7 @@
const ConstString &name,
const lldb::DataBufferSP &data_sp,
lldb::ByteOrder data_byte_order,
- uint8_t data_addr_size,
+ uint32_t data_addr_size,
lldb::addr_t address
) :
ValueObject (exe_scope),
@@ -185,7 +185,7 @@
const ConstString &name,
lldb::addr_t address,
AddressType address_type,
- uint8_t addr_byte_size
+ uint32_t addr_byte_size
)
{
return (new ValueObjectConstResult (exe_scope,
@@ -205,7 +205,7 @@
const ConstString &name,
lldb::addr_t address,
AddressType address_type,
- uint8_t addr_byte_size
+ uint32_t addr_byte_size
) :
ValueObject (exe_scope),
m_clang_ast (clang_ast),
@@ -219,7 +219,6 @@
//m_value.SetValueType(Value::eValueTypeHostAddress);
switch (address_type)
{
- default:
case eAddressTypeInvalid: m_value.SetValueType(Value::eValueTypeScalar); break;
case eAddressTypeFile: m_value.SetValueType(Value::eValueTypeFileAddress); break;
case eAddressTypeLoad: m_value.SetValueType(Value::eValueTypeLoadAddress); break;
@@ -301,7 +300,7 @@
m_byte_size = size;
}
-uint32_t
+size_t
ValueObjectConstResult::CalculateNumChildren()
{
return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
@@ -364,7 +363,7 @@
}
ValueObject *
-ValueObjectConstResult::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+ValueObjectConstResult::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
}
Index: aze/lldb/source/Core/ValueObjectConstResultImpl.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectConstResultImpl.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectConstResultImpl.cpp 2013-03-03 09:35:50.167457353 +0100
@@ -84,7 +84,7 @@
}
ValueObject *
-ValueObjectConstResultImpl::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
if (m_impl_backend == NULL)
return NULL;
Index: aze/lldb/source/Core/ValueObject.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObject.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObject.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Core/ValueObject.h"
// C Includes
@@ -19,7 +21,6 @@
// Project includes
#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
@@ -32,6 +33,8 @@
#include "lldb/Core/ValueObjectMemory.h"
#include "lldb/Core/ValueObjectSyntheticFilter.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+
#include "lldb/Host/Endian.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -81,7 +84,6 @@
m_deref_valobj(NULL),
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
- m_last_format_mgr_dynamic(parent.m_last_format_mgr_dynamic),
m_type_summary_sp(),
m_type_format_sp(),
m_synthetic_children_sp(),
@@ -94,7 +96,6 @@
m_is_deref_of_parent (false),
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
- m_is_expression_path_child(false),
m_is_child_at_offset(false),
m_is_getting_summary(false),
m_did_calculate_complete_objc_class_type(false)
@@ -127,7 +128,6 @@
m_deref_valobj(NULL),
m_format (eFormatDefault),
m_last_format_mgr_revision(0),
- m_last_format_mgr_dynamic(eNoDynamicValues),
m_type_summary_sp(),
m_type_format_sp(),
m_synthetic_children_sp(),
@@ -140,7 +140,6 @@
m_is_deref_of_parent (false),
m_is_array_item_for_pointer(false),
m_is_bitfield_for_scalar(false),
- m_is_expression_path_child(false),
m_is_child_at_offset(false),
m_is_getting_summary(false),
m_did_calculate_complete_objc_class_type(false)
@@ -159,17 +158,11 @@
bool
ValueObject::UpdateValueIfNeeded (bool update_format)
{
- return UpdateValueIfNeeded(m_last_format_mgr_dynamic, update_format);
-}
-
-bool
-ValueObject::UpdateValueIfNeeded (DynamicValueType use_dynamic, bool update_format)
-{
bool did_change_formats = false;
if (update_format)
- did_change_formats = UpdateFormatsIfNeeded(use_dynamic);
+ did_change_formats = UpdateFormatsIfNeeded();
// If this is a constant value, then our success is predicated on whether
// we have an error or not
@@ -236,7 +229,7 @@
}
bool
-ValueObject::UpdateFormatsIfNeeded(DynamicValueType use_dynamic)
+ValueObject::UpdateFormatsIfNeeded()
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
if (log)
@@ -248,17 +241,15 @@
bool any_change = false;
- if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()) ||
- m_last_format_mgr_dynamic != use_dynamic)
+ if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()))
{
SetValueFormat(DataVisualization::ValueFormats::GetFormat (*this, eNoDynamicValues));
- SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, use_dynamic));
+ SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, GetDynamicValueType()));
#ifndef LLDB_DISABLE_PYTHON
- SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, use_dynamic));
+ SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, GetDynamicValueType()));
#endif
m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
- m_last_format_mgr_dynamic = use_dynamic;
any_change = true;
}
@@ -418,9 +409,6 @@
switch (m_value.GetValueType())
{
- default:
- break;
-
case Value::eValueTypeScalar:
case Value::eValueTypeVector:
if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
@@ -511,7 +499,7 @@
}
ValueObjectSP
-ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
+ValueObject::GetChildAtIndex (size_t idx, bool can_create)
{
ValueObjectSP child_sp;
// We may need to update our value if we are dynamic
@@ -534,7 +522,87 @@
return child_sp;
}
-uint32_t
+ValueObjectSP
+ValueObject::GetChildAtIndexPath (const std::initializer_list<size_t>& idxs,
+ size_t* index_of_error)
+{
+ if (idxs.size() == 0)
+ return GetSP();
+ ValueObjectSP root(GetSP());
+ for (size_t idx : idxs)
+ {
+ root = root->GetChildAtIndex(idx, true);
+ if (!root)
+ {
+ if (index_of_error)
+ *index_of_error = idx;
+ return root;
+ }
+ }
+ return root;
+}
+
+ValueObjectSP
+ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> >& idxs,
+ size_t* index_of_error)
+{
+ if (idxs.size() == 0)
+ return GetSP();
+ ValueObjectSP root(GetSP());
+ for (std::pair<size_t, bool> idx : idxs)
+ {
+ root = root->GetChildAtIndex(idx.first, idx.second);
+ if (!root)
+ {
+ if (index_of_error)
+ *index_of_error = idx.first;
+ return root;
+ }
+ }
+ return root;
+}
+
+lldb::ValueObjectSP
+ValueObject::GetChildAtIndexPath (const std::vector<size_t> &idxs,
+ size_t* index_of_error)
+{
+ if (idxs.size() == 0)
+ return GetSP();
+ ValueObjectSP root(GetSP());
+ for (size_t idx : idxs)
+ {
+ root = root->GetChildAtIndex(idx, true);
+ if (!root)
+ {
+ if (index_of_error)
+ *index_of_error = idx;
+ return root;
+ }
+ }
+ return root;
+}
+
+lldb::ValueObjectSP
+ValueObject::GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs,
+ size_t* index_of_error)
+{
+ if (idxs.size() == 0)
+ return GetSP();
+ ValueObjectSP root(GetSP());
+ for (std::pair<size_t, bool> idx : idxs)
+ {
+ root = root->GetChildAtIndex(idx.first, idx.second);
+ if (!root)
+ {
+ if (index_of_error)
+ *index_of_error = idx.first;
+ return root;
+ }
+ }
+ return root;
+}
+
+size_t
ValueObject::GetIndexOfChildWithName (const ConstString &name)
{
bool omit_empty_base_classes = true;
@@ -589,7 +657,7 @@
}
-uint32_t
+size_t
ValueObject::GetNumChildren ()
{
UpdateValueIfNeeded();
@@ -604,12 +672,9 @@
ValueObject::MightHaveChildren()
{
bool has_children = false;
- clang_type_t clang_type = GetClangType();
- if (clang_type)
+ const uint32_t type_info = GetTypeInfo();
+ if (type_info)
{
- const uint32_t type_info = ClangASTContext::GetTypeInfo (clang_type,
- GetClangAST(),
- NULL);
if (type_info & (ClangASTContext::eTypeHasChildren |
ClangASTContext::eTypeIsPointer |
ClangASTContext::eTypeIsReference))
@@ -624,7 +689,7 @@
// Should only be called by ValueObject::GetNumChildren()
void
-ValueObject::SetNumChildren (uint32_t num_children)
+ValueObject::SetNumChildren (size_t num_children)
{
m_children_count_valid = true;
m_children.SetChildrenCount(num_children);
@@ -637,7 +702,7 @@
}
ValueObject *
-ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
ValueObject *valobj = NULL;
@@ -673,7 +738,7 @@
child_bitfield_bit_offset,
child_is_base_class,
child_is_deref_of_parent);
- if (child_clang_type && child_byte_size)
+ if (child_clang_type)
{
if (synthetic_index)
child_byte_offset += child_byte_size * synthetic_index;
@@ -807,11 +872,9 @@
ValueObject::IsCStringContainer(bool check_pointer)
{
clang_type_t elem_or_pointee_clang_type;
- const Flags type_flags (ClangASTContext::GetTypeInfo (GetClangType(),
- GetClangAST(),
- &elem_or_pointee_clang_type));
+ const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
bool is_char_arr_ptr (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
- ClangASTContext::IsCharType (elem_or_pointee_clang_type));
+ ClangASTContext::IsCharType (elem_or_pointee_clang_type));
if (!is_char_arr_ptr)
return false;
if (!check_pointer)
@@ -829,19 +892,20 @@
uint32_t item_idx,
uint32_t item_count)
{
- if (!IsPointerType() && !IsArrayType())
+ clang_type_t pointee_or_element_clang_type;
+ const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type);
+ const bool is_pointer_type = type_info & ClangASTContext::eTypeIsPointer;
+ const bool is_array_type = type_info & ClangASTContext::eTypeIsArray;
+ if (!(is_pointer_type || is_array_type))
return 0;
if (item_count == 0)
return 0;
- uint32_t stride = 0;
+ clang::ASTContext *ast = GetClangAST();
+ ClangASTType pointee_or_element_type(ast, pointee_or_element_clang_type);
- ClangASTType type(GetClangAST(),
- GetClangType());
-
- const uint64_t item_type_size = (IsPointerType() ? ClangASTType::GetTypeByteSize(GetClangAST(), type.GetPointeeType()) :
- ClangASTType::GetTypeByteSize(GetClangAST(), type.GetArrayElementType(stride)));
+ const uint64_t item_type_size = pointee_or_element_type.GetClangTypeByteSize();
const uint64_t bytes = item_count * item_type_size;
@@ -849,7 +913,7 @@
if (item_idx == 0 && item_count == 1) // simply a deref
{
- if (IsPointerType())
+ if (is_pointer_type)
{
Error error;
ValueObjectSP pointee_sp = Dereference(error);
@@ -873,7 +937,7 @@
lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
AddressType addr_type;
- lldb::addr_t addr = IsPointerType() ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
+ lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
switch (addr_type)
{
@@ -918,13 +982,18 @@
break;
case eAddressTypeHost:
{
- heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes);
- data.SetData(data_sp);
- return bytes;
+ ClangASTType valobj_type(ast, GetClangType());
+ uint64_t max_bytes = valobj_type.GetClangTypeByteSize();
+ if (max_bytes > offset)
+ {
+ size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
+ heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read);
+ data.SetData(data_sp);
+ return bytes_read;
+ }
}
break;
case eAddressTypeInvalid:
- default:
break;
}
}
@@ -962,14 +1031,14 @@
while(*str)
{
len++;str++;
- if (len > maxlen)
+ if (len >= maxlen)
return maxlen_value;
}
}
return len;
}
-void
+size_t
ValueObject::ReadPointedString (Stream& s,
Error& error,
uint32_t max_length,
@@ -979,141 +1048,149 @@
ExecutionContext exe_ctx (GetExecutionContextRef());
Target* target = exe_ctx.GetTargetPtr();
- if (target && max_length == 0)
+ if (!target)
+ {
+ s << "<no target to read from>";
+ error.SetErrorString("no target to read from");
+ return 0;
+ }
+
+ if (max_length == 0)
max_length = target->GetMaximumSizeOfStringSummary();
+ size_t bytes_read = 0;
+ size_t total_bytes_read = 0;
+
clang_type_t clang_type = GetClangType();
clang_type_t elem_or_pointee_clang_type;
- const Flags type_flags (ClangASTContext::GetTypeInfo (clang_type,
- GetClangAST(),
- &elem_or_pointee_clang_type));
+ const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
ClangASTContext::IsCharType (elem_or_pointee_clang_type))
{
- if (target == NULL)
+ addr_t cstr_address = LLDB_INVALID_ADDRESS;
+ AddressType cstr_address_type = eAddressTypeInvalid;
+
+ size_t cstr_len = 0;
+ bool capped_data = false;
+ if (type_flags.Test (ClangASTContext::eTypeIsArray))
{
- s << "<no target to read from>";
+ // We have an array
+ cstr_len = ClangASTContext::GetArraySize (clang_type);
+ if (cstr_len > max_length)
+ {
+ capped_data = true;
+ cstr_len = max_length;
+ }
+ cstr_address = GetAddressOf (true, &cstr_address_type);
+ }
+ else
+ {
+ // We have a pointer
+ cstr_address = GetPointerValue (&cstr_address_type);
+ }
+
+ if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS)
+ {
+ s << "<invalid address>";
+ error.SetErrorString("invalid address");
+ return 0;
+ }
+
+ Address cstr_so_addr (cstr_address);
+ DataExtractor data;
+ if (cstr_len > 0 && honor_array)
+ {
+ // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
+ // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
+ GetPointeeData(data, 0, cstr_len);
+
+ if ((bytes_read = data.GetByteSize()) > 0)
+ {
+ total_bytes_read = bytes_read;
+ s << '"';
+ data.Dump (&s,
+ 0, // Start offset in "data"
+ item_format,
+ 1, // Size of item (1 byte for a char!)
+ bytes_read, // How many bytes to print?
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS,// base address
+ 0, // bitfield bit size
+ 0); // bitfield bit offset
+ if (capped_data)
+ s << "...";
+ s << '"';
+ }
}
else
{
- addr_t cstr_address = LLDB_INVALID_ADDRESS;
- AddressType cstr_address_type = eAddressTypeInvalid;
+ cstr_len = max_length;
+ const size_t k_max_buf_size = 64;
+
+ size_t offset = 0;
- size_t cstr_len = 0;
- bool capped_data = false;
- if (type_flags.Test (ClangASTContext::eTypeIsArray))
- {
- // We have an array
- cstr_len = ClangASTContext::GetArraySize (clang_type);
- if (cstr_len > max_length)
+ int cstr_len_displayed = -1;
+ bool capped_cstr = false;
+ // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
+ // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
+ while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0)
+ {
+ total_bytes_read += bytes_read;
+ const char *cstr = data.PeekCStr(0);
+ size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
+ if (len > k_max_buf_size)
+ len = k_max_buf_size;
+ if (cstr && cstr_len_displayed < 0)
+ s << '"';
+
+ if (cstr_len_displayed < 0)
+ cstr_len_displayed = len;
+
+ if (len == 0)
+ break;
+ cstr_len_displayed += len;
+ if (len > bytes_read)
+ len = bytes_read;
+ if (len > cstr_len)
+ len = cstr_len;
+
+ data.Dump (&s,
+ 0, // Start offset in "data"
+ item_format,
+ 1, // Size of item (1 byte for a char!)
+ len, // How many bytes to print?
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS,// base address
+ 0, // bitfield bit size
+ 0); // bitfield bit offset
+
+ if (len < k_max_buf_size)
+ break;
+
+ if (len >= cstr_len)
{
- capped_data = true;
- cstr_len = max_length;
+ capped_cstr = true;
+ break;
}
- cstr_address = GetAddressOf (true, &cstr_address_type);
- }
- else
- {
- // We have a pointer
- cstr_address = GetPointerValue (&cstr_address_type);
+
+ cstr_len -= len;
+ offset += len;
}
- if (cstr_address != 0 && cstr_address != LLDB_INVALID_ADDRESS)
+
+ if (cstr_len_displayed >= 0)
{
- Address cstr_so_addr (cstr_address);
- DataExtractor data;
- size_t bytes_read = 0;
- if (cstr_len > 0 && honor_array)
- {
- // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
- // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
- GetPointeeData(data, 0, cstr_len);
-
- if ((bytes_read = data.GetByteSize()) > 0)
- {
- s << '"';
- data.Dump (&s,
- 0, // Start offset in "data"
- item_format,
- 1, // Size of item (1 byte for a char!)
- bytes_read, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
- if (capped_data)
- s << "...";
- s << '"';
- }
- }
- else
- {
- cstr_len = max_length;
- const size_t k_max_buf_size = 64;
-
- size_t offset = 0;
-
- int cstr_len_displayed = -1;
- bool capped_cstr = false;
- // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
- // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
- while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0)
- {
- const char *cstr = data.PeekCStr(0);
- size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
- if (len > k_max_buf_size)
- len = k_max_buf_size;
- if (cstr && cstr_len_displayed < 0)
- s << '"';
-
- if (cstr_len_displayed < 0)
- cstr_len_displayed = len;
-
- if (len == 0)
- break;
- cstr_len_displayed += len;
- if (len > bytes_read)
- len = bytes_read;
- if (len > cstr_len)
- len = cstr_len;
-
- data.Dump (&s,
- 0, // Start offset in "data"
- item_format,
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
-
- if (len < k_max_buf_size)
- break;
-
- if (len >= cstr_len)
- {
- capped_cstr = true;
- break;
- }
-
- cstr_len -= len;
- offset += len;
- }
-
- if (cstr_len_displayed >= 0)
- {
- s << '"';
- if (capped_cstr)
- s << "...";
- }
- }
+ s << '"';
+ if (capped_cstr)
+ s << "...";
}
}
}
else
{
- error.SetErrorString("impossible to read a string from this object");
+ error.SetErrorString("not a string object");
s << "<not a string object>";
}
+ return total_bytes_read;
}
const char *
@@ -1244,7 +1321,7 @@
if (UpdateValueIfNeeded(true) && m_value_str.empty())
{
lldb::Format my_format = GetFormat();
- if (m_format == lldb::eFormatDefault)
+ if (my_format == lldb::eFormatDefault)
{
if (m_type_format_sp)
my_format = m_type_format_sp->GetFormat();
@@ -1314,7 +1391,7 @@
Format custom_format)
{
clang_type_t elem_or_pointee_type;
- Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
+ Flags flags(GetTypeInfo(&elem_or_pointee_type));
if (flags.AnySet(ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer)
&& val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
@@ -1358,7 +1435,7 @@
{
clang_type_t elem_or_pointee_type;
- Flags flags(ClangASTContext::GetTypeInfo(GetClangType(), GetClangAST(), &elem_or_pointee_type));
+ Flags flags(GetTypeInfo(&elem_or_pointee_type));
bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
@@ -1396,10 +1473,10 @@
if ((custom_format == eFormatBytes) ||
(custom_format == eFormatBytesWithASCII))
{
- uint32_t count = GetNumChildren();
+ const size_t count = GetNumChildren();
s << '[';
- for (uint32_t low = 0; low < count; low++)
+ for (size_t low = 0; low < count; low++)
{
if (low)
@@ -1432,12 +1509,12 @@
(custom_format == eFormatVectorOfUInt64) ||
(custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
{
- uint32_t count = GetNumChildren();
+ const size_t count = GetNumChildren();
Format format = FormatManager::GetSingleItemFormat(custom_format);
s << '[';
- for (uint32_t low = 0; low < count; low++)
+ for (size_t low = 0; low < count; low++)
{
if (low)
@@ -1486,8 +1563,8 @@
bool var_success = false;
{
- const char * return_value;
- std::string alloc_mem;
+ const char *cstr = NULL;
+ StreamString strm;
if (custom_format != eFormatInvalid)
SetFormat(custom_format);
@@ -1495,62 +1572,49 @@
switch(val_obj_display)
{
case eValueObjectRepresentationStyleValue:
- return_value = GetValueAsCString();
+ cstr = GetValueAsCString();
break;
case eValueObjectRepresentationStyleSummary:
- return_value = GetSummaryAsCString();
+ cstr = GetSummaryAsCString();
break;
case eValueObjectRepresentationStyleLanguageSpecific:
- return_value = GetObjectDescription();
+ cstr = GetObjectDescription();
break;
case eValueObjectRepresentationStyleLocation:
- return_value = GetLocationAsCString();
+ cstr = GetLocationAsCString();
break;
case eValueObjectRepresentationStyleChildrenCount:
- {
- alloc_mem.resize(512);
- return_value = &alloc_mem[0];
- int count = GetNumChildren();
- snprintf((char*)return_value, 512, "%d", count);
- }
+ strm.Printf("%zu", GetNumChildren());
+ cstr = strm.GetString().c_str();
break;
case eValueObjectRepresentationStyleType:
- return_value = GetTypeName().AsCString();
- break;
-
- default:
+ cstr = GetTypeName().AsCString();
break;
}
- if (!return_value)
+ if (!cstr)
{
if (val_obj_display == eValueObjectRepresentationStyleValue)
- return_value = GetSummaryAsCString();
+ cstr = GetSummaryAsCString();
else if (val_obj_display == eValueObjectRepresentationStyleSummary)
{
if (ClangASTContext::IsAggregateType (GetClangType()) == true)
{
- // this thing has no value, and it seems to have no summary
- // some combination of unitialized data and other factors can also
- // raise this condition, so let's print a nice generic description
- {
- alloc_mem.resize(684);
- return_value = &alloc_mem[0];
- snprintf((char*)return_value, 684, "%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
- }
+ strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
+ cstr = strm.GetString().c_str();
}
else
- return_value = GetValueAsCString();
+ cstr = GetValueAsCString();
}
}
- if (return_value)
- s.PutCString(return_value);
+ if (cstr)
+ s.PutCString(cstr);
else
{
if (m_error.Fail())
@@ -1631,7 +1695,7 @@
case Value::eValueTypeLoadAddress:
case Value::eValueTypeFileAddress:
{
- uint32_t data_offset = 0;
+ lldb::offset_t data_offset = 0;
address = m_data.GetPointer(&data_offset);
}
break;
@@ -1787,6 +1851,12 @@
return synthetic_child_sp;
}
+uint32_t
+ValueObject::GetTypeInfo (clang_type_t *pointee_or_element_clang_type)
+{
+ return ClangASTContext::GetTypeInfo (GetClangType(), GetClangAST(), pointee_or_element_clang_type);
+}
+
bool
ValueObject::IsPointerType ()
{
@@ -1796,7 +1866,7 @@
bool
ValueObject::IsArrayType ()
{
- return ClangASTContext::IsArrayType (GetClangType());
+ return ClangASTContext::IsArrayType (GetClangType(), NULL, NULL, NULL);
}
bool
@@ -1828,13 +1898,23 @@
return ClangASTContext::IsPossibleDynamicType (GetClangAST (), GetClangType(), NULL, true, true);
}
+bool
+ValueObject::IsObjCNil ()
+{
+ bool isObjCpointer = ClangASTContext::IsObjCObjectPointerType(GetClangType(), NULL);
+ bool canReadValue = true;
+ bool isZero = GetValueAsUnsigned(0,&canReadValue) == 0;
+ return canReadValue && isZero && isObjCpointer;
+}
+
ValueObjectSP
-ValueObject::GetSyntheticArrayMember (int32_t index, bool can_create)
+ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
{
- if (IsArrayType())
+ const uint32_t type_info = GetTypeInfo ();
+ if (type_info & ClangASTContext::eTypeIsArray)
return GetSyntheticArrayMemberFromArray(index, can_create);
- if (IsPointerType())
+ if (type_info & ClangASTContext::eTypeIsPointer)
return GetSyntheticArrayMemberFromPointer(index, can_create);
return ValueObjectSP();
@@ -1842,13 +1922,13 @@
}
ValueObjectSP
-ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
+ValueObject::GetSyntheticArrayMemberFromPointer (size_t index, bool can_create)
{
ValueObjectSP synthetic_child_sp;
if (IsPointerType ())
{
char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%i]", index);
+ snprintf(index_str, sizeof(index_str), "[%zu]", index);
ConstString index_const_str(index_str);
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
@@ -1885,13 +1965,13 @@
// there are more items in "item_array".
ValueObjectSP
-ValueObject::GetSyntheticArrayMemberFromArray (int32_t index, bool can_create)
+ValueObject::GetSyntheticArrayMemberFromArray (size_t index, bool can_create)
{
ValueObjectSP synthetic_child_sp;
if (IsArrayType ())
{
char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%i]", index);
+ snprintf(index_str, sizeof(index_str), "[%zu]", index);
ConstString index_const_str(index_str);
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
@@ -1959,42 +2039,6 @@
}
ValueObjectSP
-ValueObject::GetSyntheticArrayRangeChild (uint32_t from, uint32_t to, bool can_create)
-{
- ValueObjectSP synthetic_child_sp;
- if (IsArrayType () || IsPointerType ())
- {
- char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
- ConstString index_const_str(index_str);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
- synthetic_child_sp = GetSyntheticChild (index_const_str);
- if (!synthetic_child_sp)
- {
- ValueObjectSynthetic *synthetic_child;
-
- // We haven't made a synthetic array member for INDEX yet, so
- // lets make one and cache it for any future reference.
- SyntheticArrayView *view = new SyntheticArrayView(SyntheticChildren::Flags());
- view->AddRange(from,to);
- SyntheticChildrenSP view_sp(view);
- synthetic_child = new ValueObjectSynthetic(*this, view_sp);
-
- // Cache the value if we got one back...
- if (synthetic_child)
- {
- AddSyntheticChild(index_const_str, synthetic_child);
- synthetic_child_sp = synthetic_child->GetSP();
- synthetic_child_sp->SetName(ConstString(index_str));
- synthetic_child_sp->m_is_bitfield_for_scalar = true;
- }
- }
- }
- return synthetic_child_sp;
-}
-
-ValueObjectSP
ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
{
@@ -2071,9 +2115,9 @@
// Cache the value if we got one back...
if (synthetic_child_sp.get())
{
+ // FIXME: this causes a "real" child to end up with its name changed to the contents of expression
AddSyntheticChild(name_const_string, synthetic_child_sp.get());
synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
- synthetic_child_sp->m_is_expression_path_child = true;
}
}
return synthetic_child_sp;
@@ -2094,7 +2138,7 @@
lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
- if (!UpdateFormatsIfNeeded(m_last_format_mgr_dynamic) && m_synthetic_value)
+ if (!UpdateFormatsIfNeeded() && m_synthetic_value)
return;
if (m_synthetic_children_sp.get() == NULL)
@@ -2169,7 +2213,7 @@
bool
ValueObject::HasSyntheticValue()
{
- UpdateFormatsIfNeeded(m_last_format_mgr_dynamic);
+ UpdateFormatsIfNeeded();
if (m_synthetic_children_sp.get() == NULL)
return false;
@@ -2300,8 +2344,8 @@
{
const char* dummy_first_unparsed;
- ExpressionPathScanEndReason dummy_reason_to_stop;
- ExpressionPathEndResultType dummy_final_value_type;
+ ExpressionPathScanEndReason dummy_reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnknown;
+ ExpressionPathEndResultType dummy_final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
@@ -2532,7 +2576,7 @@
if (child_valobj_sp.get()) // we know we are done, so just return
{
- *first_unparsed = '\0';
+ *first_unparsed = "";
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
return child_valobj_sp;
@@ -2556,7 +2600,7 @@
// so we hit the "else" branch, and return an error
if(child_valobj_sp.get()) // if it worked, just return
{
- *first_unparsed = '\0';
+ *first_unparsed = "";
*reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
*final_result = ValueObject::eExpressionPathEndResultTypePlain;
return child_valobj_sp;
@@ -2973,8 +3017,8 @@
}
else // expand this into list
{
- int max_index = root->GetNumChildren() - 1;
- for (int index = 0; index < max_index; index++)
+ const size_t max_index = root->GetNumChildren() - 1;
+ for (size_t index = 0; index < max_index; index++)
{
ValueObjectSP child =
root->GetChildAtIndex(index, true);
@@ -3010,8 +3054,8 @@
{
if (root_clang_type_info.Test(ClangASTContext::eTypeIsArray))
{
- int max_index = root->GetNumChildren() - 1;
- for (int index = 0; index < max_index; index++)
+ const size_t max_index = root->GetNumChildren() - 1;
+ for (size_t index = 0; index < max_index; index++)
{
ValueObjectSP child =
root->GetChildAtIndex(index, true);
@@ -3211,7 +3255,7 @@
{
if (valobj)
{
- bool update_success = valobj->UpdateValueIfNeeded (options.m_use_dynamic, true);
+ bool update_success = valobj->UpdateValueIfNeeded (true);
const char *root_valobj_name =
options.m_root_valobj_name.empty() ?
@@ -3252,47 +3296,19 @@
show_type = options.m_show_types || (curr_depth == 0 && !options.m_flat_output);
if (show_type)
- {
- const char* typeName = valobj->GetQualifiedTypeName().AsCString("<invalid type>");
- //const char* typeName = valobj->GetTypeName().AsCString("<invalid type>");
- s.Printf("(%s", typeName);
- // only show dynamic types if the user really wants to see types
- if (options.m_show_types && options.m_use_dynamic != eNoDynamicValues &&
- (/*strstr(typeName, "id") == typeName ||*/
- ClangASTType::GetMinimumLanguage(valobj->GetClangAST(), valobj->GetClangType()) == eLanguageTypeObjC))
- {
- ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- s.Printf(", dynamic type: unknown) ");
- else
- {
- ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
- if (runtime == NULL)
- s.Printf(", dynamic type: unknown) ");
- else
- {
- ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetNonKVOClassDescriptor(*valobj));
- if (objc_class_sp)
- s.Printf(", dynamic type: %s) ", objc_class_sp->GetClassName().GetCString());
- else
- s.Printf(", dynamic type: unknown) ");
- }
- }
- }
- else
- s.Printf(") ");
- }
-
+ s.Printf("(%s) ", valobj->GetQualifiedTypeName().AsCString("<invalid type>"));
if (options.m_flat_output)
{
// If we are showing types, also qualify the C++ base classes
const bool qualify_cxx_base_classes = options.m_show_types;
- valobj->GetExpressionPath(s, qualify_cxx_base_classes);
- s.PutCString(" =");
+ if (!options.m_hide_name)
+ {
+ valobj->GetExpressionPath(s, qualify_cxx_base_classes);
+ s.PutCString(" =");
+ }
}
- else
+ else if (!options.m_hide_name)
{
const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
s.Printf ("%s =", name_cstr);
@@ -3313,6 +3329,8 @@
if (options.m_omit_summary_depth > 0)
entry = NULL;
+ bool is_nil = valobj->IsObjCNil();
+
if (err_cstr == NULL)
{
if (options.m_format != eFormatDefault && options.m_format != valobj->GetFormat())
@@ -3338,7 +3356,9 @@
const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
if (print_valobj)
{
- if (options.m_omit_summary_depth == 0)
+ if (is_nil)
+ sum_cstr = "nil";
+ else if (options.m_omit_summary_depth == 0)
{
if (options.m_summary_sp)
{
@@ -3350,20 +3370,24 @@
}
// Make sure we have a value and make sure the summary didn't
- // specify that the value should not be printed
- if (!value_str.empty() && (entry == NULL || entry->DoesPrintValue() || sum_cstr == NULL))
+ // specify that the value should not be printed - and do not print
+ // the value if this thing is nil
+ if (!is_nil && !value_str.empty() && (entry == NULL || entry->DoesPrintValue() || sum_cstr == NULL) && !options.m_hide_value)
s.Printf(" %s", value_str.c_str());
if (sum_cstr)
s.Printf(" %s", sum_cstr);
- if (options.m_use_objc)
+ // let's avoid the overly verbose no description error for a nil thing
+ if (options.m_use_objc && !is_nil)
{
+ if (!options.m_hide_value || !options.m_hide_name)
+ s.Printf(" ");
const char *object_desc = valobj->GetObjectDescription();
if (object_desc)
- s.Printf(" %s\n", object_desc);
+ s.Printf("%s\n", object_desc);
else
- s.Printf (" [no Objective-C description available]\n");
+ s.Printf ("[no Objective-C description available]\n");
return;
}
}
@@ -3408,7 +3432,7 @@
ValueObjectSP synth_valobj_sp = valobj->GetSyntheticValue (options.m_use_synthetic);
synth_valobj = (synth_valobj_sp ? synth_valobj_sp.get() : valobj);
- uint32_t num_children = synth_valobj->GetNumChildren();
+ size_t num_children = synth_valobj->GetNumChildren();
bool print_dotdotdot = false;
if (num_children)
{
@@ -3424,7 +3448,7 @@
s.IndentMore();
}
- uint32_t max_num_children = valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+ const size_t max_num_children = valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
if (num_children > max_num_children && !options.m_ignore_cap)
{
@@ -3433,10 +3457,10 @@
}
ValueObject::DumpValueObjectOptions child_options(options);
- child_options.SetFormat().SetSummary().SetRootValueObjectName();
- child_options.SetScopeChecked(true)
+ child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
+ child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
.SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
- for (uint32_t idx=0; idx<num_children; ++idx)
+ for (size_t idx=0; idx<num_children; ++idx)
{
ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true));
if (child_sp.get())
@@ -3672,7 +3696,6 @@
{
switch (address_type)
{
- default:
case eAddressTypeInvalid:
{
StreamString expr_path_strm;
Index: aze/lldb/source/Core/ValueObjectDynamicValue.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectDynamicValue.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectDynamicValue.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -38,10 +38,9 @@
ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
ValueObject(parent),
m_address (),
- m_type_sp(),
+ m_dynamic_type_info(),
m_use_dynamic (use_dynamic)
{
- m_last_format_mgr_dynamic = use_dynamic;
SetName (parent.GetName());
}
@@ -53,7 +52,7 @@
lldb::clang_type_t
ValueObjectDynamicValue::GetClangTypeImpl ()
{
- if (m_type_sp)
+ if (m_dynamic_type_info.HasTypeSP())
return m_value.GetClangType();
else
return m_parent->GetClangType();
@@ -63,17 +62,35 @@
ValueObjectDynamicValue::GetTypeName()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
- return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
- else
- return m_parent->GetTypeName();
+ if (success)
+ {
+ if (m_dynamic_type_info.HasTypeSP())
+ return ClangASTType::GetConstTypeName (GetClangAST(), GetClangType());
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetTypeName();
+}
+
+ConstString
+ValueObjectDynamicValue::GetQualifiedTypeName()
+{
+ const bool success = UpdateValueIfNeeded(false);
+ if (success)
+ {
+ if (m_dynamic_type_info.HasTypeSP())
+ return ClangASTType::GetConstQualifiedTypeName (GetClangAST(), GetClangType());
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetTypeName();
}
-uint32_t
+size_t
ValueObjectDynamicValue::CalculateNumChildren()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
+ if (success && m_dynamic_type_info.HasTypeSP())
return ClangASTContext::GetNumChildren (GetClangAST (), GetClangType(), true);
else
return m_parent->GetNumChildren();
@@ -83,8 +100,8 @@
ValueObjectDynamicValue::GetClangASTImpl ()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
- return m_type_sp->GetClangAST();
+ if (success && m_dynamic_type_info.HasTypeSP())
+ return m_dynamic_type_info.GetTypeSP()->GetClangAST();
else
return m_parent->GetClangAST ();
}
@@ -93,7 +110,7 @@
ValueObjectDynamicValue::GetByteSize()
{
const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_sp)
+ if (success && m_dynamic_type_info.HasTypeSP())
return m_value.GetValueByteSize(GetClangAST(), NULL);
else
return m_parent->GetByteSize();
@@ -123,7 +140,7 @@
// parent which is equivalent to not using dynamic values.
if (m_use_dynamic == lldb::eNoDynamicValues)
{
- m_type_sp.reset();
+ m_dynamic_type_info.Clear();
return true;
}
@@ -165,8 +182,6 @@
}
}
- lldb::TypeSP dynamic_type_sp = class_type_or_name.GetTypeSP();
-
// Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
// don't...
@@ -176,8 +191,10 @@
// Or we could return false, and make ourselves an echo of our parent?
if (!found_dynamic_type)
{
- if (m_type_sp)
+ if (m_dynamic_type_info)
SetValueDidChange(true);
+ ClearDynamicTypeInformation();
+ m_dynamic_type_info.Clear();
m_value = m_parent->GetValue();
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST(), m_data, 0, GetModule().get());
return m_error.Success();
@@ -189,15 +206,15 @@
bool has_changed_type = false;
- if (!m_type_sp)
+ if (!m_dynamic_type_info)
{
- m_type_sp = dynamic_type_sp;
+ m_dynamic_type_info = class_type_or_name;
has_changed_type = true;
}
- else if (dynamic_type_sp != m_type_sp)
+ else if (class_type_or_name != m_dynamic_type_info)
{
// We are another type, we need to tear down our children...
- m_type_sp = dynamic_type_sp;
+ m_dynamic_type_info = class_type_or_name;
SetValueDidChange (true);
has_changed_type = true;
}
@@ -217,16 +234,34 @@
m_value.GetScalar() = load_address;
}
- // The type will always be the type of the dynamic object. If our parent's type was a pointer,
- // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
- // should be okay...
- lldb::clang_type_t orig_type = m_type_sp->GetClangForwardType();
- lldb::clang_type_t corrected_type = orig_type;
- if (m_parent->IsPointerType())
- corrected_type = ClangASTContext::CreatePointerType (m_type_sp->GetClangAST(), orig_type);
- else if (m_parent->IsPointerOrReferenceType())
- corrected_type = ClangASTContext::CreateLValueReferenceType (m_type_sp->GetClangAST(), orig_type);
-
+ lldb::clang_type_t corrected_type;
+ if (m_dynamic_type_info.HasTypeSP())
+ {
+ // The type will always be the type of the dynamic object. If our parent's type was a pointer,
+ // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type
+ // should be okay...
+ lldb::clang_type_t orig_type;
+ clang::ASTContext* ast;
+ orig_type = m_dynamic_type_info.GetTypeSP()->GetClangForwardType();
+ ast = m_dynamic_type_info.GetTypeSP()->GetClangAST();
+ corrected_type = orig_type;
+ if (m_parent->IsPointerType())
+ corrected_type = ClangASTContext::CreatePointerType (ast, orig_type);
+ else if (m_parent->IsPointerOrReferenceType())
+ corrected_type = ClangASTContext::CreateLValueReferenceType (ast, orig_type);
+ }
+ else /*if (m_dynamic_type_info.HasName())*/
+ {
+ // If we are here we need to adjust our dynamic type name to include the correct & or * symbol
+ std::string type_name_buf (m_dynamic_type_info.GetName().GetCString());
+ if (m_parent->IsPointerType())
+ type_name_buf.append(" *");
+ else if (m_parent->IsPointerOrReferenceType())
+ type_name_buf.append(" &");
+ corrected_type = m_parent->GetClangType();
+ m_dynamic_type_info.SetName(type_name_buf.c_str());
+ }
+
m_value.SetContext (Value::eContextTypeClangType, corrected_type);
// Our address is the location of the dynamic type stored in memory. It isn't a load address,
@@ -239,7 +274,7 @@
this,
GetTypeName().GetCString());
- if (m_address.IsValid() && m_type_sp)
+ if (m_address.IsValid() && m_dynamic_type_info)
{
// The variable value is in the Scalar value inside the m_value.
// We can point our m_data right to it.
Index: aze/lldb/source/Core/ValueObjectList.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectList.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -61,20 +61,20 @@
}
-uint32_t
+size_t
ValueObjectList::GetSize() const
{
return m_value_objects.size();
}
void
-ValueObjectList::Resize (uint32_t size)
+ValueObjectList::Resize (size_t size)
{
m_value_objects.resize (size);
}
lldb::ValueObjectSP
-ValueObjectList::GetValueObjectAtIndex (uint32_t idx)
+ValueObjectList::GetValueObjectAtIndex (size_t idx)
{
lldb::ValueObjectSP valobj_sp;
if (idx < m_value_objects.size())
@@ -83,7 +83,7 @@
}
lldb::ValueObjectSP
-ValueObjectList::RemoveValueObjectAtIndex (uint32_t idx)
+ValueObjectList::RemoveValueObjectAtIndex (size_t idx)
{
lldb::ValueObjectSP valobj_sp;
if (idx < m_value_objects.size())
@@ -95,7 +95,7 @@
}
void
-ValueObjectList::SetValueObjectAtIndex (uint32_t idx, const ValueObjectSP &valobj_sp)
+ValueObjectList::SetValueObjectAtIndex (size_t idx, const ValueObjectSP &valobj_sp)
{
if (idx >= m_value_objects.size())
m_value_objects.resize (idx + 1);
Index: aze/lldb/source/Core/ValueObjectMemory.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectMemory.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectMemory.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -146,7 +146,7 @@
return ClangASTType::GetConstTypeName (GetClangAST(), m_clang_type.GetOpaqueQualType());
}
-uint32_t
+size_t
ValueObjectMemory::CalculateNumChildren()
{
if (m_type_sp)
Index: aze/lldb/source/Core/ValueObjectRegister.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectRegister.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectRegister.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -60,7 +60,7 @@
return ConstString();
}
-uint32_t
+size_t
ValueObjectRegisterContext::CalculateNumChildren()
{
return m_reg_ctx_sp->GetRegisterSetCount();
@@ -101,11 +101,11 @@
}
ValueObject *
-ValueObjectRegisterContext::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
ValueObject *new_valobj = NULL;
- const uint32_t num_children = GetNumChildren();
+ const size_t num_children = GetNumChildren();
if (idx < num_children)
{
ExecutionContext exe_ctx(GetExecutionContextRef());
@@ -162,7 +162,7 @@
return ConstString();
}
-uint32_t
+size_t
ValueObjectRegisterSet::CalculateNumChildren()
{
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
@@ -222,12 +222,12 @@
ValueObject *
-ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
+ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
ValueObject *valobj = NULL;
if (m_reg_ctx_sp && m_reg_set)
{
- const uint32_t num_children = GetNumChildren();
+ const size_t num_children = GetNumChildren();
if (idx < num_children)
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
}
@@ -250,7 +250,7 @@
return ValueObjectSP();
}
-uint32_t
+size_t
ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
{
if (m_reg_ctx_sp && m_reg_set)
@@ -341,7 +341,7 @@
return m_type_name;
}
-uint32_t
+size_t
ValueObjectRegister::CalculateNumChildren()
{
return 0;
Index: aze/lldb/source/Core/ValueObjectSyntheticFilter.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectSyntheticFilter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectSyntheticFilter.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
#include "lldb/Core/ValueObjectSyntheticFilter.h"
@@ -14,8 +15,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatClasses.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/DataFormatters/FormatClasses.h"
using namespace lldb_private;
@@ -26,19 +27,19 @@
SyntheticChildrenFrontEnd(backend)
{}
- uint32_t
+ size_t
CalculateNumChildren()
{
return 0;
}
lldb::ValueObjectSP
- GetChildAtIndex (uint32_t idx)
+ GetChildAtIndex (size_t idx)
{
return lldb::ValueObjectSP();
}
- uint32_t
+ size_t
GetIndexOfChildWithName (const ConstString &name)
{
return UINT32_MAX;
@@ -94,7 +95,13 @@
return m_parent->GetTypeName();
}
-uint32_t
+ConstString
+ValueObjectSynthetic::GetQualifiedTypeName()
+{
+ return m_parent->GetQualifiedTypeName();
+}
+
+size_t
ValueObjectSynthetic::CalculateNumChildren()
{
UpdateValueIfNeeded();
@@ -103,6 +110,16 @@
return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren());
}
+lldb::ValueObjectSP
+ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
+{
+ if (!m_parent)
+ return lldb::ValueObjectSP();
+ if (IsDynamic() && GetDynamicValueType() == valueType)
+ return GetSP();
+ return m_parent->GetDynamicValue(valueType);
+}
+
bool
ValueObjectSynthetic::MightHaveChildren()
{
@@ -182,7 +199,7 @@
}
lldb::ValueObjectSP
-ValueObjectSynthetic::GetChildAtIndex (uint32_t idx, bool can_create)
+ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
{
UpdateValueIfNeeded();
@@ -218,7 +235,7 @@
return GetChildAtIndex(index, can_create);
}
-uint32_t
+size_t
ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
{
UpdateValueIfNeeded();
Index: aze/lldb/source/Core/ValueObjectVariable.cpp
===================================================================
--- aze.orig/lldb/source/Core/ValueObjectVariable.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/ValueObjectVariable.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -80,7 +80,7 @@
return ConstString();
}
-uint32_t
+size_t
ValueObjectVariable::CalculateNumChildren()
{
ClangASTType type(GetClangAST(),
Index: aze/lldb/source/Core/VMRange.cpp
===================================================================
--- aze.orig/lldb/source/Core/VMRange.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Core/VMRange.cpp 2013-03-03 09:35:50.171457353 +0100
@@ -40,7 +40,7 @@
return false;
}
-uint32_t
+size_t
VMRange::FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value)
{
ValueInRangeUnaryPredicate in_range_predicate(value);
Index: aze/lldb/source/DataFormatters/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/CMakeLists.txt 2013-03-03 09:35:50.171457353 +0100
@@ -0,0 +1,19 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbDataFormatters
+ CXXFormatterFunctions.cpp
+ DataVisualization.cpp
+ FormatCache.cpp
+ FormatClasses.cpp
+ FormatManager.cpp
+ LibCxx.cpp
+ LibStdcpp.cpp
+ NSArray.cpp
+ NSDictionary.cpp
+ NSSet.cpp
+ TypeCategory.cpp
+ TypeCategoryMap.cpp
+ TypeFormat.cpp
+ TypeSummary.cpp
+ TypeSynthetic.cpp
+ )
Index: aze/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/CXXFormatterFunctions.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,1162 @@
+//===-- CXXFormatterFunctions.cpp---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "llvm/Support/ConvertUTF.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::ExtractValueFromObjCExpression (ValueObject &valobj,
+ const char* target_type,
+ const char* selector,
+ uint64_t &value)
+{
+ if (!target_type || !*target_type)
+ return false;
+ if (!selector || !*selector)
+ return false;
+ StreamString expr;
+ expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
+ ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+ lldb::ValueObjectSP result_sp;
+ Target* target = exe_ctx.GetTargetPtr();
+ StackFrame* stack_frame = exe_ctx.GetFramePtr();
+ if (!target || !stack_frame)
+ return false;
+
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true);
+
+ target->EvaluateExpression(expr.GetData(),
+ stack_frame,
+ result_sp,
+ options);
+ if (!result_sp)
+ return false;
+ value = result_sp->GetValueAsUnsigned(0);
+ return true;
+}
+
+bool
+lldb_private::formatters::ExtractSummaryFromObjCExpression (ValueObject &valobj,
+ const char* target_type,
+ const char* selector,
+ Stream &stream)
+{
+ if (!target_type || !*target_type)
+ return false;
+ if (!selector || !*selector)
+ return false;
+ StreamString expr;
+ expr.Printf("(%s)[(id)0x%" PRIx64 " %s]",target_type,valobj.GetPointerValue(),selector);
+ ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+ lldb::ValueObjectSP result_sp;
+ Target* target = exe_ctx.GetTargetPtr();
+ StackFrame* stack_frame = exe_ctx.GetFramePtr();
+ if (!target || !stack_frame)
+ return false;
+
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true)
+ .SetUseDynamic(lldb::eDynamicCanRunTarget);
+
+ target->EvaluateExpression(expr.GetData(),
+ stack_frame,
+ result_sp,
+ options);
+ if (!result_sp)
+ return false;
+ stream.Printf("%s",result_sp->GetSummaryAsCString());
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
+ const char* return_type,
+ const char* selector,
+ uint64_t index)
+{
+ lldb::ValueObjectSP valobj_sp;
+ if (!return_type || !*return_type)
+ return valobj_sp;
+ if (!selector || !*selector)
+ return valobj_sp;
+ StreamString expr_path_stream;
+ valobj.GetExpressionPath(expr_path_stream, false);
+ StreamString expr;
+ expr.Printf("(%s)[%s %s:%" PRId64 "]",return_type,expr_path_stream.GetData(),selector,index);
+ ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+ lldb::ValueObjectSP result_sp;
+ Target* target = exe_ctx.GetTargetPtr();
+ StackFrame* stack_frame = exe_ctx.GetFramePtr();
+ if (!target || !stack_frame)
+ return valobj_sp;
+
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true)
+ .SetUseDynamic(lldb::eDynamicCanRunTarget);
+
+ target->EvaluateExpression(expr.GetData(),
+ stack_frame,
+ valobj_sp,
+ options);
+ return valobj_sp;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::CallSelectorOnObject (ValueObject &valobj,
+ const char* return_type,
+ const char* selector,
+ const char* key)
+{
+ lldb::ValueObjectSP valobj_sp;
+ if (!return_type || !*return_type)
+ return valobj_sp;
+ if (!selector || !*selector)
+ return valobj_sp;
+ if (!key || !*key)
+ return valobj_sp;
+ StreamString expr_path_stream;
+ valobj.GetExpressionPath(expr_path_stream, false);
+ StreamString expr;
+ expr.Printf("(%s)[%s %s:%s]",return_type,expr_path_stream.GetData(),selector,key);
+ ExecutionContext exe_ctx (valobj.GetExecutionContextRef());
+ lldb::ValueObjectSP result_sp;
+ Target* target = exe_ctx.GetTargetPtr();
+ StackFrame* stack_frame = exe_ctx.GetFramePtr();
+ if (!target || !stack_frame)
+ return valobj_sp;
+
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true)
+ .SetUseDynamic(lldb::eDynamicCanRunTarget);
+
+ target->EvaluateExpression(expr.GetData(),
+ stack_frame,
+ valobj_sp,
+ options);
+ return valobj_sp;
+}
+
+// use this call if you already have an LLDB-side buffer for the data
+template<typename SourceDataType>
+static bool
+DumpUTFBufferToStream (ConversionResult (*ConvertFunction) (const SourceDataType**,
+ const SourceDataType*,
+ UTF8**,
+ UTF8*,
+ ConversionFlags),
+ DataExtractor& data,
+ Stream& stream,
+ char prefix_token = '@',
+ char quote = '"',
+ int sourceSize = 0)
+{
+ if (prefix_token != 0)
+ stream.Printf("%c",prefix_token);
+ if (quote != 0)
+ stream.Printf("%c",quote);
+ if (data.GetByteSize() && data.GetDataStart() && data.GetDataEnd())
+ {
+ const int bufferSPSize = data.GetByteSize();
+ if (sourceSize == 0)
+ {
+ const int origin_encoding = 8*sizeof(SourceDataType);
+ sourceSize = bufferSPSize/(origin_encoding / 4);
+ }
+
+ SourceDataType *data_ptr = (SourceDataType*)data.GetDataStart();
+ SourceDataType *data_end_ptr = data_ptr + sourceSize;
+
+ while (data_ptr < data_end_ptr)
+ {
+ if (!*data_ptr)
+ {
+ data_end_ptr = data_ptr;
+ break;
+ }
+ data_ptr++;
+ }
+
+ data_ptr = (SourceDataType*)data.GetDataStart();
+
+ lldb::DataBufferSP utf8_data_buffer_sp;
+ UTF8* utf8_data_ptr = nullptr;
+ UTF8* utf8_data_end_ptr = nullptr;
+
+ if (ConvertFunction)
+ {
+ utf8_data_buffer_sp.reset(new DataBufferHeap(bufferSPSize,0));
+ utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes();
+ utf8_data_end_ptr = utf8_data_ptr + bufferSPSize;
+ ConvertFunction ( (const SourceDataType**)&data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, lenientConversion );
+ utf8_data_ptr = (UTF8*)utf8_data_buffer_sp->GetBytes(); // needed because the ConvertFunction will change the value of the data_ptr
+ }
+ else
+ {
+ // just copy the pointers - the cast is necessary to make the compiler happy
+ // but this should only happen if we are reading UTF8 data
+ utf8_data_ptr = (UTF8*)data_ptr;
+ utf8_data_end_ptr = (UTF8*)data_end_ptr;
+ }
+
+ // since we tend to accept partial data (and even partially malformed data)
+ // we might end up with no NULL terminator before the end_ptr
+ // hence we need to take a slower route and ensure we stay within boundaries
+ for (;utf8_data_ptr != utf8_data_end_ptr; utf8_data_ptr++)
+ {
+ if (!*utf8_data_ptr)
+ break;
+ stream.Printf("%c",*utf8_data_ptr);
+ }
+ }
+ if (quote != 0)
+ stream.Printf("%c",quote);
+ return true;
+}
+
+template<typename SourceDataType>
+static bool
+ReadUTFBufferAndDumpToStream (ConversionResult (*ConvertFunction) (const SourceDataType**,
+ const SourceDataType*,
+ UTF8**,
+ UTF8*,
+ ConversionFlags),
+ uint64_t location,
+ const ProcessSP& process_sp,
+ Stream& stream,
+ char prefix_token = '@',
+ char quote = '"',
+ int sourceSize = 0)
+{
+ if (location == 0 || location == LLDB_INVALID_ADDRESS)
+ return false;
+ if (!process_sp)
+ return false;
+
+ const int origin_encoding = 8*sizeof(SourceDataType);
+ if (origin_encoding != 8 && origin_encoding != 16 && origin_encoding != 32)
+ return false;
+ // if not UTF8, I need a conversion function to return proper UTF8
+ if (origin_encoding != 8 && !ConvertFunction)
+ return false;
+
+ if (sourceSize == 0)
+ sourceSize = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
+ const int bufferSPSize = sourceSize * (origin_encoding >> 2);
+
+ Error error;
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(bufferSPSize,0));
+
+ if (!buffer_sp->GetBytes())
+ return false;
+
+ size_t data_read = process_sp->ReadMemoryFromInferior(location, (char*)buffer_sp->GetBytes(), bufferSPSize, error);
+ if (error.Fail() || data_read == 0)
+ {
+ stream.Printf("unable to read data");
+ return true;
+ }
+
+ DataExtractor data(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
+
+ return DumpUTFBufferToStream(ConvertFunction, data, stream, prefix_token, quote, sourceSize);
+}
+
+bool
+lldb_private::formatters::Char16StringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ if (!ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8,valobj_addr,
+ process_sp,
+ stream,
+ 'u'))
+ {
+ stream.Printf("Summary Unavailable");
+ return true;
+ }
+
+ return true;
+}
+
+bool
+lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ if (!ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8,valobj_addr,
+ process_sp,
+ stream,
+ 'U'))
+ {
+ stream.Printf("Summary Unavailable");
+ return true;
+ }
+
+ return true;
+}
+
+bool
+lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t data_addr = 0;
+
+ if (valobj.IsPointerType())
+ data_addr = valobj.GetValueAsUnsigned(0);
+ else if (valobj.IsArrayType())
+ data_addr = valobj.GetAddressOf();
+
+ if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ clang::ASTContext* ast = valobj.GetClangAST();
+
+ if (!ast)
+ return false;
+
+ uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType());
+
+ switch (wchar_size)
+ {
+ case 8:
+ // utf 8
+ return ReadUTFBufferAndDumpToStream<UTF8>(nullptr, data_addr,
+ process_sp,
+ stream,
+ 'L');
+ case 16:
+ // utf 16
+ return ReadUTFBufferAndDumpToStream<UTF16>(ConvertUTF16toUTF8, data_addr,
+ process_sp,
+ stream,
+ 'L');
+ case 32:
+ // utf 32
+ return ReadUTFBufferAndDumpToStream<UTF32>(ConvertUTF32toUTF8, data_addr,
+ process_sp,
+ stream,
+ 'L');
+ default:
+ stream.Printf("size for wchar_t is not valid");
+ return true;
+ }
+ return true;
+}
+
+bool
+lldb_private::formatters::Char16SummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ DataExtractor data;
+ valobj.GetData(data);
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ return DumpUTFBufferToStream<UTF16>(ConvertUTF16toUTF8,data,stream, 'u','\'',1);
+}
+
+bool
+lldb_private::formatters::Char32SummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ DataExtractor data;
+ valobj.GetData(data);
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ return DumpUTFBufferToStream<UTF32>(ConvertUTF32toUTF8,data,stream, 'U','\'',1);
+}
+
+bool
+lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ DataExtractor data;
+ valobj.GetData(data);
+
+ clang::ASTContext* ast = valobj.GetClangAST();
+
+ if (!ast)
+ return false;
+
+ std::string value;
+
+ uint32_t wchar_size = ClangASTType::GetClangTypeBitWidth(ast, ClangASTType::GetBasicType(ast, lldb::eBasicTypeWChar).GetOpaqueQualType());
+
+ switch (wchar_size)
+ {
+ case 8:
+ // utf 8
+ valobj.GetValueAsCString(lldb::eFormatChar, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+ return DumpUTFBufferToStream<UTF8>(nullptr,
+ data,
+ stream,
+ 'L',
+ '\'',
+ 1);
+ case 16:
+ // utf 16
+ valobj.GetValueAsCString(lldb::eFormatUnicode16, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+ return DumpUTFBufferToStream<UTF16>(ConvertUTF16toUTF8,
+ data,
+ stream,
+ 'L',
+ '\'',
+ 1);
+ case 32:
+ // utf 32
+ valobj.GetValueAsCString(lldb::eFormatUnicode32, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+ return DumpUTFBufferToStream<UTF32>(ConvertUTF32toUTF8,
+ data,
+ stream,
+ 'L',
+ '\'',
+ 1);
+ default:
+ stream.Printf("size for wchar_t is not valid");
+ return true;
+ }
+ return true;
+}
+
+// this function extracts information from a libcxx std::basic_string<>
+// irregardless of template arguments. it reports the size (in item count not bytes)
+// and the location in memory where the string data can be found
+static bool
+ExtractLibcxxStringInfo (ValueObject& valobj,
+ ValueObjectSP &location_sp,
+ uint64_t& size)
+{
+ ValueObjectSP D(valobj.GetChildAtIndexPath({0,0,0,0}));
+ if (!D)
+ return false;
+
+ ValueObjectSP size_mode(D->GetChildAtIndexPath({1,0,0}));
+ if (!size_mode)
+ return false;
+
+ uint64_t size_mode_value(size_mode->GetValueAsUnsigned(0));
+
+ if ((size_mode_value & 1) == 0) // this means the string is in short-mode and the data is stored inline
+ {
+ ValueObjectSP s(D->GetChildAtIndex(1, true));
+ if (!s)
+ return false;
+ size = ((size_mode_value >> 1) % 256);
+ location_sp = s->GetChildAtIndex(1, true);
+ return (location_sp.get() != nullptr);
+ }
+ else
+ {
+ ValueObjectSP l(D->GetChildAtIndex(0, true));
+ if (!l)
+ return false;
+ location_sp = l->GetChildAtIndex(2, true);
+ ValueObjectSP size_vo(l->GetChildAtIndex(1, true));
+ if (!size_vo || !location_sp)
+ return false;
+ size = size_vo->GetValueAsUnsigned(0);
+ return true;
+ }
+}
+
+bool
+lldb_private::formatters::LibcxxWStringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ uint64_t size = 0;
+ ValueObjectSP location_sp((ValueObject*)nullptr);
+ if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
+ return false;
+ if (size == 0)
+ {
+ stream.Printf("L\"\"");
+ return true;
+ }
+ if (!location_sp)
+ return false;
+ return WCharStringSummaryProvider(*location_sp.get(), stream);
+}
+
+bool
+lldb_private::formatters::LibcxxStringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ uint64_t size = 0;
+ ValueObjectSP location_sp((ValueObject*)nullptr);
+ if (!ExtractLibcxxStringInfo(valobj, location_sp, size))
+ return false;
+ if (size == 0)
+ {
+ stream.Printf("\"\"");
+ return true;
+ }
+ if (!location_sp)
+ return false;
+ Error error;
+ if (location_sp->ReadPointedString(stream,
+ error,
+ 0, // max length is decided by the settings
+ false) == 0) // do not honor array (terminates on first 0 byte even for a char[])
+ stream.Printf("\"\""); // if nothing was read, print an empty string
+ return error.Success();
+}
+
+template<bool needs_at>
+bool
+lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ bool is_64bit = (process_sp->GetAddressByteSize() == 8);
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"NSConcreteData") ||
+ !strcmp(class_name,"NSConcreteMutableData") ||
+ !strcmp(class_name,"__NSCFData"))
+ {
+ uint32_t offset = (is_64bit ? 16 : 8);
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ else
+ {
+ if (!ExtractValueFromObjCExpression(valobj, "int", "length", value))
+ return false;
+ }
+
+ stream.Printf("%s%" PRIu64 " byte%s%s",
+ (needs_at ? "@\"" : ""),
+ value,
+ (value > 1 ? "s" : ""),
+ (needs_at ? "\"" : ""));
+
+ return true;
+}
+
+bool
+lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber"))
+ {
+ if (descriptor->IsTagged())
+ {
+ // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them
+ int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8;
+ uint64_t i_bits = (valobj_addr & 0xF0) >> 4;
+
+ switch (i_bits)
+ {
+ case 0:
+ stream.Printf("(char)%hhd",(char)value);
+ break;
+ case 4:
+ stream.Printf("(short)%hd",(short)value);
+ break;
+ case 8:
+ stream.Printf("(int)%d",(int)value);
+ break;
+ case 12:
+ stream.Printf("(long)%" PRId64,value);
+ break;
+ default:
+ stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value);
+ break;
+ }
+ return true;
+ }
+ else
+ {
+ Error error;
+ uint8_t data_type = (process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, 1, 0, error) & 0x1F);
+ uint64_t data_location = valobj_addr + 2*ptr_size;
+ uint64_t value = 0;
+ if (error.Fail())
+ return false;
+ switch (data_type)
+ {
+ case 1: // 0B00001
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(char)%hhd",(char)value);
+ break;
+ case 2: // 0B0010
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(short)%hd",(short)value);
+ break;
+ case 3: // 0B0011
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(int)%d",(int)value);
+ break;
+ case 17: // 0B10001
+ data_location += 8;
+ case 4: // 0B0100
+ value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
+ if (error.Fail())
+ return false;
+ stream.Printf("(long)%" PRId64,value);
+ break;
+ case 5: // 0B0101
+ {
+ uint32_t flt_as_int = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0, error);
+ if (error.Fail())
+ return false;
+ float flt_value = *((float*)&flt_as_int);
+ stream.Printf("(float)%f",flt_value);
+ break;
+ }
+ case 6: // 0B0110
+ {
+ uint64_t dbl_as_lng = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0, error);
+ if (error.Fail())
+ return false;
+ double dbl_value = *((double*)&dbl_as_lng);
+ stream.Printf("(double)%g",dbl_value);
+ break;
+ }
+ default:
+ stream.Printf("absurd: dt=%d",data_type);
+ break;
+ }
+ return true;
+ }
+ }
+ else
+ {
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "stringValue", stream);
+ }
+}
+
+static bool
+ReadAsciiBufferAndDumpToStream (lldb::addr_t location,
+ lldb::ProcessSP& process_sp,
+ Stream& dest,
+ size_t size = 0,
+ Error* error = NULL,
+ size_t *data_read = NULL,
+ char prefix_token = '@',
+ char quote = '"')
+{
+ Error my_error;
+ size_t my_data_read;
+ if (!process_sp || location == 0)
+ return false;
+
+ if (size == 0)
+ size = process_sp->GetTarget().GetMaximumSizeOfStringSummary();
+
+ lldb::DataBufferSP buffer_sp(new DataBufferHeap(size,0));
+
+ my_data_read = process_sp->ReadCStringFromMemory(location, (char*)buffer_sp->GetBytes(), size, my_error);
+
+ if (error)
+ *error = my_error;
+ if (data_read)
+ *data_read = my_data_read;
+
+ if (my_error.Fail())
+ return false;
+ if (my_data_read)
+ dest.Printf("%c%c%s%c",prefix_token,quote,(char*)buffer_sp->GetBytes(),quote);
+
+ return true;
+}
+
+bool
+lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ uint64_t info_bits_location = valobj_addr + ptr_size;
+ if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
+ info_bits_location += 3;
+
+ Error error;
+
+ uint8_t info_bits = process_sp->ReadUnsignedIntegerFromMemory(info_bits_location, 1, 0, error);
+ if (error.Fail())
+ return false;
+
+ bool is_mutable = (info_bits & 1) == 1;
+ bool is_inline = (info_bits & 0x60) == 0;
+ bool has_explicit_length = (info_bits & (1 | 4)) != 4;
+ bool is_unicode = (info_bits & 0x10) == 0x10;
+ bool is_special = strcmp(class_name,"NSPathStore2") == 0;
+
+ if (strcmp(class_name,"NSString") &&
+ strcmp(class_name,"CFStringRef") &&
+ strcmp(class_name,"CFMutableStringRef") &&
+ strcmp(class_name,"__NSCFConstantString") &&
+ strcmp(class_name,"__NSCFString") &&
+ strcmp(class_name,"NSCFConstantString") &&
+ strcmp(class_name,"NSCFString") &&
+ strcmp(class_name,"NSPathStore2"))
+ {
+ // not one of us - but tell me class name
+ stream.Printf("class name = %s",class_name);
+ return true;
+ }
+
+ if (is_mutable)
+ {
+ uint64_t location = 2 * ptr_size + valobj_addr;
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ if (has_explicit_length and is_unicode)
+ return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8,location, process_sp, stream, '@');
+ else
+ return ReadAsciiBufferAndDumpToStream(location+1,process_sp,stream);
+ }
+ else if (is_inline && has_explicit_length && !is_unicode && !is_special && !is_mutable)
+ {
+ uint64_t location = 3 * ptr_size + valobj_addr;
+ return ReadAsciiBufferAndDumpToStream(location,process_sp,stream);
+ }
+ else if (is_unicode)
+ {
+ uint64_t location = valobj_addr + 2*ptr_size;
+ if (is_inline)
+ {
+ if (!has_explicit_length)
+ {
+ stream.Printf("found new combo");
+ return true;
+ }
+ else
+ location += ptr_size;
+ }
+ else
+ {
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ }
+ return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@');
+ }
+ else if (is_special)
+ {
+ uint64_t location = valobj_addr + (ptr_size == 8 ? 12 : 8);
+ return ReadUTFBufferAndDumpToStream<UTF16> (ConvertUTF16toUTF8, location, process_sp, stream, '@');
+ }
+ else if (is_inline)
+ {
+ uint64_t location = valobj_addr + 2*ptr_size;
+ if (!has_explicit_length)
+ location++;
+ return ReadAsciiBufferAndDumpToStream(location,process_sp,stream);
+ }
+ else
+ {
+ uint64_t location = valobj_addr + 2*ptr_size;
+ location = process_sp->ReadPointerFromMemory(location, error);
+ if (error.Fail())
+ return false;
+ return ReadAsciiBufferAndDumpToStream(location,process_sp,stream);
+ }
+
+ stream.Printf("class name = %s",class_name);
+ return true;
+
+}
+
+bool
+lldb_private::formatters::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ TargetSP target_sp(valobj.GetTargetSP());
+ if (!target_sp)
+ return false;
+ uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize();
+ uint64_t pointee = valobj.GetValueAsUnsigned(0);
+ if (!pointee)
+ return false;
+ pointee += addr_size;
+ ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+ ExecutionContext exe_ctx(target_sp,false);
+ ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointee, exe_ctx, type));
+ if (!child_ptr_sp)
+ return false;
+ DataExtractor data;
+ child_ptr_sp->GetData(data);
+ ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type));
+ child_sp->GetValueAsUnsigned(0);
+ if (child_sp)
+ return NSStringSummaryProvider(*child_sp, stream);
+ return false;
+}
+
+bool
+lldb_private::formatters::NSMutableAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ return NSAttributedStringSummaryProvider(valobj, stream);
+}
+
+bool
+lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ stream.Printf("%s",valobj.GetObjectDescription());
+ return true;
+}
+
+bool
+lldb_private::formatters::NSURLSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (strcmp(class_name, "NSURL") == 0)
+ {
+ uint64_t offset_text = ptr_size + ptr_size + 8; // ISA + pointer + 8 bytes of data (even on 32bit)
+ uint64_t offset_base = offset_text + ptr_size;
+ ClangASTType type(valobj.GetClangAST(),valobj.GetClangType());
+ ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset_text, type, true));
+ ValueObjectSP base(valobj.GetSyntheticChildAtOffset(offset_base, type, true));
+ if (!text)
+ return false;
+ if (text->GetValueAsUnsigned(0) == 0)
+ return false;
+ StreamString summary;
+ if (!NSStringSummaryProvider(*text, summary))
+ return false;
+ if (base && base->GetValueAsUnsigned(0))
+ {
+ if (summary.GetSize() > 0)
+ summary.GetString().resize(summary.GetSize()-1);
+ summary.Printf(" -- ");
+ StreamString base_summary;
+ if (NSURLSummaryProvider(*base, base_summary) && base_summary.GetSize() > 0)
+ summary.Printf("%s",base_summary.GetSize() > 2 ? base_summary.GetData() + 2 : base_summary.GetData());
+ }
+ if (summary.GetSize())
+ {
+ stream.Printf("%s",summary.GetData());
+ return true;
+ }
+ }
+ else
+ {
+ return ExtractSummaryFromObjCExpression(valobj, "NSString*", "description", stream);
+ }
+ return false;
+}
+
+bool
+lldb_private::formatters::ObjCBOOLSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ const uint32_t type_info = ClangASTContext::GetTypeInfo(valobj.GetClangType(),
+ valobj.GetClangAST(),
+ NULL);
+
+ ValueObjectSP real_guy_sp = valobj.GetSP();
+
+ if (type_info & ClangASTContext::eTypeIsPointer)
+ {
+ Error err;
+ real_guy_sp = valobj.Dereference(err);
+ if (err.Fail() || !real_guy_sp)
+ return false;
+ }
+ else if (type_info & ClangASTContext::eTypeIsReference)
+ {
+ real_guy_sp = valobj.GetChildAtIndex(0, true);
+ if (!real_guy_sp)
+ return false;
+ }
+ uint64_t value = real_guy_sp->GetValueAsUnsigned(0);
+ if (value == 0)
+ {
+ stream.Printf("NO");
+ return true;
+ }
+ stream.Printf("YES");
+ return true;
+}
+
+template <bool is_sel_ptr>
+bool
+lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ lldb::ValueObjectSP valobj_sp;
+
+ if (!valobj.GetClangAST())
+ return false;
+ void* char_opaque_type = valobj.GetClangAST()->CharTy.getAsOpaquePtr();
+ if (!char_opaque_type)
+ return false;
+ ClangASTType charstar(valobj.GetClangAST(),ClangASTType::GetPointerType(valobj.GetClangAST(), char_opaque_type));
+
+ ExecutionContext exe_ctx(valobj.GetExecutionContextRef());
+
+ if (is_sel_ptr)
+ {
+ lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ if (data_address == LLDB_INVALID_ADDRESS)
+ return false;
+ valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar);
+ }
+ else
+ {
+ DataExtractor data;
+ valobj.GetData(data);
+ valobj_sp = ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar);
+ }
+
+ if (!valobj_sp)
+ return false;
+
+ stream.Printf("%s",valobj_sp->GetSummaryAsCString());
+ return true;
+}
+
+size_t
+lldb_private::formatters::ExtractIndexFromString (const char* item_name)
+{
+ if (!item_name || !*item_name)
+ return UINT32_MAX;
+ if (*item_name != '[')
+ return UINT32_MAX;
+ item_name++;
+ char* endptr = NULL;
+ unsigned long int idx = ::strtoul(item_name, &endptr, 0);
+ if (idx == 0 && endptr == item_name)
+ return UINT32_MAX;
+ if (idx == ULONG_MAX)
+ return UINT32_MAX;
+ return idx;
+}
+
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::VectorIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp,
+ ConstString item_name) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_item_name(item_name),
+m_item_sp()
+{
+ if (valobj_sp)
+ Update();
+}
+
+bool
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::Update()
+{
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ if (!valobj_sp)
+ return false;
+
+ ValueObjectSP item_ptr(valobj_sp->GetChildMemberWithName(m_item_name,true));
+ if (!item_ptr)
+ return false;
+ if (item_ptr->GetValueAsUnsigned(0) == 0)
+ return false;
+ Error err;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ m_item_sp = ValueObject::CreateValueObjectFromAddress("item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref, ClangASTType(item_ptr->GetClangAST(),ClangASTType::GetPointeeType(item_ptr->GetClangType())));
+ if (err.Fail())
+ m_item_sp.reset();
+ return (m_item_sp.get() != NULL);
+}
+
+size_t
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::CalculateNumChildren ()
+{
+ return 1;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx == 0)
+ return m_item_sp;
+ return lldb::ValueObjectSP();
+}
+
+bool
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (name == ConstString("item"))
+ return 0;
+ return UINT32_MAX;
+}
+
+lldb_private::formatters::VectorIteratorSyntheticFrontEnd::~VectorIteratorSyntheticFrontEnd ()
+{
+}
+
+template bool
+lldb_private::formatters::NSDataSummaryProvider<true> (ValueObject&, Stream&) ;
+
+template bool
+lldb_private::formatters::NSDataSummaryProvider<false> (ValueObject&, Stream&) ;
+
+template bool
+lldb_private::formatters::ObjCSELSummaryProvider<true> (ValueObject&, Stream&) ;
+
+template bool
+lldb_private::formatters::ObjCSELSummaryProvider<false> (ValueObject&, Stream&) ;
Index: aze/lldb/source/DataFormatters/DataVisualization.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/DataVisualization.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,279 @@
+//===-- DataVisualization.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/DataVisualization.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/Core/Debugger.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+static FormatManager&
+GetFormatManager()
+{
+ static FormatManager g_format_manager;
+ return g_format_manager;
+}
+
+void
+DataVisualization::ForceUpdate ()
+{
+ GetFormatManager().Changed();
+}
+
+uint32_t
+DataVisualization::GetCurrentRevision ()
+{
+ return GetFormatManager().GetCurrentRevision();
+}
+
+lldb::TypeFormatImplSP
+DataVisualization::ValueFormats::GetFormat (ValueObject& valobj, lldb::DynamicValueType use_dynamic)
+{
+ lldb::TypeFormatImplSP entry;
+ GetFormatManager().GetValueNavigator().Get(valobj, entry, use_dynamic);
+ return entry;
+}
+
+lldb::TypeFormatImplSP
+DataVisualization::ValueFormats::GetFormat (const ConstString &type)
+{
+ lldb::TypeFormatImplSP entry;
+ GetFormatManager().GetValueNavigator().Get(type, entry);
+ return entry;
+}
+
+void
+DataVisualization::ValueFormats::Add (const ConstString &type, const lldb::TypeFormatImplSP &entry)
+{
+ GetFormatManager().GetValueNavigator().Add(FormatManager::GetValidTypeName(type),entry);
+}
+
+bool
+DataVisualization::ValueFormats::Delete (const ConstString &type)
+{
+ return GetFormatManager().GetValueNavigator().Delete(type);
+}
+
+void
+DataVisualization::ValueFormats::Clear ()
+{
+ GetFormatManager().GetValueNavigator().Clear();
+}
+
+void
+DataVisualization::ValueFormats::LoopThrough (TypeFormatImpl::ValueCallback callback, void* callback_baton)
+{
+ GetFormatManager().GetValueNavigator().LoopThrough(callback, callback_baton);
+}
+
+size_t
+DataVisualization::ValueFormats::GetCount ()
+{
+ return GetFormatManager().GetValueNavigator().GetCount();
+}
+
+lldb::TypeNameSpecifierImplSP
+DataVisualization::ValueFormats::GetTypeNameSpecifierForFormatAtIndex (size_t index)
+{
+ return GetFormatManager().GetValueNavigator().GetTypeNameSpecifierAtIndex(index);
+}
+
+lldb::TypeFormatImplSP
+DataVisualization::ValueFormats::GetFormatAtIndex (size_t index)
+{
+ return GetFormatManager().GetValueNavigator().GetAtIndex(index);
+}
+
+lldb::TypeSummaryImplSP
+DataVisualization::GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ return GetFormatManager().GetSummaryFormat(valobj, use_dynamic);
+}
+
+lldb::TypeSummaryImplSP
+DataVisualization::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ return GetFormatManager().GetSummaryForType(type_sp);
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::SyntheticChildrenSP
+DataVisualization::GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ return GetFormatManager().GetSyntheticChildren(valobj, use_dynamic);
+}
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::SyntheticChildrenSP
+DataVisualization::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ return GetFormatManager().GetSyntheticChildrenForType(type_sp);
+}
+#endif
+
+lldb::TypeFilterImplSP
+DataVisualization::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ return GetFormatManager().GetFilterForType(type_sp);
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::ScriptedSyntheticChildrenSP
+DataVisualization::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ return GetFormatManager().GetSyntheticForType(type_sp);
+}
+#endif
+
+bool
+DataVisualization::AnyMatches (ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items,
+ bool only_enabled,
+ const char** matching_category,
+ TypeCategoryImpl::FormatCategoryItems* matching_type)
+{
+ return GetFormatManager().AnyMatches(type_name,
+ items,
+ only_enabled,
+ matching_category,
+ matching_type);
+}
+
+bool
+DataVisualization::Categories::GetCategory (const ConstString &category, lldb::TypeCategoryImplSP &entry,
+ bool allow_create)
+{
+ entry = GetFormatManager().GetCategory(category, allow_create);
+ return (entry.get() != NULL);
+}
+
+void
+DataVisualization::Categories::Add (const ConstString &category)
+{
+ GetFormatManager().GetCategory(category);
+}
+
+bool
+DataVisualization::Categories::Delete (const ConstString &category)
+{
+ GetFormatManager().DisableCategory(category);
+ return GetFormatManager().DeleteCategory(category);
+}
+
+void
+DataVisualization::Categories::Clear ()
+{
+ GetFormatManager().ClearCategories();
+}
+
+void
+DataVisualization::Categories::Clear (const ConstString &category)
+{
+ GetFormatManager().GetCategory(category)->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
+}
+
+void
+DataVisualization::Categories::Enable (const ConstString& category,
+ TypeCategoryMap::Position pos)
+{
+ if (GetFormatManager().GetCategory(category)->IsEnabled())
+ GetFormatManager().DisableCategory(category);
+ GetFormatManager().EnableCategory(category, pos);
+}
+
+void
+DataVisualization::Categories::Disable (const ConstString& category)
+{
+ if (GetFormatManager().GetCategory(category)->IsEnabled() == true)
+ GetFormatManager().DisableCategory(category);
+}
+
+void
+DataVisualization::Categories::Enable (const lldb::TypeCategoryImplSP& category,
+ TypeCategoryMap::Position pos)
+{
+ if (category.get())
+ {
+ if (category->IsEnabled())
+ GetFormatManager().DisableCategory(category);
+ GetFormatManager().EnableCategory(category, pos);
+ }
+}
+
+void
+DataVisualization::Categories::Disable (const lldb::TypeCategoryImplSP& category)
+{
+ if (category.get() && category->IsEnabled() == true)
+ GetFormatManager().DisableCategory(category);
+}
+
+void
+DataVisualization::Categories::LoopThrough (FormatManager::CategoryCallback callback, void* callback_baton)
+{
+ GetFormatManager().LoopThroughCategories(callback, callback_baton);
+}
+
+uint32_t
+DataVisualization::Categories::GetCount ()
+{
+ return GetFormatManager().GetCategoriesCount();
+}
+
+lldb::TypeCategoryImplSP
+DataVisualization::Categories::GetCategoryAtIndex (size_t index)
+{
+ return GetFormatManager().GetCategoryAtIndex(index);
+}
+
+bool
+DataVisualization::NamedSummaryFormats::GetSummaryFormat (const ConstString &type, lldb::TypeSummaryImplSP &entry)
+{
+ return GetFormatManager().GetNamedSummaryNavigator().Get(type,entry);
+}
+
+void
+DataVisualization::NamedSummaryFormats::Add (const ConstString &type, const lldb::TypeSummaryImplSP &entry)
+{
+ GetFormatManager().GetNamedSummaryNavigator().Add(FormatManager::GetValidTypeName(type),entry);
+}
+
+bool
+DataVisualization::NamedSummaryFormats::Delete (const ConstString &type)
+{
+ return GetFormatManager().GetNamedSummaryNavigator().Delete(type);
+}
+
+void
+DataVisualization::NamedSummaryFormats::Clear ()
+{
+ GetFormatManager().GetNamedSummaryNavigator().Clear();
+}
+
+void
+DataVisualization::NamedSummaryFormats::LoopThrough (TypeSummaryImpl::SummaryCallback callback, void* callback_baton)
+{
+ GetFormatManager().GetNamedSummaryNavigator().LoopThrough(callback, callback_baton);
+}
+
+uint32_t
+DataVisualization::NamedSummaryFormats::GetCount ()
+{
+ return GetFormatManager().GetNamedSummaryNavigator().GetCount();
+}
Index: aze/lldb/source/DataFormatters/FormatCache.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/FormatCache.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,169 @@
+//===-- FormatCache.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+// C Includes
+
+// C++ Includes
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/DataFormatters/FormatCache.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+FormatCache::Entry::Entry () :
+m_summary_cached(false),
+m_synthetic_cached(false),
+m_summary_sp(),
+m_synthetic_sp()
+{}
+
+FormatCache::Entry::Entry (lldb::TypeSummaryImplSP summary_sp) :
+m_synthetic_cached(false),
+m_synthetic_sp()
+{
+ SetSummary (summary_sp);
+}
+
+FormatCache::Entry::Entry (lldb::SyntheticChildrenSP synthetic_sp) :
+m_summary_cached(false),
+m_summary_sp()
+{
+ SetSynthetic (synthetic_sp);
+}
+
+FormatCache::Entry::Entry (lldb::TypeSummaryImplSP summary_sp,lldb::SyntheticChildrenSP synthetic_sp)
+{
+ SetSummary (summary_sp);
+ SetSynthetic (synthetic_sp);
+}
+
+bool
+FormatCache::Entry::IsSummaryCached ()
+{
+ return m_summary_cached;
+}
+
+bool
+FormatCache::Entry::IsSyntheticCached ()
+{
+ return m_synthetic_cached;
+}
+
+lldb::TypeSummaryImplSP
+FormatCache::Entry::GetSummary ()
+{
+ return m_summary_sp;
+}
+
+lldb::SyntheticChildrenSP
+FormatCache::Entry::GetSynthetic ()
+{
+ return m_synthetic_sp;
+}
+
+void
+FormatCache::Entry::SetSummary (lldb::TypeSummaryImplSP summary_sp)
+{
+ m_summary_cached = true;
+ m_summary_sp = summary_sp;
+}
+
+void
+FormatCache::Entry::SetSynthetic (lldb::SyntheticChildrenSP synthetic_sp)
+{
+ m_synthetic_cached = true;
+ m_synthetic_sp = synthetic_sp;
+}
+
+FormatCache::FormatCache () :
+m_map(),
+m_mutex (Mutex::eMutexTypeRecursive)
+#ifdef LLDB_CONFIGURATION_DEBUG
+,m_cache_hits(0),m_cache_misses(0)
+#endif
+{
+}
+
+FormatCache::Entry&
+FormatCache::GetEntry (const ConstString& type)
+{
+ auto i = m_map.find(type),
+ e = m_map.end();
+ if (i != e)
+ return i->second;
+ m_map[type] = FormatCache::Entry();
+ return m_map[type];
+}
+
+bool
+FormatCache::GetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp)
+{
+ Mutex::Locker lock(m_mutex);
+ auto entry = GetEntry(type);
+ if (entry.IsSummaryCached())
+ {
+#ifdef LLDB_CONFIGURATION_DEBUG
+ m_cache_hits++;
+#endif
+ summary_sp = entry.GetSummary();
+ return true;
+ }
+#ifdef LLDB_CONFIGURATION_DEBUG
+ m_cache_misses++;
+#endif
+ summary_sp.reset();
+ return false;
+}
+
+bool
+FormatCache::GetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp)
+{
+ Mutex::Locker lock(m_mutex);
+ auto entry = GetEntry(type);
+ if (entry.IsSyntheticCached())
+ {
+#ifdef LLDB_CONFIGURATION_DEBUG
+ m_cache_hits++;
+#endif
+ synthetic_sp = entry.GetSynthetic();
+ return true;
+ }
+#ifdef LLDB_CONFIGURATION_DEBUG
+ m_cache_misses++;
+#endif
+ synthetic_sp.reset();
+ return false;
+}
+
+void
+FormatCache::SetSummary (const ConstString& type,lldb::TypeSummaryImplSP& summary_sp)
+{
+ Mutex::Locker lock(m_mutex);
+ GetEntry(type).SetSummary(summary_sp);
+}
+
+void
+FormatCache::SetSynthetic (const ConstString& type,lldb::SyntheticChildrenSP& synthetic_sp)
+{
+ Mutex::Locker lock(m_mutex);
+ GetEntry(type).SetSynthetic(synthetic_sp);
+}
+
+void
+FormatCache::Clear ()
+{
+ Mutex::Locker lock(m_mutex);
+ m_map.clear();
+}
+
Index: aze/lldb/source/DataFormatters/FormatClasses.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/FormatClasses.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,33 @@
+//===-- FormatClasses.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+// C Includes
+
+// C++ Includes
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/DataFormatters/FormatClasses.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
Index: aze/lldb/source/DataFormatters/FormatManager.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/FormatManager.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,1074 @@
+//===-- FormatManager.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/FormatManager.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+#include "lldb/Interpreter/ScriptInterpreterPython.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+struct FormatInfo
+{
+ Format format;
+ const char format_char; // One or more format characters that can be used for this format.
+ const char *format_name; // Long format name that can be used to specify the current format
+};
+
+static FormatInfo
+g_format_infos[] =
+{
+ { eFormatDefault , '\0' , "default" },
+ { eFormatBoolean , 'B' , "boolean" },
+ { eFormatBinary , 'b' , "binary" },
+ { eFormatBytes , 'y' , "bytes" },
+ { eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
+ { eFormatChar , 'c' , "character" },
+ { eFormatCharPrintable , 'C' , "printable character" },
+ { eFormatComplexFloat , 'F' , "complex float" },
+ { eFormatCString , 's' , "c-string" },
+ { eFormatDecimal , 'd' , "decimal" },
+ { eFormatEnum , 'E' , "enumeration" },
+ { eFormatHex , 'x' , "hex" },
+ { eFormatHexUppercase , 'X' , "uppercase hex" },
+ { eFormatFloat , 'f' , "float" },
+ { eFormatOctal , 'o' , "octal" },
+ { eFormatOSType , 'O' , "OSType" },
+ { eFormatUnicode16 , 'U' , "unicode16" },
+ { eFormatUnicode32 , '\0' , "unicode32" },
+ { eFormatUnsigned , 'u' , "unsigned decimal" },
+ { eFormatPointer , 'p' , "pointer" },
+ { eFormatVectorOfChar , '\0' , "char[]" },
+ { eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
+ { eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
+ { eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
+ { eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
+ { eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
+ { eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
+ { eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
+ { eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
+ { eFormatVectorOfFloat32, '\0' , "float32[]" },
+ { eFormatVectorOfFloat64, '\0' , "float64[]" },
+ { eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
+ { eFormatComplexInteger , 'I' , "complex integer" },
+ { eFormatCharArray , 'a' , "character array" },
+ { eFormatAddressInfo , 'A' , "address" },
+ { eFormatHexFloat , '\0' , "hex float" },
+ { eFormatInstruction , 'i' , "instruction" },
+ { eFormatVoid , 'v' , "void" }
+};
+
+static uint32_t
+g_num_format_infos = sizeof(g_format_infos)/sizeof(FormatInfo);
+
+static bool
+GetFormatFromFormatChar (char format_char, Format &format)
+{
+ for (uint32_t i=0; i<g_num_format_infos; ++i)
+ {
+ if (g_format_infos[i].format_char == format_char)
+ {
+ format = g_format_infos[i].format;
+ return true;
+ }
+ }
+ format = eFormatInvalid;
+ return false;
+}
+
+static bool
+GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
+{
+ uint32_t i;
+ for (i=0; i<g_num_format_infos; ++i)
+ {
+ if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
+ {
+ format = g_format_infos[i].format;
+ return true;
+ }
+ }
+
+ if (partial_match_ok)
+ {
+ for (i=0; i<g_num_format_infos; ++i)
+ {
+ if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
+ {
+ format = g_format_infos[i].format;
+ return true;
+ }
+ }
+ }
+ format = eFormatInvalid;
+ return false;
+}
+
+bool
+FormatManager::GetFormatFromCString (const char *format_cstr,
+ bool partial_match_ok,
+ lldb::Format &format)
+{
+ bool success = false;
+ if (format_cstr && format_cstr[0])
+ {
+ if (format_cstr[1] == '\0')
+ {
+ success = GetFormatFromFormatChar (format_cstr[0], format);
+ if (success)
+ return true;
+ }
+
+ success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
+ }
+ if (!success)
+ format = eFormatInvalid;
+ return success;
+}
+
+char
+FormatManager::GetFormatAsFormatChar (lldb::Format format)
+{
+ for (uint32_t i=0; i<g_num_format_infos; ++i)
+ {
+ if (g_format_infos[i].format == format)
+ return g_format_infos[i].format_char;
+ }
+ return '\0';
+}
+
+const char *
+FormatManager::GetFormatAsCString (Format format)
+{
+ if (format >= eFormatDefault && format < kNumFormats)
+ return g_format_infos[format].format_name;
+ return NULL;
+}
+
+lldb::TypeSummaryImplSP
+FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ if (!type_sp)
+ return lldb::TypeSummaryImplSP();
+ lldb::TypeSummaryImplSP summary_chosen_sp;
+ uint32_t num_categories = m_categories_map.GetCount();
+ lldb::TypeCategoryImplSP category_sp;
+ uint32_t prio_category = UINT32_MAX;
+ for (uint32_t category_id = 0;
+ category_id < num_categories;
+ category_id++)
+ {
+ category_sp = GetCategoryAtIndex(category_id);
+ if (category_sp->IsEnabled() == false)
+ continue;
+ lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
+ if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
+ {
+ prio_category = category_sp->GetEnabledPosition();
+ summary_chosen_sp = summary_current_sp;
+ }
+ }
+ return summary_chosen_sp;
+}
+
+lldb::TypeFilterImplSP
+FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ if (!type_sp)
+ return lldb::TypeFilterImplSP();
+ lldb::TypeFilterImplSP filter_chosen_sp;
+ uint32_t num_categories = m_categories_map.GetCount();
+ lldb::TypeCategoryImplSP category_sp;
+ uint32_t prio_category = UINT32_MAX;
+ for (uint32_t category_id = 0;
+ category_id < num_categories;
+ category_id++)
+ {
+ category_sp = GetCategoryAtIndex(category_id);
+ if (category_sp->IsEnabled() == false)
+ continue;
+ lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
+ if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
+ {
+ prio_category = category_sp->GetEnabledPosition();
+ filter_chosen_sp = filter_current_sp;
+ }
+ }
+ return filter_chosen_sp;
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::ScriptedSyntheticChildrenSP
+FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ if (!type_sp)
+ return lldb::ScriptedSyntheticChildrenSP();
+ lldb::ScriptedSyntheticChildrenSP synth_chosen_sp;
+ uint32_t num_categories = m_categories_map.GetCount();
+ lldb::TypeCategoryImplSP category_sp;
+ uint32_t prio_category = UINT32_MAX;
+ for (uint32_t category_id = 0;
+ category_id < num_categories;
+ category_id++)
+ {
+ category_sp = GetCategoryAtIndex(category_id);
+ if (category_sp->IsEnabled() == false)
+ continue;
+ lldb::ScriptedSyntheticChildrenSP synth_current_sp((ScriptedSyntheticChildren*)category_sp->GetSyntheticForType(type_sp).get());
+ if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
+ {
+ prio_category = category_sp->GetEnabledPosition();
+ synth_chosen_sp = synth_current_sp;
+ }
+ }
+ return synth_chosen_sp;
+}
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::SyntheticChildrenSP
+FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ if (!type_sp)
+ return lldb::SyntheticChildrenSP();
+ lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
+ lldb::ScriptedSyntheticChildrenSP synth_sp = GetSyntheticForType(type_sp);
+ if (filter_sp->GetRevision() > synth_sp->GetRevision())
+ return lldb::SyntheticChildrenSP(filter_sp.get());
+ else
+ return lldb::SyntheticChildrenSP(synth_sp.get());
+}
+#endif
+
+lldb::TypeCategoryImplSP
+FormatManager::GetCategory (const ConstString& category_name,
+ bool can_create)
+{
+ if (!category_name)
+ return GetCategory(m_default_category_name);
+ lldb::TypeCategoryImplSP category;
+ if (m_categories_map.Get(category_name, category))
+ return category;
+
+ if (!can_create)
+ return lldb::TypeCategoryImplSP();
+
+ m_categories_map.Add(category_name,lldb::TypeCategoryImplSP(new TypeCategoryImpl(this, category_name)));
+ return GetCategory(category_name);
+}
+
+lldb::Format
+FormatManager::GetSingleItemFormat(lldb::Format vector_format)
+{
+ switch(vector_format)
+ {
+ case eFormatVectorOfChar:
+ return eFormatCharArray;
+
+ case eFormatVectorOfSInt8:
+ case eFormatVectorOfSInt16:
+ case eFormatVectorOfSInt32:
+ case eFormatVectorOfSInt64:
+ return eFormatDecimal;
+
+ case eFormatVectorOfUInt8:
+ case eFormatVectorOfUInt16:
+ case eFormatVectorOfUInt32:
+ case eFormatVectorOfUInt64:
+ case eFormatVectorOfUInt128:
+ return eFormatHex;
+
+ case eFormatVectorOfFloat32:
+ case eFormatVectorOfFloat64:
+ return eFormatFloat;
+
+ default:
+ return lldb::eFormatInvalid;
+ }
+}
+
+ConstString
+FormatManager::GetValidTypeName (const ConstString& type)
+{
+ return ::GetValidTypeName_Impl(type);
+}
+
+ConstString
+GetTypeForCache (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ if (use_dynamic == lldb::eNoDynamicValues)
+ {
+ if (valobj.IsDynamic())
+ {
+ if (valobj.GetStaticValue())
+ return valobj.GetStaticValue()->GetQualifiedTypeName();
+ else
+ return ConstString();
+ }
+ else
+ return valobj.GetQualifiedTypeName();
+ }
+ if (valobj.IsDynamic())
+ return valobj.GetQualifiedTypeName();
+ if (valobj.GetDynamicValue(use_dynamic))
+ return valobj.GetDynamicValue(use_dynamic)->GetQualifiedTypeName();
+ return ConstString();
+}
+
+#define USE_CACHE 1
+lldb::TypeSummaryImplSP
+FormatManager::GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ TypeSummaryImplSP retval;
+#if USE_CACHE
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
+ if (valobj_type)
+ {
+ if (log)
+ log->Printf("[FormatManager::GetSummaryFormat] Looking into cache for type %s", valobj_type.AsCString("<invalid>"));
+ if (m_format_cache.GetSummary(valobj_type,retval))
+ return retval;
+ if (log)
+ log->Printf("[FormatManager::GetSummaryFormat] Cache search failed. Going normal route");
+ }
+#endif
+ retval = m_categories_map.GetSummaryFormat(valobj, use_dynamic);
+#if USE_CACHE
+ if (valobj_type)
+ {
+ if (log)
+ log->Printf("[FormatManager::GetSummaryFormat] Caching %p for type %s",retval.get(),valobj_type.AsCString("<invalid>"));
+ m_format_cache.SetSummary(valobj_type,retval);
+ }
+#ifdef LLDB_CONFIGURATION_DEBUG
+ if (log)
+ log->Printf("[FormatManager::GetSummaryFormat] Cache hits: %llu - Cache Misses: %llu", m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
+#endif
+#endif
+ return retval;
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::SyntheticChildrenSP
+FormatManager::GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ SyntheticChildrenSP retval;
+#if USE_CACHE
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+ ConstString valobj_type(GetTypeForCache(valobj, use_dynamic));
+ if (valobj_type)
+ {
+ if (log)
+ log->Printf("[FormatManager::GetSyntheticChildren] Looking into cache for type %s\n", valobj_type.AsCString("<invalid>"));
+ if (m_format_cache.GetSynthetic(valobj_type,retval))
+ return retval;
+ if (log)
+ log->Printf("[FormatManager::GetSyntheticChildren] Cache search failed. Going normal route\n");
+ }
+#endif
+ retval = m_categories_map.GetSyntheticChildren(valobj, use_dynamic);
+#if USE_CACHE
+ if (valobj_type)
+ {
+ if (log)
+ log->Printf("[FormatManager::GetSyntheticChildren] Caching %p for type %s\n",retval.get(),valobj_type.AsCString("<invalid>"));
+ m_format_cache.SetSynthetic(valobj_type,retval);
+ }
+#ifdef LLDB_CONFIGURATION_DEBUG
+ if (log)
+ log->Printf("[FormatManager::GetSyntheticChildren] Cache hits: %llu - Cache Misses: %llu", m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses());
+#endif
+#endif
+ return retval;
+}
+#endif
+#undef USE_CACHE
+
+FormatManager::FormatManager() :
+ m_format_cache(),
+ m_value_nav("format",this),
+ m_named_summaries_map(this),
+ m_last_revision(0),
+ m_categories_map(this),
+ m_default_category_name(ConstString("default")),
+ m_system_category_name(ConstString("system")),
+ m_gnu_cpp_category_name(ConstString("gnu-libstdc++")),
+ m_libcxx_category_name(ConstString("libcxx")),
+ m_objc_category_name(ConstString("objc")),
+ m_corefoundation_category_name(ConstString("CoreFoundation")),
+ m_coregraphics_category_name(ConstString("CoreGraphics")),
+ m_coreservices_category_name(ConstString("CoreServices")),
+ m_vectortypes_category_name(ConstString("VectorTypes")),
+ m_appkit_category_name(ConstString("AppKit"))
+{
+ LoadSystemFormatters();
+ LoadLibStdcppFormatters();
+ LoadLibcxxFormatters();
+ LoadObjCFormatters();
+
+ EnableCategory(m_objc_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_corefoundation_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_appkit_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_coreservices_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_coregraphics_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_gnu_cpp_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_libcxx_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_vectortypes_category_name,TypeCategoryMap::Last);
+ EnableCategory(m_system_category_name,TypeCategoryMap::Last);
+}
+
+static void
+AddStringSummary(TypeCategoryImpl::SharedPointer category_sp,
+ const char* string,
+ ConstString type_name,
+ TypeSummaryImpl::Flags flags,
+ bool regex = false)
+{
+ lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags,
+ string));
+
+ if (regex)
+ {}
+ else
+ category_sp->GetSummaryNavigator()->Add(type_name, summary_sp);
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+static void
+AddScriptSummary(TypeCategoryImpl::SharedPointer category_sp,
+ const char* funct_name,
+ ConstString type_name,
+ TypeSummaryImpl::Flags flags,
+ bool regex = false)
+{
+
+ std::string code(" ");
+ code.append(funct_name).append("(valobj,internal_dict)");
+
+ lldb::TypeSummaryImplSP summary_sp(new ScriptSummaryFormat(flags,
+ funct_name,
+ code.c_str()));
+ if (regex)
+ {}
+ else
+ category_sp->GetSummaryNavigator()->Add(type_name, summary_sp);
+}
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+static void
+AddCXXSummary (TypeCategoryImpl::SharedPointer category_sp,
+ CXXFunctionSummaryFormat::Callback funct,
+ const char* description,
+ ConstString type_name,
+ TypeSummaryImpl::Flags flags,
+ bool regex = false)
+{
+ lldb::TypeSummaryImplSP summary_sp(new CXXFunctionSummaryFormat(flags,funct,description));
+ if (regex)
+ {}
+ else
+ category_sp->GetSummaryNavigator()->Add(type_name, summary_sp);
+}
+#endif
+
+#ifndef LLDB_DISABLE_PYTHON
+static void AddCXXSynthetic (TypeCategoryImpl::SharedPointer category_sp,
+ CXXSyntheticChildren::CreateFrontEndCallback generator,
+ const char* description,
+ ConstString type_name,
+ ScriptedSyntheticChildren::Flags flags,
+ bool regex = false)
+{
+ lldb::SyntheticChildrenSP synth_sp(new CXXSyntheticChildren(flags,description,generator));
+ if (regex)
+ category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())), synth_sp);
+ else
+ category_sp->GetSyntheticNavigator()->Add(type_name,synth_sp);
+}
+#endif
+
+void
+FormatManager::LoadLibStdcppFormatters()
+{
+ TypeSummaryImpl::Flags stl_summary_flags;
+ stl_summary_flags.SetCascades(true)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ lldb::TypeSummaryImplSP std_string_summary_sp(new StringSummaryFormat(stl_summary_flags,
+ "${var._M_dataplus._M_p}"));
+
+ TypeCategoryImpl::SharedPointer gnu_category_sp = GetCategory(m_gnu_cpp_category_name);
+
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::string"),
+ std_string_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char>"),
+ std_string_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
+ std_string_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
+ std_string_summary_sp);
+
+ // making sure we force-pick the summary for printing wstring (_M_p is a wchar_t*)
+ lldb::TypeSummaryImplSP std_wstring_summary_sp(new StringSummaryFormat(stl_summary_flags,
+ "${var._M_dataplus._M_p%S}"));
+
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::wstring"),
+ std_wstring_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<wchar_t>"),
+ std_wstring_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+
+
+#ifndef LLDB_DISABLE_PYTHON
+
+ SyntheticChildren::Flags stl_synth_flags;
+ stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
+
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
+ gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
+
+ stl_summary_flags.SetDontShowChildren(false);
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::vector<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::map<.+> >(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+ gnu_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::list<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags,
+ "size=${svar%#}")));
+
+ AddCXXSynthetic(gnu_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true);
+
+ AddCXXSynthetic(gnu_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true);
+
+ gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::vector<std::allocator<bool> >"),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+
+ gnu_category_sp->GetSyntheticNavigator()->Add(ConstString("std::vector<std::allocator<bool> >"),
+ SyntheticChildrenSP(new CXXSyntheticChildren(stl_synth_flags,"libc++ std::vector<bool> synthetic children",lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator)));
+
+#endif
+}
+
+void
+FormatManager::LoadLibcxxFormatters()
+{
+ TypeSummaryImpl::Flags stl_summary_flags;
+ stl_summary_flags.SetCascades(true)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+#ifndef LLDB_DISABLE_PYTHON
+ //std::string code(" lldb.formatters.cpp.libcxx.stdstring_SummaryProvider(valobj,internal_dict)");
+ //lldb::TypeSummaryImplSP std_string_summary_sp(new ScriptSummaryFormat(stl_summary_flags, "lldb.formatters.cpp.libcxx.stdstring_SummaryProvider",code.c_str()));
+
+ lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, "std::string summary provider"));
+ lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat(stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider"));
+
+ TypeCategoryImpl::SharedPointer libcxx_category_sp = GetCategory(m_libcxx_category_name);
+
+ libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::string"),
+ std_string_summary_sp);
+ libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >"),
+ std_string_summary_sp);
+
+ libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::wstring"),
+ std_wstring_summary_sp);
+ libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >"),
+ std_wstring_summary_sp);
+
+ SyntheticChildren::Flags stl_synth_flags;
+ stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(false);
+
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stdvector_SynthProvider")));
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stdlist_SynthProvider")));
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stdmap_SynthProvider")));
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)deque<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)shared_ptr<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
+ libcxx_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::__1::)weak_ptr<.+>(( )?&)?$")),
+ SyntheticChildrenSP(new ScriptedSyntheticChildren(stl_synth_flags,
+ "lldb.formatters.cpp.libcxx.stdsharedptr_SynthProvider")));
+
+ stl_summary_flags.SetDontShowChildren(false);stl_summary_flags.SetSkipPointers(true);
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::vector<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::list<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::map<.+> >(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::deque<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::shared_ptr<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "{${var.__ptr_%S}} (strong=${var.count} weak=${var.weak_count})}")));
+ libcxx_category_sp->GetRegexSummaryNavigator()->Add(RegularExpressionSP(new RegularExpression("^std::__1::weak_ptr<.+>(( )?&)?$")),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "{${var.__ptr_%S}} (strong=${var.count} weak=${var.weak_count})}")));
+
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", ConstString("^std::__1::__wrap_iter<.+>$"), stl_synth_flags, true);
+
+ AddCXXSynthetic(libcxx_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", ConstString("^std::__1::__map_iterator<.+>$"), stl_synth_flags, true);
+
+ // this summary prevails on the regex std::vector<> because we do exact matches before regex ones
+ libcxx_category_sp->GetSummaryNavigator()->Add(ConstString("std::__1::vector<std::__1::allocator<bool> >"),
+ TypeSummaryImplSP(new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
+
+ libcxx_category_sp->GetSyntheticNavigator()->Add(ConstString("std::__1::vector<std::__1::allocator<bool> >"),
+ SyntheticChildrenSP(new CXXSyntheticChildren(stl_synth_flags,"libc++ std::vector<bool> synthetic children",lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator)));
+
+#endif
+}
+
+void
+FormatManager::LoadSystemFormatters()
+{
+
+ TypeSummaryImpl::Flags string_flags;
+ string_flags.SetCascades(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(false)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ lldb::TypeSummaryImplSP string_format(new StringSummaryFormat(string_flags, "${var%s}"));
+
+
+ lldb::TypeSummaryImplSP string_array_format(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(false)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false),
+ "${var%s}"));
+
+ lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
+
+ TypeCategoryImpl::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
+
+ sys_category_sp->GetSummaryNavigator()->Add(ConstString("char *"), string_format);
+ sys_category_sp->GetSummaryNavigator()->Add(ConstString("const char *"), string_format);
+ sys_category_sp->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format);
+
+ lldb::TypeSummaryImplSP ostype_summary(new StringSummaryFormat(TypeSummaryImpl::Flags().SetCascades(false)
+ .SetSkipPointers(true)
+ .SetSkipReferences(true)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(false)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false),
+ "${var%O}"));
+
+ sys_category_sp->GetSummaryNavigator()->Add(ConstString("OSType"), ostype_summary);
+
+#ifndef LLDB_DISABLE_PYTHON
+ // FIXME because of a bug in the FormatNavigator we need to add a summary for both X* and const X* (<rdar://problem/12717717>)
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("char16_t *"), string_flags);
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "char16_t * summary provider", ConstString("const char16_t *"), string_flags);
+
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("char32_t *"), string_flags);
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char32StringSummaryProvider, "char32_t * summary provider", ConstString("const char32_t *"), string_flags);
+
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("wchar_t *"), string_flags);
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::WCharStringSummaryProvider, "wchar_t * summary provider", ConstString("const wchar_t *"), string_flags);
+
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("unichar *"), string_flags);
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16StringSummaryProvider, "unichar * summary provider", ConstString("const unichar *"), string_flags);
+
+ TypeSummaryImpl::Flags widechar_flags;
+ widechar_flags.SetDontShowValue(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetCascades(true)
+ .SetDontShowChildren(true)
+ .SetHideItemNames(true)
+ .SetShowMembersOneLiner(false);
+
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16SummaryProvider, "char16_t summary provider", ConstString("char16_t"), widechar_flags);
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char32SummaryProvider, "char32_t summary provider", ConstString("char32_t"), widechar_flags);
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::WCharSummaryProvider, "wchar_t summary provider", ConstString("wchar_t"), widechar_flags);
+
+ AddCXXSummary(sys_category_sp, lldb_private::formatters::Char16SummaryProvider, "unichar summary provider", ConstString("unichar"), widechar_flags);
+
+#endif
+}
+
+void
+FormatManager::LoadObjCFormatters()
+{
+ TypeSummaryImpl::Flags objc_flags;
+ objc_flags.SetCascades(false)
+ .SetSkipPointers(true)
+ .SetSkipReferences(true)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(true)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ TypeCategoryImpl::SharedPointer objc_category_sp = GetCategory(m_objc_category_name);
+
+ lldb::TypeSummaryImplSP ObjC_BOOL_summary(new CXXFunctionSummaryFormat(objc_flags, lldb_private::formatters::ObjCBOOLSummaryProvider,""));
+ objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL"),
+ ObjC_BOOL_summary);
+ objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL &"),
+ ObjC_BOOL_summary);
+ objc_category_sp->GetSummaryNavigator()->Add(ConstString("BOOL *"),
+ ObjC_BOOL_summary);
+
+#ifndef LLDB_DISABLE_PYTHON
+ // we need to skip pointers here since we are special casing a SEL* when retrieving its value
+ objc_flags.SetSkipPointers(true);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("SEL"), objc_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("struct objc_selector"), objc_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, "SEL summary provider", ConstString("objc_selector"), objc_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("objc_selector *"), objc_flags);
+ AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, "SEL summary provider", ConstString("SEL *"), objc_flags);
+
+ AddScriptSummary(objc_category_sp, "lldb.formatters.objc.Class.Class_Summary", ConstString("Class"), objc_flags);
+#endif // LLDB_DISABLE_PYTHON
+
+ objc_flags.SetSkipPointers(false);
+
+ TypeCategoryImpl::SharedPointer corefoundation_category_sp = GetCategory(m_corefoundation_category_name);
+
+ AddStringSummary(corefoundation_category_sp,
+ "${var.years} years, ${var.months} months, ${var.days} days, ${var.hours} hours, ${var.minutes} minutes ${var.seconds} seconds",
+ ConstString("CFGregorianUnits"),
+ objc_flags);
+ AddStringSummary(corefoundation_category_sp,
+ "location=${var.location} length=${var.length}",
+ ConstString("CFRange"),
+ objc_flags);
+ AddStringSummary(corefoundation_category_sp,
+ "(x=${var.x}, y=${var.y})",
+ ConstString("NSPoint"),
+ objc_flags);
+ AddStringSummary(corefoundation_category_sp,
+ "location=${var.location}, length=${var.length}",
+ ConstString("NSRange"),
+ objc_flags);
+ AddStringSummary(corefoundation_category_sp,
+ "${var.origin}, ${var.size}",
+ ConstString("NSRect"),
+ objc_flags);
+ AddStringSummary(corefoundation_category_sp,
+ "(${var.origin}, ${var.size}), ...",
+ ConstString("NSRectArray"),
+ objc_flags);
+ AddStringSummary(objc_category_sp,
+ "(width=${var.width}, height=${var.height})",
+ ConstString("NSSize"),
+ objc_flags);
+
+ TypeCategoryImpl::SharedPointer coregraphics_category_sp = GetCategory(m_coregraphics_category_name);
+
+ AddStringSummary(coregraphics_category_sp,
+ "(width=${var.width}, height=${var.height})",
+ ConstString("CGSize"),
+ objc_flags);
+ AddStringSummary(coregraphics_category_sp,
+ "(x=${var.x}, y=${var.y})",
+ ConstString("CGPoint"),
+ objc_flags);
+ AddStringSummary(coregraphics_category_sp,
+ "origin=${var.origin} size=${var.size}",
+ ConstString("CGRect"),
+ objc_flags);
+
+ TypeCategoryImpl::SharedPointer coreservices_category_sp = GetCategory(m_coreservices_category_name);
+
+ AddStringSummary(coreservices_category_sp,
+ "red=${var.red} green=${var.green} blue=${var.blue}",
+ ConstString("RGBColor"),
+ objc_flags);
+ AddStringSummary(coreservices_category_sp,
+ "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})",
+ ConstString("Rect"),
+ objc_flags);
+ AddStringSummary(coreservices_category_sp,
+ "(v=${var.v}, h=${var.h})",
+ ConstString("Point"),
+ objc_flags);
+ AddStringSummary(coreservices_category_sp,
+ "${var.month}/${var.day}/${var.year} ${var.hour} :${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}",
+ ConstString("DateTimeRect *"),
+ objc_flags);
+ AddStringSummary(coreservices_category_sp,
+ "${var.ld.month}/${var.ld.day}/${var.ld.year} ${var.ld.hour} :${var.ld.minute} :${var.ld.second} dayOfWeek:${var.ld.dayOfWeek}",
+ ConstString("LongDateRect"),
+ objc_flags);
+ AddStringSummary(coreservices_category_sp,
+ "(x=${var.x}, y=${var.y})",
+ ConstString("HIPoint"),
+ objc_flags);
+ AddStringSummary(coreservices_category_sp,
+ "origin=${var.origin} size=${var.size}",
+ ConstString("HIRect"),
+ objc_flags);
+
+ TypeCategoryImpl::SharedPointer appkit_category_sp = GetCategory(m_appkit_category_name);
+
+ TypeSummaryImpl::Flags appkit_flags;
+ appkit_flags.SetCascades(true)
+ .SetSkipPointers(false)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(false)
+ .SetShowMembersOneLiner(false)
+ .SetHideItemNames(false);
+
+ appkit_flags.SetDontShowChildren(false);
+
+
+#ifndef LLDB_DISABLE_PYTHON
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSArray"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFMutableArrayRef"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSDictionary"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("NSMutableDictionary"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSCFDictionary"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryI"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, "NSDictionary summary provider", ConstString("__NSDictionaryM"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFDictionaryRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, "NSDictionary summary provider", ConstString("CFMutableDictionaryRef"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSSet"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFSetRef summary", ConstString("CFSetRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetI summary", ConstString("__NSSetI"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "__NSSetM summary", ConstString("__NSSetM"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, "NSSet summary", ConstString("NSMutableSet"), appkit_flags);
+
+ // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", ConstString("$_lldb_typegen_nspair"), appkit_flags);
+
+ appkit_flags.SetDontShowChildren(true);
+
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayM"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSArrayI"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSArray"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("NSMutableArray"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), ScriptedSyntheticChildren::Flags());
+
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryM"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("__NSDictionaryI"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSDictionary"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("NSMutableDictionary"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFDictionaryRef"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), ScriptedSyntheticChildren::Flags());
+
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSSet"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("__NSSetI"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("__NSSetM"), ScriptedSyntheticChildren::Flags());
+ AddCXXSynthetic(appkit_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, "NSSet synthetic children", ConstString("NSMutableSet"), ScriptedSyntheticChildren::Flags());
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFBagRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("__CFBag"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("const struct __CFBag"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBag.CFBag_SummaryProvider", ConstString("CFMutableBagRef"), appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("CFBinaryHeapRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBinaryHeap.CFBinaryHeap_SummaryProvider", ConstString("__CFBinaryHeap"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFStringRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("CFMutableStringRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSMutableString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFConstantString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("__NSCFString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFConstantString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSCFString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSStringSummaryProvider, "NSString summary provider", ConstString("NSPathStore2"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSAttributedStringSummaryProvider, "NSAttributedString summary provider", ConstString("NSAttributedString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSMutableAttributedString"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", ConstString("NSConcreteMutableAttributedString"), appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSBundle.NSBundle_SummaryProvider", ConstString("NSBundle"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSData"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteData"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("NSConcreteMutableData"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, "NSData summary provider", ConstString("__NSCFData"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFDataRef"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSMachPort.NSMachPort_SummaryProvider", ConstString("NSMachPort"), appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSNotification"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSNotification.NSNotification_SummaryProvider", ConstString("NSConcreteNotification"), appkit_flags);
+
+ AddStringSummary(appkit_category_sp, "domain: ${var._domain} - code: ${var._code}", ConstString("NSError"), appkit_flags);
+ AddStringSummary(appkit_category_sp,"name:${var.name%S} reason:${var.reason%S}",ConstString("NSException"),appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSNumber"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSNumberSummaryProvider, "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSDecimalNumber summary provider", ConstString("NSDecimalNumber"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSHost summary provider", ConstString("NSHost"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSTask summary provider", ConstString("NSTask"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::RuntimeSpecificDescriptionSummaryProvider, "NSValue summary provider", ConstString("NSValue"), appkit_flags);
+
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("NSDate"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("__NSDate"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("__NSTaggedDate"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("NSCalendarDate"), appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSTimeZone_SummaryProvider", ConstString("NSTimeZone"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSTimeZone_SummaryProvider", ConstString("CFTimeZoneRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSTimeZone_SummaryProvider", ConstString("__NSTimeZone"), appkit_flags);
+
+ // CFAbsoluteTime is actually a double rather than a pointer to an object
+ // we do not care about the numeric value, since it is probably meaningless to users
+ appkit_flags.SetDontShowValue(true);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.CFAbsoluteTime_SummaryProvider", ConstString("CFAbsoluteTime"), appkit_flags);
+ appkit_flags.SetDontShowValue(false);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSIndexSet.NSIndexSet_SummaryProvider", ConstString("NSIndexSet"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSIndexSet.NSIndexSet_SummaryProvider", ConstString("NSMutableIndexSet"), appkit_flags);
+
+ AddStringSummary(appkit_category_sp,
+ "@\"${var.month%d}/${var.day%d}/${var.year%d} ${var.hour%d}:${var.minute%d}:${var.second}\"",
+ ConstString("CFGregorianDate"),
+ appkit_flags);
+
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("CFBitVectorRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("CFMutableBitVectorRef"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("__CFBitVector"), appkit_flags);
+ AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.CFBitVector.CFBitVector_SummaryProvider", ConstString("__CFMutableBitVector"), appkit_flags);
+#endif // LLDB_DISABLE_PYTHON
+
+ TypeCategoryImpl::SharedPointer vectors_category_sp = GetCategory(m_vectortypes_category_name);
+
+ TypeSummaryImpl::Flags vector_flags;
+ vector_flags.SetCascades(true)
+ .SetSkipPointers(true)
+ .SetSkipReferences(false)
+ .SetDontShowChildren(true)
+ .SetDontShowValue(false)
+ .SetShowMembersOneLiner(true)
+ .SetHideItemNames(true);
+
+ AddStringSummary(vectors_category_sp,
+ "${var.uint128}",
+ ConstString("builtin_type_vec128"),
+ objc_flags);
+
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("float [4]"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("int32_t [4]"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("int16_t [8]"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vDouble"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vFloat"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vSInt8"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vSInt16"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vSInt32"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vUInt16"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vUInt8"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vUInt16"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vUInt32"),
+ vector_flags);
+ AddStringSummary(vectors_category_sp,
+ "",
+ ConstString("vBool32"),
+ vector_flags);
+}
Index: aze/lldb/source/DataFormatters/LibCxx.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/LibCxx.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,287 @@
+//===-- LibCxx.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::LibcxxVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_count(0),
+m_base_data_address(0),
+m_options()
+{
+ if (valobj_sp)
+ Update();
+ m_options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true)
+ .SetUseDynamic(lldb::eDynamicCanRunTarget);
+}
+
+size_t
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::CalculateNumChildren ()
+{
+ return m_count;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx >= m_count)
+ return ValueObjectSP();
+ if (m_base_data_address == 0 || m_count == 0)
+ return ValueObjectSP();
+ size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
+ size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
+ lldb::addr_t byte_location = m_base_data_address + byte_idx;
+ ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
+ if (!process_sp)
+ return ValueObjectSP();
+ uint8_t byte = 0;
+ uint8_t mask = 0;
+ Error err;
+ size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
+ if (err.Fail() || bytes_read == 0)
+ return ValueObjectSP();
+ switch (bit_index)
+ {
+ case 0:
+ mask = 1; break;
+ case 1:
+ mask = 2; break;
+ case 2:
+ mask = 4; break;
+ case 3:
+ mask = 8; break;
+ case 4:
+ mask = 16; break;
+ case 5:
+ mask = 32; break;
+ case 6:
+ mask = 64; break;
+ case 7:
+ mask = 128; break;
+ default:
+ return ValueObjectSP();
+ }
+ bool bit_set = ((byte & mask) != 0);
+ Target& target(process_sp->GetTarget());
+ ValueObjectSP retval_sp;
+ if (bit_set)
+ target.EvaluateExpression("(bool)true", NULL, retval_sp);
+ else
+ target.EvaluateExpression("(bool)false", NULL, retval_sp);
+ StreamString name; name.Printf("[%zu]",idx);
+ if (retval_sp)
+ retval_sp->SetName(ConstString(name.GetData()));
+ return retval_sp;
+}
+
+/*(std::__1::vector<std::__1::allocator<bool> >) vBool = {
+ __begin_ = 0x00000001001000e0
+ __size_ = 56
+ __cap_alloc_ = {
+ std::__1::__libcpp_compressed_pair_imp<unsigned long, std::__1::allocator<unsigned long> > = {
+ __first_ = 1
+ }
+ }
+ }*/
+
+bool
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update()
+{
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName(ConstString("__size_"), true));
+ if (!size_sp)
+ return false;
+ m_count = size_sp->GetValueAsUnsigned(0);
+ if (!m_count)
+ return true;
+ ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true));
+ if (!begin_sp)
+ {
+ m_count = 0;
+ return false;
+ }
+ m_base_data_address = begin_sp->GetValueAsUnsigned(0);
+ if (!m_base_data_address)
+ {
+ m_count = 0;
+ return false;
+ }
+ return true;
+}
+
+bool
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (!m_count || !m_base_data_address)
+ return UINT32_MAX;
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::~LibcxxVectorBoolSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp));
+}
+
+/*
+ (lldb) fr var ibeg --raw --ptr-depth 1
+ (std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::__tree_node<std::__1::pair<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, void *> *, long> >) ibeg = {
+ __i_ = {
+ __ptr_ = 0x0000000100103870 {
+ std::__1::__tree_node_base<void *> = {
+ std::__1::__tree_end_node<std::__1::__tree_node_base<void *> *> = {
+ __left_ = 0x0000000000000000
+ }
+ __right_ = 0x0000000000000000
+ __parent_ = 0x00000001001038b0
+ __is_black_ = true
+ }
+ __value_ = {
+ first = 0
+ second = { std::string }
+ */
+
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::LibCxxMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_pair_ptr()
+{
+ if (valobj_sp)
+ Update();
+}
+
+bool
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update()
+{
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ TargetSP target_sp(valobj_sp->GetTargetSP());
+
+ if (!target_sp)
+ return false;
+
+ if (!valobj_sp)
+ return false;
+
+ // this must be a ValueObject* because it is a child of the ValueObject we are producing children for
+ // it if were a ValueObjectSP, we would end up with a loop (iterator -> synthetic -> child -> parent == iterator)
+ // and that would in turn leak memory by never allowing the ValueObjects to die and free their memory
+ m_pair_ptr = valobj_sp->GetValueForExpressionPath(".__i_.__ptr_->__value_",
+ NULL,
+ NULL,
+ NULL,
+ ValueObject::GetValueForExpressionPathOptions().DontCheckDotVsArrowSyntax().DontAllowSyntheticChildren(),
+ NULL).get();
+
+ return (m_pair_ptr != NULL);
+}
+
+size_t
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::CalculateNumChildren ()
+{
+ return 2;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (!m_pair_ptr)
+ return lldb::ValueObjectSP();
+ return m_pair_ptr->GetChildAtIndex(idx, true);
+}
+
+bool
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (name == ConstString("first"))
+ return 0;
+ if (name == ConstString("second"))
+ return 1;
+ return UINT32_MAX;
+}
+
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::~LibCxxMapIteratorSyntheticFrontEnd ()
+{
+ // this will be deleted when its parent dies (since it's a child object)
+ //delete m_pair_ptr;
+}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibCxxMapIteratorSyntheticFrontEnd(valobj_sp));
+}
+
+/*
+ (lldb) fr var ibeg --raw --ptr-depth 1 -T
+ (std::__1::__wrap_iter<int *>) ibeg = {
+ (std::__1::__wrap_iter<int *>::iterator_type) __i = 0x00000001001037a0 {
+ (int) *__i = 1
+ }
+ }
+*/
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ static ConstString g_item_name;
+ if (!g_item_name)
+ g_item_name.SetCString("__i");
+ if (!valobj_sp)
+ return NULL;
+ return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name));
+}
Index: aze/lldb/source/DataFormatters/LibStdcpp.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/LibStdcpp.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,333 @@
+//===-- LibStdcpp.cpp ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::LibstdcppVectorBoolSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_count(0),
+m_base_data_address(0),
+m_options()
+{
+ if (valobj_sp)
+ Update();
+ m_options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true)
+ .SetUseDynamic(lldb::eDynamicCanRunTarget);
+}
+
+size_t
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::CalculateNumChildren ()
+{
+ return m_count;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx >= m_count)
+ return ValueObjectSP();
+ if (m_base_data_address == 0 || m_count == 0)
+ return ValueObjectSP();
+ size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
+ size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
+ lldb::addr_t byte_location = m_base_data_address + byte_idx;
+ ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
+ if (!process_sp)
+ return ValueObjectSP();
+ uint8_t byte = 0;
+ uint8_t mask = 0;
+ Error err;
+ size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
+ if (err.Fail() || bytes_read == 0)
+ return ValueObjectSP();
+ switch (bit_index)
+ {
+ case 0:
+ mask = 1; break;
+ case 1:
+ mask = 2; break;
+ case 2:
+ mask = 4; break;
+ case 3:
+ mask = 8; break;
+ case 4:
+ mask = 16; break;
+ case 5:
+ mask = 32; break;
+ case 6:
+ mask = 64; break;
+ case 7:
+ mask = 128; break;
+ default:
+ return ValueObjectSP();
+ }
+ bool bit_set = ((byte & mask) != 0);
+ Target& target(process_sp->GetTarget());
+ ValueObjectSP retval_sp;
+ if (bit_set)
+ target.EvaluateExpression("(bool)true", NULL, retval_sp);
+ else
+ target.EvaluateExpression("(bool)false", NULL, retval_sp);
+ StreamString name; name.Printf("[%zu]",idx);
+ if (retval_sp)
+ retval_sp->SetName(ConstString(name.GetData()));
+ return retval_sp;
+}
+
+/*((std::vector<std::allocator<bool> >) vBool = {
+ (std::_Bvector_base<std::allocator<bool> >) std::_Bvector_base<std::allocator<bool> > = {
+ (std::_Bvector_base<std::allocator<bool> >::_Bvector_impl) _M_impl = {
+ (std::_Bit_iterator) _M_start = {
+ (std::_Bit_iterator_base) std::_Bit_iterator_base = {
+ (_Bit_type *) _M_p = 0x0016b160
+ (unsigned int) _M_offset = 0
+ }
+ }
+ (std::_Bit_iterator) _M_finish = {
+ (std::_Bit_iterator_base) std::_Bit_iterator_base = {
+ (_Bit_type *) _M_p = 0x0016b16c
+ (unsigned int) _M_offset = 16
+ }
+ }
+ (_Bit_type *) _M_end_of_storage = 0x0016b170
+ }
+ }
+ }
+ */
+
+bool
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::Update()
+{
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+
+ ValueObjectSP m_impl_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_impl"), true));
+ if (!m_impl_sp)
+ return false;
+
+ ValueObjectSP m_start_sp(m_impl_sp->GetChildMemberWithName(ConstString("_M_start"), true));
+ ValueObjectSP m_finish_sp(m_impl_sp->GetChildMemberWithName(ConstString("_M_finish"), true));
+
+ ValueObjectSP start_p_sp, finish_p_sp, finish_offset_sp;
+
+ if (!m_start_sp || !m_finish_sp)
+ return false;
+
+ start_p_sp = m_start_sp->GetChildMemberWithName(ConstString("_M_p"), true);
+ finish_p_sp = m_finish_sp->GetChildMemberWithName(ConstString("_M_p"), true);
+ finish_offset_sp = m_finish_sp->GetChildMemberWithName(ConstString("_M_offset"), true);
+
+ if (!start_p_sp || !finish_offset_sp || !finish_p_sp)
+ return false;
+
+ m_base_data_address = start_p_sp->GetValueAsUnsigned(0);
+ if (!m_base_data_address)
+ return false;
+
+ lldb::addr_t end_data_address(finish_p_sp->GetValueAsUnsigned(0));
+ if (!end_data_address)
+ return false;
+
+ if (end_data_address < m_base_data_address)
+ return false;
+ else
+ m_count = finish_offset_sp->GetValueAsUnsigned(0) + (end_data_address-m_base_data_address)*8;
+
+ return true;
+}
+
+bool
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (!m_count || !m_base_data_address)
+ return UINT32_MAX;
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEnd::~LibstdcppVectorBoolSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibstdcppVectorBoolSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibstdcppVectorBoolSyntheticFrontEnd(valobj_sp));
+}
+
+/*
+ (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) ibeg = {
+ (_Base_ptr) _M_node = 0x0000000100103910 {
+ (std::_Rb_tree_color) _M_color = _S_black
+ (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
+ (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
+ (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
+ }
+ }
+ */
+
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_pair_address(0),
+m_pair_type(),
+m_options(),
+m_pair_sp()
+{
+ if (valobj_sp)
+ Update();
+ m_options.SetCoerceToId(false)
+ .SetUnwindOnError(true)
+ .SetKeepInMemory(true)
+ .SetUseDynamic(lldb::eDynamicCanRunTarget);
+}
+
+bool
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::Update()
+{
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+
+ TargetSP target_sp(valobj_sp->GetTargetSP());
+
+ if (!target_sp)
+ return false;
+
+ bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8);
+
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+
+ ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true));
+ if (!_M_node_sp)
+ return false;
+
+ m_pair_address = _M_node_sp->GetValueAsUnsigned(0);
+ if (m_pair_address == 0)
+ return false;
+
+ m_pair_address += (is_64bit ? 32 : 16);
+
+ ClangASTType my_type(valobj_sp->GetClangAST(),valobj_sp->GetClangType());
+ if (ClangASTContext::GetNumTemplateArguments(valobj_sp->GetClangAST(),valobj_sp->GetClangType()) >= 1)
+ {
+ TemplateArgumentKind kind;
+ clang_type_t pair_type = ClangASTContext::GetTemplateArgument(valobj_sp->GetClangAST(),valobj_sp->GetClangType(), 0, kind);
+ if (kind != eTemplateArgumentKindType && kind != eTemplateArgumentKindTemplate && kind != eTemplateArgumentKindTemplateExpansion)
+ return false;
+ m_pair_type = ClangASTType(valobj_sp->GetClangAST(),pair_type);
+ }
+ else
+ return false;
+
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren ()
+{
+ return 2;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (m_pair_address == 0)
+ return lldb::ValueObjectSP();
+ if (m_pair_type.GetASTContext() == NULL ||
+ m_pair_type.GetOpaqueQualType() == NULL)
+ return lldb::ValueObjectSP();
+ if (!m_pair_sp)
+ m_pair_sp = ValueObject::CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type);
+ if (m_pair_sp)
+ return m_pair_sp->GetChildAtIndex(idx, true);
+ return lldb::ValueObjectSP();
+}
+
+bool
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (name == ConstString("first"))
+ return 0;
+ if (name == ConstString("second"))
+ return 1;
+ return UINT32_MAX;
+}
+
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEnd::~LibstdcppMapIteratorSyntheticFrontEnd ()
+{}
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ if (!valobj_sp)
+ return NULL;
+ return (new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp));
+}
+
+/*
+ (lldb) fr var ibeg --ptr-depth 1
+ (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >) ibeg = {
+ _M_current = 0x00000001001037a0 {
+ *_M_current = 1
+ }
+ }
+ */
+
+SyntheticChildrenFrontEnd*
+lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ static ConstString g_item_name;
+ if (!g_item_name)
+ g_item_name.SetCString("_M_current");
+ if (!valobj_sp)
+ return NULL;
+ return (new VectorIteratorSyntheticFrontEnd(valobj_sp,g_item_name));
+}
Index: aze/lldb/source/DataFormatters/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/Makefile 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,14 @@
+##===- source/DataFormatters/Makefile -------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LLDB_LEVEL := ../..
+LIBRARYNAME := lldbDataFormatters
+BUILD_ARCHIVE = 1
+
+include $(LLDB_LEVEL)/Makefile
Index: aze/lldb/source/DataFormatters/NSArray.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/NSArray.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,380 @@
+//===-- NSArray.cpp ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+bool
+lldb_private::formatters::NSArraySummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"__NSArrayI"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ else if (!strcmp(class_name,"__NSArrayM"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ else if (!strcmp(class_name,"__NSCFArray"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ }
+ else
+ {
+ if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+ return false;
+ }
+
+ stream.Printf("@\"%" PRIu64 " object%s\"",
+ value,
+ value == 1 ? "" : "s");
+ return true;
+}
+
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::NSArrayMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+ if (valobj_sp)
+ {
+ m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
+ Update();
+ }
+}
+
+size_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (m_data_32)
+ return m_data_32->_used;
+ if (m_data_64)
+ return m_data_64->_used;
+ return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (!m_data_32 && !m_data_64)
+ return lldb::ValueObjectSP();
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ lldb::addr_t object_at_idx = (m_data_32 ? m_data_32->_data : m_data_64->_data);
+ object_at_idx += (idx * m_ptr_size);
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromAddress(idx_name.GetData(),
+ object_at_idx,
+ m_exe_ctx_ref,
+ m_id_type);
+ m_children.push_back(retval_sp);
+ return retval_sp;
+}
+
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::Update()
+{
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType())
+ {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4)
+ {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+ }
+ else
+ {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
+}
+
+bool
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ if (!m_data_32 && !m_data_64)
+ return UINT32_MAX;
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+lldb_private::formatters::NSArrayMSyntheticFrontEnd::~NSArrayMSyntheticFrontEnd ()
+{
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+}
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_items(0),
+m_data_ptr(0)
+{
+ if (valobj_sp)
+ {
+ m_id_type = ClangASTType(valobj_sp->GetClangAST(),valobj_sp->GetClangAST()->ObjCBuiltinIdTy.getAsOpaquePtr());
+ Update();
+ }
+}
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd::~NSArrayISyntheticFrontEnd ()
+{
+}
+
+size_t
+lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t
+lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren ()
+{
+ return m_items;
+}
+
+bool
+lldb_private::formatters::NSArrayISyntheticFrontEnd::Update()
+{
+ m_ptr_size = 0;
+ m_items = 0;
+ m_data_ptr = 0;
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType())
+ {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ m_items = process_sp->ReadPointerFromMemory(data_location, error);
+ if (error.Fail())
+ return false;
+ m_data_ptr = data_location+m_ptr_size;
+ return false;
+}
+
+bool
+lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (idx >= CalculateNumChildren())
+ return lldb::ValueObjectSP();
+ lldb::addr_t object_at_idx = m_data_ptr;
+ object_at_idx += (idx * m_ptr_size);
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+ Error error;
+ object_at_idx = process_sp->ReadPointerFromMemory(object_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+ StreamString expr;
+ expr.Printf("(id)%" PRIu64,object_at_idx);
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ lldb::ValueObjectSP retval_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+ m_children.push_back(retval_sp);
+ return retval_sp;
+}
+
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return NULL;
+ ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return NULL;
+
+ if (!valobj_sp->IsPointerType())
+ {
+ Error error;
+ valobj_sp = valobj_sp->AddressOf(error);
+ if (error.Fail() || !valobj_sp)
+ return NULL;
+ }
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return NULL;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return NULL;
+
+ if (!strcmp(class_name,"__NSArrayI"))
+ {
+ return (new NSArrayISyntheticFrontEnd(valobj_sp));
+ }
+ else if (!strcmp(class_name,"__NSArrayM"))
+ {
+ return (new NSArrayMSyntheticFrontEnd(valobj_sp));
+ }
+ else
+ {
+ return (new NSArrayCodeRunningSyntheticFrontEnd(valobj_sp));
+ }
+}
+
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::NSArrayCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get())
+{}
+
+size_t
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
+{
+ uint64_t count = 0;
+ if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
+ return count;
+ return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ lldb::ValueObjectSP valobj_sp = CallSelectorOnObject(m_backend,"id","objectAtIndex:",idx);
+ if (valobj_sp)
+ valobj_sp->SetName(ConstString(idx_name.GetData()));
+ return valobj_sp;
+}
+
+bool
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::Update()
+{
+ return false;
+}
+
+bool
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ return 0;
+}
+
+lldb_private::formatters::NSArrayCodeRunningSyntheticFrontEnd::~NSArrayCodeRunningSyntheticFrontEnd ()
+{}
Index: aze/lldb/source/DataFormatters/NSDictionary.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/NSDictionary.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,493 @@
+//===-- NSDictionary.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+template<bool name_entries>
+bool
+lldb_private::formatters::NSDictionarySummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+ bool is_64bit = (ptr_size == 8);
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"__NSDictionaryI"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
+ else if (!strcmp(class_name,"__NSDictionaryM"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
+ else if (!strcmp(class_name,"__NSCFDictionary"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ if (is_64bit)
+ value &= ~0x0f1f000000000000UL;
+ }
+ else
+ {
+ if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+ return false;
+ }
+
+ stream.Printf("%s%" PRIu64 " %s%s",
+ (name_entries ? "@\"" : ""),
+ value,
+ (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")),
+ (name_entries ? "\"" : ""));
+ return true;
+}
+
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSDictionarySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+
+ lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return NULL;
+ ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return NULL;
+
+ if (!valobj_sp->IsPointerType())
+ {
+ Error error;
+ valobj_sp = valobj_sp->AddressOf(error);
+ if (error.Fail() || !valobj_sp)
+ return NULL;
+ }
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return NULL;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return NULL;
+
+ if (!strcmp(class_name,"__NSDictionaryI"))
+ {
+ return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
+ }
+ else if (!strcmp(class_name,"__NSDictionaryM"))
+ {
+ return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+ }
+ else
+ {
+ return (new NSDictionaryCodeRunningSyntheticFrontEnd(valobj_sp));
+ }
+}
+
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::NSDictionaryCodeRunningSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get())
+{}
+
+size_t
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::CalculateNumChildren ()
+{
+ uint64_t count = 0;
+ if (ExtractValueFromObjCExpression(m_backend, "int", "count", count))
+ return count;
+ return 0;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ StreamString key_fetcher_expr;
+ key_fetcher_expr.Printf("(id)[(NSArray*)[(id)0x%" PRIx64 " allKeys] objectAtIndex:%zu]",m_backend.GetPointerValue(),idx);
+ StreamString value_fetcher_expr;
+ value_fetcher_expr.Printf("(id)[(id)0x%" PRIx64 " objectForKey:(%s)]",m_backend.GetPointerValue(),key_fetcher_expr.GetData());
+ StreamString object_fetcher_expr;
+ object_fetcher_expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = %s; _lldb_valgen_item.value = %s; _lldb_valgen_item;",key_fetcher_expr.GetData(),value_fetcher_expr.GetData());
+ lldb::ValueObjectSP child_sp;
+ m_backend.GetTargetSP()->EvaluateExpression(object_fetcher_expr.GetData(), m_backend.GetFrameSP().get(), child_sp,
+ EvaluateExpressionOptions().SetKeepInMemory(true));
+ if (child_sp)
+ child_sp->SetName(ConstString(idx_name.GetData()));
+ return child_sp;
+}
+
+bool
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::Update()
+{
+ return false;
+}
+
+bool
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+size_t
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ return 0;
+}
+
+lldb_private::formatters::NSDictionaryCodeRunningSyntheticFrontEnd::~NSDictionaryCodeRunningSyntheticFrontEnd ()
+{}
+
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::NSDictionaryISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+ if (valobj_sp)
+ Update();
+}
+
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::~NSDictionaryISyntheticFrontEnd ()
+{
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+}
+
+size_t
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::Update()
+{
+ m_children.clear();
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+ m_ptr_size = 0;
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType())
+ {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4)
+ {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+ }
+ else
+ {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+ }
+ if (error.Fail())
+ return false;
+ m_data_ptr = data_location + m_ptr_size;
+ return false;
+}
+
+bool
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryISyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty())
+ {
+ // do the scan phase
+ lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while(tries < num_children)
+ {
+ key_at_idx = m_data_ptr + (2*test_idx * m_ptr_size);
+ val_at_idx = key_at_idx + m_ptr_size;
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+ Error error;
+ key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+ val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!key_at_idx || !val_at_idx)
+ continue;
+ tries++;
+
+ DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ DictionaryItemDescriptor &dict_item = m_children[idx];
+ if (!dict_item.valobj_sp)
+ {
+ // make the new ValueObject
+ StreamString expr;
+ expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%" PRIu64 " ; _lldb_valgen_item.value = (id)%" PRIu64 "; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+ }
+ return dict_item.valobj_sp;
+}
+
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::NSDictionaryMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+ if (valobj_sp)
+ Update ();
+}
+
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::~NSDictionaryMSyntheticFrontEnd ()
+{
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+}
+
+size_t
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update()
+{
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType())
+ {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4)
+ {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+ }
+ else
+ {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
+}
+
+bool
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ lldb::addr_t m_keys_ptr = (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
+ lldb::addr_t m_values_ptr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty())
+ {
+ // do the scan phase
+ lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while(tries < num_children)
+ {
+ key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
+ val_at_idx = m_values_ptr + (test_idx * m_ptr_size);;
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+ Error error;
+ key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+ val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!key_at_idx || !val_at_idx)
+ continue;
+ tries++;
+
+ DictionaryItemDescriptor descriptor = {key_at_idx,val_at_idx,lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ DictionaryItemDescriptor &dict_item = m_children[idx];
+ if (!dict_item.valobj_sp)
+ {
+ // make the new ValueObject
+ StreamString expr;
+ expr.Printf("struct __lldb_autogen_nspair { id key; id value; } _lldb_valgen_item; _lldb_valgen_item.key = (id)%" PRIu64 " ; _lldb_valgen_item.value = (id)%" PRIu64 "; _lldb_valgen_item;",dict_item.key_ptr,dict_item.val_ptr);
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ dict_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+ }
+ return dict_item.valobj_sp;
+}
+
+template bool
+lldb_private::formatters::NSDictionarySummaryProvider<true> (ValueObject&, Stream&) ;
+
+template bool
+lldb_private::formatters::NSDictionarySummaryProvider<false> (ValueObject&, Stream&) ;
Index: aze/lldb/source/DataFormatters/NSSet.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/NSSet.cpp 2013-03-03 09:35:50.175457353 +0100
@@ -0,0 +1,442 @@
+//===-- NSSet.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/CXXFormatterFunctions.h"
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::formatters;
+
+template<bool cf_style>
+bool
+lldb_private::formatters::NSSetSummaryProvider (ValueObject& valobj, Stream& stream)
+{
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+
+ if (!runtime)
+ return false;
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return false;
+
+ uint32_t ptr_size = process_sp->GetAddressByteSize();
+ bool is_64bit = (ptr_size == 8);
+
+ lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
+
+ if (!valobj_addr)
+ return false;
+
+ uint64_t value = 0;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (!strcmp(class_name,"__NSSetI"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
+ else if (!strcmp(class_name,"__NSSetM"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
+ }
+ else if (!strcmp(class_name,"__NSCFSet"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ if (is_64bit)
+ value &= ~0x1fff000000000000UL;
+ }
+ else if (!strcmp(class_name,"NSCountedSet"))
+ {
+ Error error;
+ value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ value = process_sp->ReadUnsignedIntegerFromMemory(value + (is_64bit ? 20 : 12), ptr_size, 0, error);
+ if (error.Fail())
+ return false;
+ if (is_64bit)
+ value &= ~0x1fff000000000000UL;
+ }
+ else
+ {
+ if (!ExtractValueFromObjCExpression(valobj, "int", "count", value))
+ return false;
+ }
+
+ stream.Printf("%s%" PRIu64 " %s%s",
+ (cf_style ? "@\"" : ""),
+ value,
+ (cf_style ? (value == 1 ? "value" : "values") : (value == 1 ? "object" : "objects")),
+ (cf_style ? "\"" : ""));
+ return true;
+}
+
+SyntheticChildrenFrontEnd* lldb_private::formatters::NSSetSyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp)
+{
+ lldb::ProcessSP process_sp (valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return NULL;
+ ObjCLanguageRuntime *runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
+ if (!runtime)
+ return NULL;
+
+ if (!valobj_sp->IsPointerType())
+ {
+ Error error;
+ valobj_sp = valobj_sp->AddressOf(error);
+ if (error.Fail() || !valobj_sp)
+ return NULL;
+ }
+
+ ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(*valobj_sp.get()));
+
+ if (!descriptor.get() || !descriptor->IsValid())
+ return NULL;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return NULL;
+
+ if (!strcmp(class_name,"__NSSetI"))
+ {
+ return (new NSSetISyntheticFrontEnd(valobj_sp));
+ }
+ else if (!strcmp(class_name,"__NSSetM"))
+ {
+ return (new NSSetMSyntheticFrontEnd(valobj_sp));
+ }
+ else
+ {
+ return /*(new NSSetCodeRunningSyntheticFrontEnd(valobj_sp))*/ NULL;
+ }
+}
+
+lldb_private::formatters::NSSetISyntheticFrontEnd::NSSetISyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+ if (valobj_sp)
+ Update();
+}
+
+lldb_private::formatters::NSSetISyntheticFrontEnd::~NSSetISyntheticFrontEnd ()
+{
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+}
+
+size_t
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t
+lldb_private::formatters::NSSetISyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool
+lldb_private::formatters::NSSetISyntheticFrontEnd::Update()
+{
+ m_children.clear();
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+ m_ptr_size = 0;
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType())
+ {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4)
+ {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+ }
+ else
+ {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+ }
+ if (error.Fail())
+ return false;
+ m_data_ptr = data_location + m_ptr_size;
+ return false;
+}
+
+bool
+lldb_private::formatters::NSSetISyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSSetISyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty())
+ {
+ // do the scan phase
+ lldb::addr_t obj_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while(tries < num_children)
+ {
+ obj_at_idx = m_data_ptr + (test_idx * m_ptr_size);
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+ Error error;
+ obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!obj_at_idx)
+ continue;
+ tries++;
+
+ SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ SetItemDescriptor &set_item = m_children[idx];
+ if (!set_item.valobj_sp)
+ {
+ // make the new ValueObject
+ StreamString expr;
+ expr.Printf("(id)%" PRIu64,set_item.item_ptr);
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ set_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+ }
+ return set_item.valobj_sp;
+}
+
+lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp) :
+SyntheticChildrenFrontEnd(*valobj_sp.get()),
+m_exe_ctx_ref(),
+m_ptr_size(8),
+m_data_32(NULL),
+m_data_64(NULL)
+{
+ if (valobj_sp)
+ Update ();
+}
+
+lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd ()
+{
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+}
+
+size_t
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetIndexOfChildWithName (const ConstString &name)
+{
+ const char* item_name = name.GetCString();
+ uint32_t idx = ExtractIndexFromString(item_name);
+ if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+ return UINT32_MAX;
+ return idx;
+}
+
+size_t
+lldb_private::formatters::NSSetMSyntheticFrontEnd::CalculateNumChildren ()
+{
+ if (!m_data_32 && !m_data_64)
+ return 0;
+ return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool
+lldb_private::formatters::NSSetMSyntheticFrontEnd::Update()
+{
+ m_children.clear();
+ ValueObjectSP valobj_sp = m_backend.GetSP();
+ m_ptr_size = 0;
+ delete m_data_32;
+ m_data_32 = NULL;
+ delete m_data_64;
+ m_data_64 = NULL;
+ if (!valobj_sp)
+ return false;
+ if (!valobj_sp)
+ return false;
+ m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+ Error error;
+ if (valobj_sp->IsPointerType())
+ {
+ valobj_sp = valobj_sp->Dereference(error);
+ if (error.Fail() || !valobj_sp)
+ return false;
+ }
+ error.Clear();
+ lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+ if (!process_sp)
+ return false;
+ m_ptr_size = process_sp->GetAddressByteSize();
+ uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
+ if (m_ptr_size == 4)
+ {
+ m_data_32 = new DataDescriptor_32();
+ process_sp->ReadMemory (data_location, m_data_32, sizeof(DataDescriptor_32), error);
+ }
+ else
+ {
+ m_data_64 = new DataDescriptor_64();
+ process_sp->ReadMemory (data_location, m_data_64, sizeof(DataDescriptor_64), error);
+ }
+ if (error.Fail())
+ return false;
+ return false;
+}
+
+bool
+lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren ()
+{
+ return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex (size_t idx)
+{
+ lldb::addr_t m_objs_addr = (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
+
+ uint32_t num_children = CalculateNumChildren();
+
+ if (idx >= num_children)
+ return lldb::ValueObjectSP();
+
+ if (m_children.empty())
+ {
+ // do the scan phase
+ lldb::addr_t obj_at_idx = 0;
+
+ uint32_t tries = 0;
+ uint32_t test_idx = 0;
+
+ while(tries < num_children)
+ {
+ obj_at_idx = m_objs_addr + (test_idx * m_ptr_size);
+ ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+ Error error;
+ obj_at_idx = process_sp->ReadPointerFromMemory(obj_at_idx, error);
+ if (error.Fail())
+ return lldb::ValueObjectSP();
+
+ test_idx++;
+
+ if (!obj_at_idx)
+ continue;
+ tries++;
+
+ SetItemDescriptor descriptor = {obj_at_idx,lldb::ValueObjectSP()};
+
+ m_children.push_back(descriptor);
+ }
+ }
+
+ if (idx >= m_children.size()) // should never happen
+ return lldb::ValueObjectSP();
+
+ SetItemDescriptor &set_item = m_children[idx];
+ if (!set_item.valobj_sp)
+ {
+ // make the new ValueObject
+ StreamString expr;
+ expr.Printf("(id)%" PRIu64,set_item.item_ptr);
+ StreamString idx_name;
+ idx_name.Printf("[%zu]",idx);
+ set_item.valobj_sp = ValueObject::CreateValueObjectFromExpression(idx_name.GetData(), expr.GetData(), m_exe_ctx_ref);
+ }
+ return set_item.valobj_sp;
+}
+
+template bool
+lldb_private::formatters::NSSetSummaryProvider<true> (ValueObject& valobj, Stream& stream);
+
+template bool
+lldb_private::formatters::NSSetSummaryProvider<false> (ValueObject& valobj, Stream& stream);
Index: aze/lldb/source/DataFormatters/TypeCategory.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/TypeCategory.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -0,0 +1,382 @@
+//===-- TypeCategory.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/TypeCategory.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+using namespace lldb;
+using namespace lldb_private;
+
+TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
+ ConstString name) :
+m_summary_nav(new SummaryNavigator("summary",clist)),
+m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
+m_filter_nav(new FilterNavigator("filter",clist)),
+m_regex_filter_nav(new RegexFilterNavigator("regex-filter",clist)),
+#ifndef LLDB_DISABLE_PYTHON
+m_synth_nav(new SynthNavigator("synth",clist)),
+m_regex_synth_nav(new RegexSynthNavigator("regex-synth",clist)),
+#endif
+m_enabled(false),
+m_change_listener(clist),
+m_mutex(Mutex::eMutexTypeRecursive),
+m_name(name)
+{}
+
+bool
+TypeCategoryImpl::Get (ValueObject& valobj,
+ lldb::TypeSummaryImplSP& entry,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* reason)
+{
+ if (!IsEnabled())
+ return false;
+ if (GetSummaryNavigator()->Get(valobj, entry, use_dynamic, reason))
+ return true;
+ bool regex = GetRegexSummaryNavigator()->Get(valobj, entry, use_dynamic, reason);
+ if (regex && reason)
+ *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
+ return regex;
+}
+
+bool
+TypeCategoryImpl::Get(ValueObject& valobj,
+ lldb::SyntheticChildrenSP& entry_sp,
+ lldb::DynamicValueType use_dynamic,
+ uint32_t* reason)
+{
+ if (!IsEnabled())
+ return false;
+ TypeFilterImpl::SharedPointer filter_sp;
+ uint32_t reason_filter = 0;
+ bool regex_filter = false;
+ // first find both Filter and Synth, and then check which is most recent
+
+ if (!GetFilterNavigator()->Get(valobj, filter_sp, use_dynamic, &reason_filter))
+ regex_filter = GetRegexFilterNavigator()->Get (valobj, filter_sp, use_dynamic, &reason_filter);
+
+#ifndef LLDB_DISABLE_PYTHON
+ bool regex_synth = false;
+ uint32_t reason_synth = 0;
+ bool pick_synth = false;
+ ScriptedSyntheticChildren::SharedPointer synth;
+ if (!GetSyntheticNavigator()->Get(valobj, synth, use_dynamic, &reason_synth))
+ regex_synth = GetRegexSyntheticNavigator()->Get (valobj, synth, use_dynamic, &reason_synth);
+ if (!filter_sp.get() && !synth.get())
+ return false;
+ else if (!filter_sp.get() && synth.get())
+ pick_synth = true;
+
+ else if (filter_sp.get() && !synth.get())
+ pick_synth = false;
+
+ else /*if (filter_sp.get() && synth.get())*/
+ {
+ if (filter_sp->GetRevision() > synth->GetRevision())
+ pick_synth = false;
+ else
+ pick_synth = true;
+ }
+ if (pick_synth)
+ {
+ if (regex_synth && reason)
+ *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
+ entry_sp = synth;
+ return true;
+ }
+ else
+ {
+ if (regex_filter && reason)
+ *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
+ entry_sp = filter_sp;
+ return true;
+ }
+
+#else
+ if (filter_sp)
+ {
+ entry_sp = filter_sp;
+ return true;
+ }
+#endif
+
+ return false;
+
+}
+
+void
+TypeCategoryImpl::Clear (FormatCategoryItems items)
+{
+ if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
+ m_summary_nav->Clear();
+ if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
+ m_regex_summary_nav->Clear();
+ if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
+ m_filter_nav->Clear();
+ if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
+ m_regex_filter_nav->Clear();
+#ifndef LLDB_DISABLE_PYTHON
+ if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
+ m_synth_nav->Clear();
+ if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
+ m_regex_synth_nav->Clear();
+#endif
+}
+
+bool
+TypeCategoryImpl::Delete (ConstString name,
+ FormatCategoryItems items)
+{
+ bool success = false;
+ if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
+ success = m_summary_nav->Delete(name) || success;
+ if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
+ success = m_regex_summary_nav->Delete(name) || success;
+ if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
+ success = m_filter_nav->Delete(name) || success;
+ if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
+ success = m_regex_filter_nav->Delete(name) || success;
+#ifndef LLDB_DISABLE_PYTHON
+ if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
+ success = m_synth_nav->Delete(name) || success;
+ if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
+ success = m_regex_synth_nav->Delete(name) || success;
+#endif
+ return success;
+}
+
+uint32_t
+TypeCategoryImpl::GetCount (FormatCategoryItems items)
+{
+ uint32_t count = 0;
+ if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
+ count += m_summary_nav->GetCount();
+ if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
+ count += m_regex_summary_nav->GetCount();
+ if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
+ count += m_filter_nav->GetCount();
+ if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
+ count += m_regex_filter_nav->GetCount();
+#ifndef LLDB_DISABLE_PYTHON
+ if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
+ count += m_synth_nav->GetCount();
+ if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
+ count += m_regex_synth_nav->GetCount();
+#endif
+ return count;
+}
+
+bool
+TypeCategoryImpl::AnyMatches(ConstString type_name,
+ FormatCategoryItems items,
+ bool only_enabled,
+ const char** matching_category,
+ FormatCategoryItems* matching_type)
+{
+ if (!IsEnabled() && only_enabled)
+ return false;
+
+ lldb::TypeSummaryImplSP summary;
+ TypeFilterImpl::SharedPointer filter;
+#ifndef LLDB_DISABLE_PYTHON
+ ScriptedSyntheticChildren::SharedPointer synth;
+#endif
+
+ if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
+ {
+ if (m_summary_nav->Get(type_name, summary))
+ {
+ if (matching_category)
+ *matching_category = m_name.GetCString();
+ if (matching_type)
+ *matching_type = eFormatCategoryItemSummary;
+ return true;
+ }
+ }
+ if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
+ {
+ if (m_regex_summary_nav->Get(type_name, summary))
+ {
+ if (matching_category)
+ *matching_category = m_name.GetCString();
+ if (matching_type)
+ *matching_type = eFormatCategoryItemRegexSummary;
+ return true;
+ }
+ }
+ if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
+ {
+ if (m_filter_nav->Get(type_name, filter))
+ {
+ if (matching_category)
+ *matching_category = m_name.GetCString();
+ if (matching_type)
+ *matching_type = eFormatCategoryItemFilter;
+ return true;
+ }
+ }
+ if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
+ {
+ if (m_regex_filter_nav->Get(type_name, filter))
+ {
+ if (matching_category)
+ *matching_category = m_name.GetCString();
+ if (matching_type)
+ *matching_type = eFormatCategoryItemRegexFilter;
+ return true;
+ }
+ }
+#ifndef LLDB_DISABLE_PYTHON
+ if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
+ {
+ if (m_synth_nav->Get(type_name, synth))
+ {
+ if (matching_category)
+ *matching_category = m_name.GetCString();
+ if (matching_type)
+ *matching_type = eFormatCategoryItemSynth;
+ return true;
+ }
+ }
+ if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
+ {
+ if (m_regex_synth_nav->Get(type_name, synth))
+ {
+ if (matching_category)
+ *matching_category = m_name.GetCString();
+ if (matching_type)
+ *matching_type = eFormatCategoryItemRegexSynth;
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+TypeCategoryImpl::SummaryNavigator::MapValueType
+TypeCategoryImpl::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ SummaryNavigator::MapValueType retval;
+
+ if (type_sp)
+ {
+ if (type_sp->IsRegex())
+ m_regex_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
+ else
+ m_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
+ }
+
+ return retval;
+}
+
+TypeCategoryImpl::FilterNavigator::MapValueType
+TypeCategoryImpl::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ FilterNavigator::MapValueType retval;
+
+ if (type_sp)
+ {
+ if (type_sp->IsRegex())
+ m_regex_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
+ else
+ m_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
+ }
+
+ return retval;
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+TypeCategoryImpl::SynthNavigator::MapValueType
+TypeCategoryImpl::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
+{
+ SynthNavigator::MapValueType retval;
+
+ if (type_sp)
+ {
+ if (type_sp->IsRegex())
+ m_regex_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
+ else
+ m_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
+ }
+
+ return retval;
+}
+#endif
+
+lldb::TypeNameSpecifierImplSP
+TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex (size_t index)
+{
+ if (index < m_summary_nav->GetCount())
+ return m_summary_nav->GetTypeNameSpecifierAtIndex(index);
+ else
+ return m_regex_summary_nav->GetTypeNameSpecifierAtIndex(index-m_summary_nav->GetCount());
+}
+
+TypeCategoryImpl::SummaryNavigator::MapValueType
+TypeCategoryImpl::GetSummaryAtIndex (size_t index)
+{
+ if (index < m_summary_nav->GetCount())
+ return m_summary_nav->GetAtIndex(index);
+ else
+ return m_regex_summary_nav->GetAtIndex(index-m_summary_nav->GetCount());
+}
+
+TypeCategoryImpl::FilterNavigator::MapValueType
+TypeCategoryImpl::GetFilterAtIndex (size_t index)
+{
+ if (index < m_filter_nav->GetCount())
+ return m_filter_nav->GetAtIndex(index);
+ else
+ return m_regex_filter_nav->GetAtIndex(index-m_filter_nav->GetCount());
+}
+
+lldb::TypeNameSpecifierImplSP
+TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex (size_t index)
+{
+ if (index < m_filter_nav->GetCount())
+ return m_filter_nav->GetTypeNameSpecifierAtIndex(index);
+ else
+ return m_regex_filter_nav->GetTypeNameSpecifierAtIndex(index-m_filter_nav->GetCount());
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+TypeCategoryImpl::SynthNavigator::MapValueType
+TypeCategoryImpl::GetSyntheticAtIndex (size_t index)
+{
+ if (index < m_synth_nav->GetCount())
+ return m_synth_nav->GetAtIndex(index);
+ else
+ return m_regex_synth_nav->GetAtIndex(index-m_synth_nav->GetCount());
+}
+
+lldb::TypeNameSpecifierImplSP
+TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex (size_t index)
+{
+ if (index < m_synth_nav->GetCount())
+ return m_synth_nav->GetTypeNameSpecifierAtIndex(index);
+ else
+ return m_regex_synth_nav->GetTypeNameSpecifierAtIndex(index - m_synth_nav->GetCount());
+}
+#endif
+
+void
+TypeCategoryImpl::Enable (bool value, uint32_t position)
+{
+ Mutex::Locker locker(m_mutex);
+ m_enabled = value;
+ m_enabled_position = position;
+ if (m_change_listener)
+ m_change_listener->Changed();
+}
Index: aze/lldb/source/DataFormatters/TypeCategoryMap.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/TypeCategoryMap.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -0,0 +1,285 @@
+//===-- TypeCategoryMap.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+#include "lldb/DataFormatters/TypeCategoryMap.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+using namespace lldb;
+using namespace lldb_private;
+
+TypeCategoryMap::TypeCategoryMap (IFormatChangeListener* lst) :
+m_map_mutex(Mutex::eMutexTypeRecursive),
+listener(lst),
+m_map(),
+m_active_categories()
+{
+ ConstString default_cs("default");
+ lldb::TypeCategoryImplSP default_sp = lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
+ Add(default_cs,default_sp);
+ Enable(default_cs,First);
+}
+
+void
+TypeCategoryMap::Add (KeyType name, const ValueSP& entry)
+{
+ Mutex::Locker locker(m_map_mutex);
+ m_map[name] = entry;
+ if (listener)
+ listener->Changed();
+}
+
+bool
+TypeCategoryMap::Delete (KeyType name)
+{
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ m_map.erase(name);
+ Disable(name);
+ if (listener)
+ listener->Changed();
+ return true;
+}
+
+bool
+TypeCategoryMap::Enable (KeyType category_name, Position pos)
+{
+ Mutex::Locker locker(m_map_mutex);
+ ValueSP category;
+ if (!Get(category_name,category))
+ return false;
+ return Enable(category, pos);
+}
+
+bool
+TypeCategoryMap::Disable (KeyType category_name)
+{
+ Mutex::Locker locker(m_map_mutex);
+ ValueSP category;
+ if (!Get(category_name,category))
+ return false;
+ return Disable(category);
+}
+
+bool
+TypeCategoryMap::Enable (ValueSP category, Position pos)
+{
+ Mutex::Locker locker(m_map_mutex);
+ if (category.get())
+ {
+ Position pos_w = pos;
+ if (pos == First || m_active_categories.size() == 0)
+ m_active_categories.push_front(category);
+ else if (pos == Last || pos == m_active_categories.size())
+ m_active_categories.push_back(category);
+ else if (pos < m_active_categories.size())
+ {
+ ActiveCategoriesList::iterator iter = m_active_categories.begin();
+ while (pos_w)
+ {
+ pos_w--,iter++;
+ }
+ m_active_categories.insert(iter,category);
+ }
+ else
+ return false;
+ category->Enable(true,
+ pos);
+ return true;
+ }
+ return false;
+}
+
+bool
+TypeCategoryMap::Disable (ValueSP category)
+{
+ Mutex::Locker locker(m_map_mutex);
+ if (category.get())
+ {
+ m_active_categories.remove_if(delete_matching_categories(category));
+ category->Disable();
+ return true;
+ }
+ return false;
+}
+
+void
+TypeCategoryMap::Clear ()
+{
+ Mutex::Locker locker(m_map_mutex);
+ m_map.clear();
+ m_active_categories.clear();
+ if (listener)
+ listener->Changed();
+}
+
+bool
+TypeCategoryMap::Get (KeyType name, ValueSP& entry)
+{
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ entry = iter->second;
+ return true;
+}
+
+bool
+TypeCategoryMap::Get (uint32_t pos, ValueSP& entry)
+{
+ Mutex::Locker locker(m_map_mutex);
+ MapIterator iter = m_map.begin();
+ MapIterator end = m_map.end();
+ while (pos > 0)
+ {
+ iter++;
+ pos--;
+ if (iter == end)
+ return false;
+ }
+ entry = iter->second;
+ return false;
+}
+
+bool
+TypeCategoryMap::AnyMatches (ConstString type_name,
+ TypeCategoryImpl::FormatCategoryItems items,
+ bool only_enabled,
+ const char** matching_category,
+ TypeCategoryImpl::FormatCategoryItems* matching_type)
+{
+ Mutex::Locker locker(m_map_mutex);
+
+ MapIterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; pos++)
+ {
+ if (pos->second->AnyMatches(type_name,
+ items,
+ only_enabled,
+ matching_category,
+ matching_type))
+ return true;
+ }
+ return false;
+}
+
+lldb::TypeSummaryImplSP
+TypeCategoryMap::GetSummaryFormat (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ Mutex::Locker locker(m_map_mutex);
+
+ uint32_t reason_why;
+ ActiveCategoriesIterator begin, end = m_active_categories.end();
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+
+ for (begin = m_active_categories.begin(); begin != end; begin++)
+ {
+ lldb::TypeCategoryImplSP category_sp = *begin;
+ lldb::TypeSummaryImplSP current_format;
+ if (log)
+ log->Printf("[CategoryMap::GetSummaryFormat] Trying to use category %s\n", category_sp->GetName());
+ if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
+ continue;
+ return current_format;
+ }
+ if (log)
+ log->Printf("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP\n");
+ return lldb::TypeSummaryImplSP();
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+lldb::SyntheticChildrenSP
+TypeCategoryMap::GetSyntheticChildren (ValueObject& valobj,
+ lldb::DynamicValueType use_dynamic)
+{
+ Mutex::Locker locker(m_map_mutex);
+
+ uint32_t reason_why;
+
+ ActiveCategoriesIterator begin, end = m_active_categories.end();
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
+
+ for (begin = m_active_categories.begin(); begin != end; begin++)
+ {
+ lldb::TypeCategoryImplSP category_sp = *begin;
+ lldb::SyntheticChildrenSP current_format;
+ if (log)
+ log->Printf("[CategoryMap::GetSyntheticChildren] Trying to use category %s\n", category_sp->GetName());
+ if (!category_sp->Get(valobj, current_format, use_dynamic, &reason_why))
+ continue;
+ return current_format;
+ }
+ if (log)
+ log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP\n");
+ return lldb::SyntheticChildrenSP();
+}
+#endif
+
+void
+TypeCategoryMap::LoopThrough(CallbackType callback, void* param)
+{
+ if (callback)
+ {
+ Mutex::Locker locker(m_map_mutex);
+
+ // loop through enabled categories in respective order
+ {
+ ActiveCategoriesIterator begin, end = m_active_categories.end();
+ for (begin = m_active_categories.begin(); begin != end; begin++)
+ {
+ lldb::TypeCategoryImplSP category = *begin;
+ ConstString type = ConstString(category->GetName());
+ if (!callback(param, category))
+ break;
+ }
+ }
+
+ // loop through disabled categories in just any order
+ {
+ MapIterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; pos++)
+ {
+ if (pos->second->IsEnabled())
+ continue;
+ KeyType type = pos->first;
+ if (!callback(param, pos->second))
+ break;
+ }
+ }
+ }
+}
+
+TypeCategoryImplSP
+TypeCategoryMap::GetAtIndex (uint32_t index)
+{
+ Mutex::Locker locker(m_map_mutex);
+
+ if (index < m_map.size())
+ {
+ MapIterator pos, end = m_map.end();
+ for (pos = m_map.begin(); pos != end; pos++)
+ {
+ if (index == 0)
+ return pos->second;
+ index--;
+ }
+ }
+
+ return TypeCategoryImplSP();
+}
Index: aze/lldb/source/DataFormatters/TypeFormat.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/TypeFormat.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -0,0 +1,52 @@
+//===-- TypeFormat.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+// C Includes
+
+// C++ Includes
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/DataFormatters/TypeFormat.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+TypeFormatImpl::TypeFormatImpl (lldb::Format f,
+ const Flags& flags) :
+m_flags(flags),
+m_format (f)
+{
+}
+
+std::string
+TypeFormatImpl::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf ("%s%s%s%s\n",
+ FormatManager::GetFormatAsCString (GetFormat()),
+ Cascades() ? "" : " (not cascading)",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "");
+ return sstr.GetString();
+}
+
Index: aze/lldb/source/DataFormatters/TypeSummary.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/TypeSummary.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -0,0 +1,250 @@
+//===-- TypeSummary.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+// C Includes
+
+// C++ Includes
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/DataFormatters/TypeSummary.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+
+#include "lldb/Host/Host.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+TypeSummaryImpl::TypeSummaryImpl (const TypeSummaryImpl::Flags& flags) :
+m_flags(flags)
+{
+}
+
+
+StringSummaryFormat::StringSummaryFormat (const TypeSummaryImpl::Flags& flags,
+ const char *format_cstr) :
+TypeSummaryImpl(flags),
+m_format()
+{
+ if (format_cstr)
+ m_format.assign(format_cstr);
+}
+
+bool
+StringSummaryFormat::FormatObject (ValueObject *valobj,
+ std::string& retval)
+{
+ if (!valobj)
+ {
+ retval.assign("NULL ValueObject");
+ return false;
+ }
+
+ StreamString s;
+ ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
+ SymbolContext sc;
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame)
+ sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
+
+ if (IsOneliner())
+ {
+ ValueObject* object;
+
+ ValueObjectSP synth_valobj = valobj->GetSyntheticValue();
+ if (synth_valobj)
+ object = synth_valobj.get();
+ else
+ object = valobj;
+
+ const uint32_t num_children = object->GetNumChildren();
+ if (num_children)
+ {
+ s.PutChar('(');
+
+ for (uint32_t idx=0; idx<num_children; ++idx)
+ {
+ lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
+ if (child_sp.get())
+ {
+ if (idx)
+ s.PutCString(", ");
+ if (!HideNames())
+ {
+ s.PutCString(child_sp.get()->GetName().AsCString());
+ s.PutCString(" = ");
+ }
+ child_sp.get()->DumpPrintableRepresentation(s,
+ ValueObject::eValueObjectRepresentationStyleSummary,
+ lldb::eFormatInvalid,
+ ValueObject::ePrintableRepresentationSpecialCasesDisable);
+ }
+ }
+
+ s.PutChar(')');
+
+ retval.assign(s.GetString());
+ return true;
+ }
+ else
+ {
+ retval.assign("error: oneliner for no children");
+ return false;
+ }
+
+ }
+ else
+ {
+ if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, valobj))
+ {
+ retval.assign(s.GetString());
+ return true;
+ }
+ else
+ {
+ retval.assign("error: summary string parsing error");
+ return false;
+ }
+ }
+}
+
+std::string
+StringSummaryFormat::GetDescription ()
+{
+ StreamString sstr;
+
+ sstr.Printf ("`%s`%s%s%s%s%s%s%s", m_format.c_str(),
+ Cascades() ? "" : " (not cascading)",
+ !DoesPrintChildren() ? "" : " (show children)",
+ !DoesPrintValue() ? " (hide value)" : "",
+ IsOneliner() ? " (one-line printout)" : "",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "",
+ HideNames() ? " (hide member names)" : "");
+ return sstr.GetString();
+}
+
+CXXFunctionSummaryFormat::CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
+ Callback impl,
+ const char* description) :
+TypeSummaryImpl(flags),
+m_impl(impl),
+m_description(description ? description : "")
+{
+}
+
+bool
+CXXFunctionSummaryFormat::FormatObject (ValueObject *valobj,
+ std::string& dest)
+{
+ dest.clear();
+ StreamString stream;
+ if (!m_impl || m_impl(*valobj,stream) == false)
+ return false;
+ dest.assign(stream.GetData());
+ return true;
+}
+
+std::string
+CXXFunctionSummaryFormat::GetDescription ()
+{
+ StreamString sstr;
+ sstr.Printf ("`%s (%p) `%s%s%s%s%s%s%s", m_description.c_str(),m_impl,
+ Cascades() ? "" : " (not cascading)",
+ !DoesPrintChildren() ? "" : " (show children)",
+ !DoesPrintValue() ? " (hide value)" : "",
+ IsOneliner() ? " (one-line printout)" : "",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "",
+ HideNames() ? " (hide member names)" : "");
+ return sstr.GetString();
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+
+
+ScriptSummaryFormat::ScriptSummaryFormat (const TypeSummaryImpl::Flags& flags,
+ const char * function_name,
+ const char * python_script) :
+TypeSummaryImpl(flags),
+m_function_name(),
+m_python_script(),
+m_script_function_sp()
+{
+ if (function_name)
+ m_function_name.assign(function_name);
+ if (python_script)
+ m_python_script.assign(python_script);
+}
+
+bool
+ScriptSummaryFormat::FormatObject (ValueObject *valobj,
+ std::string& retval)
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+
+ if (!valobj)
+ return false;
+
+ Host::SetCrashDescriptionWithFormat("[Python summary] Name: %s - Function: %s",
+ valobj->GetName().AsCString("unknown"),
+ m_function_name.c_str());
+
+ TargetSP target_sp(valobj->GetTargetSP());
+
+ if (!target_sp)
+ {
+ retval.assign("error: no target");
+ return false;
+ }
+
+ ScriptInterpreter *script_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+
+ if (!script_interpreter)
+ {
+ retval.assign("error: no ScriptInterpreter");
+ return false;
+ }
+
+ return script_interpreter->GetScriptedSummary(m_function_name.c_str(),
+ valobj->GetSP(),
+ m_script_function_sp,
+ retval);
+
+}
+
+std::string
+ScriptSummaryFormat::GetDescription ()
+{
+ StreamString sstr;
+ sstr.Printf ("%s%s%s%s%s%s%s\n%s", Cascades() ? "" : " (not cascading)",
+ !DoesPrintChildren() ? "" : " (show children)",
+ !DoesPrintValue() ? " (hide value)" : "",
+ IsOneliner() ? " (one-line printout)" : "",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "",
+ HideNames() ? " (hide member names)" : "",
+ m_python_script.c_str());
+ return sstr.GetString();
+
+}
+
+#endif // #ifndef LLDB_DISABLE_PYTHON
Index: aze/lldb/source/DataFormatters/TypeSynthetic.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/DataFormatters/TypeSynthetic.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -0,0 +1,114 @@
+//===-- TypeSynthetic.cpp ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
+// C Includes
+
+// C++ Includes
+
+// Other libraries and framework includes
+
+// Project includes
+#include "lldb/lldb-public.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/DataFormatters/TypeSynthetic.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+std::string
+TypeFilterImpl::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf("%s%s%s {\n",
+ Cascades() ? "" : " (not cascading)",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "");
+
+ for (int i = 0; i < GetCount(); i++)
+ {
+ sstr.Printf(" %s\n",
+ GetExpressionPathAtIndex(i));
+ }
+
+ sstr.Printf("}");
+ return sstr.GetString();
+}
+
+std::string
+CXXSyntheticChildren::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf("%s%s%s Generator at %p - %s\n",
+ Cascades() ? "" : " (not cascading)",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "",
+ m_create_callback,
+ m_description.c_str());
+
+ return sstr.GetString();
+}
+
+#ifndef LLDB_DISABLE_PYTHON
+
+ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass, ValueObject &backend) :
+SyntheticChildrenFrontEnd(backend),
+m_python_class(pclass),
+m_wrapper_sp(),
+m_interpreter(NULL)
+{
+ if (backend == LLDB_INVALID_UID)
+ return;
+
+ TargetSP target_sp = backend.GetTargetSP();
+
+ if (!target_sp)
+ return;
+
+ m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+
+ if (m_interpreter != NULL)
+ m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(m_python_class.c_str(), backend.GetSP());
+}
+
+ScriptedSyntheticChildren::FrontEnd::~FrontEnd()
+{
+}
+
+lldb::ValueObjectSP
+ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex (size_t idx)
+{
+ if (!m_wrapper_sp || !m_interpreter)
+ return lldb::ValueObjectSP();
+
+ return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx);
+}
+
+std::string
+ScriptedSyntheticChildren::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf("%s%s%s Python class %s",
+ Cascades() ? "" : " (not cascading)",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "",
+ m_python_class.c_str());
+
+ return sstr.GetString();
+}
+
+#endif // #ifndef LLDB_DISABLE_PYTHON
Index: aze/lldb/source/Expression/ASTResultSynthesizer.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ASTResultSynthesizer.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ASTResultSynthesizer.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -131,8 +131,6 @@
{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- ASTContext &Ctx(*m_ast_context);
-
if (!m_sema)
return false;
@@ -146,11 +144,11 @@
std::string s;
raw_string_ostream os(s);
- Ctx.getTranslationUnitDecl()->print(os);
+ function_decl->print(os);
os.flush();
- log->Printf("AST context before transforming:\n%s", s.c_str());
+ log->Printf ("Untransformed function AST:\n%s", s.c_str());
}
Stmt *function_body = function_decl->getBody();
@@ -178,9 +176,7 @@
ASTResultSynthesizer::SynthesizeObjCMethodResult (ObjCMethodDecl *MethodDecl)
{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- ASTContext &Ctx(*m_ast_context);
-
+
if (!m_sema)
return false;
@@ -192,11 +188,11 @@
std::string s;
raw_string_ostream os(s);
- Ctx.getTranslationUnitDecl()->print(os);
+ MethodDecl->print(os);
os.flush();
- log->Printf("AST context before transforming:\n%s", s.c_str());
+ log->Printf ("Untransformed method AST:\n%s", s.c_str());
}
Stmt *method_body = MethodDecl->getBody();
@@ -209,7 +205,7 @@
bool ret = SynthesizeBodyResult (compound_stmt,
MethodDecl);
- if (log)
+ if (log && log->GetVerbose())
{
std::string s;
raw_string_ostream os(s);
@@ -218,7 +214,7 @@
os.flush();
- log->Printf("Transformed function AST:\n%s", s.c_str());
+ log->Printf("Transformed method AST:\n%s", s.c_str());
}
return ret;
Index: aze/lldb/source/Expression/ClangASTSource.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ClangASTSource.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ClangASTSource.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -56,7 +56,7 @@
}
// The core lookup interface.
-DeclContext::lookup_result
+bool
ClangASTSource::FindExternalVisibleDeclsByName
(
const DeclContext *decl_ctx,
@@ -64,11 +64,17 @@
)
{
if (!m_ast_context)
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
if (GetImportInProgress())
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
-
+ {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
+
std::string decl_name (clang_decl_name.getAsString());
// if (m_decl_map.DoingASTImport ())
@@ -83,7 +89,8 @@
if (!identifier_info ||
identifier_info->getBuiltinID() != 0)
{
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
}
break;
@@ -91,12 +98,14 @@
// Operator names. Not important for now.
case DeclarationName::CXXOperatorName:
case DeclarationName::CXXLiteralOperatorName:
- return DeclContext::lookup_result();
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
// Using directives found in this context.
// Tell Sema we didn't find any or we'll end up getting asked a *lot*.
case DeclarationName::CXXUsingDirective:
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
@@ -108,13 +117,15 @@
FindObjCMethodDecls(method_search_context);
- return SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
+ SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, method_decls);
+ return (method_decls.size() > 0);
}
// These aren't possible in the global context.
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName:
- return DeclContext::lookup_result();
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
@@ -128,7 +139,8 @@
}
else
{
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
}
@@ -138,7 +150,8 @@
if (m_active_lookups.find (uniqued_const_decl_name) != m_active_lookups.end())
{
// We are currently looking up this name...
- return DeclContext::lookup_result();
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
m_active_lookups.insert(uniqued_const_decl_name);
// static uint32_t g_depth = 0;
@@ -147,10 +160,10 @@
llvm::SmallVector<NamedDecl*, 4> name_decls;
NameSearchContext name_search_context(*this, name_decls, clang_decl_name, decl_ctx);
FindExternalVisibleDecls(name_search_context);
- DeclContext::lookup_result result (SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls));
+ SetExternalVisibleDeclsForName (decl_ctx, clang_decl_name, name_decls);
// --g_depth;
m_active_lookups.erase (uniqued_const_decl_name);
- return result;
+ return (name_decls.size() != 0);
}
void
@@ -397,7 +410,7 @@
if (log)
{
- log->Printf(" FELD[%u] Original decl (Decl*)%p:", current_id, original_decl);
+ log->Printf(" FELD[%u] Original decl (ASTContext*)%p (Decl*)%p:", current_id, original_ctx, original_decl);
ASTDumper(original_decl).ToLog(log, " ");
}
@@ -615,9 +628,7 @@
const ModuleList &target_images = m_target->GetImages();
Mutex::Locker modules_locker (target_images.GetMutex());
- for (uint32_t i = 0, e = target_images.GetSize();
- i != e;
- ++i)
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
{
lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
@@ -681,7 +692,7 @@
if (!copied_type)
{
if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export the type for a constant integer result",
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a type",
current_id);
break;
@@ -689,6 +700,63 @@
context.AddTypeDecl(copied_type);
}
+ else
+ {
+ do
+ {
+ // Couldn't find any types elsewhere. Try the Objective-C runtime if one exists.
+
+ lldb::ProcessSP process(m_target->GetProcessSP());
+
+ if (!process)
+ break;
+
+ ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+
+ if (!language_runtime)
+ break;
+
+ TypeVendor *type_vendor = language_runtime->GetTypeVendor();
+
+ if (!type_vendor)
+ break;
+
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector <ClangASTType> types;
+
+ if (!type_vendor->FindTypes(name,
+ append,
+ max_matches,
+ types))
+ break;
+
+ if (log)
+ {
+ log->Printf(" CAS::FEVD[%u] Matching type found for \"%s\" in the runtime",
+ current_id,
+ name.GetCString());
+ }
+
+ const clang::Type *runtime_clang_type = QualType::getFromOpaquePtr(types[0].GetOpaqueQualType()).getTypePtr();
+
+ clang::QualType runtime_qual_type(runtime_clang_type, 0);
+
+ void *copied_type = GuardedCopyType(m_ast_context, type_vendor->GetClangASTContext(), runtime_qual_type.getAsOpaquePtr());
+
+ if (!copied_type)
+ {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a type from the runtime",
+ current_id);
+
+ break;
+ }
+
+ context.AddTypeDecl(copied_type);
+ }
+ while(0);
+ }
} while(0);
}
@@ -750,7 +818,7 @@
return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
}
-static void
+static bool
FindObjCMethodDeclsWithOrigin (unsigned int current_id,
NameSearchContext &context,
ObjCInterfaceDecl *original_interface_decl,
@@ -797,26 +865,26 @@
ObjCInterfaceDecl::lookup_result result = original_interface_decl->lookup(original_decl_name);
- if (result.first == result.second)
- return;
+ if (result.empty())
+ return false;
- if (!*result.first)
- return;
+ if (!result[0])
+ return false;
- ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(*result.first);
+ ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(result[0]);
if (!result_method)
- return;
+ return false;
Decl *copied_decl = ast_importer->CopyDecl(ast_context, &result_method->getASTContext(), result_method);
if (!copied_decl)
- return;
+ return false;
ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
if (!copied_method_decl)
- return;
+ return false;
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
@@ -828,7 +896,7 @@
context.AddNamedDecl(copied_method_decl);
- return;
+ return true;
}
void
@@ -859,12 +927,13 @@
ObjCInterfaceDecl *original_interface_decl = dyn_cast<ObjCInterfaceDecl>(original_decl);
- FindObjCMethodDeclsWithOrigin(current_id,
- context,
- original_interface_decl,
- m_ast_context,
- m_ast_importer,
- "at origin");
+ if (FindObjCMethodDeclsWithOrigin(current_id,
+ context,
+ original_interface_decl,
+ m_ast_context,
+ m_ast_importer,
+ "at origin"))
+ return; // found it, no need to look any further
} while (0);
StreamString ss;
@@ -1075,6 +1144,9 @@
ObjCLanguageRuntime *language_runtime(process->GetObjCLanguageRuntime());
+ if (!language_runtime)
+ break;
+
TypeVendor *type_vendor = language_runtime->GetTypeVendor();
if (!type_vendor)
@@ -1370,9 +1442,10 @@
if (log)
{
- log->Printf("LayoutRecordType[%u] on (RecordDecl*)%p [name = '%s']",
+ log->Printf("LayoutRecordType[%u] on (ASTContext*)%p for (RecordDecl*)%p [name = '%s']",
current_id,
m_ast_context,
+ record,
record->getNameAsString().c_str());
}
@@ -1430,14 +1503,14 @@
{
log->Printf("LRT[%u] returned:", current_id);
log->Printf("LRT[%u] Original = (RecordDecl*)%p", current_id, origin_record.decl);
- log->Printf("LRT[%u] Size = %lld", current_id, size);
- log->Printf("LRT[%u] Alignment = %lld", current_id, alignment);
+ log->Printf("LRT[%u] Size = %" PRId64, current_id, size);
+ log->Printf("LRT[%u] Alignment = %" PRId64, current_id, alignment);
log->Printf("LRT[%u] Fields:", current_id);
for (RecordDecl::field_iterator fi = record->field_begin(), fe = record->field_end();
fi != fe;
++fi)
{
- log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %lld bits",
+ log->Printf("LRT[%u] (FieldDecl*)%p, Name = '%s', Offset = %" PRId64 " bits",
current_id,
*fi,
fi->getNameAsString().c_str(),
@@ -1458,7 +1531,7 @@
DeclFromParser <RecordDecl> base_record(base_record_type->getDecl());
DeclFromParser <CXXRecordDecl> base_cxx_record = DynCast<CXXRecordDecl>(base_record);
- log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %lld chars",
+ log->Printf("LRT[%u] %s(CXXRecordDecl*)%p, Name = '%s', Offset = %" PRId64 " chars",
current_id,
(is_virtual ? "Virtual " : ""),
base_cxx_record.decl,
@@ -1541,9 +1614,7 @@
ClangNamespaceDecl null_namespace_decl;
- for (uint32_t i = 0, e = target_images.GetSize();
- i != e;
- ++i)
+ for (size_t i = 0, e = target_images.GetSize(); i < e; ++i)
{
lldb::ModuleSP image = target_images.GetModuleAtIndexUnlocked(i);
@@ -1589,9 +1660,14 @@
if (!copied_decl)
return NULL;
-
+
NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
+ if (!copied_namespace_decl)
+ return NULL;
+
+ context.m_decls.push_back(copied_namespace_decl);
+
m_ast_importer->RegisterNamespaceMap(copied_namespace_decl, namespace_decls);
return dyn_cast<NamespaceDecl>(copied_decl);
@@ -1745,10 +1821,8 @@
void
NameSearchContext::AddLookupResult (clang::DeclContextLookupConstResult result)
{
- for (clang::NamedDecl * const *decl_iterator = result.first;
- decl_iterator != result.second;
- ++decl_iterator)
- m_decls.push_back (*decl_iterator);
+ for (clang::NamedDecl *decl : result)
+ m_decls.push_back (decl);
}
void
Index: aze/lldb/source/Expression/ClangExpressionDeclMap.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ClangExpressionDeclMap.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ClangExpressionDeclMap.cpp 2013-03-03 09:35:50.179457353 +0100
@@ -40,6 +40,7 @@
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
@@ -81,16 +82,16 @@
Target *target = exe_ctx.GetTargetPtr();
if (exe_ctx.GetFramePtr())
m_parser_vars->m_sym_ctx = exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
- else if (exe_ctx.GetThreadPtr())
+ else if (exe_ctx.GetThreadPtr() && exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
m_parser_vars->m_sym_ctx = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
else if (exe_ctx.GetProcessPtr())
{
- m_parser_vars->m_sym_ctx.Clear();
+ m_parser_vars->m_sym_ctx.Clear(true);
m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
}
else if (target)
{
- m_parser_vars->m_sym_ctx.Clear();
+ m_parser_vars->m_sym_ctx.Clear(true);
m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
}
@@ -119,11 +120,12 @@
ClangExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index));
if (var_sp)
{
- if (var_sp->m_parser_vars.get() &&
- var_sp->m_parser_vars->m_lldb_value)
- delete var_sp->m_parser_vars->m_lldb_value;
+ ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
+
+ if (parser_vars && parser_vars->m_lldb_value)
+ delete parser_vars->m_lldb_value;
- var_sp->DisableParserVars();
+ var_sp->DisableParserVars(GetParserID());
}
}
@@ -133,7 +135,7 @@
{
ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
if (pvar_sp)
- pvar_sp->DisableParserVars();
+ pvar_sp->DisableParserVars(GetParserID());
}
DisableParserVars();
@@ -289,10 +291,10 @@
ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
- ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl));
+ ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl, GetParserID()));
if (!var_sp)
- var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl);
+ var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl, GetParserID());
if (!var_sp)
return ClangExpressionVariableSP();
@@ -501,10 +503,12 @@
if (log)
log->Printf("Created persistent variable with flags 0x%hx", var_sp->m_flags);
- var_sp->EnableParserVars();
+ var_sp->EnableParserVars(GetParserID());
+
+ ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
- var_sp->m_parser_vars->m_named_decl = decl;
- var_sp->m_parser_vars->m_parser_type = parser_type;
+ parser_vars->m_named_decl = decl;
+ parser_vars->m_parser_type = parser_type;
return true;
}
@@ -526,13 +530,13 @@
m_struct_vars->m_struct_laid_out = false;
- if (m_struct_members.GetVariable(decl))
+ if (m_struct_members.GetVariable(decl, GetParserID()))
return true;
- ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl));
+ ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl, GetParserID()));
if (!var_sp)
- var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl);
+ var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl, GetParserID());
if (!var_sp)
return false;
@@ -545,11 +549,17 @@
// We know entity->m_parser_vars is valid because we used a parser variable
// to find it
- var_sp->m_parser_vars->m_llvm_value = value;
- var_sp->EnableJITVars();
- var_sp->m_jit_vars->m_alignment = alignment;
- var_sp->m_jit_vars->m_size = size;
+ ClangExpressionVariable::ParserVars *parser_vars = var_sp->GetParserVars(GetParserID());
+
+ parser_vars->m_llvm_value = value;
+
+ var_sp->EnableJITVars(GetParserID());
+
+ ClangExpressionVariable::JITVars *jit_vars = var_sp->GetJITVars(GetParserID());
+
+ jit_vars->m_alignment = alignment;
+ jit_vars->m_size = size;
m_struct_members.AddVariable(var_sp);
@@ -576,18 +586,20 @@
ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
if (!member_sp)
return false;
+
+ ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
- if (!member_sp->m_jit_vars.get())
+ if (!jit_vars)
return false;
if (member_index == 0)
- m_struct_vars->m_struct_alignment = member_sp->m_jit_vars->m_alignment;
+ m_struct_vars->m_struct_alignment = jit_vars->m_alignment;
- if (cursor % member_sp->m_jit_vars->m_alignment)
- cursor += (member_sp->m_jit_vars->m_alignment - (cursor % member_sp->m_jit_vars->m_alignment));
+ if (cursor % jit_vars->m_alignment)
+ cursor += (jit_vars->m_alignment - (cursor % jit_vars->m_alignment));
- member_sp->m_jit_vars->m_offset = cursor;
- cursor += member_sp->m_jit_vars->m_size;
+ jit_vars->m_offset = cursor;
+ cursor += jit_vars->m_size;
}
m_struct_vars->m_struct_size = cursor;
@@ -635,15 +647,20 @@
ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
- if (!member_sp ||
- !member_sp->m_parser_vars.get() ||
- !member_sp->m_jit_vars.get() ||
+ if (!member_sp)
+ return false;
+
+ ClangExpressionVariable::ParserVars *parser_vars = member_sp->GetParserVars(GetParserID());
+ ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
+
+ if (!parser_vars ||
+ !jit_vars ||
!member_sp->GetValueObject())
return false;
- decl = member_sp->m_parser_vars->m_named_decl;
- value = member_sp->m_parser_vars->m_llvm_value;
- offset = member_sp->m_jit_vars->m_offset;
+ decl = parser_vars->m_named_decl;
+ value = parser_vars->m_llvm_value;
+ offset = jit_vars->m_offset;
name = member_sp->GetName();
return true;
@@ -656,7 +673,7 @@
uint64_t &ptr
)
{
- ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl));
+ ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl, GetParserID()));
if (!entity_sp)
return false;
@@ -664,7 +681,9 @@
// We know m_parser_vars is valid since we searched for the variable by
// its NamedDecl
- ptr = entity_sp->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
+ ClangExpressionVariable::ParserVars *parser_vars = entity_sp->GetParserVars(GetParserID());
+
+ ptr = parser_vars->m_lldb_value->GetScalar().ULongLong();
return true;
}
@@ -677,11 +696,32 @@
SymbolContextList &sc_list
)
{
+ SymbolContextList temp_sc_list;
if (sym_ctx.module_sp)
- sym_ctx.module_sp->FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list);
+ sym_ctx.module_sp->FindSymbolsWithNameAndType(name, eSymbolTypeAny, temp_sc_list);
- if (!sc_list.GetSize())
- sym_ctx.target_sp->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list);
+ if (!sc_list.GetSize() && sym_ctx.target_sp)
+ sym_ctx.target_sp->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, temp_sc_list);
+
+ unsigned temp_sc_list_size = temp_sc_list.GetSize();
+ for (unsigned i = 0; i < temp_sc_list_size; i++)
+ {
+ SymbolContext sym_ctx;
+ temp_sc_list.GetContextAtIndex(i, sym_ctx);
+ if (sym_ctx.symbol)
+ {
+ switch (sym_ctx.symbol->GetType())
+ {
+ case eSymbolTypeCode:
+ case eSymbolTypeResolver:
+ sc_list.Append(sym_ctx);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
}
bool
@@ -705,7 +745,7 @@
SymbolContextList sc_list;
FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list);
-
+
if (!sc_list.GetSize())
{
// We occasionally get debug information in which a const function is reported
@@ -727,29 +767,31 @@
if (!sc_list.GetSize())
return false;
-
+
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(0, sym_ctx);
-
+
const Address *func_so_addr = NULL;
-
+ bool is_indirect_function = false;
+
if (sym_ctx.function)
func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress();
- else if (sym_ctx.symbol)
+ else if (sym_ctx.symbol) {
func_so_addr = &sym_ctx.symbol->GetAddress();
- else
+ is_indirect_function = sym_ctx.symbol->IsIndirect();
+ } else
return false;
-
+
if (!func_so_addr || !func_so_addr->IsValid())
return false;
-
- func_addr = func_so_addr->GetCallableLoadAddress (target);
+
+ func_addr = func_so_addr->GetCallableLoadAddress (target, is_indirect_function);
return true;
}
addr_t
-ClangExpressionDeclMap::GetSymbolAddress (Target &target, const ConstString &name, lldb::SymbolType symbol_type)
+ClangExpressionDeclMap::GetSymbolAddress (Target &target, Process *process, const ConstString &name, lldb::SymbolType symbol_type)
{
SymbolContextList sc_list;
@@ -776,7 +818,11 @@
case eSymbolTypeTrampoline:
symbol_load_addr = sym_address->GetCallableLoadAddress (&target);
break;
-
+
+ case eSymbolTypeResolver:
+ symbol_load_addr = sym_address->GetCallableLoadAddress (&target, true);
+ break;
+
case eSymbolTypeData:
case eSymbolTypeRuntime:
case eSymbolTypeVariable:
@@ -808,6 +854,16 @@
}
}
+ if (symbol_load_addr == LLDB_INVALID_ADDRESS && process)
+ {
+ ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
+
+ if (runtime)
+ {
+ symbol_load_addr = runtime->LookupRuntimeSymbol(name);
+ }
+ }
+
return symbol_load_addr;
}
@@ -819,7 +875,7 @@
if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
return false;
- return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), name, symbol_type);
+ return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), m_parser_vars->m_exe_ctx.GetProcessPtr(), name, symbol_type);
}
// Interface for IRInterpreter
@@ -1000,21 +1056,23 @@
{
assert (m_parser_vars.get());
- ClangExpressionVariableSP expr_var_sp (m_found_entities.GetVariable(decl));
- ClangExpressionVariableSP persistent_var_sp (m_parser_vars->m_persistent_vars->GetVariable(decl));
+ ClangExpressionVariableSP expr_var_sp (m_found_entities.GetVariable(decl, GetParserID()));
+ ClangExpressionVariableSP persistent_var_sp (m_parser_vars->m_persistent_vars->GetVariable(decl, GetParserID()));
if (expr_var_sp)
{
flags = expr_var_sp->m_flags;
- if (!expr_var_sp->m_parser_vars.get())
+ ClangExpressionVariable::ParserVars *parser_vars = expr_var_sp->GetParserVars(GetParserID());
+
+ if (!parser_vars)
return Value();
bool is_reference = expr_var_sp->m_flags & ClangExpressionVariable::EVTypeIsReference;
- if (expr_var_sp->m_parser_vars->m_lldb_var)
+ if (parser_vars->m_lldb_var)
{
- std::auto_ptr<Value> value(GetVariableValue(expr_var_sp->m_parser_vars->m_lldb_var, NULL));
+ std::auto_ptr<Value> value(GetVariableValue(parser_vars->m_lldb_var, NULL));
if (is_reference && value.get() && value->GetValueType() == Value::eValueTypeLoadAddress)
{
@@ -1038,9 +1096,9 @@
else
return Value();
}
- else if (expr_var_sp->m_parser_vars->m_lldb_sym)
+ else if (parser_vars->m_lldb_sym)
{
- const Address sym_address = expr_var_sp->m_parser_vars->m_lldb_sym->GetAddress();
+ const Address sym_address = parser_vars->m_lldb_sym->GetAddress();
if (!sym_address.IsValid())
return Value();
@@ -1406,16 +1464,18 @@
s.Printf("[%s]\n", member_sp->GetName().GetCString());
- if (!member_sp->m_jit_vars.get())
+ ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
+
+ if (!jit_vars)
return false;
extractor.Dump (&s, // stream
- member_sp->m_jit_vars->m_offset, // offset
+ jit_vars->m_offset, // offset
lldb::eFormatBytesWithASCII, // format
1, // byte size of individual entries
- member_sp->m_jit_vars->m_size, // number of entries
+ jit_vars->m_size, // number of entries
16, // entries per line
- m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset, // address to print
+ m_material_vars->m_materialized_location + jit_vars->m_offset, // address to print
0, // bit size (bitfields only; 0 means ignore)
0); // bit alignment (bitfields only; 0 means ignore)
@@ -1488,7 +1548,7 @@
if (mem == LLDB_INVALID_ADDRESS)
{
- err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct",
+ err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct",
(unsigned long long)(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size));
return false;
}
@@ -1507,6 +1567,14 @@
{
ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
+ ClangExpressionVariable::JITVars *jit_vars = member_sp->GetJITVars(GetParserID());
+
+ if (!jit_vars)
+ {
+ err.SetErrorString("Variable being materialized doesn't have JIT state");
+ return false;
+ }
+
if (m_found_entities.ContainsVariable (member_sp))
{
if (!member_sp->GetValueObject())
@@ -1531,22 +1599,16 @@
if (!DoMaterializeOneRegister (dematerialize,
*reg_ctx,
*reg_info,
- m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,
+ m_material_vars->m_materialized_location + jit_vars->m_offset,
err))
return false;
}
else
- {
- if (!member_sp->m_jit_vars.get())
- {
- err.SetErrorString("Variable being materialized doesn't have necessary state");
- return false;
- }
-
+ {
if (!DoMaterializeOneVariable (dematerialize,
sym_ctx,
member_sp,
- m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,
+ m_material_vars->m_materialized_location + jit_vars->m_offset,
err))
return false;
}
@@ -1570,7 +1632,7 @@
if (!DoMaterializeOnePersistentVariable (dematerialize,
member_sp,
- m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,
+ m_material_vars->m_materialized_location + jit_vars->m_offset,
stack_frame_top,
stack_frame_bottom,
err))
@@ -1672,7 +1734,7 @@
mem = var_sp->m_live_sp->GetValue().GetScalar().ULongLong();
if (log)
- log->Printf("Dematerializing %s from 0x%llx (size = %u)", var_sp->GetName().GetCString(), (uint64_t)mem, (unsigned)pvar_byte_size);
+ log->Printf("Dematerializing %s from 0x%" PRIx64 " (size = %u)", var_sp->GetName().GetCString(), (uint64_t)mem, (unsigned)pvar_byte_size);
// Read the contents of the spare memory area
@@ -1747,7 +1809,7 @@
}
if (log)
- log->Printf("Allocated %s (0x%llx) sucessfully", var_sp->GetName().GetCString(), mem);
+ log->Printf("Allocated %s (0x%" PRIx64 ") sucessfully", var_sp->GetName().GetCString(), mem);
// Put the location of the spare memory into the live data of the ValueObject.
@@ -1800,13 +1862,80 @@
return true;
}
-bool
+bool
+ClangExpressionDeclMap::CreateLiveMemoryForExpressionVariable
+(
+ Process &process,
+ ClangExpressionVariableSP &expr_var,
+ Error &err
+)
+{
+ Error allocate_error;
+ TypeFromUser type(expr_var->GetTypeFromUser());
+ const ConstString &name(expr_var->GetName());
+
+ size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
+ size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8);
+
+ Scalar val_addr (process.AllocateMemory (value_byte_size,
+ lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+ allocate_error));
+
+ if (val_addr.ULongLong() == LLDB_INVALID_ADDRESS)
+ {
+ err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s",
+ name.GetCString(),
+ allocate_error.AsCString());
+ return false;
+ }
+
+ // Put the location of the spare memory into the live data of the ValueObject.
+
+ expr_var->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
+ type.GetASTContext(),
+ type.GetOpaqueQualType(),
+ name,
+ val_addr.ULongLong(),
+ eAddressTypeLoad,
+ value_byte_size);
+
+ return true;
+}
+
+bool
+ClangExpressionDeclMap::DeleteLiveMemoryForExpressionVariable
+(
+ Process &process,
+ ClangExpressionVariableSP &expr_var,
+ Error &err
+)
+{
+ const ConstString &name(expr_var->GetName());
+
+ Scalar &val_addr = expr_var->m_live_sp->GetValue().GetScalar();
+
+ Error deallocate_error = process.DeallocateMemory(val_addr.ULongLong());
+
+ if (!deallocate_error.Success())
+ {
+ err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s",
+ name.GetCString(),
+ deallocate_error.AsCString());
+ return false;
+ }
+
+ expr_var->m_live_sp.reset();
+
+ return true;
+}
+
+bool
ClangExpressionDeclMap::DoMaterializeOneVariable
(
bool dematerialize,
const SymbolContext &sym_ctx,
ClangExpressionVariableSP &expr_var,
- lldb::addr_t addr,
+ lldb::addr_t addr,
Error &err
)
{
@@ -1814,8 +1943,10 @@
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+
+ ClangExpressionVariable::ParserVars *var_parser_vars = expr_var->GetParserVars(GetParserID());
- if (!frame || !process || !target || !m_parser_vars.get() || !expr_var->m_parser_vars.get())
+ if (!frame || !process || !target || !m_parser_vars.get() || !var_parser_vars)
{
err.SetErrorString("Necessary state for variable materialization isn't present");
return false;
@@ -1826,8 +1957,8 @@
const ConstString &name(expr_var->GetName());
TypeFromUser type(expr_var->GetTypeFromUser());
- VariableSP &var(expr_var->m_parser_vars->m_lldb_var);
- lldb_private::Symbol *sym(expr_var->m_parser_vars->m_lldb_sym);
+ VariableSP &var(var_parser_vars->m_lldb_var);
+ const lldb_private::Symbol *symbol = var_parser_vars->m_lldb_sym;
bool is_reference(expr_var->m_flags & ClangExpressionVariable::EVTypeIsReference);
@@ -1838,9 +1969,9 @@
location_value.reset(GetVariableValue(var,
NULL));
}
- else if (sym)
+ else if (symbol)
{
- addr_t location_load_addr = GetSymbolAddress(*target, name, lldb::eSymbolTypeAny);
+ addr_t location_load_addr = GetSymbolAddress(*target, process, name, lldb::eSymbolTypeAny);
if (location_load_addr == LLDB_INVALID_ADDRESS)
{
@@ -1902,6 +2033,66 @@
return false;
}
break;
+ case Value::eValueTypeHostAddress:
+ {
+ if (dematerialize)
+ {
+ if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err))
+ return false;
+ }
+ else
+ {
+ DataExtractor value_data_extractor;
+
+ if (location_value->GetData(value_data_extractor))
+ {
+ if (value_byte_size != value_data_extractor.GetByteSize())
+ {
+ err.SetErrorStringWithFormat ("Size mismatch for %s: %" PRIu64 " versus %" PRIu64,
+ name.GetCString(),
+ (uint64_t)value_data_extractor.GetByteSize(),
+ (uint64_t)value_byte_size);
+ return false;
+ }
+
+ if (!CreateLiveMemoryForExpressionVariable(*process, expr_var, err))
+ return false;
+
+ Scalar &buf_addr = expr_var->m_live_sp->GetValue().GetScalar();
+
+ Error write_error;
+
+ if (!process->WriteMemory(buf_addr.ULongLong(),
+ value_data_extractor.GetDataStart(),
+ value_data_extractor.GetByteSize(),
+ write_error))
+ {
+ err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s",
+ name.GetCString(),
+ write_error.AsCString());
+ return false;
+ }
+
+ if (!process->WriteScalarToMemory(addr,
+ buf_addr,
+ process->GetAddressByteSize(),
+ write_error))
+ {
+ err.SetErrorStringWithFormat ("Couldn't write the address of %s to the target: %s",
+ name.GetCString(),
+ write_error.AsCString());
+ return false;
+ }
+ }
+ else
+ {
+ err.SetErrorStringWithFormat ("%s is marked as a host address but doesn't contain any data",
+ name.GetCString());
+ return false;
+ }
+ }
+ }
+ break;
case Value::eValueTypeLoadAddress:
{
if (!dematerialize)
@@ -2020,19 +2211,8 @@
return false;
}
- // Deallocate the spare area and clear the variable's live data.
-
- Error deallocate_error = process->DeallocateMemory(reg_addr.ULongLong());
-
- if (!deallocate_error.Success())
- {
- err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s",
- name.GetCString(),
- deallocate_error.AsCString());
+ if (!DeleteLiveMemoryForExpressionVariable(*process, expr_var, err))
return false;
- }
-
- expr_var->m_live_sp.reset();
}
else
{
@@ -2066,36 +2246,17 @@
return true;
}
-
+
// Allocate a spare memory area to place the register's contents into. This memory area will be pointed to by the slot in the
// struct.
- Error allocate_error;
-
- Scalar reg_addr (process->AllocateMemory (value_byte_size,
- lldb::ePermissionsReadable | lldb::ePermissionsWritable,
- allocate_error));
-
- if (reg_addr.ULongLong() == LLDB_INVALID_ADDRESS)
- {
- err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s",
- name.GetCString(),
- allocate_error.AsCString());
+ if (!CreateLiveMemoryForExpressionVariable (*process, expr_var, err))
return false;
- }
- // Put the location of the spare memory into the live data of the ValueObject.
+ // Now write the location of the area into the struct.
- expr_var->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
- type.GetASTContext(),
- type.GetOpaqueQualType(),
- name,
- reg_addr.ULongLong(),
- eAddressTypeLoad,
- value_byte_size);
+ Scalar &reg_addr = expr_var->m_live_sp->GetValue().GetScalar();
- // Now write the location of the area into the struct.
-
if (!process->WriteScalarToMemory (addr,
reg_addr,
process->GetAddressByteSize(),
@@ -2198,9 +2359,13 @@
VariableSP var_sp;
Error err;
- valobj = frame.GetValueForVariableExpressionPath(name.GetCString(),
+ valobj = frame.GetValueForVariableExpressionPath(name.GetCString(),
eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember ||
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
+ StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
+ StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
+ StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var_sp,
err);
@@ -2270,25 +2435,70 @@
return lldb::VariableSP();
}
-Symbol *
-ClangExpressionDeclMap::FindGlobalDataSymbol
-(
- Target &target,
- const ConstString &name
-)
+const Symbol *
+ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
+ const ConstString &name)
{
SymbolContextList sc_list;
- target.GetImages().FindSymbolsWithNameAndType(name,
- eSymbolTypeData,
- sc_list);
+ target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list);
- if (sc_list.GetSize())
+ const uint32_t matches = sc_list.GetSize();
+ for (uint32_t i=0; i<matches; ++i)
{
SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(0, sym_ctx);
-
- return sym_ctx.symbol;
+ sc_list.GetContextAtIndex(i, sym_ctx);
+ if (sym_ctx.symbol)
+ {
+ const Symbol *symbol = sym_ctx.symbol;
+ const Address *sym_address = &symbol->GetAddress();
+
+ if (sym_address && sym_address->IsValid())
+ {
+ switch (symbol->GetType())
+ {
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ if (symbol->GetDemangledNameIsSynthesized())
+ {
+ // If the demangled name was synthesized, then don't use it
+ // for expressions. Only let the symbol match if the mangled
+ // named matches for these symbols.
+ if (symbol->GetMangled().GetMangledName() != name)
+ break;
+ }
+ return symbol;
+
+ case eSymbolTypeCode: // We already lookup functions elsewhere
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeTrampoline:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeResolver:
+ break;
+ }
+ }
+ }
}
return NULL;
@@ -2472,7 +2682,6 @@
if (method_decl)
{
-
clang::CXXRecordDecl *class_decl = method_decl->getParent();
QualType class_qual_type(class_decl->getTypeForDecl(), 0);
@@ -2486,7 +2695,28 @@
log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
}
- AddOneType(context, class_user_type, current_id, true);
+ TypeFromParser class_type = CopyClassType(class_user_type, current_id);
+
+ if (!class_type.IsValid())
+ return;
+
+ TypeSourceInfo *type_source_info = m_ast_context->CreateTypeSourceInfo(QualType::getFromOpaquePtr(class_type.GetOpaqueQualType()));
+
+ if (!type_source_info)
+ return;
+
+ TypedefDecl *typedef_decl = TypedefDecl::Create(*m_ast_context,
+ m_ast_context->getTranslationUnitDecl(),
+ SourceLocation(),
+ SourceLocation(),
+ context.m_decl_name.getAsIdentifierInfo(),
+ type_source_info);
+
+
+ if (!typedef_decl)
+ return;
+
+ context.AddNamedDecl(typedef_decl);
if (method_decl->isInstance())
{
@@ -2537,7 +2767,7 @@
TypeFromUser class_user_type (class_type.getAsOpaquePtr(),
this_type->GetClangAST());
- AddOneType(context, class_user_type, current_id, false);
+ AddOneType(context, class_user_type, current_id);
TypeFromUser this_user_type(this_type->GetClangFullType(),
@@ -2580,7 +2810,6 @@
if (method_decl)
{
-
ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
if (!self_interface)
@@ -2597,7 +2826,7 @@
log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
}
- AddOneType(context, class_user_type, current_id, false);
+ AddOneType(context, class_user_type, current_id);
if (method_decl->isInstanceMethod())
{
@@ -2644,10 +2873,15 @@
return;
QualType self_qual_type = QualType::getFromOpaquePtr(self_type->GetClangFullType());
- const ObjCObjectPointerType *class_pointer_type = self_qual_type->getAs<ObjCObjectPointerType>();
- if (class_pointer_type)
+ if (self_qual_type->isObjCClassType())
+ {
+ return;
+ }
+ else if (self_qual_type->isObjCObjectPointerType())
{
+ const ObjCObjectPointerType *class_pointer_type = self_qual_type->getAs<ObjCObjectPointerType>();
+
QualType class_type = class_pointer_type->getPointeeType();
if (log)
@@ -2657,9 +2891,9 @@
}
TypeFromUser class_user_type (class_type.getAsOpaquePtr(),
- self_type->GetClangAST());
- AddOneType(context, class_user_type, current_id, false);
-
+ self_type->GetClangAST());
+
+ AddOneType(context, class_user_type, current_id);
TypeFromUser self_user_type(self_type->GetClangFullType(),
self_type->GetClangAST());
@@ -2746,8 +2980,11 @@
{
valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr,
eNoDynamicValues,
- StackFrame::eExpressionPathOptionCheckPtrVsMember
- | StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
+ StackFrame::eExpressionPathOptionCheckPtrVsMember ||
+ StackFrame::eExpressionPathOptionsAllowDirectIVarAccess ||
+ StackFrame::eExpressionPathOptionsNoFragileObjcIvar ||
+ StackFrame::eExpressionPathOptionsNoSyntheticChildren ||
+ StackFrame::eExpressionPathOptionsNoSyntheticArrayRange,
var,
err);
@@ -2867,7 +3104,7 @@
// We couldn't find a non-symbol variable for this. Now we'll hunt for a generic
// data symbol, and -- if it is found -- treat it as a variable.
- Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
+ const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
if (data_symbol)
{
@@ -2974,7 +3211,23 @@
}
Error err;
- if (!var_location_expr.Evaluate(&m_parser_vars->m_exe_ctx, ast, NULL, NULL, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err))
+ if (var->GetLocationIsConstantValueData())
+ {
+ DataExtractor const_value_extractor;
+
+ if (var_location_expr.GetExpressionData(const_value_extractor))
+ {
+ var_location->operator=(Value(const_value_extractor.GetDataStart(), const_value_extractor.GetByteSize()));
+ var_location->SetValueType(Value::eValueTypeHostAddress);
+ }
+ else
+ {
+ if (log)
+ log->Printf("Error evaluating constant variable: %s", err.AsCString());
+ return NULL;
+ }
+ }
+ else if (!var_location_expr.Evaluate(&m_parser_vars->m_exe_ctx, ast, NULL, NULL, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err))
{
if (log)
log->Printf("Error evaluating location: %s", err.AsCString());
@@ -3077,12 +3330,13 @@
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (valobj));
assert (entity.get());
- entity->EnableParserVars();
- entity->m_parser_vars->m_parser_type = pt;
- entity->m_parser_vars->m_named_decl = var_decl;
- entity->m_parser_vars->m_llvm_value = NULL;
- entity->m_parser_vars->m_lldb_value = var_location;
- entity->m_parser_vars->m_lldb_var = var;
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = pt;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value = var_location;
+ parser_vars->m_lldb_var = var;
if (is_reference)
entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
@@ -3118,11 +3372,12 @@
NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType()));
- pvar_sp->EnableParserVars();
- pvar_sp->m_parser_vars->m_parser_type = parser_type;
- pvar_sp->m_parser_vars->m_named_decl = var_decl;
- pvar_sp->m_parser_vars->m_llvm_value = NULL;
- pvar_sp->m_parser_vars->m_lldb_value = NULL;
+ pvar_sp->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars = pvar_sp->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = parser_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value = NULL;
if (log)
{
@@ -3133,7 +3388,7 @@
void
ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
- Symbol &symbol,
+ const Symbol &symbol,
unsigned int current_id)
{
assert(m_parser_vars.get());
@@ -3147,10 +3402,10 @@
ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
- TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, true)),
+ TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, false)),
scratch_ast_context);
- TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(m_ast_context, true)),
+ TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(m_ast_context, ClangASTContext::GetVoidPtrType(m_ast_context, false)),
m_ast_context);
NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
@@ -3166,19 +3421,20 @@
std::auto_ptr<Value> symbol_location(new Value);
- Address &symbol_address = symbol.GetAddress();
+ const Address &symbol_address = symbol.GetAddress();
lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
symbol_location->GetScalar() = symbol_load_addr;
symbol_location->SetValueType(Value::eValueTypeLoadAddress);
- entity->EnableParserVars();
- entity->m_parser_vars->m_parser_type = parser_type;
- entity->m_parser_vars->m_named_decl = var_decl;
- entity->m_parser_vars->m_llvm_value = NULL;
- entity->m_parser_vars->m_lldb_value = symbol_location.release();
- entity->m_parser_vars->m_lldb_sym = &symbol;
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = parser_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value = symbol_location.release();
+ parser_vars->m_lldb_sym = &symbol;
if (log)
{
@@ -3202,9 +3458,11 @@
{
ClangExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
+ ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+
if (entity->m_flags & ClangExpressionVariable::EVUnknownType)
{
- const NamedDecl *named_decl = entity->m_parser_vars->m_named_decl;
+ const NamedDecl *named_decl = parser_vars->m_named_decl;
const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
if (!var_decl)
@@ -3235,8 +3493,8 @@
TypeFromUser user_type(copied_type, scratch_ast_context);
- entity->m_parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
- entity->m_parser_vars->m_parser_type = parser_type;
+ parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
+ parser_vars->m_parser_type = parser_type;
entity->SetClangAST(user_type.GetASTContext());
entity->SetClangType(user_type.GetOpaqueQualType());
@@ -3278,11 +3536,12 @@
std::string decl_name(context.m_decl_name.getAsString());
entity->SetName (ConstString (decl_name.c_str()));
entity->SetRegisterInfo (reg_info);
- entity->EnableParserVars();
- entity->m_parser_vars->m_parser_type = parser_type;
- entity->m_parser_vars->m_named_decl = var_decl;
- entity->m_parser_vars->m_llvm_value = NULL;
- entity->m_parser_vars->m_lldb_value = NULL;
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ parser_vars->m_parser_type = parser_type;
+ parser_vars->m_named_decl = var_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value = NULL;
entity->m_flags |= ClangExpressionVariable::EVBareRegister;
if (log)
@@ -3309,7 +3568,9 @@
// only valid for Functions, not for Symbols
void *fun_opaque_type = NULL;
ASTContext *fun_ast_context = NULL;
-
+
+ bool is_indirect_function = false;
+
if (fun)
{
Type *fun_type = fun->GetType();
@@ -3343,7 +3604,7 @@
// We failed to copy the type we found
if (log)
{
- log->Printf (" Failed to import the function type '%s' {0x%8.8llx} into the expression parser AST contenxt",
+ log->Printf (" Failed to import the function type '%s' {0x%8.8" PRIx64 "} into the expression parser AST contenxt",
fun_type->GetName().GetCString(),
fun_type->GetID());
}
@@ -3355,6 +3616,7 @@
{
fun_address = &symbol->GetAddress();
fun_decl = context.AddGenericFunDecl();
+ is_indirect_function = symbol->IsIndirect();
}
else
{
@@ -3365,7 +3627,7 @@
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target);
+ lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function);
fun_location->SetValueType(Value::eValueTypeLoadAddress);
fun_location->GetScalar() = load_addr;
@@ -3378,10 +3640,11 @@
entity->SetClangType (fun_opaque_type);
entity->SetClangAST (fun_ast_context);
- entity->EnableParserVars();
- entity->m_parser_vars->m_named_decl = fun_decl;
- entity->m_parser_vars->m_llvm_value = NULL;
- entity->m_parser_vars->m_lldb_value = fun_location.release();
+ entity->EnableParserVars(GetParserID());
+ ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
+ parser_vars->m_named_decl = fun_decl;
+ parser_vars->m_llvm_value = NULL;
+ parser_vars->m_lldb_value = fun_location.release();
if (log)
{
@@ -3400,28 +3663,26 @@
}
}
-void
-ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
- TypeFromUser &ut,
- unsigned int current_id,
- bool add_method)
+TypeFromParser
+ClangExpressionDeclMap::CopyClassType(TypeFromUser &ut,
+ unsigned int current_id)
{
ASTContext *parser_ast_context = m_ast_context;
ASTContext *user_ast_context = ut.GetASTContext();
-
+
void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
if (!copied_type)
{
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
+
if (log)
- log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+ log->Printf("ClangExpressionDeclMap::CopyClassType - Couldn't import the type");
- return;
+ return TypeFromParser();
}
-
- if (add_method && ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type))
+
+ if (ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type))
{
void *args[1];
@@ -3454,5 +3715,28 @@
is_artificial);
}
+ return TypeFromParser(copied_type, parser_ast_context);
+}
+
+void
+ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
+ TypeFromUser &ut,
+ unsigned int current_id)
+{
+ ASTContext *parser_ast_context = m_ast_context;
+ ASTContext *user_ast_context = ut.GetASTContext();
+
+ void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
+
+ if (!copied_type)
+ {
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
+
+ return;
+ }
+
context.AddTypeDecl(copied_type);
}
Index: aze/lldb/source/Expression/ClangExpressionParser.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ClangExpressionParser.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ClangExpressionParser.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Expression/ClangExpressionParser.h"
#include "lldb/Core/ArchSpec.h"
@@ -61,8 +63,8 @@
#else
#include "llvm/ExecutionEngine/MCJIT.h"
#endif
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/DynamicLibrary.h"
@@ -238,14 +240,21 @@
m_compiler->getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();
}
+ if (target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86 ||
+ target_sp->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
+ {
+ m_compiler->getTargetOpts().Features.push_back("+sse");
+ m_compiler->getTargetOpts().Features.push_back("+sse2");
+ }
+
if (m_compiler->getTargetOpts().Triple.find("ios") != std::string::npos)
m_compiler->getTargetOpts().ABI = "apcs-gnu";
- m_compiler->createDiagnostics(0, 0);
+ m_compiler->createDiagnostics();
// Create the target instance.
m_compiler->setTarget(TargetInfo::CreateTargetInfo(m_compiler->getDiagnostics(),
- m_compiler->getTargetOpts()));
+ &m_compiler->getTargetOpts()));
assert (m_compiler->hasTarget());
@@ -263,14 +272,14 @@
break;
case lldb::eLanguageTypeC_plus_plus:
m_compiler->getLangOpts().CPlusPlus = true;
- m_compiler->getLangOpts().CPlusPlus0x = true;
+ m_compiler->getLangOpts().CPlusPlus11 = true;
break;
case lldb::eLanguageTypeObjC_plus_plus:
default:
m_compiler->getLangOpts().ObjC1 = true;
m_compiler->getLangOpts().ObjC2 = true;
m_compiler->getLangOpts().CPlusPlus = true;
- m_compiler->getLangOpts().CPlusPlus0x = true;
+ m_compiler->getLangOpts().CPlusPlus11 = true;
break;
}
@@ -366,6 +375,7 @@
m_code_generator.reset(CreateLLVMCodeGen(m_compiler->getDiagnostics(),
module_name,
m_compiler->getCodeGenOpts(),
+ m_compiler->getTargetOpts(),
*m_llvm_context));
}
@@ -598,20 +608,36 @@
}
llvm::Triple triple(module_ap->getTargetTriple());
llvm::Function *function = module_ap->getFunction (function_name.c_str());
+ llvm::Reloc::Model relocModel;
+ llvm::CodeModel::Model codeModel;
+ if (triple.isOSBinFormatELF())
+ {
+ relocModel = llvm::Reloc::Static;
+ // This will be small for 32-bit and large for 64-bit.
+ codeModel = llvm::CodeModel::JITDefault;
+ }
+ else
+ {
+ relocModel = llvm::Reloc::PIC_;
+ codeModel = llvm::CodeModel::Small;
+ }
EngineBuilder builder(module_ap.release());
builder.setEngineKind(EngineKind::JIT)
.setErrorStr(&error_string)
- .setRelocationModel(llvm::Reloc::PIC_)
+ .setRelocationModel(relocModel)
.setJITMemoryManager(jit_memory_manager)
.setOptLevel(CodeGenOpt::Less)
.setAllocateGVsWithCode(true)
- .setCodeModel(CodeModel::Small)
+ .setCodeModel(codeModel)
.setUseMCJIT(true);
StringRef mArch;
StringRef mCPU;
SmallVector<std::string, 0> mAttrs;
+ for (std::string &feature : m_compiler->getTargetOpts().Features)
+ mAttrs.push_back(feature);
+
TargetMachine *target_machine = builder.selectTarget(triple,
mArch,
mCPU,
@@ -733,7 +759,7 @@
}
if (log)
- log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
+ log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
std::pair <lldb::addr_t, lldb::addr_t> func_range;
@@ -747,7 +773,7 @@
}
if (log)
- log->Printf("Function's code range is [0x%llx+0x%llx]", func_range.first, func_range.second);
+ log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
Target *target = exe_ctx.GetTargetPtr();
if (!target)
@@ -772,7 +798,9 @@
ArchSpec arch(target->GetArchitecture());
- lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, NULL);
+ const char *plugin_name = NULL;
+ const char *flavor_string = NULL;
+ lldb::DisassemblerSP disassembler = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
if (!disassembler)
{
@@ -807,7 +835,7 @@
InstructionList &instruction_list = disassembler->GetInstructionList();
const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
- for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize();
+ for (size_t instruction_index = 0, num_instructions = instruction_list.GetSize();
instruction_index < num_instructions;
++instruction_index)
{
Index: aze/lldb/source/Expression/ClangFunction.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ClangFunction.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ClangFunction.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -19,7 +19,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Module.h"
// Project includes
#include "lldb/Expression/ASTStructExtractor.h"
@@ -136,7 +136,7 @@
// to pull the defined arguments out of the function, then add the types from the
// arguments list for the variable arguments.
- uint32_t num_args = UINT32_MAX;
+ size_t num_args = UINT32_MAX;
bool trust_function = false;
// GetArgumentCount returns -1 for an unprototyped function.
if (m_function_ptr)
@@ -186,7 +186,7 @@
char arg_buf[32];
args_buffer.append (" ");
args_buffer.append (type_name);
- snprintf(arg_buf, 31, "arg_%llu", (uint64_t)i);
+ snprintf(arg_buf, 31, "arg_%" PRIu64, (uint64_t)i);
args_buffer.push_back (' ');
args_buffer.append (arg_buf);
args_buffer.append (";\n");
@@ -277,6 +277,8 @@
return false;
if (process && m_jit_alloc != LLDB_INVALID_ADDRESS)
m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
+
+ m_JITted = true;
return true;
}
@@ -336,7 +338,7 @@
// TODO: verify fun_addr needs to be a callable address
Scalar fun_addr (function_address.GetCallableLoadAddress(exe_ctx.GetTargetPtr()));
- int first_offset = m_member_offsets[0];
+ uint64_t first_offset = m_member_offsets[0];
process->WriteScalarToMemory(args_addr_ref + first_offset, fun_addr, process->GetAddressByteSize(), error);
// FIXME: We will need to extend this for Variadic functions.
@@ -354,7 +356,7 @@
{
// FIXME: We should sanity check sizes.
- int offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
+ uint64_t offset = m_member_offsets[i+1]; // Clang sizes are in bytes.
Value *arg_value = arg_values.GetValueAtIndex(i);
// FIXME: For now just do scalars:
@@ -389,7 +391,7 @@
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
- log->Printf ("Call Address: 0x%llx Struct Address: 0x%llx.\n", m_jit_start_addr, args_addr_ref);
+ log->Printf ("Call Address: 0x%" PRIx64 " Struct Address: 0x%" PRIx64 ".\n", m_jit_start_addr, args_addr_ref);
return true;
}
@@ -400,7 +402,8 @@
lldb::addr_t &args_addr,
Stream &errors,
bool stop_others,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
lldb::addr_t *this_arg,
lldb::addr_t *cmd_arg)
{
@@ -420,7 +423,8 @@
ClangASTType(),
args_addr,
stop_others,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
this_arg,
cmd_arg);
new_plan->SetIsMasterPlan(true);
@@ -477,8 +481,10 @@
ClangFunction::ExecuteFunction(ExecutionContext &exe_ctx, Stream &errors, bool stop_others, Value &results)
{
const bool try_all_threads = false;
- const bool discard_on_error = true;
- return ExecuteFunction (exe_ctx, NULL, errors, stop_others, 0UL, try_all_threads, discard_on_error, results);
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
+ return ExecuteFunction (exe_ctx, NULL, errors, stop_others, 0UL, try_all_threads,
+ unwind_on_error, ignore_breakpoints, results);
}
ExecutionResults
@@ -490,9 +496,10 @@
Value &results)
{
const bool stop_others = true;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
return ExecuteFunction (exe_ctx, NULL, errors, stop_others, timeout_usec,
- try_all_threads, discard_on_error, results);
+ try_all_threads, unwind_on_error, ignore_breakpoints, results);
}
// This is the static function
@@ -503,7 +510,8 @@
lldb::addr_t &void_arg,
bool stop_others,
bool try_all_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
uint32_t timeout_usec,
Stream &errors,
lldb::addr_t *this_arg)
@@ -513,13 +521,12 @@
void_arg,
errors,
stop_others,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
this_arg));
if (!call_plan_sp)
return eExecutionSetupError;
-
- call_plan_sp->SetPrivate(true);
-
+
// <rdar://problem/12027563> we need to make sure we record the fact that we are running an expression here
// otherwise this fact will fail to be recorded when fetching an Objective-C object description
if (exe_ctx.GetProcessPtr())
@@ -528,7 +535,8 @@
ExecutionResults results = exe_ctx.GetProcessRef().RunThreadPlan (exe_ctx, call_plan_sp,
stop_others,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
errors);
@@ -546,7 +554,8 @@
bool stop_others,
uint32_t timeout_usec,
bool try_all_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
Value &results)
{
using namespace clang;
@@ -573,7 +582,8 @@
args_addr,
stop_others,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
errors);
Index: aze/lldb/source/Expression/ClangUserExpression.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ClangUserExpression.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ClangUserExpression.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -58,7 +58,7 @@
m_language (language),
m_transformed_text (),
m_desired_type (desired_type),
- m_enforce_valid_object (false),
+ m_enforce_valid_object (true),
m_cplusplus (false),
m_objectivec (false),
m_static_method(false),
@@ -106,31 +106,56 @@
void
ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
{
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf("ClangUserExpression::ScanContext()");
+
m_target = exe_ctx.GetTargetPtr();
if (!(m_allow_cxx || m_allow_objc))
+ {
+ if (log)
+ log->Printf(" [CUE::SC] Settings inhibit C++ and Objective-C");
return;
+ }
StackFrame *frame = exe_ctx.GetFramePtr();
if (frame == NULL)
+ {
+ if (log)
+ log->Printf(" [CUE::SC] Null stack frame");
return;
+ }
SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
if (!sym_ctx.function)
+ {
+ if (log)
+ log->Printf(" [CUE::SC] Null function");
return;
+ }
// Find the block that defines the function represented by "sym_ctx"
Block *function_block = sym_ctx.GetFunctionBlock();
if (!function_block)
+ {
+ if (log)
+ log->Printf(" [CUE::SC] Null function block");
return;
+ }
clang::DeclContext *decl_context = function_block->GetClangDeclContext();
if (!decl_context)
+ {
+ if (log)
+ log->Printf(" [CUE::SC] Null decl context");
return;
-
+ }
+
if (clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context))
{
if (m_allow_cxx && method_decl->isInstance())
@@ -209,13 +234,94 @@
lldb::LanguageType language = metadata->GetObjectPtrLanguage();
if (language == lldb::eLanguageTypeC_plus_plus)
{
+ if (m_enforce_valid_object)
+ {
+ lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
+
+ const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
+
+ if (!variable_list_sp)
+ {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+
+ lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
+
+ if (!this_var_sp ||
+ !this_var_sp->IsInScope(frame) ||
+ !this_var_sp->LocationIsValidForFrame (frame))
+ {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+ }
+
m_cplusplus = true;
m_needs_object_ptr = true;
}
else if (language == lldb::eLanguageTypeObjC)
{
- m_objectivec = true;
- m_needs_object_ptr = true;
+ if (m_enforce_valid_object)
+ {
+ lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
+
+ const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
+
+ if (!variable_list_sp)
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
+
+ if (!self_variable_sp ||
+ !self_variable_sp->IsInScope(frame) ||
+ !self_variable_sp->LocationIsValidForFrame (frame))
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ Type *self_type = self_variable_sp->GetType();
+
+ if (!self_type)
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ lldb::clang_type_t self_opaque_type = self_type->GetClangForwardType();
+
+ if (!self_opaque_type)
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ clang::QualType self_qual_type = clang::QualType::getFromOpaquePtr(self_opaque_type);
+
+ if (self_qual_type->isObjCClassType())
+ {
+ return;
+ }
+ else if (self_qual_type->isObjCObjectPointerType())
+ {
+ m_objectivec = true;
+ m_needs_object_ptr = true;
+ }
+ else
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+ }
+ else
+ {
+ m_objectivec = true;
+ m_needs_object_ptr = true;
+ }
}
}
}
@@ -463,19 +569,19 @@
#if 0
// jingham: look here
StreamFile logfile ("/tmp/exprs.txt", "a");
- logfile.Printf("0x%16.16llx: thread = 0x%4.4x, expr = '%s'\n", m_jit_start_addr, exe_ctx.thread ? exe_ctx.thread->GetID() : -1, m_expr_text.c_str());
+ logfile.Printf("0x%16.16" PRIx64 ": thread = 0x%4.4x, expr = '%s'\n", m_jit_start_addr, exe_ctx.thread ? exe_ctx.thread->GetID() : -1, m_expr_text.c_str());
#endif
if (log)
{
log->Printf("-- [ClangUserExpression::PrepareToExecuteJITExpression] Materializing for execution --");
- log->Printf(" Function address : 0x%llx", (uint64_t)m_jit_start_addr);
+ log->Printf(" Function address : 0x%" PRIx64, (uint64_t)m_jit_start_addr);
if (m_needs_object_ptr)
- log->Printf(" Object pointer : 0x%llx", (uint64_t)object_ptr);
+ log->Printf(" Object pointer : 0x%" PRIx64, (uint64_t)object_ptr);
- log->Printf(" Structure address : 0x%llx", (uint64_t)struct_address);
+ log->Printf(" Structure address : 0x%" PRIx64, (uint64_t)struct_address);
StreamString args;
@@ -512,12 +618,16 @@
// ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
// forcing unwind_on_error to be true here, in practical terms that can't happen.
+ const bool stop_others = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = false;
return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
m_jit_start_addr,
struct_address,
error_stream,
- true,
- true,
+ stop_others,
+ unwind_on_error,
+ ignore_breakpoints,
(m_needs_object_ptr ? &object_ptr : NULL),
(m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
}
@@ -568,7 +678,8 @@
ExecutionResults
ClangUserExpression::Execute (Stream &error_stream,
ExecutionContext &exe_ctx,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
lldb::ClangExpressionVariableSP &result,
bool run_others,
@@ -592,14 +703,15 @@
}
const bool stop_others = true;
- const bool try_all_threads = true;
+ const bool try_all_threads = run_others;
Address wrapper_address (m_jit_start_addr);
lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
wrapper_address,
struct_address,
stop_others,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
(m_needs_object_ptr ? &object_ptr : NULL),
((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
shared_ptr_to_me));
@@ -608,9 +720,7 @@
return eExecutionSetupError;
lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
-
- call_plan_sp->SetPrivate(true);
-
+
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression begins --");
@@ -621,7 +731,8 @@
call_plan_sp,
stop_others,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
error_stream);
@@ -631,7 +742,7 @@
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
- if (execution_result == eExecutionInterrupted)
+ if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
{
const char *error_desc = NULL;
@@ -646,10 +757,11 @@
else
error_stream.Printf ("Execution was interrupted.");
- if (discard_on_error)
- error_stream.Printf ("\nThe process has been returned to the state before execution.");
+ if ((execution_result == eExecutionInterrupted && unwind_on_error)
+ || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
+ error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
else
- error_stream.Printf ("\nThe process has been left at the point where it was interrupted.");
+ error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
return execution_result;
}
@@ -679,7 +791,8 @@
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
ResultType desired_type,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp,
@@ -691,7 +804,8 @@
execution_policy,
language,
desired_type,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
expr_cstr,
expr_prefix,
result_valobj_sp,
@@ -705,7 +819,8 @@
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
ResultType desired_type,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp,
@@ -784,7 +899,8 @@
execution_results = user_expression_sp->Execute (error_stream,
exe_ctx,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
user_expression_sp,
expr_result,
run_others,
Index: aze/lldb/source/Expression/ClangUtilityFunction.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ClangUtilityFunction.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ClangUtilityFunction.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -22,6 +22,7 @@
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/ClangExpressionParser.h"
#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
@@ -40,9 +41,11 @@
ClangUtilityFunction::ClangUtilityFunction (const char *text,
const char *name) :
ClangExpression (),
- m_function_text (text),
+ m_function_text (ExpressionSourceCode::g_expression_prefix),
m_function_name (name)
{
+ if (text && text[0])
+ m_function_text.append (text);
}
ClangUtilityFunction::~ClangUtilityFunction ()
@@ -153,7 +156,7 @@
#if 0
// jingham: look here
StreamFile logfile ("/tmp/exprs.txt", "a");
- logfile.Printf ("0x%16.16llx: func = %s, source =\n%s\n",
+ logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n",
m_jit_start_addr,
m_function_name.c_str(),
m_function_text.c_str());
Index: aze/lldb/source/Expression/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Expression/CMakeLists.txt 2013-03-03 09:35:50.183457353 +0100
@@ -0,0 +1,22 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbExpression
+ ASTDumper.cpp
+ ASTResultSynthesizer.cpp
+ ASTStructExtractor.cpp
+ ClangASTSource.cpp
+ ClangExpressionDeclMap.cpp
+ ClangExpressionParser.cpp
+ ClangExpressionVariable.cpp
+ ClangFunction.cpp
+ ClangPersistentVariables.cpp
+ ClangUserExpression.cpp
+ ClangUtilityFunction.cpp
+ DWARFExpression.cpp
+ ExpressionSourceCode.cpp
+ IRDynamicChecks.cpp
+ IRForTarget.cpp
+ IRInterpreter.cpp
+ ProcessDataAllocator.cpp
+ RecordingMemoryManager.cpp
+ )
Index: aze/lldb/source/Expression/DWARFExpression.cpp
===================================================================
--- aze.orig/lldb/source/Expression/DWARFExpression.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/DWARFExpression.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -233,7 +233,7 @@
}
-DWARFExpression::DWARFExpression(const DataExtractor& data, uint32_t data_offset, uint32_t data_length) :
+DWARFExpression::DWARFExpression(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) :
m_data(data, data_offset, data_length),
m_reg_kind (eRegisterKindDWARF),
m_loclist_slide(LLDB_INVALID_ADDRESS)
@@ -261,7 +261,7 @@
}
void
-DWARFExpression::CopyOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
+DWARFExpression::CopyOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
{
const uint8_t *bytes = data.PeekData(data_offset, data_length);
if (bytes)
@@ -273,21 +273,21 @@
}
void
-DWARFExpression::SetOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
+DWARFExpression::SetOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
{
m_data.SetData(data, data_offset, data_length);
}
void
-DWARFExpression::DumpLocation (Stream *s, uint32_t offset, uint32_t length, lldb::DescriptionLevel level, ABI *abi) const
+DWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t length, lldb::DescriptionLevel level, ABI *abi) const
{
if (!m_data.ValidOffsetForDataOfSize(offset, length))
return;
- const uint32_t start_offset = offset;
- const uint32_t end_offset = offset + length;
+ const lldb::offset_t start_offset = offset;
+ const lldb::offset_t end_offset = offset + length;
while (m_data.ValidOffset(offset) && offset < end_offset)
{
- const uint32_t op_offset = offset;
+ const lldb::offset_t op_offset = offset;
const uint8_t op = m_data.GetU8(&offset);
switch (level)
@@ -308,7 +308,7 @@
if (level == lldb::eDescriptionLevelFull)
break;
// Fall through for verbose and print offset and DW_OP prefix..
- s->Printf("0x%8.8x: %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
+ s->Printf("0x%8.8" PRIx64 ": %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
break;
}
@@ -322,10 +322,10 @@
case DW_OP_const2s: s->Printf("DW_OP_const2s(0x%4.4x) ", m_data.GetU16(&offset)); break; // 0x0b 1 2-byte constant
case DW_OP_const4u: s->Printf("DW_OP_const4u(0x%8.8x) ", m_data.GetU32(&offset)); break; // 0x0c 1 4-byte constant
case DW_OP_const4s: s->Printf("DW_OP_const4s(0x%8.8x) ", m_data.GetU32(&offset)); break; // 0x0d 1 4-byte constant
- case DW_OP_const8u: s->Printf("DW_OP_const8u(0x%16.16llx) ", m_data.GetU64(&offset)); break; // 0x0e 1 8-byte constant
- case DW_OP_const8s: s->Printf("DW_OP_const8s(0x%16.16llx) ", m_data.GetU64(&offset)); break; // 0x0f 1 8-byte constant
- case DW_OP_constu: s->Printf("DW_OP_constu(0x%llx) ", m_data.GetULEB128(&offset)); break; // 0x10 1 ULEB128 constant
- case DW_OP_consts: s->Printf("DW_OP_consts(0x%lld) ", m_data.GetSLEB128(&offset)); break; // 0x11 1 SLEB128 constant
+ case DW_OP_const8u: s->Printf("DW_OP_const8u(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset)); break; // 0x0e 1 8-byte constant
+ case DW_OP_const8s: s->Printf("DW_OP_const8s(0x%16.16" PRIx64 ") ", m_data.GetU64(&offset)); break; // 0x0f 1 8-byte constant
+ case DW_OP_constu: s->Printf("DW_OP_constu(0x%" PRIx64 ") ", m_data.GetULEB128(&offset)); break; // 0x10 1 ULEB128 constant
+ case DW_OP_consts: s->Printf("DW_OP_consts(0x%" PRId64 ") ", m_data.GetSLEB128(&offset)); break; // 0x11 1 SLEB128 constant
case DW_OP_dup: s->PutCString("DW_OP_dup"); break; // 0x12
case DW_OP_drop: s->PutCString("DW_OP_drop"); break; // 0x13
case DW_OP_over: s->PutCString("DW_OP_over"); break; // 0x14
@@ -344,7 +344,7 @@
case DW_OP_or: s->PutCString("DW_OP_or"); break; // 0x21
case DW_OP_plus: s->PutCString("DW_OP_plus"); break; // 0x22
case DW_OP_plus_uconst: // 0x23 1 ULEB128 addend
- s->Printf("DW_OP_plus_uconst(0x%llx) ", m_data.GetULEB128(&offset));
+ s->Printf("DW_OP_plus_uconst(0x%" PRIx64 ") ", m_data.GetULEB128(&offset));
break;
case DW_OP_shl: s->PutCString("DW_OP_shl"); break; // 0x24
@@ -490,23 +490,23 @@
{
if (reg_info.name)
{
- s->Printf("[%s%+lli]", reg_info.name, reg_offset);
+ s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
break;
}
else if (reg_info.alt_name)
{
- s->Printf("[%s%+lli]", reg_info.alt_name, reg_offset);
+ s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
break;
}
}
}
- s->Printf("DW_OP_breg%i(0x%llx)", reg_num, reg_offset);
+ s->Printf("DW_OP_breg%i(0x%" PRIx64 ")", reg_num, reg_offset);
}
break;
case DW_OP_regx: // 0x90 1 ULEB128 register
{
- uint64_t reg_num = m_data.GetULEB128(&offset);
+ uint32_t reg_num = m_data.GetULEB128(&offset);
if (abi)
{
RegisterInfo reg_info;
@@ -524,11 +524,11 @@
}
}
}
- s->Printf("DW_OP_regx(%llu)", reg_num); break;
+ s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num); break;
}
break;
case DW_OP_fbreg: // 0x91 1 SLEB128 offset
- s->Printf("DW_OP_fbreg(%lli)",m_data.GetSLEB128(&offset));
+ s->Printf("DW_OP_fbreg(%" PRIi64 ")",m_data.GetSLEB128(&offset));
break;
case DW_OP_bregx: // 0x92 2 ULEB128 register followed by SLEB128 offset
{
@@ -541,21 +541,21 @@
{
if (reg_info.name)
{
- s->Printf("[%s%+lli]", reg_info.name, reg_offset);
+ s->Printf("[%s%+" PRIi64 "]", reg_info.name, reg_offset);
break;
}
else if (reg_info.alt_name)
{
- s->Printf("[%s%+lli]", reg_info.alt_name, reg_offset);
+ s->Printf("[%s%+" PRIi64 "]", reg_info.alt_name, reg_offset);
break;
}
}
}
- s->Printf("DW_OP_bregx(reg=%u,offset=%lli)", reg_num, reg_offset);
+ s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num, reg_offset);
}
break;
case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed
- s->Printf("DW_OP_piece(0x%llx)", m_data.GetULEB128(&offset));
+ s->Printf("DW_OP_piece(0x%" PRIx64 ")", m_data.GetULEB128(&offset));
break;
case DW_OP_deref_size: // 0x94 1 1-byte size of data retrieved
s->Printf("DW_OP_deref_size(0x%2.2x)", m_data.GetU8(&offset));
@@ -572,7 +572,7 @@
s->Printf("DW_OP_call4(0x%8.8x)", m_data.GetU32(&offset));
break;
case DW_OP_call_ref: // 0x9a DWARF3 1 4- or 8-byte offset of DIE
- s->Printf("DW_OP_call_ref(0x%8.8llx)", m_data.GetAddress(&offset));
+ s->Printf("DW_OP_call_ref(0x%8.8" PRIx64 ")", m_data.GetAddress(&offset));
break;
// case DW_OP_form_tls_address: s << "form_tls_address"; break; // 0x9b DWARF3
// case DW_OP_call_frame_cfa: s << "call_frame_cfa"; break; // 0x9c DWARF3
@@ -582,7 +582,7 @@
// case DW_OP_lo_user: s->PutCString("DW_OP_lo_user"); break; // 0xe0
// case DW_OP_hi_user: s->PutCString("DW_OP_hi_user"); break; // 0xff
// case DW_OP_APPLE_extern:
-// s->Printf("DW_OP_APPLE_extern(%llu)", m_data.GetULEB128(&offset));
+// s->Printf("DW_OP_APPLE_extern(%" PRIu64 ")", m_data.GetULEB128(&offset));
// break;
// case DW_OP_APPLE_array_ref:
// s->PutCString("DW_OP_APPLE_array_ref");
@@ -603,7 +603,7 @@
// s->PutCString("DW_OP_APPLE_deref_type");
// break;
// case DW_OP_APPLE_expr_local: // 0xF5 - ULEB128 expression local index
-// s->Printf("DW_OP_APPLE_expr_local(%llu)", m_data.GetULEB128(&offset));
+// s->Printf("DW_OP_APPLE_expr_local(%" PRIu64 ")", m_data.GetULEB128(&offset));
// break;
// case DW_OP_APPLE_constf: // 0xF6 - 1 byte float size, followed by constant float data
// {
@@ -664,7 +664,7 @@
if (IsLocationList())
{
// We have a location list
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t count = 0;
addr_t curr_base_addr = location_list_base_addr;
while (m_data.ValidOffset(offset))
@@ -678,7 +678,7 @@
VMRange addr_range(curr_base_addr + begin_addr_offset, curr_base_addr + end_addr_offset);
addr_range.Dump(s, 0, 8);
s->PutChar('{');
- uint32_t location_length = m_data.GetU16(&offset);
+ lldb::offset_t location_length = m_data.GetU16(&offset);
DumpLocation (s, offset, location_length, level, abi);
s->PutChar('}');
offset += location_length;
@@ -782,7 +782,7 @@
//
// if (IsLocationList())
// {
-// uint32_t offset = 0;
+// lldb::offset_t offset = 0;
//
// addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process);
//
@@ -811,10 +811,10 @@
// return false;
//}
-static uint32_t
-GetOpcodeDataSize (const DataExtractor &data, const uint32_t data_offset, const uint8_t op)
+static offset_t
+GetOpcodeDataSize (const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op)
{
- uint32_t offset = data_offset;
+ lldb::offset_t offset = data_offset;
switch (op)
{
case DW_OP_addr:
@@ -1006,7 +1006,7 @@
default:
break;
}
- return UINT32_MAX;
+ return LLDB_INVALID_OFFSET;
}
bool
@@ -1015,7 +1015,7 @@
error = false;
if (IsLocationList())
return false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset))
{
const uint8_t op = m_data.GetU8(&offset);
@@ -1030,8 +1030,8 @@
}
else
{
- const uint32_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
- if (op_arg_size == UINT32_MAX)
+ const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
+ if (op_arg_size == LLDB_INVALID_OFFSET)
{
error = true;
break;
@@ -1047,14 +1047,14 @@
{
if (IsLocationList())
return false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset))
{
const uint8_t op = m_data.GetU8(&offset);
if (op == DW_OP_addr)
{
- const uint8_t addr_byte_size = m_data.GetAddressByteSize();
+ const uint32_t addr_byte_size = m_data.GetAddressByteSize();
// We have to make a copy of the data as we don't know if this
// data is from a read only memory mapped buffer, so we duplicate
// all of the data first, then modify it, and if all goes well,
@@ -1083,8 +1083,8 @@
}
else
{
- const uint32_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
- if (op_arg_size == UINT32_MAX)
+ const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
+ if (op_arg_size == LLDB_INVALID_OFFSET)
break;
offset += op_arg_size;
}
@@ -1100,7 +1100,7 @@
if (IsLocationList())
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (loclist_base_addr == LLDB_INVALID_ADDRESS)
return false;
@@ -1128,7 +1128,7 @@
}
bool
-DWARFExpression::GetLocation (addr_t base_addr, addr_t pc, uint32_t &offset, uint32_t &length)
+DWARFExpression::GetLocation (addr_t base_addr, addr_t pc, lldb::offset_t &offset, lldb::offset_t &length)
{
offset = 0;
if (!IsLocationList())
@@ -1164,7 +1164,7 @@
}
}
}
- offset = UINT32_MAX;
+ offset = LLDB_INVALID_OFFSET;
length = 0;
return false;
}
@@ -1176,8 +1176,8 @@
addr_t address,
ABI *abi)
{
- uint32_t offset = 0;
- uint32_t length = 0;
+ lldb::offset_t offset = 0;
+ lldb::offset_t length = 0;
if (GetLocation (base_addr, address, offset, length))
{
@@ -1223,7 +1223,7 @@
{
if (IsLocationList())
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
addr_t pc;
StackFrame *frame = NULL;
if (reg_ctx)
@@ -1294,8 +1294,8 @@
ClangExpressionDeclMap *decl_map,
RegisterContext *reg_ctx,
const DataExtractor& opcodes,
- const uint32_t opcodes_offset,
- const uint32_t opcodes_length,
+ const lldb::offset_t opcodes_offset,
+ const lldb::offset_t opcodes_length,
const uint32_t reg_kind,
const Value* initial_value_ptr,
Value& result,
@@ -1318,8 +1318,8 @@
if (initial_value_ptr)
stack.push_back(*initial_value_ptr);
- uint32_t offset = opcodes_offset;
- const uint32_t end_offset = opcodes_offset + opcodes_length;
+ lldb::offset_t offset = opcodes_offset;
+ const lldb::offset_t end_offset = opcodes_offset + opcodes_length;
Value tmp;
uint32_t reg_num;
@@ -1335,7 +1335,7 @@
while (opcodes.ValidOffset(offset) && offset < end_offset)
{
- const uint32_t op_offset = offset;
+ const lldb::offset_t op_offset = offset;
const uint8_t op = opcodes.GetU8(&offset);
if (log && log->GetVerbose())
@@ -1345,11 +1345,11 @@
for (size_t i=0; i<count; ++i)
{
StreamString new_value;
- new_value.Printf("[%llu]", (uint64_t)i);
+ new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
stack[i].Dump(&new_value);
log->Printf(" %s", new_value.GetData());
}
- log->Printf("0x%8.8x: %s", op_offset, DW_OP_value_to_name(op));
+ log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
}
switch (op)
{
@@ -1431,14 +1431,14 @@
if (process->ReadMemory(pointer_addr, &addr_bytes, addr_size, error) == addr_size)
{
DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), addr_size);
- uint32_t addr_data_offset = 0;
+ lldb::offset_t addr_data_offset = 0;
stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
stack.back().ClearContext();
}
else
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%llx for DW_OP_deref: %s\n",
+ error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%" PRIx64 " for DW_OP_deref: %s\n",
pointer_addr,
error.AsCString());
return false;
@@ -1522,7 +1522,7 @@
if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) == size)
{
DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), size);
- uint32_t addr_data_offset = 0;
+ lldb::offset_t addr_data_offset = 0;
switch (size)
{
case 1: stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); break;
@@ -1536,7 +1536,7 @@
else
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%llx for DW_OP_deref: %s\n",
+ error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%" PRIx64 " for DW_OP_deref: %s\n",
pointer_addr,
error.AsCString());
return false;
@@ -1996,7 +1996,7 @@
}
else
{
- uint32_t uconst_value = opcodes.GetULEB128(&offset);
+ const uint64_t uconst_value = opcodes.GetULEB128(&offset);
// Implicit conversion from a UINT to a Scalar...
stack.back().ResolveValue(exe_ctx, ast_context) += uconst_value;
if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid())
@@ -2113,7 +2113,7 @@
case DW_OP_skip:
{
int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
- uint32_t new_offset = offset + skip_offset;
+ lldb::offset_t new_offset = offset + skip_offset;
if (new_offset >= opcodes_offset && new_offset < end_offset)
offset = new_offset;
else
@@ -2143,7 +2143,7 @@
Scalar zero(0);
if (tmp.ResolveValue(exe_ctx, ast_context) != zero)
{
- uint32_t new_offset = offset + bra_offset;
+ lldb::offset_t new_offset = offset + bra_offset;
if (new_offset >= opcodes_offset && new_offset < end_offset)
offset = new_offset;
else
@@ -2709,7 +2709,7 @@
if (size && (index >= size || index < 0))
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat("Out of bounds array access. %lld is not in [0, %llu]", index, size);
+ error_ptr->SetErrorStringWithFormat("Out of bounds array access. %" PRId64 " is not in [0, %" PRIu64 "]", index, size);
return false;
}
@@ -2892,7 +2892,7 @@
new_value))
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat ("Failed to write value to memory at 0x%llx.\n", addr);
+ error_ptr->SetErrorStringWithFormat ("Failed to write value to memory at 0x%" PRIx64 ".\n", addr);
return false;
}
}
@@ -3186,7 +3186,7 @@
for (size_t i=0; i<count; ++i)
{
StreamString new_value;
- new_value.Printf("[%llu]", (uint64_t)i);
+ new_value.Printf("[%" PRIu64 "]", (uint64_t)i);
stack[i].Dump(&new_value);
log->Printf(" %s", new_value.GetData());
}
Index: aze/lldb/source/Expression/ExpressionSourceCode.cpp
===================================================================
--- aze.orig/lldb/source/Expression/ExpressionSourceCode.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/ExpressionSourceCode.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -13,18 +13,33 @@
using namespace lldb_private;
-static const char *global_defines = "#undef NULL \n"
- "#undef Nil \n"
- "#undef nil \n"
- "#undef YES \n"
- "#undef NO \n"
- "#define NULL ((int)0) \n"
- "#define Nil ((Class)0) \n"
- "#define nil ((id)0) \n"
- "#define YES ((BOOL)1) \n"
- "#define NO ((BOOL)0) \n"
- "typedef int BOOL; \n"
- "typedef unsigned short unichar; \n";
+const char *
+ExpressionSourceCode::g_expression_prefix = R"(
+#undef NULL
+#undef Nil
+#undef nil
+#undef YES
+#undef NO
+#define NULL (__null)
+#define Nil (__null)
+#define nil (__null)
+#define YES ((BOOL)1)
+#define NO ((BOOL)0)
+typedef signed char BOOL;
+typedef signed __INT8_TYPE__ int8_t;
+typedef unsigned __INT8_TYPE__ uint8_t;
+typedef signed __INT16_TYPE__ int16_t;
+typedef unsigned __INT16_TYPE__ uint16_t;
+typedef signed __INT32_TYPE__ int32_t;
+typedef unsigned __INT32_TYPE__ uint32_t;
+typedef signed __INT64_TYPE__ int64_t;
+typedef unsigned __INT64_TYPE__ uint64_t;
+typedef signed __INTPTR_TYPE__ intptr_t;
+typedef unsigned __INTPTR_TYPE__ uintptr_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef unsigned short unichar;
+)";
bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method) const
@@ -56,7 +71,7 @@
" %s; \n"
"} \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
m_body.c_str());
break;
@@ -69,7 +84,7 @@
" %s; \n"
"} \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
(const_object ? "const" : ""),
m_body.c_str());
@@ -89,7 +104,7 @@
"} \n"
"@end \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
m_name.c_str(),
m_body.c_str());
@@ -108,7 +123,7 @@
"} \n"
"@end \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
m_name.c_str(),
m_body.c_str());
Index: aze/lldb/source/Expression/IRDynamicChecks.cpp
===================================================================
--- aze.orig/lldb/source/Expression/IRDynamicChecks.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/IRDynamicChecks.cpp 2013-03-03 09:35:50.183457353 +0100
@@ -18,11 +18,11 @@
#include "lldb/Target/StackFrame.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Value.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Value.h"
using namespace llvm;
using namespace lldb_private;
Index: aze/lldb/source/Expression/IRForTarget.cpp
===================================================================
--- aze.orig/lldb/source/Expression/IRForTarget.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/IRForTarget.cpp 2013-03-03 09:35:50.187457353 +0100
@@ -10,15 +10,15 @@
#include "lldb/Expression/IRForTarget.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Constants.h"
-#include "llvm/DataLayout.h"
-#include "llvm/InstrTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Transforms/IPO.h"
-#include "llvm/ValueSymbolTable.h"
+#include "llvm/IR/ValueSymbolTable.h"
#include "clang/AST/ASTContext.h"
@@ -294,7 +294,7 @@
}
if (log)
- log->Printf("Found \"%s\" at 0x%llx", name.GetCString(), fun_addr);
+ log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);
return true;
}
@@ -869,7 +869,7 @@
}
if (log)
- log->Printf("Found CFStringCreateWithBytes at 0x%llx", CFStringCreateWithBytes_addr);
+ log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
// Build the function type:
//
@@ -1262,7 +1262,7 @@
return false;
if (log)
- log->Printf("Found sel_registerName at 0x%llx", sel_registerName_addr);
+ log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
// Build the function type: struct objc_selector *sel_registerName(uint8_t*)
@@ -1678,7 +1678,7 @@
off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7) / 8;
if (log)
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %lu, align %lld]",
+ log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %lu, align %" PRId64 "]",
name.c_str(),
qual_type.getAsString().c_str(),
PrintType(value_type).c_str(),
@@ -1728,7 +1728,7 @@
}
if (log)
- log->Printf("Found \"%s\" at 0x%llx", name.GetCString(), symbol_addr);
+ log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
Type *symbol_type = symbol->getType();
IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
@@ -2529,7 +2529,7 @@
}
if (log)
- log->Printf(" \"%s\" (\"%s\") placed at %lld",
+ log->Printf(" \"%s\" (\"%s\") placed at %" PRId64,
name.GetCString(),
decl->getNameAsString().c_str(),
offset);
@@ -2573,7 +2573,7 @@
}
if (log)
- log->Printf("Total structure [align %lld, size %lu]", alignment, size);
+ log->Printf("Total structure [align %" PRId64 ", size %lu]", alignment, size);
return true;
}
@@ -2679,9 +2679,10 @@
GlobalValue::use_iterator ui = global_var->use_begin();
- log->Printf("Couldn't remove %s because of %s",
- PrintValue(global_var).c_str(),
- PrintValue(*ui).c_str());
+ if (log)
+ log->Printf("Couldn't remove %s because of %s",
+ PrintValue(global_var).c_str(),
+ PrintValue(*ui).c_str());
}
return true;
Index: aze/lldb/source/Expression/IRInterpreter.cpp
===================================================================
--- aze.orig/lldb/source/Expression/IRInterpreter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/IRInterpreter.cpp 2013-03-03 09:35:50.187457353 +0100
@@ -15,12 +15,12 @@
#include "lldb/Expression/IRForTarget.h"
#include "lldb/Expression/IRInterpreter.h"
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/DataLayout.h"
+#include "llvm/IR/DataLayout.h"
#include <map>
@@ -28,8 +28,7 @@
IRInterpreter::IRInterpreter(lldb_private::ClangExpressionDeclMap &decl_map,
lldb_private::Stream *error_stream) :
- m_decl_map(decl_map),
- m_error_stream(error_stream)
+ m_decl_map(decl_map)
{
}
@@ -389,7 +388,7 @@
lldb_private::Value base = GetAccessTarget(region.m_base);
- ss.Printf("%llx [%s - %s %llx]",
+ ss.Printf("%" PRIx64 " [%s - %s %llx]",
region.m_base,
lldb_private::Value::GetValueTypeAsCString(base.GetValueType()),
lldb_private::Value::GetContextTypeAsCString(base.GetContextType()),
@@ -507,7 +506,7 @@
size_t value_size = m_target_data.getTypeStoreSize(value->getType());
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint64_t u64value = value_extractor->GetMaxU64(&offset, value_size);
return AssignToMatchType(scalar, u64value, value->getType());
@@ -525,7 +524,7 @@
if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
return false;
- lldb_private::DataBufferHeap buf(cast_scalar.GetByteSize(), 0);
+ lldb_private::DataBufferHeap buf(region.m_extent, 0);
lldb_private::Error err;
@@ -534,6 +533,9 @@
DataEncoderSP region_encoder = m_memory.GetEncoder(region);
+ if (buf.GetByteSize() > region_encoder->GetByteSize())
+ return false; // This should not happen
+
memcpy(region_encoder->GetDataStart(), buf.GetBytes(), buf.GetByteSize());
return true;
@@ -558,6 +560,7 @@
default:
return false;
case Instruction::IntToPtr:
+ case Instruction::PtrToInt:
case Instruction::BitCast:
return ResolveConstantValue(value, constant_expr->getOperand(0));
case Instruction::GetElementPtr:
@@ -619,7 +622,7 @@
// array then we need to build an extra level of indirection
// for it. This is the default; only magic arguments like
// "this", "self", and "_cmd" are direct.
- bool indirect_variable = true;
+ bool variable_is_this = false;
// Attempt to resolve the value using the program's data.
// If it is, the values to be created are:
@@ -662,71 +665,124 @@
if (name_str == "this" ||
name_str == "self" ||
name_str == "_cmd")
+ {
resolved_value = m_decl_map.GetSpecialValue(lldb_private::ConstString(name_str.c_str()));
-
- indirect_variable = false;
+ variable_is_this = true;
+ }
}
if (resolved_value.GetScalar().GetType() != lldb_private::Scalar::e_void)
{
if (resolved_value.GetContextType() == lldb_private::Value::eContextTypeRegisterInfo)
{
- bool bare_register = (flags & lldb_private::ClangExpressionVariable::EVBareRegister);
-
- if (bare_register)
- indirect_variable = false;
-
- lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo();
- Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ?
+ if (variable_is_this)
+ {
+ Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
+
+ lldb_private::Value origin;
+
+ origin.SetValueType(lldb_private::Value::eValueTypeLoadAddress);
+ origin.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
+ origin.GetScalar() = resolved_value.GetScalar();
+
+ data_region.m_allocation->m_origin = origin;
+
+ Memory::Region ref_region = m_memory.Malloc(value->getType());
+
+ if (ref_region.IsInvalid())
+ return Memory::Region();
+
+ DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
+
+ if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
+ return Memory::Region();
+
+ if (log)
+ {
+ log->Printf("Made an allocation for \"this\" register variable %s", PrintValue(value).c_str());
+ log->Printf(" Data region : %llx", (unsigned long long)data_region.m_base);
+ log->Printf(" Ref region : %llx", (unsigned long long)ref_region.m_base);
+ }
+
+ m_values[value] = ref_region;
+ return ref_region;
+ }
+ else if (flags & lldb_private::ClangExpressionVariable::EVBareRegister)
+ {
+ lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo();
+ Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ?
m_memory.Malloc(reg_info->byte_size, m_target_data.getPrefTypeAlignment(value->getType())) :
m_memory.Malloc(value->getType());
-
- data_region.m_allocation->m_origin = resolved_value;
- Memory::Region ref_region = m_memory.Malloc(value->getType());
- Memory::Region pointer_region;
-
- if (indirect_variable)
+
+ data_region.m_allocation->m_origin = resolved_value;
+ Memory::Region ref_region = m_memory.Malloc(value->getType());
+
+ if (!Cache(data_region.m_allocation, value->getType()))
+ return Memory::Region();
+
+ if (ref_region.IsInvalid())
+ return Memory::Region();
+
+ DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
+
+ if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
+ return Memory::Region();
+
+ if (log)
+ {
+ log->Printf("Made an allocation for bare register variable %s", PrintValue(value).c_str());
+ log->Printf(" Data contents : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
+ log->Printf(" Data region : %llx", (unsigned long long)data_region.m_base);
+ log->Printf(" Ref region : %llx", (unsigned long long)ref_region.m_base);
+ }
+
+ m_values[value] = ref_region;
+ return ref_region;
+ }
+ else
+ {
+ lldb_private::RegisterInfo *reg_info = resolved_value.GetRegisterInfo();
+ Memory::Region data_region = (reg_info->encoding == lldb::eEncodingVector) ?
+ m_memory.Malloc(reg_info->byte_size, m_target_data.getPrefTypeAlignment(value->getType())) :
+ m_memory.Malloc(value->getType());
+
+ data_region.m_allocation->m_origin = resolved_value;
+ Memory::Region ref_region = m_memory.Malloc(value->getType());
+ Memory::Region pointer_region;
+
pointer_region = m_memory.Malloc(value->getType());
-
- if (!Cache(data_region.m_allocation, value->getType()))
- return Memory::Region();
-
- if (ref_region.IsInvalid())
- return Memory::Region();
-
- if (pointer_region.IsInvalid() && indirect_variable)
- return Memory::Region();
-
- DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
-
- if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
- return Memory::Region();
-
- if (log)
- {
- log->Printf("Made an allocation for register variable %s", PrintValue(value).c_str());
- log->Printf(" Data contents : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
- log->Printf(" Data region : %llx", (unsigned long long)data_region.m_base);
- log->Printf(" Ref region : %llx", (unsigned long long)ref_region.m_base);
- if (indirect_variable)
+
+ if (!Cache(data_region.m_allocation, value->getType()))
+ return Memory::Region();
+
+ if (ref_region.IsInvalid())
+ return Memory::Region();
+
+ if (pointer_region.IsInvalid())
+ return Memory::Region();
+
+ DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
+
+ if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
+ return Memory::Region();
+
+ if (log)
+ {
+ log->Printf("Made an allocation for ordinary register variable %s", PrintValue(value).c_str());
+ log->Printf(" Data contents : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
+ log->Printf(" Data region : %llx", (unsigned long long)data_region.m_base);
+ log->Printf(" Ref region : %llx", (unsigned long long)ref_region.m_base);
log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base);
- }
-
- if (indirect_variable)
- {
- DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
+ }
+ DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
+
if (pointer_encoder->PutAddress(0, ref_region.m_base) == UINT32_MAX)
return Memory::Region();
m_values[value] = pointer_region;
return pointer_region;
}
- else
- {
- m_values[value] = ref_region;
- return ref_region;
- }
}
else
{
@@ -734,13 +790,13 @@
Memory::Region ref_region = m_memory.Malloc(value->getType());
Memory::Region pointer_region;
- if (indirect_variable)
+ if (!variable_is_this)
pointer_region = m_memory.Malloc(value->getType());
if (ref_region.IsInvalid())
return Memory::Region();
- if (pointer_region.IsInvalid() && indirect_variable)
+ if (pointer_region.IsInvalid() && !variable_is_this)
return Memory::Region();
DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -748,7 +804,7 @@
if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
return Memory::Region();
- if (indirect_variable)
+ if (!variable_is_this)
{
DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
@@ -764,14 +820,14 @@
log->Printf(" Data contents : %s", m_memory.PrintData(data_region.m_base, data_region.m_extent).c_str());
log->Printf(" Data region : %llx", (unsigned long long)data_region.m_base);
log->Printf(" Ref region : %llx", (unsigned long long)ref_region.m_base);
- if (indirect_variable)
+ if (!variable_is_this)
log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base);
}
- if (indirect_variable)
- return pointer_region;
- else
+ if (variable_is_this)
return ref_region;
+ else
+ return pointer_region;
}
}
}
@@ -780,9 +836,7 @@
// Fall back and allocate space [allocation type Alloca]
Type *type = value->getType();
-
- lldb::ValueSP backing_value(new lldb_private::Value);
-
+
Memory::Region data_region = m_memory.Malloc(type);
data_region.m_allocation->m_origin.GetScalar() = (unsigned long long)data_region.m_allocation->m_data->GetBytes();
data_region.m_allocation->m_origin.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
@@ -833,7 +887,7 @@
return false;
Type *R_ty = pointer_ptr_ty->getElementType();
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
lldb::addr_t pointer = P_extractor->GetAddress(&offset);
Memory::Region R = m_memory.Lookup(pointer, R_ty);
@@ -990,14 +1044,23 @@
}
}
break;
+ case Instruction::And:
+ case Instruction::AShr:
case Instruction::IntToPtr:
+ case Instruction::PtrToInt:
case Instruction::Load:
+ case Instruction::LShr:
case Instruction::Mul:
+ case Instruction::Or:
case Instruction::Ret:
case Instruction::SDiv:
+ case Instruction::Shl:
+ case Instruction::SRem:
case Instruction::Store:
case Instruction::Sub:
case Instruction::UDiv:
+ case Instruction::URem:
+ case Instruction::Xor:
case Instruction::ZExt:
break;
}
@@ -1082,6 +1145,14 @@
case Instruction::Mul:
case Instruction::SDiv:
case Instruction::UDiv:
+ case Instruction::SRem:
+ case Instruction::URem:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
{
const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
@@ -1139,6 +1210,31 @@
case Instruction::UDiv:
result = L.GetRawBits64(0) / R.GetRawBits64(1);
break;
+ case Instruction::SRem:
+ result = L % R;
+ break;
+ case Instruction::URem:
+ result = L.GetRawBits64(0) % R.GetRawBits64(1);
+ break;
+ case Instruction::Shl:
+ result = L << R;
+ break;
+ case Instruction::AShr:
+ result = L >> R;
+ break;
+ case Instruction::LShr:
+ result = L;
+ result.ShiftRightLogical(R);
+ break;
+ case Instruction::And:
+ result = L & R;
+ break;
+ case Instruction::Or:
+ result = L | R;
+ break;
+ case Instruction::Xor:
+ result = L ^ R;
+ break;
}
frame.AssignValue(inst, result, llvm_module);
@@ -1506,6 +1602,42 @@
}
}
break;
+ case Instruction::PtrToInt:
+ {
+ const PtrToIntInst *ptr_to_int_inst = dyn_cast<PtrToIntInst>(inst);
+
+ if (!ptr_to_int_inst)
+ {
+ if (log)
+ log->Printf("getOpcode() returns PtrToInt, but instruction is not an PtrToIntInst");
+ err.SetErrorToGenericError();
+ err.SetErrorString(interpreter_internal_error);
+ return false;
+ }
+
+ Value *src_operand = ptr_to_int_inst->getOperand(0);
+
+ lldb_private::Scalar I;
+
+ if (!frame.EvaluateValue(I, src_operand, llvm_module))
+ {
+ if (log)
+ log->Printf("Couldn't evaluate %s", PrintValue(src_operand).c_str());
+ err.SetErrorToGenericError();
+ err.SetErrorString(bad_value_error);
+ return false;
+ }
+
+ frame.AssignValue(inst, I, llvm_module);
+
+ if (log)
+ {
+ log->Printf("Interpreted a PtrToInt");
+ log->Printf(" Src : %s", frame.SummarizeValue(src_operand).c_str());
+ log->Printf(" = : %s", frame.SummarizeValue(inst).c_str());
+ }
+ }
+ break;
case Instruction::Load:
{
const LoadInst *load_inst = dyn_cast<LoadInst>(inst);
@@ -1563,7 +1695,7 @@
DataExtractorSP P_extractor(memory.GetExtractor(P));
DataEncoderSP D_encoder(memory.GetEncoder(D));
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
lldb::addr_t pointer = P_extractor->GetAddress(&offset);
Memory::Region R = memory.Lookup(pointer, target_ty);
@@ -1676,7 +1808,7 @@
if (!P_extractor || !D_extractor)
return false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
lldb::addr_t pointer = P_extractor->GetAddress(&offset);
Memory::Region R = memory.Lookup(pointer, target_ty);
Index: aze/lldb/source/Expression/RecordingMemoryManager.cpp
===================================================================
--- aze.orig/lldb/source/Expression/RecordingMemoryManager.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Expression/RecordingMemoryManager.cpp 2013-03-03 09:35:50.187457353 +0100
@@ -89,7 +89,7 @@
if (m_log)
{
- m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%llu, Alignment=%u) = %p",
+ m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
allocation.dump(m_log);
}
@@ -113,7 +113,7 @@
if (m_log)
{
- m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
+ m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, return_value);
allocation.dump(m_log);
}
@@ -124,9 +124,9 @@
}
uint8_t *
-RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
+RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly)
{
- uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID);
+ uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
Allocation allocation;
allocation.m_size = Size;
@@ -136,7 +136,7 @@
if (m_log)
{
- m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%llx, Alignment=%u, SectionID=%u) = %p",
+ m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
(uint64_t)Size, Alignment, SectionID, return_value);
allocation.dump(m_log);
}
@@ -158,7 +158,7 @@
if (m_log)
{
- m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%llx, Alignment=%u) = %p",
+ m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
(uint64_t)Size, Alignment, return_value);
allocation.dump(m_log);
}
@@ -294,6 +294,8 @@
engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
}
+ // Trigger re-application of relocations.
+ engine.finalizeObject();
}
bool
Index: aze/lldb/source/Host/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Host/CMakeLists.txt 2013-03-03 09:35:50.187457353 +0100
@@ -0,0 +1,3 @@
+add_subdirectory(common)
+add_subdirectory(linux)
+#add_subdirectory(windows)
Index: aze/lldb/source/Host/common/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Host/common/CMakeLists.txt 2013-03-03 09:35:50.187457353 +0100
@@ -0,0 +1,14 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbHostCommon
+ Condition.cpp
+ DynamicLibrary.cpp
+ File.cpp
+ FileSpec.cpp
+ Host.cpp
+ Mutex.cpp
+ SocketAddress.cpp
+ Symbols.cpp
+ Terminal.cpp
+ TimeValue.cpp
+ )
Index: aze/lldb/source/Host/common/File.cpp
===================================================================
--- aze.orig/lldb/source/Host/common/File.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/common/File.cpp 2013-03-03 09:35:50.187457353 +0100
@@ -625,12 +625,12 @@
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-int
+size_t
File::Printf (const char *format, ...)
{
va_list args;
va_start (args, format);
- int result = PrintfVarArg (format, args);
+ size_t result = PrintfVarArg (format, args);
va_end (args);
return result;
}
@@ -638,10 +638,10 @@
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-int
+size_t
File::PrintfVarArg (const char *format, va_list args)
{
- int result = 0;
+ size_t result = 0;
if (DescriptorIsValid())
{
char *s = NULL;
Index: aze/lldb/source/Host/common/FileSpec.cpp
===================================================================
--- aze.orig/lldb/source/Host/common/FileSpec.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/common/FileSpec.cpp 2013-03-03 09:35:50.187457353 +0100
@@ -110,7 +110,7 @@
}
else
{
- int user_name_len = first_slash - src_path - 1;
+ size_t user_name_len = first_slash - src_path - 1;
::memcpy (user_home, src_path + 1, user_name_len);
user_home[user_name_len] = '\0';
user_name = user_home;
@@ -938,7 +938,6 @@
switch (result)
{
- default:
case eEnumerateDirectoryResultNext:
// Enumerate next entry in the current directory. We just
// exit this switch and will continue enumerating the
Index: aze/lldb/source/Host/common/Host.cpp
===================================================================
--- aze.orig/lldb/source/Host/common/Host.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/common/Host.cpp 2013-03-03 09:35:50.191457353 +0100
@@ -7,32 +7,18 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Host/Host.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Core/ThreadSafeSTLMap.h"
-#include "lldb/Host/Config.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/TargetList.h"
-
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MachO.h"
+#include "lldb/lldb-python.h"
+// C includes
#include <dlfcn.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <netdb.h>
#include <pwd.h>
+#include <sys/sysctl.h>
#include <sys/types.h>
-
+#include <unistd.h>
#if defined (__APPLE__)
@@ -40,8 +26,6 @@
#include <libproc.h>
#include <mach-o/dyld.h>
#include <mach/mach_port.h>
-#include <sys/sysctl.h>
-
#elif defined (__linux__)
@@ -50,11 +34,33 @@
#elif defined (__FreeBSD__)
#include <sys/wait.h>
-#include <sys/sysctl.h>
#include <pthread_np.h>
#endif
+#include "lldb/Host/Host.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ThreadSafeSTLMap.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/TargetList.h"
+
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MachO.h"
+#include "llvm/ADT/Twine.h"
+
+
+
+
+
using namespace lldb;
using namespace lldb_private;
@@ -89,7 +95,7 @@
info_ptr->monitor_signals = monitor_signals;
char thread_name[256];
- ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%i)>", pid);
+ ::snprintf (thread_name, sizeof(thread_name), "<lldb.host.wait4(pid=%" PRIu64 ")>", pid);
thread = ThreadCreate (thread_name,
MonitorChildProcessThreadFunction,
info_ptr,
@@ -144,16 +150,18 @@
delete info;
int status = -1;
- const int options = 0;
+ const int options = __WALL;
+
while (1)
{
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
- log->Printf("%s ::wait_pid (pid = %i, &status, options = %i)...", function, pid, options);
+ log->Printf("%s ::wait_pid (pid = %" PRIu64 ", &status, options = %i)...", function, pid, options);
// Wait for all child processes
::pthread_testcancel ();
- const lldb::pid_t wait_pid = ::waitpid (pid, &status, options);
+ // Get signals from all children with same process group of pid
+ const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
::pthread_testcancel ();
if (wait_pid == -1)
@@ -163,7 +171,7 @@
else
break;
}
- else if (wait_pid == pid)
+ else if (wait_pid > 0)
{
bool exited = false;
int signal = 0;
@@ -178,14 +186,17 @@
{
exit_status = WEXITSTATUS(status);
status_cstr = "EXITED";
- exited = true;
+ if (wait_pid == pid)
+ exited = true;
}
else if (WIFSIGNALED(status))
{
signal = WTERMSIG(status);
status_cstr = "SIGNALED";
- exited = true;
- exit_status = -1;
+ if (wait_pid == pid) {
+ exited = true;
+ exit_status = -1;
+ }
}
else
{
@@ -198,7 +209,7 @@
log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS);
if (log)
- log->Printf ("%s ::waitpid (pid = %i, &status, options = %i) => pid = %i, status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+ log->Printf ("%s ::waitpid (pid = %" PRIu64 ", &status, options = %i) => pid = %" PRIu64 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
function,
wait_pid,
options,
@@ -212,7 +223,7 @@
{
bool callback_return = false;
if (callback)
- callback_return = callback (callback_baton, pid, exited, signal, exit_status);
+ callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
// If our process exited, then this thread should exit
if (exited)
@@ -353,7 +364,6 @@
case llvm::Triple::sparcv9:
case llvm::Triple::ppc64:
- case llvm::Triple::cellspu:
g_host_arch_64.SetTriple(triple);
g_supports_64 = true;
break;
@@ -605,92 +615,44 @@
return err == 0;
}
-// rdar://problem/8153284
-// Fixed a crasher where during shutdown, loggings attempted to access the
-// thread name but the static map instance had already been destructed.
-// So we are using a ThreadSafeSTLMap POINTER, initializing it with a
-// pthread_once action. That map will get leaked.
-//
-// Another approach is to introduce a static guard object which monitors its
-// own destruction and raises a flag, but this incurs more overhead.
-
-static pthread_once_t g_thread_map_once = PTHREAD_ONCE_INIT;
-static ThreadSafeSTLMap<uint64_t, std::string> *g_thread_names_map_ptr;
-
-static void
-InitThreadNamesMap()
-{
- g_thread_names_map_ptr = new ThreadSafeSTLMap<uint64_t, std::string>();
-}
-
-//------------------------------------------------------------------
-// Control access to a static file thread name map using a single
-// static function to avoid a static constructor.
-//------------------------------------------------------------------
-static const char *
-ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name)
-{
- int success = ::pthread_once (&g_thread_map_once, InitThreadNamesMap);
- if (success != 0)
- return NULL;
-
- uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid;
-
- if (get)
- {
- // See if the thread name exists in our thread name pool
- std::string value;
- bool found_it = g_thread_names_map_ptr->GetValueForKey (pid_tid, value);
- if (found_it)
- return value.c_str();
- else
- return NULL;
- }
- else if (name)
- {
- // Set the thread name
- g_thread_names_map_ptr->SetValueForKey (pid_tid, std::string(name));
- }
- return NULL;
-}
-const char *
+std::string
Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
{
- const char *name = ThreadNameAccessor (true, pid, tid, NULL);
- if (name == NULL)
- {
+ std::string thread_name;
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
- // We currently can only get the name of a thread in the current process.
- if (pid == Host::GetCurrentProcessID())
+ // We currently can only get the name of a thread in the current process.
+ if (pid == Host::GetCurrentProcessID())
+ {
+ char pthread_name[1024];
+ if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
{
- char pthread_name[1024];
- if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
+ if (pthread_name[0])
{
- if (pthread_name[0])
- {
- // Set the thread in our string pool
- ThreadNameAccessor (false, pid, tid, pthread_name);
- // Get our copy of the thread name string
- name = ThreadNameAccessor (true, pid, tid, NULL);
- }
+ thread_name = pthread_name;
}
-
- if (name == NULL)
+ }
+ else
+ {
+ dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
+ if (current_queue != NULL)
{
- dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
- if (current_queue != NULL)
- name = dispatch_queue_get_label (current_queue);
+ const char *queue_name = dispatch_queue_get_label (current_queue);
+ if (queue_name && queue_name[0])
+ {
+ thread_name = queue_name;
+ }
}
}
-#endif
}
- return name;
+#endif
+ return thread_name;
}
void
Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
{
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
lldb::pid_t curr_pid = Host::GetCurrentProcessID();
lldb::tid_t curr_tid = Host::GetCurrentThreadID();
if (pid == LLDB_INVALID_PROCESS_ID)
@@ -699,14 +661,12 @@
if (tid == LLDB_INVALID_THREAD_ID)
tid = curr_tid;
-#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
// Set the pthread name if possible
if (pid == curr_pid && tid == curr_tid)
{
::pthread_setname_np (name);
}
#endif
- ThreadNameAccessor (false, pid, tid, name);
}
FileSpec
@@ -996,13 +956,6 @@
case ePathTypePythonDir:
{
- // TODO: Anyone know how we can determine this for linux? Other systems?
- // For linux and FreeBSD we are currently assuming the
- // location of the lldb binary that contains this function is
- // the directory that will contain a python directory which
- // has our lldb module. This is how files get placed when
- // compiling with Makefiles.
-
static ConstString g_lldb_python_dir;
if (!g_lldb_python_dir)
{
@@ -1021,9 +974,19 @@
::strncpy (framework_pos, "/Resources/Python", PATH_MAX - (framework_pos - raw_path));
}
#else
+ llvm::Twine python_version_dir;
+ python_version_dir = "/python"
+ + llvm::Twine(PY_MAJOR_VERSION)
+ + "."
+ + llvm::Twine(PY_MINOR_VERSION)
+ + "/site-packages";
+
// We may get our string truncated. Should we protect
// this with an assert?
- ::strncat(raw_path, "/python", sizeof(raw_path) - strlen(raw_path) - 1);
+
+ ::strncat(raw_path, python_version_dir.str().c_str(),
+ sizeof(raw_path) - strlen(raw_path) - 1);
+
#endif
FileSpec::Resolve (raw_path, resolved_path, sizeof(resolved_path));
g_lldb_python_dir.SetCString(resolved_path);
@@ -1092,9 +1055,6 @@
// TODO: where would user LLDB plug-ins be located on linux? Other systems?
return false;
}
- default:
- assert (!"Unhandled PathType");
- break;
}
return false;
@@ -1426,6 +1386,52 @@
}
+uint32_t
+Host::GetNumberCPUS ()
+{
+ static uint32_t g_num_cores = UINT32_MAX;
+ if (g_num_cores == UINT32_MAX)
+ {
+#if defined(__APPLE__) or defined (__linux__)
+
+ g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+
+ // Header file for this might need to be included at the top of this file
+ SYSTEM_INFO system_info;
+ ::GetSystemInfo (&system_info);
+ g_num_cores = system_info.dwNumberOfProcessors;
+
+#else
+
+ // Assume POSIX support if a host specific case has not been supplied above
+ g_num_cores = 0;
+ int num_cores = 0;
+ size_t num_cores_len = sizeof(num_cores);
+ int mib[] = { CTL_HW, HW_AVAILCPU };
+
+ /* get the number of CPUs from the system */
+ if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
+ {
+ g_num_cores = num_cores;
+ }
+ else
+ {
+ mib[1] = HW_NCPU;
+ num_cores_len = sizeof(num_cores);
+ if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
+ {
+ if (num_cores > 0)
+ g_num_cores = num_cores;
+ }
+ }
+#endif
+ }
+ return g_num_cores;
+}
+
+
#if !defined (__APPLE__)
bool
Index: aze/lldb/source/Host/common/Mutex.cpp
===================================================================
--- aze.orig/lldb/source/Host/common/Mutex.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/common/Mutex.cpp 2013-03-03 09:35:50.191457353 +0100
@@ -27,6 +27,7 @@
// Enable extra mutex error checking
#ifdef LLDB_CONFIGURATION_DEBUG
#define ENABLE_MUTEX_ERROR_CHECKING 1
+#include <inttypes.h>
#endif
#if ENABLE_MUTEX_ERROR_CHECKING
@@ -218,10 +219,6 @@
case eMutexTypeRecursive:
err = ::pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
break;
-
- default:
- err = -1;
- break;
}
assert(err == 0);
err = ::pthread_mutex_init (&m_mutex, &attr);
@@ -275,7 +272,7 @@
int
Mutex::Lock()
{
- DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex);
+ DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p)...\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex);
#if ENABLE_MUTEX_ERROR_CHECKING
error_check_mutex (&m_mutex, eMutexActionAssertInitialized);
@@ -291,7 +288,7 @@
assert(err == 0);
}
#endif
- DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
+ DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_lock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
return err;
}
@@ -311,7 +308,7 @@
#endif
int err = ::pthread_mutex_trylock (&m_mutex);
- DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
+ DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_trylock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
return err;
}
@@ -340,7 +337,7 @@
assert(err == 0);
}
#endif
- DEBUG_LOG ("[%4.4llx/%4.4llx] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
+ DEBUG_LOG ("[%4.4" PRIx64 "/%4.4" PRIx64 "] pthread_mutex_unlock (%p) => %i\n", Host::GetCurrentProcessID(), Host::GetCurrentThreadID(), &m_mutex, err);
return err;
}
@@ -356,6 +353,38 @@
assert (m_failure_message.empty());
return Mutex::Unlock();
}
+
+int
+LoggingMutex::Lock ()
+{
+ printf("locking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+ int x = Mutex::Lock();
+ m_locked = true;
+ printf("%d\n",x);
+ return x;
+}
+
+int
+LoggingMutex::Unlock ()
+{
+ printf("unlocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+ int x = Mutex::Unlock();
+ m_locked = false;
+ printf("%d\n",x);
+ return x;
+}
+
+int
+LoggingMutex::TryLock (const char *failure_message)
+{
+ printf("trylocking mutex %p by [%4.4" PRIx64 "/%4.4" PRIx64 "]...", this, Host::GetCurrentProcessID(), Host::GetCurrentThreadID());
+ int x = Mutex::TryLock(failure_message);
+ if (x == 0)
+ m_locked = true;
+ printf("%d\n",x);
+ return x;
+}
+
#endif
-
+
Index: aze/lldb/source/Host/common/Terminal.cpp
===================================================================
--- aze.orig/lldb/source/Host/common/Terminal.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/common/Terminal.cpp 2013-03-03 09:35:50.191457353 +0100
@@ -120,6 +120,15 @@
{
}
+void
+TerminalState::Clear ()
+{
+ m_tty.Clear();
+ m_tflags = -1;
+ m_termios_ap.reset();
+ m_process_group = -1;
+}
+
//----------------------------------------------------------------------
// Save the current state of the TTY for the file descriptor "fd"
// and if "save_process_group" is true, attempt to save the process
Index: aze/lldb/source/Host/freebsd/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Host/freebsd/CMakeLists.txt 2013-03-03 09:35:50.191457353 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbHostFreeBSD
+ Host.cpp
+ )
Index: aze/lldb/source/Host/linux/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Host/linux/CMakeLists.txt 2013-03-03 09:35:50.191457353 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbHostLinux
+ Host.cpp
+ )
Index: aze/lldb/source/Host/linux/Host.cpp
===================================================================
--- aze.orig/lldb/source/Host/linux/Host.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/linux/Host.cpp 2013-03-03 09:35:50.191457353 +0100
@@ -65,7 +65,7 @@
// dynamically generated by the kernel) which is incompatible with the
// current ReadFileContents implementation. Therefore we simply stream the
// data into a DataBuffer ourselves.
- if (snprintf(path, path_size, "/proc/%d/auxv", process->GetID()) < 0)
+ if (snprintf(path, path_size, "/proc/%" PRIu64 "/auxv", process->GetID()) < 0)
return buf_sp;
if ((fd = open(path, O_RDONLY, 0)) < 0)
Index: aze/lldb/source/Host/macosx/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Host/macosx/CMakeLists.txt 2013-03-03 09:35:50.191457353 +0100
@@ -0,0 +1,6 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbHostMacOSX
+ Host.cpp
+ Symbols.cpp
+ )
Index: aze/lldb/source/Host/macosx/Host.mm
===================================================================
--- aze.orig/lldb/source/Host/macosx/Host.mm 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/macosx/Host.mm 2013-03-03 09:35:50.191457353 +0100
@@ -1079,7 +1079,7 @@
if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
{
DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *));
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t argc = data.GetU32 (&offset);
const char *cstr;
@@ -1377,7 +1377,7 @@
return error;
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
-
+
uid_t requested_uid = launch_info.GetUserID();
const char *xpc_service = nil;
bool send_auth = false;
@@ -1394,7 +1394,7 @@
}
else
{
- error.SetError(4, eErrorTypeGeneric);
+ error.SetError(3, eErrorTypeGeneric);
error.SetErrorStringWithFormat("Launching root via XPC needs to externalize authorization reference.");
if (log)
{
@@ -1406,7 +1406,7 @@
}
else
{
- error.SetError(3, eErrorTypeGeneric);
+ error.SetError(4, eErrorTypeGeneric);
error.SetErrorStringWithFormat("Launching via XPC is only currently available for either the login user or root.");
if (log)
{
@@ -1422,7 +1422,7 @@
if (type == XPC_TYPE_ERROR) {
if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
- // The service has either canceled itself, crashed, or been terminated.
+ // The service has either canceled itself, crashed, or been terminated.
// The XPC connection is still valid and sending a message to it will re-launch the service.
// If the service is state-full, this is the time to initialize the new service.
return;
@@ -1435,12 +1435,12 @@
// printf("Unexpected error from service: %s", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
}
- } else {
+ } else {
// printf("Received unexpected event in handler");
}
});
- xpc_connection_set_finalizer_f (conn, xpc_finalizer_t(xpc_release));
+ xpc_connection_set_finalizer_f (conn, xpc_finalizer_t(xpc_release));
xpc_connection_resume (conn);
xpc_object_t message = xpc_dictionary_create (nil, nil, 0);
@@ -1457,24 +1457,36 @@
xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, GetPosixspawnFlags(launch_info));
xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, message);
-
- pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey);
- if (pid == 0)
+ xpc_type_t returnType = xpc_get_type(reply);
+ if (returnType == XPC_TYPE_DICTIONARY)
{
- int errorType = xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey);
- int errorCode = xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey);
-
- error.SetError(errorCode, eErrorTypeGeneric);
- error.SetErrorStringWithFormat("Problems with launching via XPC. Error type : %i, code : %i", errorType, errorCode);
- if (log)
+ pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey);
+ if (pid == 0)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ int errorType = xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey);
+ int errorCode = xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey);
+
+ error.SetError(errorCode, eErrorTypeGeneric);
+ error.SetErrorStringWithFormat("Problems with launching via XPC. Error type : %i, code : %i", errorType, errorCode);
+ if (log)
+ {
+ error.PutToLog(log.get(), "%s", error.AsCString());
+ }
+
+ if (authorizationRef)
+ {
+ AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
+ authorizationRef = NULL;
+ }
}
-
- if (authorizationRef)
+ }
+ else if (returnType == XPC_TYPE_ERROR)
+ {
+ error.SetError(5, eErrorTypeGeneric);
+ error.SetErrorStringWithFormat("Problems with launching via XPC. XPC error : %s", xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION));
+ if (log)
{
- AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
- authorizationRef = NULL;
+ error.PutToLog(log.get(), "%s", error.AsCString());
}
}
Index: aze/lldb/source/Host/macosx/Symbols.cpp
===================================================================
--- aze.orig/lldb/source/Host/macosx/Symbols.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Host/macosx/Symbols.cpp 2013-03-03 09:35:50.191457353 +0100
@@ -58,7 +58,7 @@
const lldb_private::UUID *uuid, // the UUID we are looking for
off_t file_offset,
DataExtractor& data,
- uint32_t data_offset,
+ lldb::offset_t data_offset,
const uint32_t magic
)
{
@@ -83,7 +83,7 @@
{
ArchSpec file_arch(eArchTypeMachO, cputype, cpusubtype);
- if (file_arch != *arch)
+ if (!file_arch.IsCompatibleMatch(*arch))
return false;
}
@@ -116,7 +116,7 @@
for (i=0; i<ncmds; i++)
{
- const uint32_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry!
+ const lldb::offset_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry!
uint32_t cmd = data.GetU32(&data_offset);
uint32_t cmd_size = data.GetU32(&data_offset);
if (cmd == LoadCommandUUID)
@@ -124,18 +124,6 @@
lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
if (file_uuid == *uuid)
return true;
-
- // Emit some warning messages since the UUIDs do not match!
- char path_buf[PATH_MAX];
- path_buf[0] = '\0';
- const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf
- : file_spec.GetFilename().AsCString();
- StreamString ss_m_uuid, ss_o_uuid;
- uuid->Dump(&ss_m_uuid);
- file_uuid.Dump(&ss_o_uuid);
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: UUID mismatch detected between binary (%s) and:\n\t'%s' (%s)\n",
- ss_m_uuid.GetData(), path, ss_o_uuid.GetData());
return false;
}
data_offset = cmd_offset + cmd_size;
@@ -151,7 +139,7 @@
const lldb_private::UUID *uuid,
off_t file_offset,
DataExtractor& data,
- uint32_t data_offset,
+ lldb::offset_t data_offset,
const uint32_t magic
)
{
@@ -181,7 +169,7 @@
if (arch)
{
ArchSpec fat_arch(eArchTypeMachO, arch_cputype, arch_cpusubtype);
- if (fat_arch != *arch)
+ if (!fat_arch.IsExactMatch(*arch))
continue;
}
@@ -189,7 +177,7 @@
DataExtractor arch_data;
DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));
arch_data.SetData(data_buffer_sp);
- uint32_t arch_data_offset = 0;
+ lldb::offset_t arch_data_offset = 0;
uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
switch (arch_magic)
@@ -222,7 +210,7 @@
{
data.SetData(data_buffer_sp);
- uint32_t data_offset = 0;
+ lldb::offset_t data_offset = 0;
uint32_t magic = data.GetU32(&data_offset);
switch (magic)
@@ -701,7 +689,7 @@
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
if (!g_dsym_for_uuid_exe_exists)
{
- int bufsize;
+ long bufsize;
if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1)
{
char buffer[bufsize];
@@ -770,7 +758,7 @@
CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
- if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
+ if (plist.get() && CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
{
if (uuid_cstr)
{
@@ -797,7 +785,7 @@
ModuleSpec curr_module_spec;
if (GetModuleSpecInfoFromUUIDDictionary (values[i], curr_module_spec))
{
- if (module_spec.GetArchitecture() == curr_module_spec.GetArchitecture())
+ if (module_spec.GetArchitecture().IsCompatibleMatch(curr_module_spec.GetArchitecture()))
{
module_spec = curr_module_spec;
return true;
Index: aze/lldb/source/Interpreter/Args.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/Args.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/Args.cpp 2013-03-03 09:35:50.191457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <getopt.h>
#include <cstdlib>
@@ -14,12 +16,17 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/Args.h"
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+//#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+//#include "lldb/Target/Thread.h"
using namespace lldb;
using namespace lldb_private;
@@ -91,15 +98,15 @@
void
Args::Dump (Stream *s)
{
- const int argc = m_argv.size();
- for (int i=0; i<argc; ++i)
+ const size_t argc = m_argv.size();
+ for (size_t i=0; i<argc; ++i)
{
s->Indent();
const char *arg_cstr = m_argv[i];
if (arg_cstr)
- s->Printf("argv[%i]=\"%s\"\n", i, arg_cstr);
+ s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr);
else
- s->Printf("argv[%i]=NULL\n", i);
+ s->Printf("argv[%zi]=NULL\n", i);
}
s->EOL();
}
@@ -108,8 +115,8 @@
Args::GetCommandString (std::string &command) const
{
command.clear();
- int argc = GetArgumentCount();
- for (int i=0; i<argc; ++i)
+ const size_t argc = GetArgumentCount();
+ for (size_t i=0; i<argc; ++i)
{
if (i > 0)
command += ' ';
@@ -122,7 +129,7 @@
Args::GetQuotedCommandString (std::string &command) const
{
command.clear ();
- size_t argc = GetArgumentCount ();
+ const size_t argc = GetArgumentCount();
for (size_t i = 0; i < argc; ++i)
{
if (i > 0)
@@ -564,7 +571,7 @@
}
void
-Args::SetArguments (int argc, const char **argv)
+Args::SetArguments (size_t argc, const char **argv)
{
// m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
// no need to clear it here.
@@ -625,13 +632,16 @@
{
if (long_options[i].flag == NULL)
{
- sstr << (char)long_options[i].val;
- switch (long_options[i].has_arg)
+ if (isprint8(long_options[i].val))
{
- default:
- case no_argument: break;
- case required_argument: sstr << ':'; break;
- case optional_argument: sstr << "::"; break;
+ sstr << (char)long_options[i].val;
+ switch (long_options[i].has_arg)
+ {
+ default:
+ case no_argument: break;
+ case required_argument: sstr << ':'; break;
+ case optional_argument: sstr << "::"; break;
+ }
}
}
}
@@ -645,7 +655,10 @@
while (1)
{
int long_options_index = -1;
- val = ::getopt_long(GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
+ val = ::getopt_long(GetArgumentCount(),
+ GetArgumentVector(),
+ sstr.GetData(),
+ long_options,
&long_options_index);
if (val == -1)
break;
@@ -710,11 +723,12 @@
if (s && s[0])
{
char *end = NULL;
- int32_t uval = ::strtol (s, &end, base);
+ const long sval = ::strtol (s, &end, base);
if (*end == '\0')
{
- if (success_ptr) *success_ptr = true;
- return uval; // All characters were used, return the result
+ if (success_ptr)
+ *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN));
+ return (int32_t)sval; // All characters were used, return the result
}
}
if (success_ptr) *success_ptr = false;
@@ -727,11 +741,12 @@
if (s && s[0])
{
char *end = NULL;
- uint32_t uval = ::strtoul (s, &end, base);
+ const unsigned long uval = ::strtoul (s, &end, base);
if (*end == '\0')
{
- if (success_ptr) *success_ptr = true;
- return uval; // All characters were used, return the result
+ if (success_ptr)
+ *success_ptr = (uval <= UINT32_MAX);
+ return (uint32_t)uval; // All characters were used, return the result
}
}
if (success_ptr) *success_ptr = false;
@@ -774,26 +789,119 @@
}
lldb::addr_t
-Args::StringToAddress (const char *s, lldb::addr_t fail_value, bool *success_ptr)
+Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr)
{
+ bool error_set = false;
if (s && s[0])
{
char *end = NULL;
lldb::addr_t addr = ::strtoull (s, &end, 0);
if (*end == '\0')
{
- if (success_ptr) *success_ptr = true;
+ if (error_ptr)
+ error_ptr->Clear();
return addr; // All characters were used, return the result
}
// Try base 16 with no prefix...
addr = ::strtoull (s, &end, 16);
if (*end == '\0')
{
- if (success_ptr) *success_ptr = true;
+ if (error_ptr)
+ error_ptr->Clear();
return addr; // All characters were used, return the result
}
+
+ if (exe_ctx)
+ {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
+ {
+ lldb::ValueObjectSP valobj_sp;
+ EvaluateExpressionOptions options;
+ options.SetCoerceToId(false);
+ options.SetUnwindOnError(true);
+ options.SetKeepInMemory(false);
+ options.SetRunOthers(true);
+
+ ExecutionResults expr_result = target->EvaluateExpression(s,
+ exe_ctx->GetFramePtr(),
+ valobj_sp,
+ options);
+
+ bool success = false;
+ if (expr_result == eExecutionCompleted)
+ {
+ // Get the address to watch.
+ addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
+ if (success)
+ {
+ if (error_ptr)
+ error_ptr->Clear();
+ return addr;
+ }
+ else
+ {
+ if (error_ptr)
+ {
+ error_set = true;
+ error_ptr->SetErrorStringWithFormat("address expression \"%s\" resulted in a value whose type can't be converted to an address: %s", s, valobj_sp->GetTypeName().GetCString());
+ }
+ }
+
+ }
+ else
+ {
+ // Since the compiler can't handle things like "main + 12" we should
+ // try to do this for now. The compliler doesn't like adding offsets
+ // to function pointer types.
+ RegularExpression symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+ if (symbol_plus_offset_regex.Execute(s, 3))
+ {
+ uint64_t offset = 0;
+ bool add = true;
+ std::string name;
+ std::string str;
+ if (symbol_plus_offset_regex.GetMatchAtIndex(s, 1, name))
+ {
+ if (symbol_plus_offset_regex.GetMatchAtIndex(s, 2, str))
+ {
+ add = str[0] == '+';
+
+ if (symbol_plus_offset_regex.GetMatchAtIndex(s, 3, str))
+ {
+ offset = Args::StringToUInt64(str.c_str(), 0, 0, &success);
+
+ if (success)
+ {
+ Error error;
+ addr = StringToAddress (exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error);
+ if (addr != LLDB_INVALID_ADDRESS)
+ {
+ if (add)
+ return addr + offset;
+ else
+ return addr - offset;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (error_ptr)
+ {
+ error_set = true;
+ error_ptr->SetErrorStringWithFormat("address expression \"%s\" evaluation failed", s);
+ }
+ }
+ }
+ }
+ }
+ if (error_ptr)
+ {
+ if (!error_set)
+ error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s);
}
- if (success_ptr) *success_ptr = false;
return fail_value;
}
@@ -835,8 +943,7 @@
if (s && s[0])
{
char *pos = NULL;
- uint32_t uval32;
- uval32 = ::strtoul (s, &pos, 0);
+ unsigned long uval32 = ::strtoul (s, &pos, 0);
if (pos == s)
return s;
major = uval32;
@@ -886,7 +993,7 @@
}
-int32_t
+int64_t
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
{
if (enum_values)
@@ -946,7 +1053,7 @@
(
const char *s,
lldb::Format &format,
- uint32_t *byte_size_ptr
+ size_t *byte_size_ptr
)
{
format = eFormatInvalid;
@@ -1092,7 +1199,7 @@
{
char short_buffer[3];
char long_buffer[255];
- ::snprintf (short_buffer, sizeof (short_buffer), "-%c", (char) long_options[long_options_index].val);
+ ::snprintf (short_buffer, sizeof (short_buffer), "-%c", long_options[long_options_index].val);
::snprintf (long_buffer, sizeof (long_buffer), "--%s", long_options[long_options_index].name);
size_t end = GetArgumentCount ();
size_t idx = 0;
@@ -1216,7 +1323,7 @@
if (long_options_index >= 0)
{
StreamString option_str;
- option_str.Printf ("-%c", (char) val);
+ option_str.Printf ("-%c", val);
switch (long_options[long_options_index].has_arg)
{
@@ -1256,16 +1363,14 @@
}
break;
default:
- result.AppendErrorWithFormat
- ("error with options table; invalid value in has_arg field for option '%c'.\n",
- (char) val);
+ result.AppendErrorWithFormat ("error with options table; invalid value in has_arg field for option '%c'.\n", val);
result.SetStatus (eReturnStatusFailed);
break;
}
}
else
{
- result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", (char) val);
+ result.AppendErrorWithFormat ("Invalid option with value '%c'.\n", val);
result.SetStatus (eReturnStatusFailed);
}
@@ -1570,8 +1675,7 @@
unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
if (octal_value <= UINT8_MAX)
{
- const char octal_char = octal_value;
- dst.append(1, octal_char);
+ dst.append(1, (char)octal_value);
}
}
break;
@@ -1622,7 +1726,7 @@
{
for (const char *p = src; *p != '\0'; ++p)
{
- if (isprint(*p))
+ if (isprint8(*p))
dst.append(1, *p);
else
{
Index: aze/lldb/source/Interpreter/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Interpreter/CMakeLists.txt 2013-03-03 09:35:50.191457353 +0100
@@ -0,0 +1,45 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbInterpreter
+ Args.cpp
+ CommandInterpreter.cpp
+ CommandObject.cpp
+ CommandObjectRegexCommand.cpp
+ CommandObjectScript.cpp
+ CommandReturnObject.cpp
+ OptionGroupArchitecture.cpp
+ OptionGroupBoolean.cpp
+ OptionGroupFile.cpp
+ OptionGroupFormat.cpp
+ OptionGroupOutputFile.cpp
+ OptionGroupPlatform.cpp
+ OptionGroupString.cpp
+ OptionGroupUInt64.cpp
+ OptionGroupUUID.cpp
+ OptionGroupValueObjectDisplay.cpp
+ OptionValue.cpp
+ OptionValueArch.cpp
+ OptionValueArgs.cpp
+ OptionValueArray.cpp
+ OptionValueBoolean.cpp
+ OptionValueDictionary.cpp
+ OptionValueEnumeration.cpp
+ OptionValueFileSpec.cpp
+ OptionValueFileSpecLIst.cpp
+ OptionValueFormat.cpp
+ OptionValuePathMappings.cpp
+ OptionValueProperties.cpp
+ OptionValueRegex.cpp
+ OptionValueSInt64.cpp
+ OptionValueString.cpp
+ OptionValueUInt64.cpp
+ OptionValueUUID.cpp
+ OptionGroupVariable.cpp
+ OptionGroupWatchpoint.cpp
+ Options.cpp
+ Property.cpp
+ PythonDataObjects.cpp
+ ScriptInterpreter.cpp
+ ScriptInterpreterNone.cpp
+ ScriptInterpreterPython.cpp
+ )
Index: aze/lldb/source/Interpreter/CommandInterpreter.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/CommandInterpreter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/CommandInterpreter.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include <string>
#include <vector>
@@ -70,12 +72,14 @@
g_properties[] =
{
{ "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." },
+ { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." },
{ NULL , OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL }
};
enum
{
- ePropertyExpandRegexAliases = 0
+ ePropertyExpandRegexAliases = 0,
+ ePropertyPromptOnQuit = 1
};
ConstString &
@@ -119,7 +123,12 @@
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
}
-
+bool
+CommandInterpreter::GetPromptOnQuit () const
+{
+ const uint32_t idx = ePropertyPromptOnQuit;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
void
CommandInterpreter::Initialize ()
@@ -211,13 +220,19 @@
AddAlias ("t", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact ("source list", false);
+ cmd_obj_sp = GetCommandSPExact ("_regexp-list", false);
if (cmd_obj_sp)
{
AddAlias ("l", cmd_obj_sp);
AddAlias ("list", cmd_obj_sp);
}
+ cmd_obj_sp = GetCommandSPExact ("_regexp-env", false);
+ if (cmd_obj_sp)
+ {
+ AddAlias ("env", cmd_obj_sp);
+ }
+
cmd_obj_sp = GetCommandSPExact ("memory read", false);
if (cmd_obj_sp)
AddAlias ("x", cmd_obj_sp);
@@ -277,7 +292,7 @@
AddOrReplaceAliasOptions ("call", alias_arguments_vector_sp);
alias_arguments_vector_sp.reset (new OptionArgVector);
- ProcessAliasOptionsArgs (cmd_obj_sp, "-o --", alias_arguments_vector_sp);
+ ProcessAliasOptionsArgs (cmd_obj_sp, "-O --", alias_arguments_vector_sp);
AddAlias ("po", cmd_obj_sp);
AddOrReplaceAliasOptions ("po", alias_arguments_vector_sp);
}
@@ -340,34 +355,15 @@
{
Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
- //
- // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref)
- // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use
- // the cross-referencing stuff) are created!!!
- //
- // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
-
-
- // Command objects that inherit from CommandObjectCrossref must be created before other command objects
- // are created. This is so that when another command is created that needs to go into a crossref object,
- // the crossref object exists and is ready to take the cross reference. Put the cross referencing command
- // objects into the CommandDictionary now, so they are ready for use when the other commands get created.
-
- // Non-CommandObjectCrossref commands can now be created.
-
lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this));
m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
- //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall (*this));
m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
-// m_command_dict["file"] = CommandObjectSP (new CommandObjectFile (*this));
m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this));
- /// m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this));
m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this));
m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this));
m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this));
@@ -386,10 +382,11 @@
const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
{"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
- {"^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
- {"^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
+ {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
+ {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
{"^(-.*)$", "breakpoint set %1"},
{"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"},
+ {"^\\&(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1' --skip-prologue=0"},
{"^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"}};
size_t num_regexes = sizeof break_regexes/sizeof(char *[2]);
@@ -453,8 +450,10 @@
"_regexp-attach [<pid>]\n_regexp-attach [<process-name>]", 2));
if (attach_regex_cmd_ap.get())
{
- if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)$", "process attach --pid %1") &&
- attach_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*$", "process attach --name '%1'"))
+ if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
+ attach_regex_cmd_ap->AddRegexCommand("^(-.*|.* -.*)$", "process attach %1") && // Any options that are specified get passed to 'process attach'
+ attach_regex_cmd_ap->AddRegexCommand("^(.+)$", "process attach --name '%1'") &&
+ attach_regex_cmd_ap->AddRegexCommand("^$", "process attach"))
{
CommandObjectSP attach_regex_cmd_sp(attach_regex_cmd_ap.release());
m_command_dict[attach_regex_cmd_sp->GetCommandName ()] = attach_regex_cmd_sp;
@@ -569,6 +568,40 @@
}
}
+ std::auto_ptr<CommandObjectRegexCommand>
+ list_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+ "_regexp-list",
+ "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.",
+ "_regexp-list [<line>]\n_regexp-attach [<file>:<line>]\n_regexp-attach [<file>:<line>]", 2));
+ if (list_regex_cmd_ap.get())
+ {
+ if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") &&
+ list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") &&
+ list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") &&
+ list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", "source list --reverse") &&
+ list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") &&
+ list_regex_cmd_ap->AddRegexCommand("^$", "source list"))
+ {
+ CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release());
+ m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp;
+ }
+ }
+
+ std::auto_ptr<CommandObjectRegexCommand>
+ env_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+ "_regexp-env",
+ "Implements a shortcut to viewing and setting environment variables.",
+ "_regexp-env\n_regexp-env FOO=BAR", 2));
+ if (env_regex_cmd_ap.get())
+ {
+ if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") &&
+ env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1"))
+ {
+ CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release());
+ m_command_dict[env_regex_cmd_sp->GetCommandName ()] = env_regex_cmd_sp;
+ }
+ }
+
}
int
@@ -589,7 +622,7 @@
CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
{
CommandObject::CommandMap::iterator pos;
- CommandObjectSP ret_val;
+ CommandObjectSP command_sp;
std::string cmd(cmd_cstr);
@@ -597,24 +630,24 @@
{
pos = m_command_dict.find(cmd);
if (pos != m_command_dict.end())
- ret_val = pos->second;
+ command_sp = pos->second;
}
if (include_aliases && HasAliases())
{
pos = m_alias_dict.find(cmd);
if (pos != m_alias_dict.end())
- ret_val = pos->second;
+ command_sp = pos->second;
}
if (HasUserCommands())
{
pos = m_user_dict.find(cmd);
if (pos != m_user_dict.end())
- ret_val = pos->second;
+ command_sp = pos->second;
}
- if (!exact && !ret_val)
+ if (!exact && !command_sp)
{
// We will only get into here if we didn't find any exact matches.
@@ -684,13 +717,13 @@
return user_match_sp;
}
}
- else if (matches && ret_val)
+ else if (matches && command_sp)
{
matches->AppendString (cmd_cstr);
}
- return ret_val;
+ return command_sp;
}
bool
@@ -860,7 +893,7 @@
options_string)));
else
{
- int argc = args.GetArgumentCount();
+ const size_t argc = args.GetArgumentCount();
for (size_t i = 0; i < argc; ++i)
if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
option_arg_vector->push_back
@@ -970,7 +1003,7 @@
uint32_t cmd_types)
{
CommandObject::CommandMap::const_iterator pos;
- uint32_t max_len = FindLongestCommandWord (m_command_dict);
+ size_t max_len = FindLongestCommandWord (m_command_dict);
if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
{
@@ -1316,6 +1349,7 @@
EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
+ .SetIgnoreBreakpoints(true)
.SetKeepInMemory(false)
.SetRunOthers(true)
.SetTimeoutUsec(0);
@@ -1371,6 +1405,9 @@
case eExecutionInterrupted:
error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
break;
+ case eExecutionHitBreakpoint:
+ error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
+ break;
case eExecutionTimedOut:
error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
break;
@@ -1580,21 +1617,15 @@
if (cmd_obj == NULL)
{
- uint32_t num_matches = matches.GetSize();
+ const size_t num_matches = matches.GetSize();
if (matches.GetSize() > 1) {
- std::string error_msg;
- error_msg.assign ("Ambiguous command '");
- error_msg.append(next_word.c_str());
- error_msg.append ("'.");
-
- error_msg.append (" Possible matches:");
+ StreamString error_msg;
+ error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
for (uint32_t i = 0; i < num_matches; ++i) {
- error_msg.append ("\n\t");
- error_msg.append (matches.GetStringAtIndex(i));
+ error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
}
- error_msg.append ("\n");
- result.AppendRawError (error_msg.c_str(), error_msg.size());
+ result.AppendRawError (error_msg.GetString().c_str());
} else {
// We didn't have only one match, otherwise we wouldn't get here.
assert(num_matches == 0);
@@ -1762,7 +1793,7 @@
error_msg.append (matches.GetStringAtIndex (i));
}
error_msg.append ("\n");
- result.AppendRawError (error_msg.c_str(), error_msg.size());
+ result.AppendRawError (error_msg.c_str());
}
else
result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
@@ -1942,7 +1973,7 @@
std::string common_prefix;
matches.LongestCommonPrefix (common_prefix);
- int partial_name_len = command_partial_str.size();
+ const size_t partial_name_len = command_partial_str.size();
// If we matched a unique single command, add a space...
// Only do this if the completer told us this was a complete word, however...
@@ -2089,20 +2120,6 @@
return response;
}
-
-void
-CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
-{
- CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true);
-
- if (cmd_obj_sp)
- {
- CommandObject *cmd_obj = cmd_obj_sp.get();
- if (cmd_obj->IsCrossRefObject ())
- cmd_obj->AddObject (object_type);
- }
-}
-
OptionArgVectorSP
CommandInterpreter::GetAliasOptions (const char *alias_name)
{
@@ -2196,7 +2213,7 @@
}
OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
- int old_size = cmd_args.GetArgumentCount();
+ const size_t old_size = cmd_args.GetArgumentCount();
std::vector<bool> used (old_size + 1, false);
used[0] = true;
@@ -2587,8 +2604,6 @@
case eScriptLanguageNone:
m_script_interpreter_ap.reset (new ScriptInterpreterNone (*this));
break;
- default:
- break;
};
return m_script_interpreter_ap.get();
@@ -2613,7 +2628,7 @@
const char *word_text,
const char *separator,
const char *help_text,
- uint32_t max_word_len)
+ size_t max_word_len)
{
const uint32_t max_columns = m_debugger.GetTerminalWidth();
@@ -2622,7 +2637,7 @@
strm.IndentMore (indent_size);
StreamString text_strm;
- text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text);
+ text_strm.Printf ("%-*s %s %s", (int)max_word_len, word_text, separator, help_text);
size_t len = text_strm.GetSize();
const char *text = text_strm.GetData();
@@ -2642,10 +2657,9 @@
// We need to break it up into multiple lines.
bool first_line = true;
int text_width;
- int start = 0;
- int end = start;
- int final_end = strlen (text);
- int sub_len;
+ size_t start = 0;
+ size_t end = start;
+ const size_t final_end = strlen (text);
while (end < final_end)
{
@@ -2673,7 +2687,7 @@
assert (end > 0);
}
- sub_len = end - start;
+ const size_t sub_len = end - start;
if (start != 0)
strm.EOL();
if (!first_line)
@@ -2782,7 +2796,7 @@
void
CommandInterpreter::DumpHistory (Stream &stream, uint32_t start, uint32_t end) const
{
- const size_t last_idx = std::min<size_t>(m_command_history.size(), end + 1);
+ const size_t last_idx = std::min<size_t>(m_command_history.size(), end==UINT32_MAX ? UINT32_MAX : end + 1);
for (size_t i = start; i < last_idx; i++)
{
if (!m_command_history[i].empty())
@@ -2801,7 +2815,7 @@
if (input_str[1] == '-')
{
bool success;
- uint32_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
+ size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
if (!success)
return NULL;
if (idx > m_command_history.size())
Index: aze/lldb/source/Interpreter/CommandObject.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/CommandObject.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/CommandObject.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/CommandObject.h"
#include <string>
@@ -206,8 +208,77 @@
bool
-CommandObject::CheckFlags (CommandReturnObject &result)
+CommandObject::CheckRequirements (CommandReturnObject &result)
{
+#ifdef LLDB_CONFIGURATION_DEBUG
+ // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx
+ // has shared pointers to the target, process, thread and frame and we don't
+ // want any CommandObject instances to keep any of these objects around
+ // longer than for a single command. Every command should call
+ // CommandObject::Cleanup() after it has completed
+ assert (m_exe_ctx.GetTargetPtr() == NULL);
+ assert (m_exe_ctx.GetProcessPtr() == NULL);
+ assert (m_exe_ctx.GetThreadPtr() == NULL);
+ assert (m_exe_ctx.GetFramePtr() == NULL);
+#endif
+
+ // Lock down the interpreter's execution context prior to running the
+ // command so we guarantee the selected target, process, thread and frame
+ // can't go away during the execution
+ m_exe_ctx = m_interpreter.GetExecutionContext();
+
+ const uint32_t flags = GetFlags().Get();
+ if (flags & (eFlagRequiresTarget |
+ eFlagRequiresProcess |
+ eFlagRequiresThread |
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock ))
+ {
+
+ if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+ {
+ result.AppendError (GetInvalidTargetDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+ {
+ result.AppendError (GetInvalidProcessDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+ {
+ result.AppendError (GetInvalidThreadDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+ {
+ result.AppendError (GetInvalidFrameDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == NULL))
+ {
+ result.AppendError (GetInvalidRegContextDescription());
+ return false;
+ }
+
+ if (flags & eFlagTryTargetAPILock)
+ {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target)
+ {
+ if (m_api_locker.TryLock (target->GetAPIMutex(), NULL) == false)
+ {
+ result.AppendError ("failed to get API lock");
+ return false;
+ }
+ }
+ }
+ }
+
if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
{
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
@@ -261,6 +332,14 @@
return true;
}
+void
+CommandObject::Cleanup ()
+{
+ m_exe_ctx.Clear();
+ m_api_locker.Unlock();
+}
+
+
class CommandDictCommandPartialMatch
{
public:
@@ -272,13 +351,9 @@
{
// A NULL or empty string matches everything.
if (m_match_str == NULL || *m_match_str == '\0')
- return 1;
+ return true;
- size_t found = map_element.first.find (m_match_str, 0);
- if (found == std::string::npos)
- return 0;
- else
- return found == 0;
+ return map_element.first.find (m_match_str, 0) == 0;
}
private:
@@ -752,9 +827,9 @@
StreamString sstr;
sstr << "One of the following languages:\n";
- for (LanguageType l = eLanguageTypeUnknown; l < eNumLanguageTypes; ++l)
+ for (unsigned int l = eLanguageTypeUnknown; l < eNumLanguageTypes; ++l)
{
- sstr << " " << LanguageRuntime::GetNameForLanguageType(l) << "\n";
+ sstr << " " << LanguageRuntime::GetNameForLanguageType(static_cast<LanguageType>(l)) << "\n";
}
sstr.Flush();
@@ -886,14 +961,16 @@
cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
}
- if (!CheckFlags(result))
- return false;
-
- if (!ParseOptions (cmd_args, result))
- return false;
+ if (CheckRequirements(result))
+ {
+ if (ParseOptions (cmd_args, result))
+ {
+ // Call the command-specific version of 'Execute', passing it the already processed arguments.
+ handled = DoExecute (cmd_args, result);
+ }
+ }
- // Call the command-specific version of 'Execute', passing it the already processed arguments.
- handled = DoExecute (cmd_args, result);
+ Cleanup();
}
return handled;
}
@@ -914,10 +991,10 @@
}
if (!handled)
{
- if (!CheckFlags(result))
- return false;
- else
+ if (CheckRequirements(result))
handled = DoExecute (args_string, result);
+
+ Cleanup();
}
return handled;
}
@@ -940,6 +1017,7 @@
CommandObject::g_arguments_data[] =
{
{ eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { NULL, false }, "A valid address in the target program's execution space." },
+ { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { NULL, false }, "An expression that resolves to an address." },
{ eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of an abbreviation (alias) for a debugger command." },
{ eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { NULL, false }, "Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.)" },
{ eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
@@ -951,6 +1029,7 @@
{ eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
{ eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
{ eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { NULL, false }, "A directory name." },
+ { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { NULL, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
{ eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
Index: aze/lldb/source/Interpreter/CommandObjectRegexCommand.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/CommandObjectRegexCommand.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/CommandObjectRegexCommand.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/CommandObjectRegexCommand.h"
// C Includes
Index: aze/lldb/source/Interpreter/CommandObjectScript.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/CommandObjectScript.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/CommandObjectScript.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "CommandObjectScript.h"
// C Includes
@@ -14,13 +16,14 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
using namespace lldb;
using namespace lldb_private;
@@ -33,8 +36,7 @@
CommandObjectRaw (interpreter,
"script",
"Pass an expression to the script interpreter for evaluation and return the results. Drop into the interactive interpreter if no expression is given.",
- "script [<script-expression-for-evaluation>]"),
- m_script_lang (script_lang)
+ "script [<script-expression-for-evaluation>]")
{
}
@@ -49,6 +51,19 @@
CommandReturnObject &result
)
{
+#ifdef LLDB_DISABLE_PYTHON
+ // if we ever support languages other than Python this simple #ifdef won't work
+ result.AppendError("your copy of LLDB does not support scripting.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+#else
+ if (m_interpreter.GetDebugger().GetScriptLanguage() == lldb::eScriptLanguageNone)
+ {
+ result.AppendError("the script-lang setting is set to none - scripting not available");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
ScriptInterpreter *script_interpreter = m_interpreter.GetScriptInterpreter ();
if (script_interpreter == NULL)
@@ -74,4 +89,5 @@
result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
+#endif
}
Index: aze/lldb/source/Interpreter/CommandObjectScript.h
===================================================================
--- aze.orig/lldb/source/Interpreter/CommandObjectScript.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/CommandObjectScript.h 2013-03-03 09:35:50.195457352 +0100
@@ -35,9 +35,6 @@
protected:
virtual bool
DoExecute (const char *command, CommandReturnObject &result);
-
-private:
- lldb::ScriptLanguage m_script_lang;
};
} // namespace lldb_private
Index: aze/lldb/source/Interpreter/CommandReturnObject.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/CommandReturnObject.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/CommandReturnObject.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -104,47 +104,37 @@
}
void
-CommandReturnObject::AppendMessage (const char *in_string, int len)
+CommandReturnObject::AppendMessage (const char *in_string)
{
- if (!in_string || len == 0)
+ if (!in_string || *in_string == '\0')
return;
- if (len < 0)
- GetOutputStream().Printf("%s\n", in_string);
- else
- GetOutputStream().Printf("%*.*s\n", len, len, in_string);
+ GetOutputStream().Printf("%s\n", in_string);
}
void
-CommandReturnObject::AppendWarning (const char *in_string, int len)
+CommandReturnObject::AppendWarning (const char *in_string)
{
- if (!in_string)
+ if (!in_string || *in_string == '\0')
return;
- if (len < 0)
- len = ::strlen (in_string);
- GetErrorStream().Printf("warning: %*.*s\n", len, len, in_string);
+ GetErrorStream().Printf("warning: %s\n", in_string);
}
// Similar to AppendWarning, but do not prepend 'warning: ' to message, and
// don't append "\n" to the end of it.
void
-CommandReturnObject::AppendRawWarning (const char *in_string, int len)
+CommandReturnObject::AppendRawWarning (const char *in_string)
{
- if (!in_string)
- return;
- if (len < 0)
- len = ::strlen (in_string);
- GetErrorStream().Printf("%*.*s", len, len, in_string);
+ if (in_string && in_string[0])
+ GetErrorStream().PutCString(in_string);
}
void
-CommandReturnObject::AppendError (const char *in_string, int len)
+CommandReturnObject::AppendError (const char *in_string)
{
- if (!in_string)
+ if (!in_string || *in_string == '\0')
return;
- if (len < 0)
- len = ::strlen (in_string);
- GetErrorStream().Printf ("error: %*.*s\n", len, len, in_string);
+ GetErrorStream().Printf ("error: %s\n", in_string);
}
void
@@ -160,13 +150,10 @@
// don't append "\n" to the end of it.
void
-CommandReturnObject::AppendRawError (const char *in_string, int len)
+CommandReturnObject::AppendRawError (const char *in_string)
{
- if (!in_string)
- return;
- if (len < 0)
- len = ::strlen (in_string);
- GetErrorStream().Printf ("%*.*s", len, len, in_string);
+ if (in_string && in_string[0])
+ GetErrorStream().PutCString(in_string);
}
void
Index: aze/lldb/source/Interpreter/Makefile
===================================================================
--- aze.orig/lldb/source/Interpreter/Makefile 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/Makefile 2013-03-03 09:35:50.195457352 +0100
@@ -16,6 +16,13 @@
include $(LLDB_LEVEL)/Makefile
-include $(PROJ_OBJ_DIR)/LLDBWrapPython.cpp.d
+# Drop -Wfour-char-constants, which we are not currently clean with.
+EXTRA_OPTIONS += -Wno-four-char-constants
+
+# Drop -Wself-assign, -Wmissing-field-initializers and -Wsometimes-uninitialized,
+# which we are not currently clean with (due to SWIG generated cpp source).
+EXTRA_OPTIONS += -Wno-missing-field-initializers -Wno-self-assign -Wno-sometimes-uninitialized
+
# edit-swig-python-wrapper-file.py needs $(SRCROOT)
export SRCROOT := $(PROJ_SRC_DIR)/$(LLDB_LEVEL)
Index: aze/lldb/source/Interpreter/OptionGroupArchitecture.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupArchitecture.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupArchitecture.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -62,7 +62,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
Index: aze/lldb/source/Interpreter/OptionGroupBoolean.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupBoolean.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupBoolean.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -20,7 +20,7 @@
OptionGroupBoolean::OptionGroupBoolean (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
const char *usage_text,
bool default_value,
bool no_argument_toggle_default) :
Index: aze/lldb/source/Interpreter/OptionGroupFile.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupFile.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupFile.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -20,7 +20,7 @@
OptionGroupFile::OptionGroupFile (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text) :
@@ -43,8 +43,8 @@
Error
OptionGroupFile::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error (m_file.SetValueFromCString (option_arg));
return error;
@@ -60,7 +60,7 @@
OptionGroupFileList::OptionGroupFileList (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text) :
@@ -83,8 +83,8 @@
Error
OptionGroupFileList::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error (m_file_list.SetValueFromCString (option_arg));
return error;
Index: aze/lldb/source/Interpreter/OptionGroupFormat.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupFormat.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupFormat.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,12 +7,18 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionGroupFormat.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/Utils.h"
using namespace lldb;
@@ -67,7 +73,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
@@ -119,7 +125,7 @@
Format format = eFormatDefault;
uint32_t byte_size = 0;
- while (ParserGDBFormatLetter (gdb_format_cstr[0], format, byte_size))
+ while (ParserGDBFormatLetter (interpreter, gdb_format_cstr[0], format, byte_size))
{
++gdb_format_cstr;
}
@@ -139,7 +145,7 @@
// Anything that wasn't set correctly should be set to the
// previous default
if (format == eFormatInvalid)
- ParserGDBFormatLetter (m_prev_gdb_format, format, byte_size);
+ ParserGDBFormatLetter (interpreter, m_prev_gdb_format, format, byte_size);
const bool byte_size_enabled = m_byte_size.GetDefaultValue() < UINT64_MAX;
const bool count_enabled = m_count.GetDefaultValue() < UINT64_MAX;
@@ -147,7 +153,7 @@
{
// Byte size is enabled
if (byte_size == 0)
- ParserGDBFormatLetter (m_prev_gdb_size, format, byte_size);
+ ParserGDBFormatLetter (interpreter, m_prev_gdb_size, format, byte_size);
}
else
{
@@ -199,8 +205,9 @@
}
bool
-OptionGroupFormat::ParserGDBFormatLetter (char format_letter, Format &format, uint32_t &byte_size)
+OptionGroupFormat::ParserGDBFormatLetter (CommandInterpreter &interpreter, char format_letter, Format &format, uint32_t &byte_size)
{
+ m_has_gdb_format = true;
switch (format_letter)
{
case 'o': format = eFormatOctal; m_prev_gdb_format = format_letter; return true;
@@ -209,7 +216,15 @@
case 'u': format = eFormatUnsigned; m_prev_gdb_format = format_letter; return true;
case 't': format = eFormatBinary; m_prev_gdb_format = format_letter; return true;
case 'f': format = eFormatFloat; m_prev_gdb_format = format_letter; return true;
- case 'a': format = eFormatAddressInfo; m_prev_gdb_format = format_letter; return true;
+ case 'a': format = eFormatAddressInfo;
+ {
+ ExecutionContext exe_ctx(interpreter.GetExecutionContext());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target)
+ byte_size = target->GetArchitecture().GetAddressByteSize();
+ m_prev_gdb_format = format_letter;
+ return true;
+ }
case 'i': format = eFormatInstruction; m_prev_gdb_format = format_letter; return true;
case 'c': format = eFormatChar; m_prev_gdb_format = format_letter; return true;
case 's': format = eFormatCString; m_prev_gdb_format = format_letter; return true;
@@ -230,4 +245,5 @@
m_format.Clear();
m_byte_size.Clear();
m_count.Clear();
+ m_has_gdb_format = false;
}
Index: aze/lldb/source/Interpreter/OptionGroupOutputFile.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupOutputFile.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupOutputFile.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -32,7 +32,7 @@
g_option_table[] =
{
{ LLDB_OPT_SET_1 , false, "outfile", 'o', required_argument, NULL, 0, eArgTypeFilename , "Specify a path for capturing command output."},
- { LLDB_OPT_SET_1 , false, "append-outfile" , 'A', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile <path>'."},
+ { LLDB_OPT_SET_1 , false, "append-outfile" , 'apnd', no_argument, NULL, 0, eArgTypeNone , "Append to the the file specified with '--outfile <path>'."},
};
uint32_t
@@ -49,11 +49,11 @@
Error
OptionGroupOutputFile::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
@@ -61,7 +61,7 @@
error = m_file.SetValueFromCString (option_arg);
break;
- case 'A':
+ case 'apnd':
m_append.SetCurrentValue(true);
break;
Index: aze/lldb/source/Interpreter/OptionGroupPlatform.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupPlatform.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupPlatform.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionGroupPlatform.h"
// C Includes
@@ -34,7 +36,7 @@
platform_sp = Platform::Create (m_platform_name.c_str(), error);
if (platform_sp)
{
- if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
+ if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
{
error.SetErrorStringWithFormat("platform '%s' doesn't support '%s'", platform_sp->GetName(), arch.GetTriple().getTriple().c_str());
platform_sp.reset();
@@ -84,7 +86,7 @@
{ LLDB_OPT_SET_ALL, false, "platform", 'p', required_argument, NULL, 0, eArgTypePlatform, "Specify name of the platform to use for this target, creating the platform if necessary."},
{ LLDB_OPT_SET_ALL, false, "version" , 'v', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting." },
{ LLDB_OPT_SET_ALL, false, "build" , 'b', required_argument, NULL, 0, eArgTypeNone, "Specify the initial SDK build number." },
- { LLDB_OPT_SET_ALL, false, "sysroot" , 's', required_argument, NULL, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." }
+ { LLDB_OPT_SET_ALL, false, "sysroot" , 'S', required_argument, NULL, 0, eArgTypeFilename, "Specify the SDK root directory that contains a root of all remote system files." }
};
const OptionDefinition*
@@ -113,7 +115,7 @@
if (!m_include_platform_option)
++option_idx;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
Index: aze/lldb/source/Interpreter/OptionGroupString.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupString.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupString.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -20,7 +20,7 @@
OptionGroupString::OptionGroupString (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text,
Index: aze/lldb/source/Interpreter/OptionGroupUInt64.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupUInt64.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupUInt64.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -20,7 +20,7 @@
OptionGroupUInt64::OptionGroupUInt64 (uint32_t usage_mask,
bool required,
const char *long_option,
- char short_option,
+ int short_option,
uint32_t completion_type,
lldb::CommandArgumentType argument_type,
const char *usage_text,
Index: aze/lldb/source/Interpreter/OptionGroupUUID.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupUUID.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupUUID.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -47,11 +47,11 @@
Error
OptionGroupUUID::SetOptionValue (CommandInterpreter &interpreter,
- uint32_t option_idx,
- const char *option_arg)
+ uint32_t option_idx,
+ const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
Index: aze/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
// C Includes
@@ -31,17 +33,17 @@
static OptionDefinition
g_option_table[] =
{
- { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, g_dynamic_value_types, 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."},
- { LLDB_OPT_SET_1, false, "synthetic-type", 'S', required_argument, NULL, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."},
- { LLDB_OPT_SET_1, false, "depth", 'D', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."},
- { LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."},
- { LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, eArgTypeNone, "Show variable location information."},
- { LLDB_OPT_SET_1, false, "objc", 'O', no_argument, NULL, 0, eArgTypeNone, "Print as an Objective-C object."},
- { LLDB_OPT_SET_1, false, "ptr-depth", 'P', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."},
- { LLDB_OPT_SET_1, false, "show-types", 'T', no_argument, NULL, 0, eArgTypeNone, "Show variable types when dumping values."},
- { LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', optional_argument, NULL, 0, eArgTypeCount, "Set the depth at which omitting summary information stops (default is 1)."},
- { LLDB_OPT_SET_1, false, "raw-output", 'R', no_argument, NULL, 0, eArgTypeNone, "Don't use formatting options."},
- { LLDB_OPT_SET_1, false, "show-all-children",'A', no_argument, NULL, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."},
+ { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, g_dynamic_value_types, 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."},
+ { LLDB_OPT_SET_1, false, "synthetic-type", 'S', required_argument, NULL, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."},
+ { LLDB_OPT_SET_1, false, "depth", 'D', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."},
+ { LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."},
+ { LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, eArgTypeNone, "Show variable location information."},
+ { LLDB_OPT_SET_1, false, "object-description", 'O', no_argument, NULL, 0, eArgTypeNone, "Print as an Objective-C object."},
+ { LLDB_OPT_SET_1, false, "ptr-depth", 'P', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."},
+ { LLDB_OPT_SET_1, false, "show-types", 'T', no_argument, NULL, 0, eArgTypeNone, "Show variable types when dumping values."},
+ { LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', optional_argument, NULL, 0, eArgTypeCount, "Set the depth at which omitting summary information stops (default is 1)."},
+ { LLDB_OPT_SET_1, false, "raw-output", 'R', no_argument, NULL, 0, eArgTypeNone, "Don't use formatting options."},
+ { LLDB_OPT_SET_1, false, "show-all-children", 'A', no_argument, NULL, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -64,7 +66,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
bool success = false;
switch (short_option)
Index: aze/lldb/source/Interpreter/OptionGroupVariable.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupVariable.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupVariable.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -7,14 +7,18 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionGroupVariable.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Target/Target.h"
+#include "lldb/Core/Error.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/Utils.h"
using namespace lldb;
@@ -24,20 +28,40 @@
static OptionDefinition
g_option_table[] =
{
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', no_argument, NULL, 0, eArgTypeNone, "Omit function arguments."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', no_argument, NULL, 0, eArgTypeNone, "Omit local variables."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', no_argument, NULL, 0, eArgTypeNone, "Show the current frame source file global and static variables."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', no_argument, NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."},
- { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', no_argument, NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."},
- { LLDB_OPT_SET_1, false, "summary", 'y', required_argument, NULL, 0, eArgTypeName, "Specify the summary that the variable output should use."},
- { LLDB_OPT_SET_2, false, "summary-string", 'z', required_argument, NULL, 0, eArgTypeName, "Specify a summary string to use to format the variable output."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', no_argument, NULL, 0, eArgTypeNone, "Omit function arguments."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', no_argument, NULL, 0, eArgTypeNone, "Omit local variables."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', no_argument, NULL, 0, eArgTypeNone, "Show the current frame source file global and static variables."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration",'c', no_argument, NULL, 0, eArgTypeNone, "Show variable declaration information (source file and line where the variable was declared)."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', no_argument, NULL, 0, eArgTypeRegularExpression, "The <variable-name> argument for name lookups are regular expressions."},
+ { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', no_argument, NULL, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."},
+ { LLDB_OPT_SET_1, false, "summary", 'y', required_argument, NULL, 0, eArgTypeName, "Specify the summary that the variable output should use."},
+ { LLDB_OPT_SET_2, false, "summary-string", 'z', required_argument, NULL, 0, eArgTypeName, "Specify a summary string to use to format the variable output."},
};
+static Error
+ValidateNamedSummary (const char* str, void*)
+{
+ if (!str || !str[0])
+ return Error("must specify a valid named summary");
+ TypeSummaryImplSP summary_sp;
+ if (DataVisualization::NamedSummaryFormats::GetSummaryFormat(ConstString(str), summary_sp) == false)
+ return Error("must specify a valid named summary");
+ return Error();
+}
+
+static Error
+ValidateSummaryString (const char* str, void*)
+{
+ if (!str || !str[0])
+ return Error("must specify a non-empty summary string");
+ return Error();
+}
OptionGroupVariable::OptionGroupVariable (bool show_frame_options) :
OptionGroup(),
- include_frame_options (show_frame_options)
+ include_frame_options (show_frame_options),
+ summary(ValidateNamedSummary),
+ summary_string(ValidateSummaryString)
{
}
@@ -53,7 +77,7 @@
Error error;
if (!include_frame_options)
option_idx += 3;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 'r': use_regex = true; break;
@@ -65,10 +89,10 @@
show_scope = true;
break;
case 'y':
- summary.SetCurrentValue(option_arg);
+ error = summary.SetCurrentValue(option_arg);
break;
case 'z':
- summary_string.SetCurrentValue(option_arg);
+ error = summary_string.SetCurrentValue(option_arg);
break;
default:
error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
Index: aze/lldb/source/Interpreter/OptionGroupWatchpoint.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionGroupWatchpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionGroupWatchpoint.cpp 2013-03-03 09:35:50.195457352 +0100
@@ -73,7 +73,7 @@
const char *option_arg)
{
Error error;
- char short_option = (char) g_option_table[option_idx].short_option;
+ const int short_option = g_option_table[option_idx].short_option;
switch (short_option)
{
case 'w':
Index: aze/lldb/source/Interpreter/Options.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/Options.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/Options.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,13 +7,15 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/Options.h"
// C Includes
// C++ Includes
#include <algorithm>
#include <bitset>
-#include <set>
+#include <map>
// Other libraries and framework includes
// Project includes
@@ -58,7 +60,7 @@
void
Options::OptionSeen (int option_idx)
{
- m_seen_options.insert ((char) option_idx);
+ m_seen_options.insert (option_idx);
}
// Returns true is set_a is a subset of set_b; Otherwise returns false.
@@ -266,33 +268,54 @@
return NULL;
uint32_t i;
- uint32_t j;
const OptionDefinition *opt_defs = GetDefinitions();
- std::bitset<256> option_seen;
+ std::map<int, uint32_t> option_seen;
m_getopt_table.resize(num_options + 1);
- for (i = 0, j = 0; i < num_options; ++i)
+ for (i = 0; i < num_options; ++i)
{
- char short_opt = opt_defs[i].short_option;
+ const int short_opt = opt_defs[i].short_option;
- if (option_seen.test(short_opt) == false)
- {
- m_getopt_table[j].name = opt_defs[i].long_option;
- m_getopt_table[j].has_arg = opt_defs[i].option_has_arg;
- m_getopt_table[j].flag = NULL;
- m_getopt_table[j].val = opt_defs[i].short_option;
- option_seen.set(short_opt);
- ++j;
+ m_getopt_table[i].name = opt_defs[i].long_option;
+ m_getopt_table[i].has_arg = opt_defs[i].option_has_arg;
+ m_getopt_table[i].flag = NULL;
+ m_getopt_table[i].val = short_opt;
+
+ if (option_seen.find(short_opt) == option_seen.end())
+ {
+ option_seen[short_opt] = i;
+ }
+ else if (short_opt)
+ {
+ m_getopt_table[i].val = 0;
+ std::map<int, uint32_t>::const_iterator pos = option_seen.find(short_opt);
+ StreamString strm;
+ if (isprint8(short_opt))
+ Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option -%c that conflicts with option[%u] --%s, short option won't be used for --%s\n",
+ i,
+ opt_defs[i].long_option,
+ short_opt,
+ pos->second,
+ m_getopt_table[pos->second].name,
+ opt_defs[i].long_option);
+ else
+ Host::SystemLog (Host::eSystemLogError, "option[%u] --%s has a short option 0x%x that conflicts with option[%u] --%s, short option won't be used for --%s\n",
+ i,
+ opt_defs[i].long_option,
+ short_opt,
+ pos->second,
+ m_getopt_table[pos->second].name,
+ opt_defs[i].long_option);
}
}
//getopt_long requires a NULL final entry in the table:
- m_getopt_table[j].name = NULL;
- m_getopt_table[j].has_arg = 0;
- m_getopt_table[j].flag = NULL;
- m_getopt_table[j].val = 0;
+ m_getopt_table[i].name = NULL;
+ m_getopt_table[i].has_arg = 0;
+ m_getopt_table[i].flag = NULL;
+ m_getopt_table[i].val = 0;
}
if (m_getopt_table.empty())
@@ -389,6 +412,57 @@
return false;
}
+enum OptionDisplayType
+{
+ eDisplayBestOption,
+ eDisplayShortOption,
+ eDisplayLongOption
+};
+
+static bool
+PrintOption (const OptionDefinition &opt_def,
+ OptionDisplayType display_type,
+ const char *header,
+ const char *footer,
+ bool show_optional,
+ Stream &strm)
+{
+ const bool has_short_option = isprint8(opt_def.short_option) != 0;
+
+ if (display_type == eDisplayShortOption && !has_short_option)
+ return false;
+
+ if (header && header[0])
+ strm.PutCString(header);
+
+ if (show_optional && !opt_def.required)
+ strm.PutChar('[');
+ const bool show_short_option = has_short_option && display_type != eDisplayLongOption;
+ if (show_short_option)
+ strm.Printf ("-%c", opt_def.short_option);
+ else
+ strm.Printf ("--%s", opt_def.long_option);
+ switch (opt_def.option_has_arg)
+ {
+ case no_argument:
+ break;
+ case required_argument:
+ strm.Printf (" <%s>", CommandObject::GetArgumentName (opt_def.argument_type));
+ break;
+
+ case optional_argument:
+ strm.Printf ("%s[<%s>]",
+ show_short_option ? "" : "=",
+ CommandObject::GetArgumentName (opt_def.argument_type));
+ break;
+ }
+ if (show_optional && !opt_def.required)
+ strm.PutChar(']');
+ if (footer && footer[0])
+ strm.PutCString(footer);
+ return true;
+}
+
void
Options::GenerateOptionUsage
(
@@ -446,12 +520,12 @@
// a single string. If a command has "-a" "-b" and "-c", this will show
// up as [-abc]
- std::set<char> options;
- std::set<char>::const_iterator options_pos, options_end;
+ std::set<int> options;
+ std::set<int>::const_iterator options_pos, options_end;
bool first;
for (i = 0, first = true; i < num_options; ++i)
{
- if (opt_defs[i].usage_mask & opt_set_mask)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
{
// Add current option to the end of out_stream.
@@ -472,17 +546,17 @@
options_pos != options_end;
++options_pos)
{
- if (i==0 && ::isupper (*options_pos))
+ if (i==0 && ::islower (*options_pos))
continue;
- if (i==1 && ::islower (*options_pos))
+ if (i==1 && ::isupper (*options_pos))
continue;
- strm << *options_pos;
+ strm << (char)*options_pos;
}
}
for (i = 0, options.clear(); i < num_options; ++i)
{
- if (opt_defs[i].usage_mask & opt_set_mask)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
{
// Add current option to the end of out_stream.
@@ -503,11 +577,11 @@
options_pos != options_end;
++options_pos)
{
- if (i==0 && ::isupper (*options_pos))
+ if (i==0 && ::islower (*options_pos))
continue;
- if (i==1 && ::islower (*options_pos))
+ if (i==1 && ::isupper (*options_pos))
continue;
- strm << *options_pos;
+ strm << (char)*options_pos;
}
strm.PutChar(']');
}
@@ -516,26 +590,10 @@
for (i = 0; i < num_options; ++i)
{
- if (opt_defs[i].usage_mask & opt_set_mask)
+ if (opt_defs[i].usage_mask & opt_set_mask && isprint8(opt_defs[i].short_option))
{
- // Add current option to the end of out_stream.
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- if (opt_defs[i].required)
- {
- if (opt_defs[i].option_has_arg == required_argument)
- {
- strm.Printf (" -%c <%s>",
- opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- }
- else if (opt_defs[i].option_has_arg == optional_argument)
- {
- strm.Printf (" -%c [<%s>]",
- opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- }
- }
+ if (opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
+ PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
}
}
@@ -547,17 +605,8 @@
{
// Add current option to the end of out_stream.
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- if (! opt_defs[i].required)
- {
- if (opt_defs[i].option_has_arg == required_argument)
- strm.Printf (" [-%c <%s>]", opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- else if (opt_defs[i].option_has_arg == optional_argument)
- strm.Printf (" [-%c [<%s>]]", opt_defs[i].short_option,
- CommandObject::GetArgumentName (arg_type));
- }
+ if (!opt_defs[i].required && opt_defs[i].option_has_arg != no_argument)
+ PrintOption (opt_defs[i], eDisplayBestOption, " ", NULL, true, strm);
}
}
@@ -588,86 +637,69 @@
// This variable is used to keep track of which options' info we've printed out, because some options can be in
// more than one usage level, but we only want to print the long form of its information once.
- OptionSet options_seen;
- OptionSet::iterator pos;
+ std::multimap<int, uint32_t> options_seen;
strm.IndentMore (5);
- std::vector<char> sorted_options;
-
-
// Put the unique command options in a vector & sort it, so we can output them alphabetically (by short_option)
// when writing out detailed help for each option.
for (i = 0; i < num_options; ++i)
- {
- pos = options_seen.find (opt_defs[i].short_option);
- if (pos == options_seen.end())
- {
- options_seen.insert (opt_defs[i].short_option);
- sorted_options.push_back (opt_defs[i].short_option);
- }
- }
-
- std::sort (sorted_options.begin(), sorted_options.end());
+ options_seen.insert(std::make_pair(opt_defs[i].short_option, i));
// Go through the unique'd and alphabetically sorted vector of options, find the table entry for each option
// and write out the detailed help information for that option.
- int first_option_printed = 1;
- size_t end = sorted_options.size();
- for (size_t j = 0; j < end; ++j)
- {
- char option = sorted_options[j];
- bool found = false;
- for (i = 0; i < num_options && !found; ++i)
- {
- if (opt_defs[i].short_option == option)
- {
- found = true;
- //Print out the help information for this option.
-
- // Put a newline separation between arguments
- if (first_option_printed)
- first_option_printed = 0;
+ bool first_option_printed = false;;
+
+ for (auto pos : options_seen)
+ {
+ i = pos.second;
+ //Print out the help information for this option.
+
+ // Put a newline separation between arguments
+ if (first_option_printed)
+ strm.EOL();
+ else
+ first_option_printed = true;
+
+ CommandArgumentType arg_type = opt_defs[i].argument_type;
+
+ StreamString arg_name_str;
+ arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
+
+ strm.Indent ();
+ if (opt_defs[i].short_option && isprint8(opt_defs[i].short_option))
+ {
+ PrintOption (opt_defs[i], eDisplayShortOption, NULL, NULL, false, strm);
+ PrintOption (opt_defs[i], eDisplayLongOption, " ( ", " )", false, strm);
+ }
+ else
+ {
+ // Short option is not printable, just print long option
+ PrintOption (opt_defs[i], eDisplayLongOption, NULL, NULL, false, strm);
+ }
+ strm.EOL();
+
+ strm.IndentMore (5);
+
+ if (opt_defs[i].usage_text)
+ OutputFormattedUsageText (strm,
+ opt_defs[i].usage_text,
+ screen_width);
+ if (opt_defs[i].enum_values != NULL)
+ {
+ strm.Indent ();
+ strm.Printf("Values: ");
+ for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++)
+ {
+ if (k == 0)
+ strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
else
- strm.EOL();
-
- CommandArgumentType arg_type = opt_defs[i].argument_type;
-
- StreamString arg_name_str;
- arg_name_str.Printf ("<%s>", CommandObject::GetArgumentName (arg_type));
-
- strm.Indent ();
- strm.Printf ("-%c", opt_defs[i].short_option);
- if (arg_type != eArgTypeNone)
- strm.Printf (" <%s>", CommandObject::GetArgumentName (arg_type));
- strm.Printf (" ( --%s", opt_defs[i].long_option);
- if (arg_type != eArgTypeNone)
- strm.Printf (" <%s>", CommandObject::GetArgumentName (arg_type));
- strm.PutCString(" )\n");
-
- strm.IndentMore (5);
-
- if (opt_defs[i].usage_text)
- OutputFormattedUsageText (strm,
- opt_defs[i].usage_text,
- screen_width);
- if (opt_defs[i].enum_values != NULL)
- {
- strm.Indent ();
- strm.Printf("Values: ");
- for (int k = 0; opt_defs[i].enum_values[k].string_value != NULL; k++)
- {
- if (k == 0)
- strm.Printf("%s", opt_defs[i].enum_values[k].string_value);
- else
- strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
- }
- strm.EOL();
- }
- strm.IndentLess (5);
+ strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value);
}
+ strm.EOL();
}
+ strm.IndentLess (5);
}
// Restore the indent level
Index: aze/lldb/source/Interpreter/OptionValueArch.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueArch.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueArch.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,14 +7,16 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionValueArch.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
Index: aze/lldb/source/Interpreter/OptionValueArray.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueArray.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueArray.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -126,9 +126,9 @@
if (array_count == 0)
error.SetErrorStringWithFormat("index %i is not valid for an empty array", idx);
else if (idx > 0)
- error.SetErrorStringWithFormat("index %i out of range, valid values are 0 through %llu", idx, (uint64_t)(array_count - 1));
+ error.SetErrorStringWithFormat("index %i out of range, valid values are 0 through %" PRIu64, idx, (uint64_t)(array_count - 1));
else
- error.SetErrorStringWithFormat("negative index %i out of range, valid values are -1 through -%llu", idx, (uint64_t)array_count);
+ error.SetErrorStringWithFormat("negative index %i out of range, valid values are -1 through -%" PRIu64, idx, (uint64_t)array_count);
}
}
}
Index: aze/lldb/source/Interpreter/OptionValueDictionary.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueDictionary.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueDictionary.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionValueDictionary.h"
// C Includes
@@ -14,8 +16,8 @@
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/OptionValueString.h"
Index: aze/lldb/source/Interpreter/OptionValueEnumeration.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueEnumeration.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueEnumeration.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -50,7 +50,7 @@
return;
}
}
- strm.Printf("%llu", (uint64_t)m_current_value);
+ strm.Printf("%" PRIu64, (uint64_t)m_current_value);
}
}
Index: aze/lldb/source/Interpreter/OptionValueFileSpec.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueFileSpec.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueFileSpec.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,14 +7,16 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionValueFileSpec.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
@@ -92,8 +94,17 @@
case eVarSetOperationAssign:
if (value_cstr && value_cstr[0])
{
- m_value_was_set = true;
- m_current_value.SetFile(value_cstr, value_cstr[0] == '~');
+ Args args(value_cstr);
+ if (args.GetArgumentCount() == 1)
+ {
+ const char *path = args.GetArgumentAtIndex(0);
+ m_value_was_set = true;
+ m_current_value.SetFile(path, true);
+ }
+ else
+ {
+ error.SetErrorString("please supply a single path argument for this file or quote the path if it contains spaces");
+ }
}
else
{
Index: aze/lldb/source/Interpreter/OptionValueFormat.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueFormat.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueFormat.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,14 +7,16 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionValueFormat.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/Stream.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
Index: aze/lldb/source/Interpreter/OptionValueSInt64.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueSInt64.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueSInt64.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -22,7 +22,7 @@
void
OptionValueSInt64::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
{
- //printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %lli\n", this, exe_ctx, m_current_value);
+ //printf ("%p: DumpValue (exe_ctx=%p, strm, mask) m_current_value = %" PRIi64 "\n", this, exe_ctx, m_current_value);
if (dump_mask & eDumpOptionType)
strm.Printf ("(%s)", GetTypeAsCString ());
// if (dump_mask & eDumpOptionName)
@@ -31,7 +31,7 @@
{
if (dump_mask & eDumpOptionType)
strm.PutCString (" = ");
- strm.Printf ("%lli", m_current_value);
+ strm.Printf ("%" PRIi64, m_current_value);
}
}
@@ -59,7 +59,7 @@
m_current_value = value;
}
else
- error.SetErrorStringWithFormat ("%lli is out of range, valid values must be between %lli and %lli.",
+ error.SetErrorStringWithFormat ("%" PRIi64 " is out of range, valid values must be between %" PRIi64 " and %" PRIi64 ".",
value,
m_min_value,
m_max_value);
Index: aze/lldb/source/Interpreter/OptionValueString.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueString.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueString.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -61,20 +61,36 @@
case eVarSetOperationInsertBefore:
case eVarSetOperationInsertAfter:
case eVarSetOperationRemove:
+ if (m_validator)
+ {
+ error = m_validator(value_cstr,m_validator_baton);
+ if (error.Fail())
+ return error;
+ }
error = OptionValue::SetValueFromCString (value_cstr, op);
break;
case eVarSetOperationAppend:
+ {
+ std::string new_value(m_current_value);
if (value_cstr && value_cstr[0])
{
if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
{
std::string str;
Args::EncodeEscapeSequences (value_cstr, str);
- m_current_value += str;
+ new_value.append(str);
}
else
- m_current_value += value_cstr;
+ new_value.append(value_cstr);
+ }
+ if (m_validator)
+ {
+ error = m_validator(new_value.c_str(),m_validator_baton);
+ if (error.Fail())
+ return error;
+ }
+ m_current_value.assign(new_value);
}
break;
@@ -84,6 +100,12 @@
case eVarSetOperationReplace:
case eVarSetOperationAssign:
+ if (m_validator)
+ {
+ error = m_validator(value_cstr,m_validator_baton);
+ if (error.Fail())
+ return error;
+ }
m_value_was_set = true;
if (m_options.Test (eOptionEncodeCharacterEscapeSequences))
{
@@ -104,3 +126,39 @@
{
return OptionValueSP(new OptionValueString(*this));
}
+
+Error
+OptionValueString::SetCurrentValue (const char *value)
+{
+ if (m_validator)
+ {
+ Error error(m_validator(value,m_validator_baton));
+ if (error.Fail())
+ return error;
+ }
+ if (value && value[0])
+ m_current_value.assign (value);
+ else
+ m_current_value.clear();
+ return Error();
+}
+
+Error
+OptionValueString::AppendToCurrentValue (const char *value)
+{
+ if (value && value[0])
+ {
+ if (m_validator)
+ {
+ std::string new_value(m_current_value);
+ new_value.append(value);
+ Error error(m_validator(value,m_validator_baton));
+ if (error.Fail())
+ return error;
+ m_current_value.assign(new_value);
+ }
+ else
+ m_current_value.append (value);
+ }
+ return Error();
+}
Index: aze/lldb/source/Interpreter/OptionValueUInt64.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueUInt64.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueUInt64.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -39,7 +39,7 @@
{
if (dump_mask & eDumpOptionType)
strm.PutCString (" = ");
- strm.Printf ("%llu", m_current_value);
+ strm.Printf ("%" PRIu64, m_current_value);
}
}
Index: aze/lldb/source/Interpreter/OptionValueUUID.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/OptionValueUUID.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/OptionValueUUID.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionValueUUID.h"
// C Includes
Index: aze/lldb/source/Interpreter/Property.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/Property.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/Property.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/Property.h"
// C Includes
Index: aze/lldb/source/Interpreter/PythonDataObjects.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/PythonDataObjects.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/PythonDataObjects.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -22,294 +22,358 @@
#endif
#include "lldb/Interpreter/PythonDataObjects.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
using namespace lldb_private;
using namespace lldb;
-PythonDataObject::PythonDataObject (PyObject* object) :
- m_object(object)
+//----------------------------------------------------------------------
+// PythonObject
+//----------------------------------------------------------------------
+PythonObject::PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ m_py_obj (NULL)
{
+ if (script_object_sp)
+ Reset ((PyObject *)script_object_sp->GetObject());
}
-PythonDataObject::PythonDataObject () :
- m_object()
+//----------------------------------------------------------------------
+// PythonString
+//----------------------------------------------------------------------
+
+PythonString::PythonString (PyObject *py_obj) :
+ PythonObject(py_obj)
{
}
-PythonDataObject::~PythonDataObject ()
+PythonString::PythonString (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
}
-PythonDataString
-PythonDataObject::GetStringObject ()
+PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
- return PythonDataString(GetPythonObject());
}
-
-PythonDataInteger
-PythonDataObject::GetIntegerObject ()
+
+PythonString::PythonString (const char* string) :
+ PythonObject(PyString_FromString(string))
+{
+}
+
+PythonString::PythonString () :
+ PythonObject()
{
- return PythonDataInteger(GetPythonObject());
}
-PythonDataArray
-PythonDataObject::GetArrayObject()
+PythonString::~PythonString ()
{
- return PythonDataArray(GetPythonObject());
}
-PythonDataDictionary
-PythonDataObject::GetDictionaryObject()
+bool
+PythonString::Reset (PyObject *py_obj)
{
- return PythonDataDictionary(GetPythonObject());
+ if (py_obj && PyString_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
-PythonDataInteger::PythonDataInteger (bool create_empty) :
- m_object(create_empty ? PyInt_FromLong(0) : NULL)
+const char*
+PythonString::GetString() const
{
+ if (m_py_obj)
+ return PyString_AsString(m_py_obj);
+ return NULL;
}
-PythonDataInteger::PythonDataInteger (PyObject* object) :
- m_object(object)
+size_t
+PythonString::GetSize() const
{
- if (object && !PyInt_Check(GetPythonObject()))
- m_object.Reset();
+ if (m_py_obj)
+ return PyString_Size(m_py_obj);
+ return 0;
}
-PythonDataInteger::PythonDataInteger (int64_t value) :
- m_object(PyInt_FromLong(value))
+void
+PythonString::SetString (const char* string)
{
+ PythonObject::Reset(PyString_FromString(string));
}
+//----------------------------------------------------------------------
+// PythonInteger
+//----------------------------------------------------------------------
-PythonDataInteger::~PythonDataInteger ()
+PythonInteger::PythonInteger (PyObject *py_obj) :
+ PythonObject(py_obj)
{
}
-int64_t
-PythonDataInteger::GetInteger()
+PythonInteger::PythonInteger (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
- if (m_object)
- return PyInt_AsLong(GetPythonObject());
- else
- return UINT64_MAX;
}
-void
-PythonDataInteger::SetInteger (int64_t value)
+PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
- m_object.Reset(PyInt_FromLong(value));
}
-PythonDataString::PythonDataString (bool create_empty) :
- m_object(create_empty ? PyString_FromString("") : NULL)
+PythonInteger::PythonInteger (int64_t value) :
+ PythonObject(PyInt_FromLong(value))
{
}
-PythonDataString::PythonDataString (PyObject* object) :
- m_object(object)
+
+PythonInteger::~PythonInteger ()
{
- if (object && !PyString_Check(GetPythonObject()))
- m_object.Reset();
}
-PythonDataString::PythonDataString (const char* string) :
- m_object(PyString_FromString(string))
+bool
+PythonInteger::Reset (PyObject *py_obj)
{
+ if (py_obj && PyInt_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
-PythonDataString::~PythonDataString ()
+int64_t
+PythonInteger::GetInteger()
{
+ if (m_py_obj)
+ return PyInt_AsLong(m_py_obj);
+ else
+ return UINT64_MAX;
}
-const char*
-PythonDataString::GetString() const
+void
+PythonInteger::SetInteger (int64_t value)
{
- if (m_object)
- return PyString_AsString(GetPythonObject());
- return NULL;
+ PythonObject::Reset(PyInt_FromLong(value));
}
-size_t
-PythonDataString::GetSize() const
+//----------------------------------------------------------------------
+// PythonList
+//----------------------------------------------------------------------
+
+PythonList::PythonList () :
+ PythonObject(PyList_New(0))
{
- if (m_object)
- return PyString_Size(GetPythonObject());
- return 0;
}
-void
-PythonDataString::SetString (const char* string)
+PythonList::PythonList (uint32_t count) :
+ PythonObject(PyList_New(count))
+{
+}
+
+PythonList::PythonList (PyObject *py_obj) :
+ PythonObject(py_obj)
{
- m_object.Reset(PyString_FromString(string));
}
-PythonDataArray::PythonDataArray (bool create_empty) :
- m_object(create_empty ? PyList_New(0) : NULL)
+
+PythonList::PythonList (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
}
-PythonDataArray::PythonDataArray (uint32_t count) :
- m_object(PyList_New(count))
+PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
}
-PythonDataArray::PythonDataArray (PyObject* object) :
- m_object(object)
+PythonList::~PythonList ()
{
- if (object && !PyList_Check(GetPythonObject()))
- m_object.Reset();
}
-PythonDataArray::~PythonDataArray ()
+bool
+PythonList::Reset (PyObject *py_obj)
{
+ if (py_obj && PyList_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
uint32_t
-PythonDataArray::GetSize()
+PythonList::GetSize()
{
- if (m_object)
- return PyList_GET_SIZE(GetPythonObject());
+ if (m_py_obj)
+ return PyList_GET_SIZE(m_py_obj);
return 0;
}
-PythonDataObject
-PythonDataArray::GetItemAtIndex (uint32_t index)
+PythonObject
+PythonList::GetItemAtIndex (uint32_t index)
{
- if (m_object)
- return PythonDataObject(PyList_GetItem(GetPythonObject(), index));
+ if (m_py_obj)
+ return PythonObject(PyList_GetItem(m_py_obj, index));
return NULL;
}
void
-PythonDataArray::SetItemAtIndex (uint32_t index, const PythonDataObject & object)
+PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object)
{
- if (m_object && object)
- PyList_SetItem(GetPythonObject(), index, object.GetPythonObject());
+ if (m_py_obj && object)
+ PyList_SetItem(m_py_obj, index, object.GetPythonObject());
}
void
-PythonDataArray::AppendItem (const PythonDataObject &object)
+PythonList::AppendItem (const PythonObject &object)
+{
+ if (m_py_obj && object)
+ PyList_Append(m_py_obj, object.GetPythonObject());
+}
+
+//----------------------------------------------------------------------
+// PythonDictionary
+//----------------------------------------------------------------------
+
+PythonDictionary::PythonDictionary () :
+ PythonObject(PyDict_New())
+{
+}
+
+PythonDictionary::PythonDictionary (PyObject *py_obj) :
+ PythonObject(py_obj)
+{
+}
+
+
+PythonDictionary::PythonDictionary (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
- if (m_object && object)
- PyList_Append(GetPythonObject(), object.GetPythonObject());
}
-PythonDataDictionary::PythonDataDictionary (bool create_empty) :
- m_object(create_empty ? PyDict_New() : NULL)
+PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
}
-PythonDataDictionary::PythonDataDictionary (PyObject* object) :
- m_object(object)
+PythonDictionary::~PythonDictionary ()
{
- if (object && !PyDict_Check(GetPythonObject()))
- m_object.Reset();
}
-PythonDataDictionary::~PythonDataDictionary ()
+bool
+PythonDictionary::Reset (PyObject *py_obj)
{
+ if (py_obj && PyDict_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
uint32_t
-PythonDataDictionary::GetSize()
+PythonDictionary::GetSize()
{
- if (m_object)
- return PyDict_Size(GetPythonObject());
+ if (m_py_obj)
+ return PyDict_Size(m_py_obj);
return 0;
}
-PythonDataObject
-PythonDataDictionary::GetItemForKey (const char *key) const
+PythonObject
+PythonDictionary::GetItemForKey (const char *key) const
{
if (key && key[0])
{
- PythonDataString python_key(key);
+ PythonString python_key(key);
return GetItemForKey(python_key);
}
return NULL;
}
-PythonDataObject
-PythonDataDictionary::GetItemForKey (const PythonDataString &key) const
+PythonObject
+PythonDictionary::GetItemForKey (const PythonString &key) const
{
- if (m_object && key)
- return PythonDataObject(PyDict_GetItem(GetPythonObject(), key.GetPythonObject()));
- return PythonDataObject();
+ if (m_py_obj && key)
+ return PythonObject(PyDict_GetItem(m_py_obj, key.GetPythonObject()));
+ return PythonObject();
}
const char *
-PythonDataDictionary::GetItemForKeyAsString (const PythonDataString &key, const char *fail_value) const
+PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const
{
- if (m_object && key)
+ if (m_py_obj && key)
{
- PyObject *object = PyDict_GetItem(GetPythonObject(), key.GetPythonObject());
- if (object && PyString_Check(object))
- return PyString_AsString(object);
+ PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
+ if (py_obj && PyString_Check(py_obj))
+ return PyString_AsString(py_obj);
}
return fail_value;
}
int64_t
-PythonDataDictionary::GetItemForKeyAsInteger (const PythonDataString &key, int64_t fail_value) const
+PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const
{
- if (m_object && key)
+ if (m_py_obj && key)
{
- PyObject *object = PyDict_GetItem(GetPythonObject(), key.GetPythonObject());
- if (object && PyInt_Check(object))
- return PyInt_AsLong(object);
+ PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
+ if (py_obj)
+ {
+ if (PyInt_Check(py_obj))
+ return PyInt_AsLong(py_obj);
+
+ if (PyLong_Check(py_obj))
+ return PyLong_AsLong(py_obj);
+ }
}
return fail_value;
}
-PythonDataArray
-PythonDataDictionary::GetKeys () const
+PythonList
+PythonDictionary::GetKeys () const
{
- if (m_object)
- return PythonDataArray(PyDict_Keys(GetPythonObject()));
- return PythonDataArray();
+ if (m_py_obj)
+ return PythonList(PyDict_Keys(m_py_obj));
+ return PythonList();
}
-PythonDataString
-PythonDataDictionary::GetKeyAtPosition (uint32_t pos) const
+PythonString
+PythonDictionary::GetKeyAtPosition (uint32_t pos) const
{
PyObject *key, *value;
Py_ssize_t pos_iter = 0;
- if (m_object)
+ if (m_py_obj)
{
- while (PyDict_Next(GetPythonObject(), &pos_iter, &key, &value))
+ while (PyDict_Next(m_py_obj, &pos_iter, &key, &value))
{
if (pos-- == 0)
- return PythonDataString(key);
+ return PythonString(key);
}
}
- return PythonDataString();
+ return PythonString();
}
-PythonDataObject
-PythonDataDictionary::GetValueAtPosition (uint32_t pos) const
+PythonObject
+PythonDictionary::GetValueAtPosition (uint32_t pos) const
{
PyObject *key, *value;
Py_ssize_t pos_iter = 0;
- if (!m_object)
+ if (!m_py_obj)
return NULL;
- while (PyDict_Next(GetPythonObject(), &pos_iter, &key, &value)) {
+ while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) {
if (pos-- == 0)
- return PythonDataObject(value);
+ return PythonObject(value);
}
- return PythonDataObject();
+ return PythonObject();
}
void
-PythonDataDictionary::SetItemForKey (const PythonDataString &key, const PythonDataObject &value)
+PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value)
{
- if (m_object && key && value)
- PyDict_SetItem(GetPythonObject(), key.GetPythonObject(), value.GetPythonObject());
+ if (m_py_obj && key && value)
+ PyDict_SetItem(m_py_obj, key.GetPythonObject(), value.GetPythonObject());
}
#endif
Index: aze/lldb/source/Interpreter/ScriptInterpreter.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/ScriptInterpreter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/ScriptInterpreter.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/ScriptInterpreter.h"
#include <string>
Index: aze/lldb/source/Interpreter/ScriptInterpreterNone.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/ScriptInterpreterNone.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/ScriptInterpreterNone.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/ScriptInterpreterNone.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StringList.h"
Index: aze/lldb/source/Interpreter/ScriptInterpreterPython.cpp
===================================================================
--- aze.orig/lldb/source/Interpreter/ScriptInterpreterPython.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Interpreter/ScriptInterpreterPython.cpp 2013-03-03 09:35:50.199457351 +0100
@@ -64,72 +64,65 @@
// on linkage-time resolution because the SWIG stuff and this file
// get built at different times
extern "C" bool
-LLDBSwigPythonBreakpointCallbackFunction
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& sb_frame,
- const lldb::BreakpointLocationSP& sb_bp_loc
- );
+LLDBSwigPythonBreakpointCallbackFunction (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& sb_frame,
+ const lldb::BreakpointLocationSP& sb_bp_loc);
extern "C" bool
-LLDBSwigPythonWatchpointCallbackFunction
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& sb_frame,
- const lldb::WatchpointSP& sb_wp
- );
+LLDBSwigPythonWatchpointCallbackFunction (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& sb_frame,
+ const lldb::WatchpointSP& sb_wp);
extern "C" bool
-LLDBSwigPythonCallTypeScript
-(
- const char *python_function_name,
- void *session_dictionary,
- const lldb::ValueObjectSP& valobj_sp,
- void** pyfunct_wrapper,
- std::string& retval
- );
+LLDBSwigPythonCallTypeScript (const char *python_function_name,
+ void *session_dictionary,
+ const lldb::ValueObjectSP& valobj_sp,
+ void** pyfunct_wrapper,
+ std::string& retval);
extern "C" void*
-LLDBSwigPythonCreateSyntheticProvider
-(
- const std::string python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP& valobj_sp
- );
+LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp);
-extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor);
-extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
-extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
-extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
-extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
-extern "C" bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
+extern "C" uint32_t
+LLDBSwigPython_CalculateNumChildren (void *implementor);
-extern "C" bool LLDBSwigPythonCallCommand
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger,
- const char* args,
- std::string& err_msg,
- lldb_private::CommandReturnObject& cmd_retobj
- );
+extern "C" void *
+LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
-extern "C" bool LLDBSwigPythonCallModuleInit
-(
- const std::string python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger
- );
+extern "C" int
+LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
-extern "C" void* LLDBSWIGPythonCreateOSPlugin
-(
- const std::string python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP& process_sp
-);
+extern "C" void *
+LLDBSWIGPython_CastPyObjectToSBValue (void* data);
+
+extern "C" bool
+LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
+
+extern "C" bool
+LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
+
+extern "C" bool
+LLDBSwigPythonCallCommand (const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger,
+ const char* args,
+ std::string& err_msg,
+ lldb_private::CommandReturnObject& cmd_retobj);
+
+extern "C" bool
+LLDBSwigPythonCallModuleInit (const char *python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger);
+
+extern "C" void*
+LLDBSWIGPythonCreateOSPlugin (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP& process_sp);
static int
_check_and_flush (FILE *stream)
@@ -142,7 +135,7 @@
uint16_t on_entry,
uint16_t on_leave,
FILE* wait_msg_handle) :
- m_need_session( (on_leave & TearDownSession) == TearDownSession ),
+ m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
m_python_interpreter(py_interpreter),
m_tmp_fh(wait_msg_handle)
{
@@ -150,8 +143,14 @@
m_tmp_fh = (m_python_interpreter->m_dbg_stdout ? m_python_interpreter->m_dbg_stdout : stdout);
DoAcquireLock();
- if ( (on_entry & InitSession) == InitSession )
- DoInitSession();
+ if ((on_entry & InitSession) == InitSession)
+ {
+ if (DoInitSession((on_entry & InitGlobals) == InitGlobals) == false)
+ {
+ // Don't teardown the session if we didn't init it.
+ m_teardown_session = false;
+ }
+ }
}
bool
@@ -165,12 +164,11 @@
}
bool
-ScriptInterpreterPython::Locker::DoInitSession()
+ScriptInterpreterPython::Locker::DoInitSession(bool init_lldb_globals)
{
if (!m_python_interpreter)
return false;
- m_python_interpreter->EnterSession ();
- return true;
+ return m_python_interpreter->EnterSession (init_lldb_globals);
}
bool
@@ -194,7 +192,7 @@
ScriptInterpreterPython::Locker::~Locker()
{
- if (m_need_session)
+ if (m_teardown_session)
DoTearDownSession();
DoFreeLock();
}
@@ -261,14 +259,11 @@
}
size_t
-ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback
-(
- void *baton,
- InputReader &reader,
- InputReaderAction notification,
- const char *bytes,
- size_t bytes_len
- )
+ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback (void *baton,
+ InputReader &reader,
+ InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len)
{
lldb::thread_t embedded_interpreter_thread;
LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
@@ -308,7 +303,7 @@
if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
{
ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
ScriptInterpreterPython::Locker::FreeAcquiredLock);
run_string.Printf ("run_one_line (%s, 'save_stderr = sys.stderr')", script_interpreter->m_dictionary_name.c_str());
PyRun_SimpleString (run_string.GetData());
@@ -334,7 +329,7 @@
if (IS_VALID_LLDB_HOST_THREAD(embedded_interpreter_thread))
{
if (log)
- log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", embedded_interpreter_thread);
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", (void *)embedded_interpreter_thread);
Error detach_error;
Host::ThreadDetach (embedded_interpreter_thread, &detach_error);
}
@@ -371,7 +366,22 @@
break;
case eInputReaderInterrupt:
- reader.SetIsDone(true);
+ {
+ PyThreadState* state = _PyThreadState_Current;
+ if (!state)
+ state = script_interpreter->m_command_thread_state;
+ if (state)
+ {
+ long tid = state->thread_id;
+ _PyThreadState_Current = state;
+ int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
+ if (log)
+ log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
+ tid,num_threads,state);
+ }
+ else if (log)
+ log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
+ }
break;
case eInputReaderEndOfFile:
@@ -396,36 +406,30 @@
bytes_len);
reader.SetIsDone (true);
}
-
break;
case eInputReaderDone:
- {
- StreamString run_string;
- char error_str[1024];
- const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str));
- if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
{
- ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
- run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin')", script_interpreter->m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
+ StreamString run_string;
+ char error_str[1024];
+ const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str));
+ if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
+ {
+ ScriptInterpreterPython::Locker locker(script_interpreter,
+ ScriptInterpreterPython::Locker::AcquireLock,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin; sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear();
+ }
+ // Restore terminal settings if they were validly saved
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
- run_string.Printf ("run_one_line (%s, 'sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
- }
- }
-
- // Restore terminal settings if they were validly saved
- if (log)
- log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
-
- script_interpreter->RestoreTerminalState ();
-
- script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor();
+ script_interpreter->RestoreTerminalState ();
+
+ script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor();
+ }
break;
}
@@ -446,7 +450,8 @@
m_dictionary_name (interpreter.GetDebugger().GetInstanceName().AsCString()),
m_terminal_state (),
m_session_is_active (false),
- m_valid_session (true)
+ m_valid_session (true),
+ m_command_thread_state (NULL)
{
static int g_initialized = false;
@@ -493,7 +498,7 @@
Debugger::Terminate();
run_string.Clear();
- run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %llu; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
+ run_string.Printf ("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 "; pydoc.pager = pydoc.plainpager')", m_dictionary_name.c_str(),
interpreter.GetDebugger().GetID());
PyRun_SimpleString (run_string.GetData());
@@ -577,6 +582,10 @@
void
ScriptInterpreterPython::LeaveSession ()
{
+ LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+ if (log)
+ log->PutCString("ScriptInterpreterPython::LeaveSession()");
+
// checking that we have a valid thread state - since we use our own threading and locking
// in some (rare) cases during cleanup Python may end up believing we have no thread state
// and PyImport_AddModule will crash if that is the case - since that seems to only happen
@@ -601,33 +610,44 @@
m_session_is_active = false;
}
-void
-ScriptInterpreterPython::EnterSession ()
+bool
+ScriptInterpreterPython::EnterSession (bool init_lldb_globals)
{
// If we have already entered the session, without having officially 'left' it, then there is no need to
// 'enter' it again.
-
+ LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
if (m_session_is_active)
- return;
+ {
+ if (log)
+ log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i) session is already active, returning without doing anything", init_lldb_globals);
+ return false;
+ }
+
+ if (log)
+ log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i)", init_lldb_globals);
+
m_session_is_active = true;
StreamString run_string;
- run_string.Printf ( "run_one_line (%s, 'lldb.debugger_unique_id = %llu", m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
- run_string.Printf ( "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%llu)", GetCommandInterpreter().GetDebugger().GetID());
- run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
- run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
- run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
- run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
- // Make sure STDIN is closed since when we run this as an embedded
- // interpreter we don't want someone to call "line = sys.stdin.readline()"
- // and lock up. We don't have multiple windows and when the interpreter is
- // embedded we don't know we should be feeding input to the embedded
- // interpreter or to the python sys.stdin. We also don't want to let python
- // play with the real stdin from this process, so we need to close it...
- //run_string.PutCString ("; sys.stdin.close()");
- run_string.PutCString ("')");
+ if (init_lldb_globals)
+ {
+ run_string.Printf ( "run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
+ run_string.Printf ( "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
+ run_string.PutCString ("; lldb.target = lldb.debugger.GetSelectedTarget()");
+ run_string.PutCString ("; lldb.process = lldb.target.GetProcess()");
+ run_string.PutCString ("; lldb.thread = lldb.process.GetSelectedThread ()");
+ run_string.PutCString ("; lldb.frame = lldb.thread.GetSelectedFrame ()");
+ run_string.PutCString ("')");
+ }
+ else
+ {
+ // If we aren't initing the globals, we should still always set the debugger (since that is always unique.)
+ run_string.Printf ( "run_one_line (%s, \"lldb.debugger_unique_id = %" PRIu64, m_dictionary_name.c_str(), GetCommandInterpreter().GetDebugger().GetID());
+ run_string.Printf ( "; lldb.debugger = lldb.SBDebugger.FindDebuggerWithID (%" PRIu64 ")", GetCommandInterpreter().GetDebugger().GetID());
+ run_string.PutCString ("\")");
+ }
PyRun_SimpleString (run_string.GetData());
run_string.Clear();
@@ -648,6 +668,8 @@
if (PyErr_Occurred())
PyErr_Clear ();
+
+ return true;
}
static PyObject*
@@ -720,8 +742,8 @@
// method to pass the command string directly down to Python.
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitSession : 0),
- ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0));
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
bool success = false;
@@ -842,7 +864,7 @@
{
ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
ScriptInterpreterPython::Locker::FreeAcquiredLock);
}
@@ -859,7 +881,7 @@
if (IS_VALID_LLDB_HOST_THREAD(embedded_interpreter_thread))
{
if (log)
- log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", embedded_interpreter_thread);
+ log->Printf ("ScriptInterpreterPython::InputReaderCallback, Activate, succeeded in creating thread (thread_t = %p)", (void *)embedded_interpreter_thread);
Error detach_error;
Host::ThreadDetach (embedded_interpreter_thread, &detach_error);
}
@@ -886,9 +908,9 @@
case eInputReaderReactivate:
{
- ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ ScriptInterpreterPython::Locker locker (script_interpreter,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
}
break;
@@ -992,8 +1014,8 @@
{
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitSession : 0),
- ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0));
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
PyObject *py_return = NULL;
PyObject *mainmod = PyImport_AddModule ("__main__");
@@ -1129,8 +1151,6 @@
success = PyArg_Parse (py_return, format, (char *) ret_value);
break;
}
- default:
- {}
}
Py_DECREF (py_return);
if (success)
@@ -1161,8 +1181,8 @@
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitSession : 0),
- ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0));
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
bool success = false;
PyObject *py_return = NULL;
@@ -1584,10 +1604,11 @@
// Wrap everything up inside the function, increasing the indentation.
+ auto_generated_function.AppendString(" if True:");
for (int i = 0; i < num_lines; ++i)
{
sstr.Clear ();
- sstr.Printf (" %s", input.GetStringAtIndex (i));
+ sstr.Printf (" %s", input.GetStringAtIndex (i));
auto_generated_function.AppendString (sstr.GetData());
}
auto_generated_function.AppendString (" for key in new_keys:"); // Iterate over all the keys from session dict
@@ -1677,7 +1698,8 @@
auto_generated_class.AppendString (sstr.GetData());
// Wrap everything up inside the class, increasing the indentation.
-
+ // we don't need to play any fancy indentation tricks here because there is no
+ // surrounding code whose indentation we need to honor
for (int i = 0; i < num_lines; ++i)
{
sstr.Clear ();
@@ -1699,10 +1721,9 @@
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateOSPlugin (std::string class_name,
- lldb::ProcessSP process_sp)
+ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
{
- if (class_name.empty())
+ if (class_name == NULL || class_name[0] == '\0')
return lldb::ScriptInterpreterObjectSP();
if (!process_sp)
@@ -1721,16 +1742,16 @@
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object)
+ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
static char callee_name[] = "get_register_info";
- if (!object)
+ if (!os_plugin_object_sp)
return lldb::ScriptInterpreterObjectSP();
- PyObject* implementor = (PyObject*)object->GetObject();
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
if (implementor == NULL || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
@@ -1780,16 +1801,16 @@
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterObjectSP object)
+ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
static char callee_name[] = "get_thread_info";
- if (!object)
+ if (!os_plugin_object_sp)
return lldb::ScriptInterpreterObjectSP();
- PyObject* implementor = (PyObject*)object->GetObject();
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
if (implementor == NULL || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
@@ -1838,19 +1859,45 @@
return MakeScriptObject(py_return);
}
+// GetPythonValueFormatString provides a system independent type safe way to
+// convert a variable's type into a python value format. Python value formats
+// are defined in terms of builtin C types and could change from system to
+// as the underlying typedef for uint* types, size_t, off_t and other values
+// change.
+
+template <typename T>
+const char *GetPythonValueFormatString(T t)
+{
+ assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
+ return NULL;
+}
+template <> const char *GetPythonValueFormatString (char *) { return "s"; }
+template <> const char *GetPythonValueFormatString (char) { return "b"; }
+template <> const char *GetPythonValueFormatString (unsigned char) { return "B"; }
+template <> const char *GetPythonValueFormatString (short) { return "h"; }
+template <> const char *GetPythonValueFormatString (unsigned short) { return "H"; }
+template <> const char *GetPythonValueFormatString (int) { return "i"; }
+template <> const char *GetPythonValueFormatString (unsigned int) { return "I"; }
+template <> const char *GetPythonValueFormatString (long) { return "l"; }
+template <> const char *GetPythonValueFormatString (unsigned long) { return "k"; }
+template <> const char *GetPythonValueFormatString (long long) { return "L"; }
+template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
+template <> const char *GetPythonValueFormatString (float t) { return "f"; }
+template <> const char *GetPythonValueFormatString (double t) { return "d"; }
+
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
- lldb::tid_t thread_id)
+ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid)
{
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
static char callee_name[] = "get_register_data";
- static char param_format[] = "l";
+ static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
- if (!object)
+ if (!os_plugin_object_sp)
return lldb::ScriptInterpreterObjectSP();
- PyObject* implementor = (PyObject*)object->GetObject();
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
if (implementor == NULL || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
@@ -1887,8 +1934,72 @@
Py_XDECREF(pmeth);
// right now we know this function exists and is callable..
- PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, thread_id);
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid);
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ return MakeScriptObject(py_return);
+}
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid,
+ lldb::addr_t context)
+{
+ Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+
+ static char callee_name[] = "create_thread";
+ std::string param_format;
+ param_format += GetPythonValueFormatString(tid);
+ param_format += GetPythonValueFormatString(context);
+
+ if (!os_plugin_object_sp)
+ return lldb::ScriptInterpreterObjectSP();
+
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
+
+ if (implementor == NULL || implementor == Py_None)
+ return lldb::ScriptInterpreterObjectSP();
+
+ PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == NULL || pmeth == Py_None)
+ {
+ Py_XDECREF(pmeth);
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ if (PyCallable_Check(pmeth) == 0)
+ {
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+
+ // right now we know this function exists and is callable..
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, &param_format[0], tid, context);
+
// if it fails, print the error but otherwise go on
if (PyErr_Occurred())
{
@@ -1900,10 +2011,10 @@
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
+ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
lldb::ValueObjectSP valobj)
{
- if (class_name.empty())
+ if (class_name == NULL || class_name[0] == '\0')
return lldb::ScriptInterpreterObjectSP();
if (!valobj.get())
@@ -2171,7 +2282,7 @@
// we can just release the GIL after finishing our work.
// If finer-grained locking is desirable, we can lock and unlock the GIL only when calling a python function.
Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
run_string.Printf ("run_one_line (%s, 'save_stderr = sys.stderr')", script_interpreter->m_dictionary_name.c_str());
@@ -2249,7 +2360,7 @@
return NULL;
}
-uint32_t
+size_t
ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
if (!implementor_sp)
@@ -2383,10 +2494,67 @@
return ret_val;
}
+static std::string
+ReadPythonBacktrace (PyObject* py_backtrace)
+{
+ PyObject* traceback_module = NULL,
+ *stringIO_module = NULL,
+ *stringIO_builder = NULL,
+ *stringIO_buffer = NULL,
+ *printTB = NULL,
+ *printTB_args = NULL,
+ *printTB_result = NULL,
+ *stringIO_getvalue = NULL,
+ *printTB_string = NULL;
+
+ std::string retval("backtrace unavailable");
+
+ if (py_backtrace && py_backtrace != Py_None)
+ {
+ traceback_module = PyImport_ImportModule("traceback");
+ stringIO_module = PyImport_ImportModule("StringIO");
+
+ if (traceback_module && traceback_module != Py_None && stringIO_module && stringIO_module != Py_None)
+ {
+ stringIO_builder = PyObject_GetAttrString(stringIO_module, "StringIO");
+ if (stringIO_builder && stringIO_builder != Py_None)
+ {
+ stringIO_buffer = PyObject_CallObject(stringIO_builder, NULL);
+ if (stringIO_buffer && stringIO_buffer != Py_None)
+ {
+ printTB = PyObject_GetAttrString(traceback_module, "print_tb");
+ if (printTB && printTB != Py_None)
+ {
+ printTB_args = Py_BuildValue("OOO",py_backtrace,Py_None,stringIO_buffer);
+ printTB_result = PyObject_CallObject(printTB, printTB_args);
+ stringIO_getvalue = PyObject_GetAttrString(stringIO_buffer, "getvalue");
+ if (stringIO_getvalue && stringIO_getvalue != Py_None)
+ {
+ printTB_string = PyObject_CallObject (stringIO_getvalue,NULL);
+ if (printTB_string && printTB_string != Py_None && PyString_Check(printTB_string))
+ retval.assign(PyString_AsString(printTB_string));
+ }
+ }
+ }
+ }
+ }
+ }
+ Py_XDECREF(traceback_module);
+ Py_XDECREF(stringIO_module);
+ Py_XDECREF(stringIO_builder);
+ Py_XDECREF(stringIO_buffer);
+ Py_XDECREF(printTB);
+ Py_XDECREF(printTB_args);
+ Py_XDECREF(printTB_result);
+ Py_XDECREF(stringIO_getvalue);
+ Py_XDECREF(printTB_string);
+ return retval;
+}
+
bool
ScriptInterpreterPython::LoadScriptingModule (const char* pathname,
bool can_reload,
- bool init_lldb_globals,
+ bool init_session,
lldb_private::Error& error)
{
if (!pathname || !pathname[0])
@@ -2419,8 +2587,8 @@
// Before executing Pyton code, lock the GIL.
Locker py_lock (this,
- Locker::AcquireLock | (init_lldb_globals ? Locker::InitSession : 0),
- Locker::FreeAcquiredLock | (init_lldb_globals ? Locker::TearDownSession : 0));
+ Locker::AcquireLock | (init_session ? Locker::InitSession : 0),
+ Locker::FreeAcquiredLock | (init_session ? Locker::TearDownSession : 0));
// now make sure that Python has "directory" in the search path
StreamString command_stream;
@@ -2436,10 +2604,13 @@
// strip .py or .pyc extension
ConstString extension = target_file.GetFileNameExtension();
- if (::strcmp(extension.GetCString(), "py") == 0)
- basename.resize(basename.length()-3);
- else if(::strcmp(extension.GetCString(), "pyc") == 0)
- basename.resize(basename.length()-4);
+ if (extension)
+ {
+ if (::strcmp(extension.GetCString(), "py") == 0)
+ basename.resize(basename.length()-3);
+ else if(::strcmp(extension.GetCString(), "pyc") == 0)
+ basename.resize(basename.length()-4);
+ }
// check if the module is already import-ed
command_stream.Clear();
@@ -2467,24 +2638,30 @@
{
if (py_error) // if we have a Python error..
{
+ PyObject *type = NULL,*value = NULL,*traceback = NULL;
+ PyErr_Fetch (&type,&value,&traceback);
+
if (PyErr_GivenExceptionMatches (py_error, PyExc_ImportError)) // and it is an ImportError
{
- PyObject *type,*value,*traceback;
- PyErr_Fetch (&type,&value,&traceback);
-
if (value && value != Py_None)
error.SetErrorString(PyString_AsString(PyObject_Str(value)));
else
error.SetErrorString("ImportError raised by imported module");
-
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
}
else // any other error
{
- error.SetErrorString("Python raised an error while importing module");
+ // get the backtrace
+ std::string bt = ReadPythonBacktrace(traceback);
+
+ if (value && value != Py_None)
+ error.SetErrorStringWithFormat("Python error raised while importing module: %s - traceback: %s", PyString_AsString(PyObject_Str(value)),bt.c_str());
+ else
+ error.SetErrorStringWithFormat("Python raised an error while importing module - traceback: %s",bt.c_str());
}
+
+ Py_XDECREF(type);
+ Py_XDECREF(value);
+ Py_XDECREF(traceback);
}
else // we failed but have no error to explain why
{
@@ -2498,9 +2675,9 @@
// if we are here, everything worked
// call __lldb_init_module(debugger,dict)
- if (!g_swig_call_module_init (basename,
- m_dictionary_name.c_str(),
- debugger_sp))
+ if (!g_swig_call_module_init (basename.c_str(),
+ m_dictionary_name.c_str(),
+ debugger_sp))
{
error.SetErrorString("calling __lldb_init_module failed");
return false;
@@ -2565,9 +2742,19 @@
std::string err_msg;
{
- Locker py_lock(this);
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession,
+ Locker::FreeLock | Locker::TearDownSession);
+
SynchronicityHandler synch_handler(debugger_sp,
synchronicity);
+
+ // we need to save the thread state when we first start the command
+ // because we might decide to interrupt it while some action is taking
+ // place outside of Python (e.g. printing to screen, waiting for the network, ...)
+ // in that case, _PyThreadState_Current will be NULL - and we would be unable
+ // to set the asynchronous exception - not a desirable situation
+ m_command_thread_state = _PyThreadState_Current;
PythonInputReaderManager py_input(this);
@@ -2602,8 +2789,9 @@
char* result_ptr = NULL; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
if (ExecuteOneLineWithReturn (command.c_str(),
- ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
- &result_ptr, ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false) /*.SetSetLLDBGlobals(false)*/))
+ ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
+ &result_ptr,
+ ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
{
if (result_ptr)
dest.assign(result_ptr);
Index: aze/lldb/source/lldb.cpp
===================================================================
--- aze.orig/lldb/source/lldb.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/lldb.cpp 2013-03-03 09:35:50.203457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/lldb-private.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Core/ArchSpec.h"
@@ -25,7 +27,6 @@
#include "Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h"
#include "Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h"
#include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h"
-#include "Plugins/Disassembler/llvm/DisassemblerLLVM.h"
#include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h"
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
#include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h"
@@ -40,6 +41,7 @@
#include "Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h"
#include "Plugins/Platform/FreeBSD/PlatformFreeBSD.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
+#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
#ifndef LLDB_DISABLE_PYTHON
#include "Plugins/OperatingSystem/Python/OperatingSystemPython.h"
#endif
@@ -47,13 +49,11 @@
#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
#include "Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.h"
-#include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h"
#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h"
#include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
-#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
#include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h"
@@ -66,12 +66,12 @@
#endif
#if defined (__FreeBSD__)
-#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/Process/POSIX/ProcessPOSIX.h"
#include "Plugins/Process/FreeBSD/ProcessFreeBSD.h"
#endif
#include "Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
#include "Plugins/DynamicLoader/Static/DynamicLoaderStatic.h"
using namespace lldb;
@@ -96,7 +96,6 @@
ABIMacOSX_arm::Initialize();
ABISysV_x86_64::Initialize();
DisassemblerLLVMC::Initialize();
- DisassemblerLLVM::Initialize();
ObjectContainerBSDArchive::Initialize();
ObjectFileELF::Initialize();
SymbolFileDWARF::Initialize();
@@ -108,6 +107,8 @@
DynamicLoaderPOSIXDYLD::Initialize ();
PlatformFreeBSD::Initialize();
PlatformLinux::Initialize();
+ SymbolFileDWARFDebugMap::Initialize();
+ ItaniumABILanguageRuntime::Initialize();
#ifndef LLDB_DISABLE_PYTHON
OperatingSystemPython::Initialize();
#endif
@@ -119,13 +120,10 @@
DynamicLoaderMacOSXDYLD::Initialize();
DynamicLoaderDarwinKernel::Initialize();
OperatingSystemDarwinKernel::Initialize();
- SymbolFileDWARFDebugMap::Initialize();
- ItaniumABILanguageRuntime::Initialize();
AppleObjCRuntimeV2::Initialize();
AppleObjCRuntimeV1::Initialize();
ObjectContainerUniversalMachO::Initialize();
ObjectFileMachO::Initialize();
- ProcessGDBRemote::Initialize();
ProcessKDP::Initialize();
ProcessMachCore::Initialize();
SymbolVendorMacOSX::Initialize();
@@ -141,12 +139,12 @@
#endif
#if defined (__FreeBSD__)
ProcessFreeBSD::Initialize();
- ProcessGDBRemote::Initialize();
#endif
//----------------------------------------------------------------------
// Platform agnostic plugins
//----------------------------------------------------------------------
PlatformRemoteGDBServer::Initialize ();
+ ProcessGDBRemote::Initialize();
DynamicLoaderStatic::Initialize();
// Scan for any system or user LLDB plug-ins
@@ -177,7 +175,6 @@
ABIMacOSX_arm::Terminate();
ABISysV_x86_64::Terminate();
DisassemblerLLVMC::Terminate();
- DisassemblerLLVM::Terminate();
ObjectContainerBSDArchive::Terminate();
ObjectFileELF::Terminate();
SymbolFileDWARF::Terminate();
@@ -189,6 +186,8 @@
DynamicLoaderPOSIXDYLD::Terminate ();
PlatformFreeBSD::Terminate();
PlatformLinux::Terminate();
+ SymbolFileDWARFDebugMap::Terminate();
+ ItaniumABILanguageRuntime::Terminate();
#ifndef LLDB_DISABLE_PYTHON
OperatingSystemPython::Terminate();
#endif
@@ -197,14 +196,11 @@
DynamicLoaderMacOSXDYLD::Terminate();
DynamicLoaderDarwinKernel::Terminate();
OperatingSystemDarwinKernel::Terminate();
- SymbolFileDWARFDebugMap::Terminate();
- ItaniumABILanguageRuntime::Terminate();
AppleObjCRuntimeV2::Terminate();
AppleObjCRuntimeV1::Terminate();
ObjectContainerUniversalMachO::Terminate();
ObjectFileMachO::Terminate();
ProcessMachCore::Terminate();
- ProcessGDBRemote::Terminate();
ProcessKDP::Terminate();
SymbolVendorMacOSX::Terminate();
PlatformMacOSX::Terminate();
@@ -220,23 +216,90 @@
#if defined (__FreeBSD__)
ProcessFreeBSD::Terminate();
- ProcessGDBRemote::Terminate();
#endif
+ ProcessGDBRemote::Terminate();
DynamicLoaderStatic::Terminate();
Log::Terminate();
}
+
+#if defined (__APPLE__)
extern "C" const double liblldb_coreVersionNumber;
+#else
+
+#include "clang/Basic/Version.h"
+
+static const char *
+GetLLDBRevision()
+{
+#ifdef LLDB_REVISION
+ return LLDB_REVISION;
+#else
+ return NULL;
+#endif
+}
+
+static const char *
+GetLLDBRepository()
+{
+#ifdef LLDB_REPOSITORY
+ return LLDB_REPOSITORY;
+#else
+ return NULL;
+#endif
+}
+
+#endif
+
const char *
lldb_private::GetVersion ()
{
+#if defined (__APPLE__)
static char g_version_string[32];
if (g_version_string[0] == '\0')
::snprintf (g_version_string, sizeof(g_version_string), "LLDB-%g", liblldb_coreVersionNumber);
return g_version_string;
+#else
+ // On Linux/FreeBSD/Windows, report a version number in the same style as the clang tool.
+ static std::string g_version_str;
+ if (g_version_str.empty())
+ {
+ g_version_str += "lldb version ";
+ g_version_str += CLANG_VERSION_STRING;
+ const char * lldb_repo = GetLLDBRepository();
+ if (lldb_repo)
+ {
+ g_version_str += " (";
+ g_version_str += lldb_repo;
+ }
+
+ const char *lldb_rev = GetLLDBRevision();
+ if (lldb_rev)
+ {
+ g_version_str += " revision ";
+ g_version_str += lldb_rev;
+ }
+ std::string clang_rev (clang::getClangRevision());
+ if (clang_rev.length() > 0)
+ {
+ g_version_str += " clang revision ";
+ g_version_str += clang_rev;
+ }
+ std::string llvm_rev (clang::getLLVMRevision());
+ if (llvm_rev.length() > 0)
+ {
+ g_version_str += " llvm revision ";
+ g_version_str += llvm_rev;
+ }
+
+ if (lldb_repo)
+ g_version_str += ")";
+ }
+ return g_version_str.c_str();
+#endif
}
const char *
@@ -247,8 +310,6 @@
case eVoteNo: return "no";
case eVoteNoOpinion: return "no opinion";
case eVoteYes: return "yes";
- default:
- break;
}
return "invalid";
}
@@ -325,9 +386,6 @@
return regex.Execute (name);
}
break;
- default:
- assert (!"unhandled NameMatchType in lldb_private::NameMatches()");
- break;
}
}
return false;
Index: aze/lldb/source/lldb-log.cpp
===================================================================
--- aze.orig/lldb/source/lldb-log.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/lldb-log.cpp 2013-03-03 09:35:50.203457351 +0100
@@ -126,6 +126,7 @@
else if (0 == ::strcasecmp(arg, "state")) flag_bits &= ~LIBLLDB_LOG_STATE;
else if (0 == ::strcasecmp(arg, "step")) flag_bits &= ~LIBLLDB_LOG_STEP;
else if (0 == ::strcasecmp(arg, "thread")) flag_bits &= ~LIBLLDB_LOG_THREAD;
+ else if (0 == ::strcasecmp(arg, "target")) flag_bits &= ~LIBLLDB_LOG_TARGET;
else if (0 == ::strcasecmp(arg, "verbose")) flag_bits &= ~LIBLLDB_LOG_VERBOSE;
else if (0 == ::strncasecmp(arg, "watch", 5)) flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS;
else if (0 == ::strncasecmp(arg, "temp", 4)) flag_bits &= ~LIBLLDB_LOG_TEMPORARY;
@@ -136,6 +137,7 @@
else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits &= ~LIBLLDB_LOG_TYPES;
else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits &= ~LIBLLDB_LOG_SYMBOLS;
else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits &= ~LIBLLDB_LOG_MODULES;
+ else if (0 == ::strncasecmp(arg, "mmap", 4)) flag_bits &= ~LIBLLDB_LOG_MMAP;
else
{
feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg);
@@ -193,6 +195,7 @@
else if (0 == ::strcasecmp(arg, "state")) flag_bits |= LIBLLDB_LOG_STATE;
else if (0 == ::strcasecmp(arg, "step")) flag_bits |= LIBLLDB_LOG_STEP;
else if (0 == ::strcasecmp(arg, "thread")) flag_bits |= LIBLLDB_LOG_THREAD;
+ else if (0 == ::strcasecmp(arg, "target")) flag_bits |= LIBLLDB_LOG_TARGET;
else if (0 == ::strcasecmp(arg, "verbose")) flag_bits |= LIBLLDB_LOG_VERBOSE;
else if (0 == ::strncasecmp(arg, "watch", 5)) flag_bits |= LIBLLDB_LOG_WATCHPOINTS;
else if (0 == ::strncasecmp(arg, "temp", 4)) flag_bits |= LIBLLDB_LOG_TEMPORARY;
@@ -203,6 +206,7 @@
else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits |= LIBLLDB_LOG_TYPES;
else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits |= LIBLLDB_LOG_SYMBOLS;
else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits |= LIBLLDB_LOG_MODULES;
+ else if (0 == ::strncasecmp(arg, "mmap", 4)) flag_bits |= LIBLLDB_LOG_MMAP;
else
{
feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
@@ -237,6 +241,7 @@
" state - log private and public process state changes\n"
" step - log step related activities\n"
" symbol - log symbol related issues and warnings\n"
+ " target - log target events and activities\n"
" thread - log thread events and activities\n"
" types - log type system related activities\n"
" unwind - log stack unwind activities\n"
Index: aze/lldb/source/Makefile
===================================================================
--- aze.orig/lldb/source/Makefile 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Makefile 2013-03-03 09:35:50.203457351 +0100
@@ -8,14 +8,30 @@
##===----------------------------------------------------------------------===##
LLDB_LEVEL := ..
-DIRS := API Breakpoint Commands Core Expression Host Interpreter Plugins Symbol Target Utility
+DIRS := API Breakpoint Commands Core DataFormatters Expression Host Interpreter Plugins Symbol Target Utility
LIBRARYNAME := lldbInitAndLog
BUILD_ARCHIVE = 1
+# Although LLVM makefiles provide $(HOST_OS), we cannot use that here because it is defined by including the $(LLDB_LEVEL)/Makefile
+# below. Instead, we use uname -s to detect the HOST_OS and generate LLDB_vers.c only on Mac. On Linux, the version number is
+# calculated in the same way as Clang's version.
+ifeq (Darwin,$(shell uname -s))
BUILT_SOURCES = LLDB_vers.c
+endif
+
SOURCES := lldb-log.cpp lldb.cpp
include $(LLDB_LEVEL)/Makefile
+ifeq ($(HOST_OS),Darwin)
LLDB_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj
"$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj" > LLDB_vers.c
+else
+LLDB_REVISION := $(strip \
+ $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(LLVM_SRC_ROOT)/tools/lldb))
+
+LLDB_REPOSITORY := $(strip \
+ $(shell $(LLVM_SRC_ROOT)/utils/GetRepositoryPath $(LLVM_SRC_ROOT)/tools/lldb))
+
+CPP.Defines += -DLLDB_REVISION='"$(LLDB_REVISION)"' -DLLDB_REPOSITORY='"$(LLDB_REPOSITORY)"'
+endif
Index: aze/lldb/source/Plugins/ABI/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ABI/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1,3 @@
+add_subdirectory(SysV-x86_64)
+add_subdirectory(MacOSX-i386)
+add_subdirectory(MacOSX-arm)
Index: aze/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp 2013-03-03 09:35:50.203457351 +0100
@@ -332,10 +332,7 @@
if (!reg_ctx)
return false;
- addr_t sp = reg_ctx->GetSP(0);
-
- if (!sp)
- return false;
+ addr_t sp = 0;
for (uint32_t value_idx = 0; value_idx < num_values; ++value_idx)
{
@@ -405,6 +402,14 @@
}
else
{
+ if (sp == 0)
+ {
+ // Read the stack pointer if it already hasn't been read
+ sp = reg_ctx->GetSP(0);
+ if (sp == 0)
+ return false;
+ }
+
// Arguments 5 on up are on the stack
const uint32_t arg_byte_size = (bit_width + (8-1)) / 8;
Error error;
@@ -421,7 +426,7 @@
ValueObjectSP
ABIMacOSX_arm::GetReturnValueObjectImpl (Thread &thread,
- lldb_private::ClangASTType &ast_type) const
+ lldb_private::ClangASTType &ast_type) const
{
Value value;
ValueObjectSP return_valobj_sp;
@@ -543,7 +548,7 @@
{
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (num_bytes <= 8)
{
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
Index: aze/lldb/source/Plugins/ABI/MacOSX-arm/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ABI/MacOSX-arm/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginABIMacOSX_arm
+ ABIMacOSX_arm.cpp
+ )
Index: aze/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp 2013-03-03 09:35:50.203457351 +0100
@@ -453,7 +453,6 @@
switch (scalar.GetType())
{
case Scalar::e_void:
- default:
return false;
case Scalar::e_sint:
case Scalar::e_uint:
@@ -723,7 +722,7 @@
{
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (num_bytes <= 8)
{
const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
@@ -928,22 +927,24 @@
bool
ABIMacOSX_i386::RegisterIsVolatile (const RegisterInfo *reg_info)
{
- return RegisterIsCalleeSaved (reg_info);
+ return !RegisterIsCalleeSaved (reg_info);
}
+// v. http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW4
+
bool
ABIMacOSX_i386::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
{
if (reg_info)
{
- // Volatile registers include: ebx, ebp, esi, edi, esp, eip
+ // Saved registers are ebx, ebp, esi, edi, esp, eip
const char *name = reg_info->name;
if (name[0] == 'e')
{
switch (name[1])
{
case 'b':
- if (name[2] == 'x') // ebp is volatile in the ABI, but the unwinders can find it
+ if (name[2] == 'x' || name[2] == 'p')
return name[3] == '\0';
break;
case 'd':
@@ -960,6 +961,12 @@
break;
}
}
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
}
return false;
}
Index: aze/lldb/source/Plugins/ABI/MacOSX-i386/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ABI/MacOSX-i386/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginABIMacOSX_i386
+ ABIMacOSX_i386.cpp
+ )
Index: aze/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp 2013-03-03 09:35:50.203457351 +0100
@@ -318,7 +318,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
- log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%llx\n func_addr = 0x%llx\n return_addr = 0x%llx\n arg1_ptr = %p (0x%llx)\n arg2_ptr = %p (0x%llx)\n arg3_ptr = %p (0x%llx)\n)",
+ log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%" PRIx64 "\n func_addr = 0x%" PRIx64 "\n return_addr = 0x%" PRIx64 "\n arg1_ptr = %p (0x%" PRIx64 ")\n arg2_ptr = %p (0x%" PRIx64 ")\n arg3_ptr = %p (0x%" PRIx64 ")\n)",
(void*)&thread,
(uint64_t)sp,
(uint64_t)func_addr,
@@ -336,7 +336,7 @@
{
reg_info = reg_ctx->GetRegisterInfoByName("rdi", 0);
if (log)
- log->Printf("About to write arg1 (0x%llx) into %s", (uint64_t)*arg1_ptr, reg_info->name);
+ log->Printf("About to write arg1 (0x%" PRIx64 ") into %s", (uint64_t)*arg1_ptr, reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg1_ptr))
return false;
@@ -345,7 +345,7 @@
{
reg_info = reg_ctx->GetRegisterInfoByName("rsi", 0);
if (log)
- log->Printf("About to write arg2 (0x%llx) into %s", (uint64_t)*arg2_ptr, reg_info->name);
+ log->Printf("About to write arg2 (0x%" PRIx64 ") into %s", (uint64_t)*arg2_ptr, reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg2_ptr))
return false;
@@ -353,7 +353,7 @@
{
reg_info = reg_ctx->GetRegisterInfoByName("rdx", 0);
if (log)
- log->Printf("About to write arg3 (0x%llx) into %s", (uint64_t)*arg3_ptr, reg_info->name);
+ log->Printf("About to write arg3 (0x%" PRIx64 ") into %s", (uint64_t)*arg3_ptr, reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg3_ptr))
return false;
@@ -361,7 +361,7 @@
{
reg_info = reg_ctx->GetRegisterInfoByName("rcx", 0);
if (log)
- log->Printf("About to write arg4 (0x%llx) into %s", (uint64_t)*arg4_ptr, reg_info->name);
+ log->Printf("About to write arg4 (0x%" PRIx64 ") into %s", (uint64_t)*arg4_ptr, reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg4_ptr))
return false;
@@ -369,7 +369,7 @@
{
reg_info = reg_ctx->GetRegisterInfoByName("r8", 0);
if (log)
- log->Printf("About to write arg5 (0x%llx) into %s", (uint64_t)*arg5_ptr, reg_info->name);
+ log->Printf("About to write arg5 (0x%" PRIx64 ") into %s", (uint64_t)*arg5_ptr, reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg5_ptr))
return false;
@@ -377,7 +377,7 @@
{
reg_info = reg_ctx->GetRegisterInfoByName("r9", 0);
if (log)
- log->Printf("About to write arg6 (0x%llx) into %s", (uint64_t)*arg6_ptr, reg_info->name);
+ log->Printf("About to write arg6 (0x%" PRIx64 ") into %s", (uint64_t)*arg6_ptr, reg_info->name);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_info, *arg6_ptr))
return false;
}
@@ -391,7 +391,7 @@
// First, align the SP
if (log)
- log->Printf("16-byte aligning SP: 0x%llx to 0x%llx", (uint64_t)sp, (uint64_t)(sp & ~0xfull));
+ log->Printf("16-byte aligning SP: 0x%" PRIx64 " to 0x%" PRIx64, (uint64_t)sp, (uint64_t)(sp & ~0xfull));
sp &= ~(0xfull); // 16-byte alignment
@@ -402,7 +402,7 @@
reg_value.SetUInt64 (return_addr);
if (log)
- log->Printf("Pushing the return address onto the stack: new SP 0x%llx, return address 0x%llx", (uint64_t)sp, (uint64_t)return_addr);
+ log->Printf("Pushing the return address onto the stack: new SP 0x%" PRIx64 ", return address 0x%" PRIx64, (uint64_t)sp, (uint64_t)return_addr);
const RegisterInfo *pc_reg_info = reg_ctx->GetRegisterInfoByName("rip");
Error error (reg_ctx->WriteRegisterValueToMemory(pc_reg_info, sp, pc_reg_info->byte_size, reg_value));
@@ -412,7 +412,7 @@
// %rsp is set to the actual stack value.
if (log)
- log->Printf("Writing SP (0x%llx) down", (uint64_t)sp);
+ log->Printf("Writing SP (0x%" PRIx64 ") down", (uint64_t)sp);
if (!reg_ctx->WriteRegisterFromUnsigned (reg_ctx->GetRegisterInfoByName("rsp"), sp))
return false;
@@ -420,7 +420,7 @@
// %rip is set to the address of the called function.
if (log)
- log->Printf("Writing new IP (0x%llx) down", (uint64_t)func_addr);
+ log->Printf("Writing new IP (0x%" PRIx64 ") down", (uint64_t)func_addr);
if (!reg_ctx->WriteRegisterFromUnsigned (pc_reg_info, func_addr))
return false;
@@ -588,7 +588,7 @@
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (num_bytes <= 8)
{
uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
@@ -727,7 +727,7 @@
DataExtractor data;
if (xmm0_value.GetData(data))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
switch (bit_width)
{
default:
@@ -1153,14 +1153,23 @@
-
+// See "Register Usage" in the
+// "System V Application Binary Interface"
+// "AMD64 Architecture Processor Supplement"
+// (or "x86-64(tm) Architecture Processor Supplement" in earlier revisions)
+// Edited by Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
+// current version is 0.99.6 released 2012-05-15 at http://x86-64.org/documentation/abi.pdf
bool
ABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
{
if (reg_info)
{
- // Volatile registers include: rbx, rbp, rsp, r12, r13, r14, r15, rip
+ // Preserved registers are :
+ // rbx, rsp, rbp, r12, r13, r14, r15
+ // mxcsr (partially preserved)
+ // x87 control word
+
const char *name = reg_info->name;
if (name[0] == 'r')
{
@@ -1198,6 +1207,12 @@
}
}
+ if (name[0] == 's' && name[1] == 'p' && name[2] == '\0') // sp
+ return true;
+ if (name[0] == 'f' && name[1] == 'p' && name[2] == '\0') // fp
+ return true;
+ if (name[0] == 'p' && name[1] == 'c' && name[2] == '\0') // pc
+ return true;
}
return false;
}
Index: aze/lldb/source/Plugins/ABI/SysV-x86_64/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ABI/SysV-x86_64/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginABISysV_x86_64
+ ABISysV_x86_64.cpp
+ )
Index: aze/lldb/source/Plugins/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1,13 @@
+add_subdirectory(ABI)
+add_subdirectory(Disassembler)
+add_subdirectory(DynamicLoader)
+add_subdirectory(Instruction)
+add_subdirectory(LanguageRuntime)
+add_subdirectory(ObjectContainer)
+add_subdirectory(ObjectFile)
+add_subdirectory(OperatingSystem)
+add_subdirectory(Platform)
+add_subdirectory(Process)
+add_subdirectory(SymbolFile)
+add_subdirectory(SymbolVendor)
+add_subdirectory(UnwindAssembly)
Index: aze/lldb/source/Plugins/Disassembler/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Disassembler/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1 @@
+add_subdirectory(llvm)
Index: aze/lldb/source/Plugins/Disassembler/llvm/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Disassembler/llvm/CMakeLists.txt 2013-03-03 09:35:50.203457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginDisassemblerLLVM
+ DisassemblerLLVMC.cpp
+ )
Index: aze/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp 2013-03-03 09:35:50.203457351 +0100
@@ -10,7 +10,20 @@
#include "DisassemblerLLVMC.h"
#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/ADT/SmallString.h"
+
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
@@ -68,7 +81,7 @@
virtual size_t
Decode (const lldb_private::Disassembler &disassembler,
const lldb_private::DataExtractor &data,
- uint32_t data_offset)
+ lldb::offset_t data_offset)
{
// All we have to do is read the opcode which can be easy for some
// architetures
@@ -113,19 +126,20 @@
}
if (!got_op)
{
- ::LLVMDisasmContextRef disasm_context = m_disasm.m_disasm_context;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = m_disasm.m_disasm_ap.get();
bool is_altnernate_isa = false;
- if (m_disasm.m_alternate_disasm_context)
+ if (m_disasm.m_alternate_disasm_ap.get() != NULL)
{
const AddressClass address_class = GetAddressClass ();
if (address_class == eAddressClassCodeAlternateISA)
{
- disasm_context = m_disasm.m_alternate_disasm_context;
+ mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
is_altnernate_isa = true;
}
}
+
const llvm::Triple::ArchType machine = arch.GetMachine();
if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{
@@ -155,19 +169,16 @@
{
// The opcode isn't evenly sized, so we need to actually use the llvm
// disassembler to parse it and get the size.
- char out_string[512];
m_disasm.Lock(this, NULL);
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
const size_t opcode_data_len = data.GetByteSize() - data_offset;
const addr_t pc = m_address.GetFileAddress();
- const size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
- opcode_data,
- opcode_data_len,
- pc, // PC value
- out_string,
- sizeof(out_string));
- // The address lookup function could have caused us to fill in our comment
- m_comment.clear();
+ llvm::MCInst inst;
+
+ const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
m_disasm.Unlock();
if (inst_size == 0)
m_opcode.Clear();
@@ -203,12 +214,12 @@
{
char out_string[512];
- ::LLVMDisasmContextRef disasm_context;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
if (address_class == eAddressClassCodeAlternateISA)
- disasm_context = m_disasm.m_alternate_disasm_context;
+ mc_disasm_ptr = m_disasm.m_alternate_disasm_ap.get();
else
- disasm_context = m_disasm.m_disasm_context;
+ mc_disasm_ptr = m_disasm.m_disasm_ap.get();
lldb::addr_t pc = LLDB_INVALID_ADDRESS;
@@ -223,14 +234,17 @@
pc = m_address.GetFileAddress();
m_disasm.Lock(this, exe_ctx);
+
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
const size_t opcode_data_len = data.GetByteSize();
- size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
- opcode_data,
+ llvm::MCInst inst;
+ size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
opcode_data_len,
pc,
- out_string,
- sizeof(out_string));
+ inst);
+
+ if (inst_size > 0)
+ mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
m_disasm.Unlock();
@@ -239,7 +253,7 @@
m_comment.assign ("unknown opcode");
inst_size = m_opcode.GetByteSize();
StreamString mnemonic_strm;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
switch (inst_size)
{
case 1:
@@ -271,7 +285,7 @@
const uint64_t uval64 = data.GetU64(&offset);
m_opcode.SetOpcode64(uval64);
m_opcode_name.assign (".quad");
- mnemonic_strm.Printf("0x%16.16llx", uval64);
+ mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
}
break;
default:
@@ -290,17 +304,19 @@
}
break;
}
- m_mnemocics.swap(mnemonic_strm.GetString());
+ m_mnemonics.swap(mnemonic_strm.GetString());
return;
}
else
{
if (m_does_branch == eLazyBoolCalculate)
{
- if (StringRepresentsBranch (out_string, strlen(out_string)))
+ bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
m_does_branch = eLazyBoolYes;
else
m_does_branch = eLazyBoolNo;
+
}
}
@@ -317,7 +333,7 @@
if (matches[1].rm_so != -1)
m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
if (matches[2].rm_so != -1)
- m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
+ m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
}
}
}
@@ -335,88 +351,6 @@
}
protected:
- bool StringRepresentsBranch (const char *data, size_t size)
- {
- const char *cursor = data;
-
- bool inWhitespace = true;
-
- while (inWhitespace && cursor < data + size)
- {
- switch (*cursor)
- {
- default:
- inWhitespace = false;
- break;
- case ' ':
- break;
- case '\t':
- break;
- }
-
- if (inWhitespace)
- ++cursor;
- }
-
- if (cursor >= data + size)
- return false;
-
- llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine();
-
- switch (arch)
- {
- default:
- return false;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (cursor[0])
- {
- default:
- return false;
- case 'j':
- return true;
- case 'c':
- if (cursor[1] == 'a' &&
- cursor[2] == 'l' &&
- cursor[3] == 'l')
- return true;
- else
- return false;
- }
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (cursor[0])
- {
- default:
- return false;
- case 'b':
- {
- switch (cursor[1])
- {
- default:
- return true;
- case 'f':
- case 'i':
- case 'k':
- return false;
- }
- }
- case 'c':
- {
- switch (cursor[1])
- {
- default:
- return false;
- case 'b':
- return true;
- }
- }
- }
- }
-
- return false;
- }
-
bool m_is_valid;
DisassemblerLLVMC &m_disasm;
DisassemblerSP m_disasm_sp; // for ownership
@@ -429,12 +363,159 @@
bool InstructionLLVMC::s_regex_compiled = false;
::regex_t InstructionLLVMC::s_regex;
+DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
+ m_is_valid(true)
+{
+ std::string Error;
+ const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
+ if (!curr_target)
+ {
+ m_is_valid = false;
+ return;
+ }
+
+ m_instr_info_ap.reset(curr_target->createMCInstrInfo());
+ m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
+
+ std::string features_str;
+
+ m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
+ features_str));
+
+ m_asm_info_ap.reset(curr_target->createMCAsmInfo(triple));
+
+ if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
+ {
+ m_is_valid = NULL;
+ return;
+ }
+
+ m_context_ap.reset(new llvm::MCContext(*m_asm_info_ap.get(), *(m_reg_info_ap.get()), 0));
+
+ m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
+ if (m_disasm_ap.get())
+ {
+ m_disasm_ap->setupForSymbolicDisassembly(NULL,
+ DisassemblerLLVMC::SymbolLookupCallback,
+ (void *) &owner,
+ m_context_ap.get());
+
+ unsigned asm_printer_variant;
+ if (flavor == ~0U)
+ asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
+ else
+ {
+ asm_printer_variant = flavor;
+ }
+
+ m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
+ *m_asm_info_ap.get(),
+ *m_instr_info_ap.get(),
+ *m_reg_info_ap.get(),
+ *m_subtarget_info_ap.get()));
+ if (m_instr_printer_ap.get() == NULL)
+ {
+ m_disasm_ap.reset();
+ m_is_valid = false;
+ }
+ }
+ else
+ m_is_valid = false;
+}
+
+namespace {
+ // This is the memory object we use in GetInstruction.
+ class LLDBDisasmMemoryObject : public llvm::MemoryObject {
+ uint8_t *m_bytes;
+ uint64_t m_size;
+ uint64_t m_base_PC;
+ public:
+ LLDBDisasmMemoryObject(uint8_t *bytes, uint64_t size, uint64_t basePC) :
+ m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
+
+ uint64_t getBase() const { return m_base_PC; }
+ uint64_t getExtent() const { return m_size; }
+
+ int readByte(uint64_t addr, uint8_t *byte) const {
+ if (addr - m_base_PC >= m_size)
+ return -1;
+ *byte = m_bytes[addr - m_base_PC];
+ return 0;
+ }
+ };
+} // End Anonymous Namespace
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (
+ uint8_t *opcode_data,
+ size_t opcode_data_len,
+ lldb::addr_t pc,
+ llvm::MCInst &mc_inst)
+{
+ LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
+ llvm::MCInst inst;
+ llvm::MCDisassembler::DecodeStatus status;
+
+ uint64_t new_inst_size;
+ status = m_disasm_ap->getInstruction(mc_inst,
+ new_inst_size,
+ memory_object,
+ pc,
+ llvm::nulls(),
+ llvm::nulls());
+ if (status == llvm::MCDisassembler::Success)
+ return new_inst_size;
+ else
+ return 0;
+}
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len)
+{
+ llvm::StringRef unused_annotations;
+ llvm::SmallString<64> inst_string;
+ llvm::raw_svector_ostream inst_stream(inst_string);
+ m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
+ inst_stream.flush();
+
+ size_t output_size = std::min(out_buffer_len -1, inst_string.size());
+ std::memcpy(output_buffer, inst_string.data(), output_size);
+ output_buffer[output_size] = '\0';
+
+ return output_size;
+}
+
+bool
+DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
+{
+ return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
+}
+
+bool
+DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
+{
+ llvm::Triple triple = arch.GetTriple();
+ if (flavor == NULL || strcmp (flavor, "default") == 0)
+ return true;
+
+ if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
+ {
+ if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
+ return true;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+
Disassembler *
-DisassemblerLLVMC::CreateInstance (const ArchSpec &arch)
+DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
{
if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
{
- std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch));
+ std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
if (disasm_ap.get() && disasm_ap->IsValid())
return disasm_ap.release();
@@ -442,18 +523,41 @@
return NULL;
}
-DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) :
- Disassembler(arch),
+DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
+ Disassembler(arch, flavor_string),
m_exe_ctx (NULL),
- m_inst (NULL),
- m_disasm_context (NULL),
- m_alternate_disasm_context (NULL)
-{
- m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- DisassemblerLLVMC::SymbolLookupCallback);
+ m_inst (NULL)
+{
+ if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
+ {
+ m_flavor.assign("default");
+ }
+
+ const char *triple = arch.GetTriple().getTriple().c_str();
+ unsigned flavor = ~0U;
+
+ // So far the only supported flavor is "intel" on x86. The base class will set this
+ // correctly coming in.
+ if (arch.GetTriple().getArch() == llvm::Triple::x86
+ || arch.GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ if (m_flavor == "intel")
+ {
+ flavor = 1;
+ }
+ else if (m_flavor == "att")
+ {
+ flavor = 0;
+ }
+ }
+
+ m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
+ if (!m_disasm_ap->IsValid())
+ {
+ // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
+ // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
+ m_disasm_ap.reset();
+ }
if (arch.GetTriple().getArch() == llvm::Triple::arm)
{
@@ -461,33 +565,24 @@
thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
std::string thumb_triple(thumb_arch.GetTriple().getTriple());
- m_alternate_disasm_context = ::LLVMCreateDisasm(thumb_triple.c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- DisassemblerLLVMC::SymbolLookupCallback);
+ m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
+ if (!m_alternate_disasm_ap->IsValid())
+ {
+ m_disasm_ap.reset();
+ m_alternate_disasm_ap.reset();
+ }
}
}
DisassemblerLLVMC::~DisassemblerLLVMC()
{
- if (m_disasm_context)
- {
- ::LLVMDisasmDispose(m_disasm_context);
- m_disasm_context = NULL;
- }
- if (m_alternate_disasm_context)
- {
- ::LLVMDisasmDispose(m_alternate_disasm_context);
- m_alternate_disasm_context = NULL;
- }
}
size_t
DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
const DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
+ lldb::offset_t data_offset,
+ size_t num_instructions,
bool append)
{
if (!append)
@@ -506,7 +601,7 @@
AddressClass address_class = eAddressClassCode;
- if (m_alternate_disasm_context)
+ if (m_alternate_disasm_ap.get() != NULL)
address_class = inst_addr.GetAddressClass ();
InstructionSP inst_sp(new InstructionLLVMC(*this,
@@ -644,7 +739,7 @@
m_inst->AppendComment(ss.GetString());
}
}
- //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16llx, type=%llu, pc=0x%16.16llx, name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
+ //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16" PRIx64 ", type=%" PRIu64 ", pc=0x%16.16" PRIx64 ", name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
}
}
Index: aze/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
===================================================================
--- aze.orig/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h 2013-03-03 09:35:50.207457352 +0100
@@ -10,9 +10,23 @@
#ifndef liblldb_DisassemblerLLVMC_h_
#define liblldb_DisassemblerLLVMC_h_
+#include <string>
#include "llvm-c/Disassembler.h"
+// Opaque references to C++ Objects in LLVM's MC.
+namespace llvm
+{
+ class MCContext;
+ class MCInst;
+ class MCInstrInfo;
+ class MCRegisterInfo;
+ class MCDisassembler;
+ class MCInstPrinter;
+ class MCAsmInfo;
+ class MCSubtargetInfo;
+}
+
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/PluginManager.h"
@@ -22,6 +36,34 @@
class DisassemblerLLVMC : public lldb_private::Disassembler
{
+ // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), and there's a bit of goo to set up and own
+ // in the MC disassembler world, I added this class to manage the actual disassemblers.
+ class LLVMCDisassembler
+ {
+ public:
+ LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner);
+
+ ~LLVMCDisassembler() {};
+
+ uint64_t GetMCInst (uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
+ uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len);
+ bool CanBranch (llvm::MCInst &mc_inst);
+ bool IsValid()
+ {
+ return m_is_valid;
+ }
+
+ private:
+ bool m_is_valid;
+ std::auto_ptr<llvm::MCContext> m_context_ap;
+ std::auto_ptr<llvm::MCAsmInfo> m_asm_info_ap;
+ std::auto_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
+ std::auto_ptr<llvm::MCInstrInfo> m_instr_info_ap;
+ std::auto_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
+ std::auto_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
+ std::auto_ptr<llvm::MCDisassembler> m_disasm_ap;
+ };
+
public:
//------------------------------------------------------------------
// Static Functions
@@ -39,10 +81,9 @@
GetPluginDescriptionStatic();
static lldb_private::Disassembler *
- CreateInstance(const lldb_private::ArchSpec &arch);
-
-
- DisassemblerLLVMC(const lldb_private::ArchSpec &arch);
+ CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
+
+ DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
virtual
~DisassemblerLLVMC();
@@ -50,8 +91,8 @@
size_t
DecodeInstructions (const lldb_private::Address &base_addr,
const lldb_private::DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
+ lldb::offset_t data_offset,
+ size_t num_instructions,
bool append);
//------------------------------------------------------------------
@@ -69,10 +110,13 @@
protected:
friend class InstructionLLVMC;
+ virtual bool
+ FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor);
+
bool
IsValid()
{
- return (m_disasm_context != NULL);
+ return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
}
int OpInfo(uint64_t PC,
@@ -117,8 +161,9 @@
const lldb_private::ExecutionContext *m_exe_ctx;
InstructionLLVMC *m_inst;
lldb_private::Mutex m_mutex;
- ::LLVMDisasmContextRef m_disasm_context;
- ::LLVMDisasmContextRef m_alternate_disasm_context;
+
+ std::auto_ptr<LLVMCDisassembler> m_disasm_ap;
+ std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
};
#endif // liblldb_DisassemblerLLVM_h_
Index: aze/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.cpp 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,529 +0,0 @@
-//===-- DisassemblerLLVM.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DisassemblerLLVM.h"
-
-#include "llvm-c/EnhancedDisassembly.h"
-#include "llvm/Support/TargetSelect.h"
-
-#include "lldb/Core/Address.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Disassembler.h"
-#include "lldb/Core/Module.h"
-#include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Stream.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Symbol/SymbolContext.h"
-
-#include "lldb/Target/ExecutionContext.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/RegisterContext.h"
-#include "lldb/Target/Target.h"
-
-#include <assert.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-
-static int
-DataExtractorByteReader (uint8_t *byte, uint64_t address, void *arg)
-{
- DataExtractor &extractor = *((DataExtractor *)arg);
-
- if (extractor.ValidOffset(address))
- {
- *byte = *(extractor.GetDataStart() + address);
- return 0;
- }
- else
- {
- return -1;
- }
-}
-
-namespace {
- struct RegisterReaderArg {
- const lldb::addr_t instructionPointer;
- const EDDisassemblerRef disassembler;
-
- RegisterReaderArg(lldb::addr_t ip,
- EDDisassemblerRef dis) :
- instructionPointer(ip),
- disassembler(dis)
- {
- }
- };
-}
-
-static int IPRegisterReader(uint64_t *value, unsigned regID, void* arg)
-{
- uint64_t instructionPointer = ((RegisterReaderArg*)arg)->instructionPointer;
- EDDisassemblerRef disassembler = ((RegisterReaderArg*)arg)->disassembler;
-
- if (EDRegisterIsProgramCounter(disassembler, regID)) {
- *value = instructionPointer;
- return 0;
- }
-
- return -1;
-}
-
-InstructionLLVM::InstructionLLVM (const Address &addr,
- AddressClass addr_class,
- EDDisassemblerRef disassembler,
- llvm::Triple::ArchType arch_type) :
- Instruction (addr, addr_class),
- m_disassembler (disassembler),
- m_inst (NULL),
- m_arch_type (arch_type)
-{
-}
-
-InstructionLLVM::~InstructionLLVM()
-{
- if (m_inst)
- {
- EDReleaseInst(m_inst);
- m_inst = NULL;
- }
-}
-
-static void
-PadString(Stream *s, const std::string &str, size_t width)
-{
- int diff = width - str.length();
-
- if (diff > 0)
- s->Printf("%s%*.*s", str.c_str(), diff, diff, "");
- else
- s->Printf("%s ", str.c_str());
-}
-static void
-AddSymbolicInfo (const ExecutionContext *exe_ctx,
- StreamString &comment,
- uint64_t operand_value,
- const Address &inst_addr)
-{
- Address so_addr;
- Target *target = NULL;
- if (exe_ctx)
- target = exe_ctx->GetTargetPtr();
- if (target && !target->GetSectionLoadList().IsEmpty())
- {
- if (target->GetSectionLoadList().ResolveLoadAddress(operand_value, so_addr))
- so_addr.Dump (&comment,
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
- Address::DumpStyleResolvedDescriptionNoModule,
- Address::DumpStyleSectionNameOffset);
- }
- else
- {
- ModuleSP module_sp (inst_addr.GetModule());
- if (module_sp)
- {
- if (module_sp->ResolveFileAddress(operand_value, so_addr))
- so_addr.Dump (&comment,
- exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL,
- Address::DumpStyleResolvedDescriptionNoModule,
- Address::DumpStyleSectionNameOffset);
- }
- }
-}
-
-#include "llvm/ADT/StringRef.h"
-static inline void StripSpaces(llvm::StringRef &Str)
-{
- while (!Str.empty() && isspace(Str[0]))
- Str = Str.substr(1);
- while (!Str.empty() && isspace(Str.back()))
- Str = Str.substr(0, Str.size()-1);
-}
-static inline void RStrip(llvm::StringRef &Str, char c)
-{
- if (!Str.empty() && Str.back() == c)
- Str = Str.substr(0, Str.size()-1);
-}
-// Aligns the raw disassembly (passed as 'str') with the rest of edis'ed disassembly output.
-// This is called from non-raw mode when edis of the current m_inst fails for some reason.
-static void
-Align(Stream *s, const char *str, size_t opcodeColWidth, size_t operandColWidth)
-{
- llvm::StringRef raw_disasm(str);
- StripSpaces(raw_disasm);
- // Split the raw disassembly into opcode and operands.
- std::pair<llvm::StringRef, llvm::StringRef> p = raw_disasm.split('\t');
- PadString(s, p.first, opcodeColWidth);
- if (!p.second.empty())
- PadString(s, p.second, operandColWidth);
-}
-
-#define AlignPC(pc_val) (pc_val & 0xFFFFFFFC)
-
-void
-InstructionLLVM::CalculateMnemonicOperandsAndComment (const ExecutionContext* exe_ctx)
-{
- const int num_tokens = EDNumTokens(m_inst);
- if (num_tokens > 0)
- {
- const char *token_cstr = NULL;
- int currentOpIndex = -1;
- StreamString comment;
- uint32_t addr_nibble_size = 8;
- addr_t base_addr = LLDB_INVALID_ADDRESS;
- Target *target = exe_ctx ? exe_ctx->GetTargetPtr() : NULL;
- if (target)
- {
- addr_nibble_size = target->GetArchitecture().GetAddressByteSize() * 2;
- if (!target->GetSectionLoadList().IsEmpty())
- base_addr = GetAddress().GetLoadAddress (target);
- }
-
- if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = GetAddress().GetFileAddress ();
-
- lldb::addr_t PC = base_addr + EDInstByteSize(m_inst);
-
- // When executing an ARM instruction, PC reads as the address of the
- // current instruction plus 8. And for Thumb, it is plus 4.
- if (m_arch_type == llvm::Triple::arm)
- PC = base_addr + 8;
- else if (m_arch_type == llvm::Triple::thumb)
- PC = base_addr + 4;
-
- RegisterReaderArg rra(PC, m_disassembler);
-
- for (int token_idx = 0; token_idx < num_tokens; ++token_idx)
- {
- EDTokenRef token;
- if (EDGetToken(&token, m_inst, token_idx))
- break;
-
- if (EDTokenIsOpcode(token) == 1)
- {
- if (EDGetTokenString(&token_cstr, token) == 0) // 0 on success
- {
- if (token_cstr)
- m_opcode_name.assign(token_cstr);
- }
- }
- else
- {
- int operandIndex = EDOperandIndexForToken(token);
-
- if (operandIndex >= 0)
- {
- if (operandIndex != currentOpIndex)
- {
- currentOpIndex = operandIndex;
- EDOperandRef operand;
-
- if (!EDGetOperand(&operand, m_inst, currentOpIndex))
- {
- if (EDOperandIsMemory(operand))
- {
- uint64_t operand_value;
-
- if (!EDEvaluateOperand(&operand_value, operand, IPRegisterReader, &rra))
- {
- comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
- AddSymbolicInfo (exe_ctx, comment, operand_value, GetAddress());
- }
- }
- }
- }
- }
- if (m_mnemocics.empty() && EDTokenIsWhitespace (token) == 1)
- continue;
- if (EDGetTokenString (&token_cstr, token))
- break;
- m_mnemocics.append (token_cstr);
- }
- }
- // FIXME!!!
- // Workaround for llvm::tB's operands not properly parsed by ARMAsmParser.
- if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("b") == 0)
- {
- const char *inst_str;
- const char *pos = NULL;
- comment.Clear();
- if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL)
- {
- uint64_t operand_value = PC + atoi(++pos);
- // Put the address value into the operands.
- comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
- AddSymbolicInfo (exe_ctx, comment, operand_value, GetAddress());
- }
- }
- // Yet more workaround for "bl #..." and "blx #...".
- if ((m_arch_type == llvm::Triple::arm || m_arch_type == llvm::Triple::thumb) &&
- (m_opcode_name.compare("bl") == 0 || m_opcode_name.compare("blx") == 0))
- {
- const char *inst_str;
- const char *pos = NULL;
- comment.Clear();
- if (EDGetInstString(&inst_str, m_inst) == 0 && (pos = strstr(inst_str, "#")) != NULL)
- {
- if (m_arch_type == llvm::Triple::thumb && m_opcode_name.compare("blx") == 0)
- {
- // A8.6.23 BLX (immediate)
- // Target Address = Align(PC,4) + offset value
- PC = AlignPC(PC);
- }
- uint64_t operand_value = PC + atoi(++pos);
- // Put the address value into the comment.
- comment.Printf("0x%*.*llx ", addr_nibble_size, addr_nibble_size, operand_value);
- // And the original token string into the operands.
-// llvm::StringRef Str(pos - 1);
-// RStrip(Str, '\n');
-// operands.PutCString(Str.str().c_str());
- AddSymbolicInfo (exe_ctx, comment, operand_value, GetAddress());
- }
- }
- // END of workaround.
-
- m_comment.swap (comment.GetString());
- }
-}
-
-bool
-InstructionLLVM::DoesBranch() const
-{
- return EDInstIsBranch(m_inst);
-}
-
-size_t
-InstructionLLVM::Decode (const Disassembler &disassembler,
- const lldb_private::DataExtractor &data,
- uint32_t data_offset)
-{
- if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data)))
- {
- const int byte_size = EDInstByteSize(m_inst);
- uint32_t offset = data_offset;
- // Make a copy of the opcode in m_opcode
- switch (disassembler.GetArchitecture().GetMachine())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- m_opcode.SetOpcodeBytes (data.PeekData (data_offset, byte_size), byte_size);
- break;
-
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (byte_size)
- {
- case 2:
- m_opcode.SetOpcode16 (data.GetU16 (&offset));
- break;
-
- case 4:
- {
- if (GetAddressClass() == eAddressClassCodeAlternateISA)
- {
- // If it is a 32-bit THUMB instruction, we need to swap the upper & lower halves.
- uint32_t orig_bytes = data.GetU32 (&offset);
- uint16_t upper_bits = (orig_bytes >> 16) & ((1u << 16) - 1);
- uint16_t lower_bits = orig_bytes & ((1u << 16) - 1);
- uint32_t swapped = (lower_bits << 16) | upper_bits;
- m_opcode.SetOpcode32 (swapped);
- }
- else
- m_opcode.SetOpcode32 (data.GetU32 (&offset));
- }
- break;
-
- default:
- assert (!"Invalid ARM opcode size");
- break;
- }
- break;
-
- default:
- assert (!"This shouldn't happen since we control the architecture we allow DisassemblerLLVM to be created for");
- break;
- }
- return byte_size;
- }
- else
- return 0;
-}
-
-static inline EDAssemblySyntax_t
-SyntaxForArchSpec (const ArchSpec &arch)
-{
- switch (arch.GetMachine ())
- {
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return kEDAssemblySyntaxX86ATT;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- return kEDAssemblySyntaxARMUAL;
- default:
- break;
- }
- return (EDAssemblySyntax_t)0; // default
-}
-
-Disassembler *
-DisassemblerLLVM::CreateInstance(const ArchSpec &arch)
-{
- std::auto_ptr<DisassemblerLLVM> disasm_ap (new DisassemblerLLVM(arch));
-
- if (disasm_ap.get() && disasm_ap->IsValid())
- return disasm_ap.release();
-
- return NULL;
-}
-
-DisassemblerLLVM::DisassemblerLLVM(const ArchSpec &arch) :
- Disassembler (arch),
- m_disassembler (NULL),
- m_disassembler_thumb (NULL) // For ARM only
-{
- // Initialize the LLVM objects needed to use the disassembler.
- static struct InitializeLLVM {
- InitializeLLVM() {
- llvm::InitializeAllTargetInfos();
- llvm::InitializeAllTargetMCs();
- llvm::InitializeAllAsmParsers();
- llvm::InitializeAllDisassemblers();
- }
- } InitializeLLVM;
-
- const std::string &arch_triple = arch.GetTriple().str();
- if (!arch_triple.empty())
- {
- if (EDGetDisassembler(&m_disassembler, arch_triple.c_str(), SyntaxForArchSpec (arch)))
- m_disassembler = NULL;
- llvm::Triple::ArchType llvm_arch = arch.GetTriple().getArch();
- // Don't have the lldb::Triple::thumb architecture here. If someone specifies
- // "thumb" as the architecture, we want a thumb only disassembler. But if any
- // architecture starting with "arm" if specified, we want to auto detect the
- // arm/thumb code automatically using the AddressClass from section offset
- // addresses.
- if (llvm_arch == llvm::Triple::arm)
- {
- ArchSpec thumb_arch(arch);
- thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
- std::string thumb_triple(thumb_arch.GetTriple().getTriple());
- if (EDGetDisassembler(&m_disassembler_thumb, thumb_triple.c_str(), kEDAssemblySyntaxARMUAL))
- m_disassembler_thumb = NULL;
- }
- }
-}
-
-DisassemblerLLVM::~DisassemblerLLVM()
-{
-}
-
-size_t
-DisassemblerLLVM::DecodeInstructions
-(
- const Address &base_addr,
- const DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
- bool append
-)
-{
- if (m_disassembler == NULL)
- return 0;
-
- size_t total_inst_byte_size = 0;
-
- if (!append)
- m_instruction_list.Clear();
-
- while (data.ValidOffset(data_offset) && num_instructions)
- {
- Address inst_addr (base_addr);
- inst_addr.Slide(data_offset);
-
- bool use_thumb = false;
- // If we have a thumb disassembler, then we have an ARM architecture
- // so we need to check what the instruction address class is to make
- // sure we shouldn't be disassembling as thumb...
- AddressClass inst_address_class = eAddressClassInvalid;
- if (m_disassembler_thumb)
- {
- inst_address_class = inst_addr.GetAddressClass ();
- if (inst_address_class == eAddressClassCodeAlternateISA)
- use_thumb = true;
- }
-
- InstructionSP inst_sp (new InstructionLLVM (inst_addr,
- inst_address_class,
- use_thumb ? m_disassembler_thumb : m_disassembler,
- use_thumb ? llvm::Triple::thumb : m_arch.GetMachine()));
-
- size_t inst_byte_size = inst_sp->Decode (*this, data, data_offset);
-
- if (inst_byte_size == 0)
- break;
-
- m_instruction_list.Append (inst_sp);
-
- total_inst_byte_size += inst_byte_size;
- data_offset += inst_byte_size;
- num_instructions--;
- }
-
- return total_inst_byte_size;
-}
-
-void
-DisassemblerLLVM::Initialize()
-{
- PluginManager::RegisterPlugin (GetPluginNameStatic(),
- GetPluginDescriptionStatic(),
- CreateInstance);
-}
-
-void
-DisassemblerLLVM::Terminate()
-{
- PluginManager::UnregisterPlugin (CreateInstance);
-}
-
-
-const char *
-DisassemblerLLVM::GetPluginNameStatic()
-{
- return "llvm-edis";
-}
-
-const char *
-DisassemblerLLVM::GetPluginDescriptionStatic()
-{
- return "Disassembler that uses the LLVM enhanced disassembler to disassemble i386, x86_64 and ARM.";
-}
-
-//------------------------------------------------------------------
-// PluginInterface protocol
-//------------------------------------------------------------------
-const char *
-DisassemblerLLVM::GetPluginName()
-{
- return "DisassemblerLLVM";
-}
-
-const char *
-DisassemblerLLVM::GetShortPluginName()
-{
- return GetPluginNameStatic();
-}
-
-uint32_t
-DisassemblerLLVM::GetPluginVersion()
-{
- return 1;
-}
-
Index: aze/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h
===================================================================
--- aze.orig/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVM.h 2013-03-03 09:35:47.783457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,105 +0,0 @@
-//===-- DisassemblerLLVM.h --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_DisassemblerLLVM_h_
-#define liblldb_DisassemblerLLVM_h_
-
-
-#include "llvm-c/EnhancedDisassembly.h"
-
-#include "lldb/Core/Disassembler.h"
-#include "lldb/Host/Mutex.h"
-
-class InstructionLLVM : public lldb_private::Instruction
-{
-public:
- InstructionLLVM (const lldb_private::Address &addr,
- lldb::AddressClass addr_class,
- EDDisassemblerRef disassembler,
- llvm::Triple::ArchType arch_type);
-
- virtual
- ~InstructionLLVM();
-
- virtual bool
- DoesBranch () const;
-
- virtual size_t
- Decode (const lldb_private::Disassembler &disassembler,
- const lldb_private::DataExtractor &data,
- uint32_t data_offset);
-
- virtual void
- CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext* exe_ctx);
-
-protected:
- EDDisassemblerRef m_disassembler;
- EDInstRef m_inst;
- llvm::Triple::ArchType m_arch_type;
-};
-
-
-class DisassemblerLLVM : public lldb_private::Disassembler
-{
-public:
- //------------------------------------------------------------------
- // Static Functions
- //------------------------------------------------------------------
- static void
- Initialize();
-
- static void
- Terminate();
-
- static const char *
- GetPluginNameStatic();
-
- static const char *
- GetPluginDescriptionStatic();
-
- static lldb_private::Disassembler *
- CreateInstance(const lldb_private::ArchSpec &arch);
-
-
- DisassemblerLLVM(const lldb_private::ArchSpec &arch);
-
- virtual
- ~DisassemblerLLVM();
-
- size_t
- DecodeInstructions (const lldb_private::Address &base_addr,
- const lldb_private::DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
- bool append);
-
- //------------------------------------------------------------------
- // PluginInterface protocol
- //------------------------------------------------------------------
- virtual const char *
- GetPluginName();
-
- virtual const char *
- GetShortPluginName();
-
- virtual uint32_t
- GetPluginVersion();
-
-protected:
- bool
- IsValid() const
- {
- return m_disassembler != NULL;
- }
-
- EDDisassemblerRef m_disassembler;
- EDDisassemblerRef m_disassembler_thumb;
-};
-
-#endif // liblldb_DisassemblerLLVM_h_
Index: aze/lldb/source/Plugins/DynamicLoader/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/DynamicLoader/CMakeLists.txt 2013-03-03 09:35:50.207457352 +0100
@@ -0,0 +1,4 @@
+add_subdirectory(Darwin-Kernel)
+add_subdirectory(MacOSX-DYLD)
+add_subdirectory(POSIX-DYLD)
+add_subdirectory(Static)
Index: aze/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/CMakeLists.txt 2013-03-03 09:35:50.207457352 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginDynamicLoaderDarwinKernel
+ DynamicLoaderDarwinKernel.cpp
+ )
Index: aze/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp 2013-03-03 09:35:50.207457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -39,15 +41,39 @@
using namespace lldb;
using namespace lldb_private;
+// Progressively greater amounts of scanning we will allow
+// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
+// so a setting is needed that can completely disable the KASLR scans.
+
+enum KASLRScanType
+{
+ eKASLRScanNone = 0, // No reading into the inferior at all
+ eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel addr, then see if a kernel is there
+ eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
+ eKASLRScanExhaustiveScan // Scan through the entire possible kernel address range looking for a kernel
+};
+
+OptionEnumValueElement
+g_kaslr_kernel_scan_enum_values[] =
+{
+ { eKASLRScanNone, "none", "Do not read memory looking for a Darwin kernel when attaching." },
+ { eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load addr in the lowglo page (boot-args=debug) only." },
+ { eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find the Darwin kernel's load address."},
+ { eKASLRScanExhaustiveScan, "exhaustive-scan", "Scan through the entire potential address range of Darwin kernel (only on 32-bit targets)."},
+ { 0, NULL, NULL }
+};
+
static PropertyDefinition
g_properties[] =
{
{ "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." },
+ { "scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL, g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make while searching for a Darwin kernel on attach." },
{ NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
};
enum {
- ePropertyLoadKexts
+ ePropertyLoadKexts,
+ ePropertyScanType
};
class DynamicLoaderDarwinKernelProperties : public Properties
@@ -72,14 +98,22 @@
~DynamicLoaderDarwinKernelProperties()
{
}
-
+
bool
GetLoadKexts() const
{
const uint32_t idx = ePropertyLoadKexts;
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
}
-
+
+ KASLRScanType
+ GetScanType() const
+ {
+ const uint32_t idx = ePropertyScanType;
+ return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+ }
+
+
};
typedef STD_SHARED_PTR(DynamicLoaderDarwinKernelProperties) DynamicLoaderDarwinKernelPropertiesSP;
@@ -101,54 +135,325 @@
DynamicLoader *
DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
{
- bool create = force;
- if (!create)
+ if (!force)
{
+ // If the user provided an executable binary and it is not a kernel,
+ // this plugin should not create an instance.
Module* exe_module = process->GetTarget().GetExecutableModulePointer();
if (exe_module)
{
ObjectFile *object_file = exe_module->GetObjectFile();
if (object_file)
{
- create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
+ if (object_file->GetStrata() != ObjectFile::eStrataKernel)
+ {
+ return NULL;
+ }
}
}
-
- if (create)
+
+ // If the target's architecture does not look like an Apple environment,
+ // this plugin should not create an instance.
+ const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS())
{
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ if (triple_ref.getVendor() != llvm::Triple::Apple)
+ {
+ return NULL;
+ }
+ break;
+ // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
+ case llvm::Triple::UnknownOS:
+ break;
+ default:
+ return NULL;
+ break;
}
}
-
- if (create)
+
+ // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.
+ // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
+
+ addr_t kernel_load_address = SearchForDarwinKernel (process);
+ if (kernel_load_address != LLDB_INVALID_ADDRESS)
{
process->SetCanJIT(false);
- return new DynamicLoaderDarwinKernel (process);
+ return new DynamicLoaderDarwinKernel (process, kernel_load_address);
}
return NULL;
}
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
+{
+ addr_t kernel_load_address = process->GetImageInfoAddress();
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelAtSameLoadAddr (process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelWithDebugHints (process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelNearPC (process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
+ }
+ }
+ }
+ }
+ return kernel_load_address;
+}
+
+//----------------------------------------------------------------------
+// Check if the kernel binary is loaded in memory without a slide.
+// First verify that the ExecutableModule is a kernel before we proceed.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
+{
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module == NULL)
+ return LLDB_INVALID_ADDRESS;
+
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ if (exe_objfile == NULL)
+ return LLDB_INVALID_ADDRESS;
+
+ if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
+ return LLDB_INVALID_ADDRESS;
+
+ if (!exe_objfile->GetHeaderAddress().IsValid())
+ return LLDB_INVALID_ADDRESS;
+
+ if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
+ return exe_objfile->GetHeaderAddress().GetFileAddress();
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// If the debug flag is included in the boot-args nvram setting, the kernel's load address
+// will be noted in the lowglo page at a fixed address
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
+{
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
+ return LLDB_INVALID_ADDRESS;
+
+ Error read_err;
+ addr_t addr = LLDB_INVALID_ADDRESS;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ {
+ addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
+ }
+ else
+ {
+ addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, LLDB_INVALID_ADDRESS, read_err);
+ }
+
+ if (addr == 0)
+ addr = LLDB_INVALID_ADDRESS;
+
+ if (addr != LLDB_INVALID_ADDRESS)
+ {
+ if (CheckForKernelImageAtAddress (addr, process).IsValid())
+ return addr;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// If the kernel is currently executing when lldb attaches, and we don't have
+// a better way of finding the kernel's load address, try searching backwards
+// from the current pc value looking for the kernel's Mach header in memory.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
+{
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone
+ || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ ThreadSP thread = process->GetThreadList().GetSelectedThread ();
+ if (thread.get() == NULL)
+ return LLDB_INVALID_ADDRESS;
+ addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);
+
+ if (pc == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t kernel_range_low, kernel_range_high;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ {
+ kernel_range_low = 1ULL << 63;
+ kernel_range_high = UINT64_MAX;
+ }
+ else
+ {
+ kernel_range_low = 1ULL << 31;
+ kernel_range_high = UINT32_MAX;
+ }
+
+ // Outside the normal kernel address range, this is probably userland code running right now
+ if (pc < kernel_range_low)
+ LLDB_INVALID_ADDRESS;
+
+ // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus
+ // an offset of one page (0x1000) or two, depending on the device.
+
+ // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
+ addr_t addr = pc & ~0xfffff;
+
+ int i = 0;
+ while (i < 32 && pc >= kernel_range_low)
+ {
+ if (CheckForKernelImageAtAddress (addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ i++;
+ addr -= 0x100000;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// Scan through the valid address range for a kernel binary.
+// This is uselessly slow in 64-bit environments so we don't even try it.
+// This scan is not enabled by default even for 32-bit targets.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
+{
+ if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ addr_t kernel_range_low, kernel_range_high;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ {
+ kernel_range_low = 1ULL << 63;
+ kernel_range_high = UINT64_MAX;
+ }
+ else
+ {
+ kernel_range_low = 1ULL << 31;
+ kernel_range_high = UINT32_MAX;
+ }
+
+ // Stepping through memory at one-megabyte resolution looking for a kernel
+ // rarely works (fast enough) with a 64-bit address space -- for now, let's
+ // not even bother. We may be attaching to something which *isn't* a kernel
+ // and we don't want to spin for minutes on-end looking for a kernel.
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t addr = kernel_range_low;
+
+ while (addr >= kernel_range_low && addr < kernel_range_high)
+ {
+ if (CheckForKernelImageAtAddress (addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ addr += 0x100000;
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// Given an address in memory, look to see if there is a kernel image at that
+// address.
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
+//----------------------------------------------------------------------
+lldb_private::UUID
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
+{
+ if (addr == LLDB_INVALID_ADDRESS)
+ return UUID();
+
+ // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
+ // (the first field of the mach_header/mach_header_64 struct).
+
+ Error read_error;
+ uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
+ if (result != llvm::MachO::HeaderMagic64
+ && result != llvm::MachO::HeaderMagic32
+ && result != llvm::MachO::HeaderMagic32Swapped
+ && result != llvm::MachO::HeaderMagic64Swapped)
+ {
+ return UUID();
+ }
+
+ // Read the mach header and see whether it looks like a kernel
+ llvm::MachO::mach_header header;
+ if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != sizeof(header))
+ return UUID();
+
+ if (header.magic == llvm::MachO::HeaderMagic32Swapped ||
+ header.magic == llvm::MachO::HeaderMagic64Swapped)
+ {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // A kernel is an executable which does not have the dynamic link object flag set.
+ if (header.filetype == llvm::MachO::HeaderFileTypeExecutable
+ && (header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
+ {
+ // Create a full module to get the UUID
+ ModuleSP memory_module_sp = process->ReadModuleFromMemory (FileSpec ("temp_mach_kernel", false), addr);
+ if (!memory_module_sp.get())
+ return UUID();
+
+ ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
+ if (exe_objfile == NULL)
+ return UUID();
+
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
+ {
+ return memory_module_sp->GetUUID();
+ }
+ }
+
+ return UUID();
+}
+
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
+DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::addr_t kernel_addr) :
DynamicLoader(process),
+ m_kernel_load_address (kernel_addr),
m_kernel(),
m_kext_summary_header_ptr_addr (),
m_kext_summary_header_addr (),
m_kext_summary_header (),
- m_kext_summaries(),
+ m_known_kexts (),
m_mutex(Mutex::eMutexTypeRecursive),
m_break_id (LLDB_INVALID_BREAK_ID)
{
@@ -208,138 +513,358 @@
if (clear_process)
m_process = NULL;
- m_kernel.Clear(false);
+ m_kernel.Clear();
+ m_known_kexts.clear();
m_kext_summary_header_ptr_addr.Clear();
m_kext_summary_header_addr.Clear();
- m_kext_summaries.clear();
m_break_id = LLDB_INVALID_BREAK_ID;
}
bool
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process)
+DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
{
if (IsLoaded())
return true;
- if (module_sp)
+ if (m_module_sp)
{
bool changed = false;
- if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
- load_process_stop_id = process->GetStopID();
+ if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
+ m_load_process_stop_id = process->GetStopID();
}
return false;
}
-bool
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
{
- if (IsLoaded())
- return true;
+ m_module_sp = module_sp;
+ if (module_sp.get() && module_sp->GetObjectFile())
+ {
+ if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
+ && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
+ {
+ m_kernel_image = true;
+ }
+ else
+ {
+ m_kernel_image = false;
+ }
+ }
+}
- bool uuid_is_valid = uuid.IsValid();
- bool memory_module_is_kernel = false;
+ModuleSP
+DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
+{
+ return m_module_sp;
+}
- Target &target = process->GetTarget();
- ModuleSP memory_module_sp;
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
+{
+ m_load_address = load_addr;
+}
- // If this is a kext and the user asked us to ignore kexts, don't try to load it.
- if (kernel_image == false && GetGlobalProperties()->GetLoadKexts() == false)
+addr_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
+{
+ return m_load_address;
+}
+
+uint64_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
+{
+ return m_size;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
+{
+ m_size = size;
+}
+
+uint32_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
+{
+ return m_load_process_stop_id;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
+{
+ m_load_process_stop_id = stop_id;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
+{
+ if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
{
+ if (m_uuid == rhs.GetUUID())
+ {
+ return true;
+ }
return false;
}
- // Use the memory module as the module if we have one
- if (address != LLDB_INVALID_ADDRESS)
+ if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
+ return true;
+
+ return false;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
+{
+ m_name = name;
+}
+
+std::string
+DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
+{
+ return m_name;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
+{
+ m_uuid = uuid;
+}
+
+UUID
+DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
+{
+ return m_uuid;
+}
+
+// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
+// Module at that address. Require that the MemoryModule have a matching UUID and detect
+// if this MemoryModule is a kernel or a kext.
+//
+// Returns true if m_memory_module_sp is now set to a valid Module.
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
+{
+ if (m_memory_module_sp.get() != NULL)
+ return true;
+ if (m_load_address == LLDB_INVALID_ADDRESS)
+ return false;
+
+ FileSpec file_spec;
+ file_spec.SetFile (m_name.c_str(), false);
+
+ ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);
+
+ if (memory_module_sp.get() == NULL)
+ return false;
+
+ bool is_kernel = false;
+ if (memory_module_sp->GetObjectFile())
{
- FileSpec file_spec;
- if (module_sp)
- file_spec = module_sp->GetFileSpec();
- else
- file_spec.SetFile (name, false);
-
- memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
- if (memory_module_sp && !uuid_is_valid)
+ if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
+ && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
{
- uuid = memory_module_sp->GetUUID();
- uuid_is_valid = uuid.IsValid();
+ is_kernel = true;
}
- if (memory_module_sp
- && memory_module_sp->GetObjectFile()
- && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
- && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
+ else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
{
- memory_module_is_kernel = true;
- if (memory_module_sp->GetArchitecture().IsValid())
- {
- target.SetArchitecture(memory_module_sp->GetArchitecture());
- }
+ is_kernel = false;
}
}
- if (!module_sp)
+ // If this is a kext, and the kernel specified what UUID we should find at this
+ // load address, require that the memory module have a matching UUID or something
+ // has gone wrong and we should discard it.
+ if (m_uuid.IsValid())
{
- if (uuid_is_valid)
+ if (m_uuid != memory_module_sp->GetUUID())
{
- const ModuleList &target_images = target.GetImages();
- module_sp = target_images.FindModule(uuid);
+ return false;
+ }
+ }
- if (!module_sp)
- {
- ModuleSpec module_spec;
- module_spec.GetUUID() = uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
+ // If the in-memory Module has a UUID, let's use that.
+ if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
+ {
+ m_uuid = memory_module_sp->GetUUID();
+ }
- // For the kernel, we really do need an on-disk file copy of the
- // binary.
- bool force_symbols_search = false;
- if (memory_module_is_kernel)
+ m_memory_module_sp = memory_module_sp;
+ m_kernel_image = is_kernel;
+ if (is_kernel)
+ {
+ if (memory_module_sp->GetArchitecture().IsValid())
+ {
+ process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
+ }
+ if (m_uuid.IsValid())
+ {
+ Module* exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module && exe_module->GetUUID().IsValid())
+ {
+ if (m_uuid != exe_module->GetUUID())
{
- force_symbols_search = true;
+ Stream *s = &process->GetTarget().GetDebugger().GetOutputStream();
+ if (s)
+ {
+ char memory_module_uuidbuf[64];
+ char exe_module_uuidbuf[64];
+ s->Printf ("warning: Host-side kernel file has Mach-O UUID of %s but remote kernel has a UUID of %s -- a mismatched kernel file will result in a poor debugger experience.\n",
+ exe_module->GetUUID().GetAsCString(exe_module_uuidbuf, sizeof (exe_module_uuidbuf)),
+ m_uuid.GetAsCString(memory_module_uuidbuf, sizeof (memory_module_uuidbuf)));
+ s->Flush ();
+ }
}
+ }
+ }
+ }
+
+ return true;
+}
- if (Symbols::DownloadObjectAndSymbolFile (module_spec, force_symbols_search))
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
+{
+ return m_kernel_image == true;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel)
+{
+ m_kernel_image = is_kernel;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
+{
+ if (IsLoaded())
+ return true;
+
+
+ Target &target = process->GetTarget();
+
+ // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
+ // have the correct segment load addresses.
+ if (!ReadMemoryModule (process))
+ {
+ return false;
+ }
+
+ bool uuid_is_valid = m_uuid.IsValid();
+
+ if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
+ {
+ Stream *s = &target.GetDebugger().GetOutputStream();
+ if (s)
+ {
+ char uuidbuf[64];
+ s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf)));
+ s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
+ }
+ }
+
+ if (!m_module_sp)
+ {
+ // See if the kext has already been loaded into the target, probably by the user doing target modules add.
+ const ModuleList &target_images = target.GetImages();
+ m_module_sp = target_images.FindModule(m_uuid);
+
+ // Search for the kext on the local filesystem via the UUID
+ if (!m_module_sp && uuid_is_valid)
+ {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = m_uuid;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
+ // This will force a clal to
+ if (IsKernel())
+ {
+ if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
{
if (module_spec.GetFileSpec().Exists())
{
- module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
- if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec))
+ m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
+ if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
{
ModuleList loaded_module_list;
- loaded_module_list.Append (module_sp);
+ loaded_module_list.Append (m_module_sp);
target.ModulesDidLoad (loaded_module_list);
}
}
}
-
- // Ask the Target to find this file on the local system, if possible.
- // This will search in the list of currently-loaded files, look in the
- // standard search paths on the system, and on a Mac it will try calling
- // the DebugSymbols framework with the UUID to find the binary via its
- // search methods.
- if (!module_sp)
+ }
+
+ // Ask the Target to find this file on the local system, if possible.
+ // This will search in the list of currently-loaded files, look in the
+ // standard search paths on the system, and on a Mac it will try calling
+ // the DebugSymbols framework with the UUID to find the binary via its
+ // search methods.
+ if (!m_module_sp)
+ {
+ m_module_sp = target.GetSharedModule (module_spec);
+ }
+
+ if (IsKernel() && !m_module_sp)
+ {
+ Stream *s = &target.GetDebugger().GetOutputStream();
+ if (s)
{
- module_sp = target.GetSharedModule (module_spec);
+ s->Printf ("WARNING: Unable to locate kernel binary on this system.\n");
}
}
}
- }
-
- if (memory_module_sp && module_sp)
- {
- if (module_sp->GetUUID() == memory_module_sp->GetUUID())
+ // If we managed to find a module, append it to the target's list of images.
+ // If we also have a memory module, require that they have matching UUIDs
+ if (m_module_sp)
{
- target.GetImages().Append(module_sp);
- if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get())
+ bool uuid_match_ok = true;
+ if (m_memory_module_sp)
+ {
+ if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
+ {
+ uuid_match_ok = false;
+ }
+ }
+ if (uuid_match_ok)
{
- target.SetExecutableModule (module_sp, false);
+ target.GetImages().AppendIfNeeded(m_module_sp);
+ if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
+ {
+ target.SetExecutableModule (m_module_sp, false);
+ }
}
+ }
+ }
+
+ if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
+ {
+ Stream *s = &target.GetDebugger().GetOutputStream();
+ if (s)
+ {
+ char uuidbuf[64];
+ s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n",
+ m_name.c_str(), m_uuid.GetAsCString(uuidbuf, sizeof (uuidbuf)));
+ }
+ }
+
+ static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
- ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
- ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
+ if (m_memory_module_sp && m_module_sp)
+ {
+ if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
+ {
+ ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+ ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
+
if (memory_object_file && ondisk_object_file)
{
+ // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
+ const bool ignore_linkedit = !IsKernel ();
+
SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
SectionList *memory_section_list = memory_object_file->GetSectionList ();
if (memory_section_list && ondisk_section_list)
@@ -361,6 +886,14 @@
SectionSP ondisk_section_sp(ondisk_section_list->GetSectionAtIndex(sect_idx));
if (ondisk_section_sp)
{
+ // Don't ever load __LINKEDIT as it may or may not be actually
+ // mapped into memory and there is no current way to tell.
+ // I filed rdar://problem/12851706 to track being able to tell
+ // if the __LINKEDIT is actually mapped, but until then, we need
+ // to not load the __LINKEDIT
+ if (ignore_linkedit && ondisk_section_sp->GetName() == g_section_name_LINKEDIT)
+ continue;
+
const Section *memory_section = memory_section_list->FindSectionByName(ondisk_section_sp->GetName()).get();
if (memory_section)
{
@@ -370,48 +903,45 @@
}
}
if (num_sections_loaded > 0)
- load_process_stop_id = process->GetStopID();
+ m_load_process_stop_id = process->GetStopID();
else
- module_sp.reset(); // No sections were loaded
+ m_module_sp.reset(); // No sections were loaded
}
else
- module_sp.reset(); // One or both section lists
+ m_module_sp.reset(); // One or both section lists
}
else
- module_sp.reset(); // One or both object files missing
+ m_module_sp.reset(); // One or both object files missing
}
else
- module_sp.reset(); // UUID mismatch
+ m_module_sp.reset(); // UUID mismatch
}
bool is_loaded = IsLoaded();
- if (so_address.IsValid())
- {
- if (is_loaded)
- so_address.SetLoadAddress (address, &target);
- else
- target.GetImages().ResolveFileAddress (address, so_address);
-
- }
-
- if (is_loaded && module_sp && memory_module_is_kernel)
+ if (is_loaded && m_module_sp && IsKernel())
{
Stream *s = &target.GetDebugger().GetOutputStream();
if (s)
{
- char uuidbuf[64];
- s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf)));
- s->Printf ("Load Address: 0x%llx\n", address);
- if (module_sp->GetFileSpec().GetDirectory().IsEmpty())
+ ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
+ if (kernel_object_file)
+ {
+ addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
+ if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
+ {
+ s->Printf ("Kernel slid 0x%llx in memory.\n", m_load_address - file_address);
+ }
+ }
+ if (m_module_sp->GetFileSpec().GetDirectory().IsEmpty())
{
- s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString());
+ s->Printf ("Loaded kernel file %s\n", m_module_sp->GetFileSpec().GetFilename().AsCString());
}
else
{
s->Printf ("Loaded kernel file %s/%s\n",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString());
+ m_module_sp->GetFileSpec().GetDirectory().AsCString(),
+ m_module_sp->GetFileSpec().GetFilename().AsCString());
}
s->Flush ();
}
@@ -420,26 +950,32 @@
}
uint32_t
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize ()
+DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
{
- if (module_sp)
- return module_sp->GetArchitecture().GetAddressByteSize();
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetAddressByteSize();
return 0;
}
lldb::ByteOrder
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder()
+DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
{
- if (module_sp)
- return module_sp->GetArchitecture().GetByteOrder();
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetByteOrder();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetByteOrder();
return lldb::endian::InlHostByteOrder();
}
lldb_private::ArchSpec
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const
+DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
{
- if (module_sp)
- return module_sp->GetArchitecture();
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture();
return lldb_private::ArchSpec ();
}
@@ -455,53 +991,52 @@
{
if (!m_kext_summary_header_ptr_addr.IsValid())
{
- m_kernel.Clear(false);
- m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
- m_kernel.kernel_image = true;
+ m_kernel.Clear();
+ m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
+ m_kernel.SetIsKernel(true);
ConstString kernel_name("mach_kernel");
- if (m_kernel.module_sp.get()
- && m_kernel.module_sp->GetObjectFile()
- && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
+ if (m_kernel.GetModule().get()
+ && m_kernel.GetModule()->GetObjectFile()
+ && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
{
- kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename();
+ kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
}
- strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name));
- m_kernel.name[sizeof (m_kernel.name) - 1] = '\0';
+ m_kernel.SetName (kernel_name.AsCString());
- if (m_kernel.address == LLDB_INVALID_ADDRESS)
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
{
- m_kernel.address = m_process->GetImageInfoAddress ();
- if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
+ m_kernel.SetLoadAddress(m_kernel_load_address);
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
{
// We didn't get a hint from the process, so we will
// try the kernel at the address that it exists at in
// the file if we have one
- ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
+ ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
if (kernel_object_file)
{
addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
{
- m_kernel.address = load_address;
+ m_kernel.SetLoadAddress (load_address);
if (load_address != file_address)
{
// Don't accidentally relocate the kernel to the File address --
// the Load address has already been set to its actual in-memory address.
// Mark it as IsLoaded.
- m_kernel.load_process_stop_id = m_process->GetStopID();
+ m_kernel.SetProcessStopId (m_process->GetStopID());
}
}
else
{
- m_kernel.address = file_address;
+ m_kernel.SetLoadAddress(file_address);
}
}
}
}
- if (m_kernel.address != LLDB_INVALID_ADDRESS)
+ if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
{
if (!m_kernel.LoadImageUsingMemoryModule (m_process))
{
@@ -509,10 +1044,10 @@
}
}
- if (m_kernel.IsLoaded() && m_kernel.module_sp)
+ if (m_kernel.IsLoaded() && m_kernel.GetModule())
{
static ConstString kext_summary_symbol ("gLoadedKextSummaries");
- const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
+ const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
if (symbol)
{
m_kext_summary_header_ptr_addr = symbol->GetAddress();
@@ -522,7 +1057,7 @@
}
else
{
- m_kernel.Clear(false);
+ m_kernel.Clear();
}
}
}
@@ -567,7 +1102,6 @@
// the all image infos is already valid for this process stop ID
- m_kext_summaries.clear();
if (m_kext_summary_header_ptr_addr.IsValid())
{
const uint32_t addr_size = m_kernel.GetAddressByteSize ();
@@ -591,7 +1125,7 @@
const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
if (bytes_read == count)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
m_kext_summary_header.version = data.GetU32(&offset);
if (m_kext_summary_header.version >= 2)
{
@@ -612,72 +1146,194 @@
return false;
}
+// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
+// and we need to figure out what kexts have been added or removed.
+// Read the kext summaries from the inferior kernel memory, compare them against the
+// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
+// inferior.
bool
-DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
- uint32_t count)
+DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
{
- OSKextLoadedKextSummary::collection kext_summaries;
+ KextImageInfo::collection kext_summaries;
LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
- log->Printf ("Adding %d modules.\n", count);
+ log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
Mutex::Locker locker(m_mutex);
if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
return false;
- Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
- if (s)
- s->Printf ("Loading %d kext modules ", count);
- for (uint32_t i = 0; i < count; i++)
+ // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no
+ // kext loading, don't print any messages about kexts & don't try to read them.
+ const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
+
+ // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
+ // we just found out about from ReadKextSummaries are marked as "add".
+ std::vector<bool> to_be_removed(m_known_kexts.size(), true);
+ std::vector<bool> to_be_added(count, true);
+
+ int number_of_new_kexts_being_added = 0;
+ int number_of_old_kexts_being_removed = m_known_kexts.size();
+
+ const uint32_t new_kexts_size = kext_summaries.size();
+ const uint32_t old_kexts_size = m_known_kexts.size();
+
+ // The m_known_kexts vector may have entries that have been Cleared,
+ // or are a kernel.
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
+ {
+ bool ignore = false;
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ if (image_info.IsKernel())
+ {
+ ignore = true;
+ }
+ else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
+ {
+ ignore = true;
+ }
+
+ if (ignore)
+ {
+ number_of_old_kexts_being_removed--;
+ to_be_removed[old_kext] = false;
+ }
+ }
+
+ // Scan over the list of kexts we just read from the kernel, note those that
+ // need to be added and those already loaded.
+ for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
{
- if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
- kext_summaries[i].LoadImageAtFileAddress (m_process);
+ bool add_this_one = true;
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
+ {
+ if (m_known_kexts[old_kext] == kext_summaries[new_kext])
+ {
+ // We already have this kext, don't re-load it.
+ to_be_added[new_kext] = false;
+ // This kext is still present, do not remove it.
+ to_be_removed[old_kext] = false;
- if (s)
- s->Printf (".");
+ number_of_old_kexts_being_removed--;
+ add_this_one = false;
+ break;
+ }
+ }
+ if (add_this_one)
+ {
+ number_of_new_kexts_being_added++;
+ }
+ }
+
+ if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
+ return true;
- if (log)
- kext_summaries[i].PutToLog (log.get());
+ Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
+ if (s && load_kexts)
+ {
+ if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
+ {
+ s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
+ else if (number_of_new_kexts_being_added > 0)
+ {
+ s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
+ }
+ else if (number_of_old_kexts_being_removed > 0)
+ {
+ s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
+ }
}
- if (s)
+
+ if (log)
{
- s->Printf (" done.\n");
- s->Flush ();
+ if (load_kexts)
+ {
+ log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
+ else
+ {
+ log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
}
- bool return_value = AddModulesUsingImageInfos (kext_summaries);
- return return_value;
-}
-// Adds the modules in image_infos to m_kext_summaries.
-// NB don't call this passing in m_kext_summaries.
+ if (number_of_new_kexts_being_added > 0)
+ {
+ ModuleList loaded_module_list;
-bool
-DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
-{
- // Now add these images to the main list.
- ModuleList loaded_module_list;
-
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
+ const uint32_t num_of_new_kexts = kext_summaries.size();
+ for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++)
+ {
+ if (to_be_added[new_kext] == true)
+ {
+ KextImageInfo &image_info = kext_summaries[new_kext];
+ if (load_kexts)
+ {
+ if (!image_info.LoadImageUsingMemoryModule (m_process))
+ {
+ image_info.LoadImageAtFileAddress (m_process);
+ }
+ }
+
+ m_known_kexts.push_back(image_info);
+
+ if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
+ loaded_module_list.AppendIfNeeded (image_info.GetModule());
+
+ if (s && load_kexts)
+ s->Printf (".");
+
+ if (log)
+ kext_summaries[new_kext].PutToLog (log.get());
+ }
+ }
+ m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ }
+
+ if (number_of_old_kexts_being_removed > 0)
{
- OSKextLoadedKextSummary &image_info = image_infos[idx];
- m_kext_summaries.push_back(image_info);
-
- if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
- loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
+ ModuleList loaded_module_list;
+ const uint32_t num_of_old_kexts = m_known_kexts.size();
+ for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
+ {
+ ModuleList unloaded_module_list;
+ if (to_be_removed[old_kext])
+ {
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ // You can't unload the kernel.
+ if (!image_info.IsKernel())
+ {
+ if (image_info.GetModule())
+ {
+ unloaded_module_list.AppendIfNeeded (image_info.GetModule());
+ }
+ if (s)
+ s->Printf (".");
+ image_info.Clear();
+ // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
+ // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
+ }
+ }
+ m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
+ }
}
-
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+
+ if (s && load_kexts)
+ {
+ s->Printf (" done.\n");
+ s->Flush ();
+ }
+
return true;
}
-
uint32_t
DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
uint32_t image_infos_count,
- OSKextLoadedKextSummary::collection &image_infos)
+ KextImageInfo::collection &image_infos)
{
const ByteOrder endian = m_kernel.GetByteOrder();
const uint32_t addr_size = m_kernel.GetAddressByteSize();
@@ -702,35 +1358,15 @@
i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
++i, kext_summary_offset += m_kext_summary_header.entry_size)
{
- uint32_t offset = kext_summary_offset;
+ lldb::offset_t offset = kext_summary_offset;
const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
if (name_data == NULL)
break;
- memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
- image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
- image_infos[i].address = extractor.GetU64(&offset);
- if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
- m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
- image_infos[i].size = extractor.GetU64(&offset);
- image_infos[i].version = extractor.GetU64(&offset);
- image_infos[i].load_tag = extractor.GetU32(&offset);
- image_infos[i].flags = extractor.GetU32(&offset);
- if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
- {
- image_infos[i].reference_list = extractor.GetU64(&offset);
- }
- else
- {
- image_infos[i].reference_list = 0;
- }
-// printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n",
-// i,
-// KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data,
-// image_infos[i].address,
-// image_infos[i].size,
-// image_infos[i].version,
-// image_infos[i].load_tag,
-// image_infos[i].flags);
+ image_infos[i].SetName ((const char *) name_data);
+ UUID uuid (extractor.GetData (&offset, 16), 16);
+ image_infos[i].SetUUID (uuid);
+ image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
+ image_infos[i].SetSize (extractor.GetU64(&offset));
}
if (i < image_infos.size())
image_infos.resize(i);
@@ -757,7 +1393,7 @@
summary_addr.Slide(m_kext_summary_header.GetSize());
if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
{
- m_kext_summaries.clear();
+ m_known_kexts.clear();
}
return true;
}
@@ -769,13 +1405,13 @@
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
+DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
{
if (log == NULL)
return;
- const uint8_t *u = (uint8_t *)uuid.GetBytes();
+ const uint8_t *u = (uint8_t *) m_uuid.GetBytes();
- if (address == LLDB_INVALID_ADDRESS)
+ if (m_load_address == LLDB_INVALID_ADDRESS)
{
if (u)
{
@@ -784,26 +1420,25 @@
u[ 4], u[ 5], u[ 6], u[ 7],
u[ 8], u[ 9], u[10], u[11],
u[12], u[13], u[14], u[15],
- name);
+ m_name.c_str());
}
else
- log->Printf("\tname=\"%s\" (UNLOADED)", name);
+ log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
}
else
{
if (u)
{
- log->Printf("\taddr=0x%16.16llx size=0x%16.16llx version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
- address, size, version, load_tag, flags, reference_list,
+ log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
+ m_load_address, m_size,
u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
- name);
+ m_name.c_str());
}
else
{
- log->Printf("\t[0x%16.16llx - 0x%16.16llx) version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx name=\"%s\"",
- address, address+size, version, load_tag, flags, reference_list,
- name);
+ log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
+ m_load_address, m_load_address+m_size, m_name.c_str());
}
}
}
@@ -819,19 +1454,19 @@
return;
Mutex::Locker locker(m_mutex);
- log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u }",
+ log->Printf("gLoadedKextSummaries = 0x%16.16" PRIx64 " { version=%u, entry_size=%u, entry_count=%u }",
m_kext_summary_header_addr.GetFileAddress(),
m_kext_summary_header.version,
m_kext_summary_header.entry_size,
m_kext_summary_header.entry_count);
size_t i;
- const size_t count = m_kext_summaries.size();
+ const size_t count = m_known_kexts.size();
if (count > 0)
{
log->PutCString("Loaded:");
for (i = 0; i<count; i++)
- m_kext_summaries[i].PutToLog(log);
+ m_known_kexts[i].PutToLog(log);
}
}
@@ -846,7 +1481,7 @@
void
DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
{
- if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
+ if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
{
DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
@@ -854,7 +1489,7 @@
const bool internal_bp = true;
const LazyBool skip_prologue = eLazyBoolNo;
FileSpecList module_spec_list;
- module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
+ module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
NULL,
"OSKextLoadedKextSummariesUpdated",
@@ -895,9 +1530,6 @@
case eStateCrashed:
case eStateSuspended:
break;
-
- default:
- break;
}
}
Index: aze/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h 2013-03-03 09:35:50.207457352 +0100
@@ -50,10 +50,14 @@
static void
DebuggerInitialize (lldb_private::Debugger &debugger);
- DynamicLoaderDarwinKernel (lldb_private::Process *process);
+ DynamicLoaderDarwinKernel (lldb_private::Process *process, lldb::addr_t kernel_addr);
+
+ static lldb::addr_t
+ SearchForDarwinKernel (lldb_private::Process *process);
virtual
~DynamicLoaderDarwinKernel ();
+
//------------------------------------------------------------------
/// Called after attaching a process.
///
@@ -92,7 +96,7 @@
void
PrivateProcessStateChanged (lldb_private::Process *process,
lldb::StateType state);
-
+
void
UpdateIfNeeded();
@@ -112,8 +116,8 @@
lldb::user_id_t break_loc_id);
bool
- BreakpointHit (lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
+ BreakpointHit (lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
uint32_t
GetAddrByteSize()
@@ -133,60 +137,51 @@
// 4 byte flags
KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
};
-
- struct OSKextLoadedKextSummary
+
+ // class KextImageInfo represents a single kext or kernel binary image.
+ // The class was designed to hold the information from the OSKextLoadedKextSummary
+ // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel maintains
+ // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure,
+ // which points to an array of OSKextLoadedKextSummary's).
+ //
+ // A KextImageInfos may have -
+ //
+ // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
+ // (read straight out of the kernel's list-of-kexts loaded)
+ // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
+ // (very unlikely to have any symbolic information)
+ // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
+ // or a dSYM
+ //
+ // For performance reasons, the developer may prefer that lldb not load the kexts out
+ // of memory at the start of a kernel session. But we should build up / maintain a
+ // list of kexts that the kernel has told us about so we can relocate a kext module
+ // later if the user explicitly adds it to the target.
+
+ class KextImageInfo
{
- char name[KERNEL_MODULE_MAX_NAME];
- lldb::ModuleSP module_sp;
- uint32_t load_process_stop_id;
- lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
- lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files
- uint64_t address;
- uint64_t size;
- uint64_t version;
- uint32_t load_tag;
- uint32_t flags;
- uint64_t reference_list;
- bool kernel_image; // true if this is the kernel, false if this is a kext
-
- OSKextLoadedKextSummary() :
- module_sp (),
- load_process_stop_id (UINT32_MAX),
- uuid (),
- so_address (),
- address (LLDB_INVALID_ADDRESS),
- size (0),
- version (0),
- load_tag (0),
- flags (0),
- reference_list (0),
- kernel_image (false)
- {
- name[0] = '\0';
- }
-
- bool
- IsLoaded ()
- {
- return load_process_stop_id != UINT32_MAX;
- }
+ public:
+ KextImageInfo () :
+ m_name (),
+ m_module_sp (),
+ m_memory_module_sp (),
+ m_load_process_stop_id (UINT32_MAX),
+ m_uuid (),
+ m_load_address (LLDB_INVALID_ADDRESS),
+ m_size (0),
+ m_kernel_image (false)
+ { }
void
- Clear (bool load_cmd_data_only)
+ Clear ()
{
- if (!load_cmd_data_only)
- {
- so_address.Clear();
- address = LLDB_INVALID_ADDRESS;
- size = 0;
- version = 0;
- load_tag = 0;
- flags = 0;
- reference_list = 0;
- name[0] = '\0';
- }
- module_sp.reset();
- load_process_stop_id = UINT32_MAX;
+ m_load_address = LLDB_INVALID_ADDRESS;
+ m_size = 0;
+ m_name.clear ();
+ m_uuid.Clear();
+ m_module_sp.reset();
+ m_memory_module_sp.reset();
+ m_load_process_stop_id = UINT32_MAX;
}
bool
@@ -194,42 +189,88 @@
bool
LoadImageUsingMemoryModule (lldb_private::Process *process);
-
-// bool
-// operator == (const OSKextLoadedKextSummary& rhs) const
-// {
-// return address == rhs.address
-// && size == rhs.size
-// //&& module_sp.get() == rhs.module_sp.get()
-// && uuid == rhs.uuid
-// && version == rhs.version
-// && load_tag == rhs.load_tag
-// && flags == rhs.flags
-// && reference_list == rhs.reference_list
-// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
-// }
-//
+
bool
- UUIDValid() const
+ IsLoaded ()
{
- return uuid.IsValid();
+ return m_load_process_stop_id != UINT32_MAX;
}
+ void
+ SetLoadAddress (lldb::addr_t load_addr); // Address of the Mach-O header for this binary
+
+ lldb::addr_t
+ GetLoadAddress () const; // Address of the Mach-O header for this binary
+
+ lldb_private::UUID
+ GetUUID () const;
+
+ void
+ SetUUID (const lldb_private::UUID &uuid);
+
+ void
+ SetName (const char *);
+
+ std::string
+ GetName () const;
+
+ void
+ SetModule (lldb::ModuleSP module);
+
+ lldb::ModuleSP
+ GetModule ();
+
+ // try to fill in m_memory_module_sp from memory based on the m_load_address
+ bool
+ ReadMemoryModule (lldb_private::Process *process);
+
+ bool
+ IsKernel () const; // true if this is the mach_kernel; false if this is a kext
+
+ void
+ SetIsKernel (bool is_kernel);
+
+ uint64_t
+ GetSize () const;
+
+ void
+ SetSize (uint64_t size);
+
uint32_t
- GetAddressByteSize ();
+ GetProcessStopId () const; // the stop-id when this binary was first noticed
+
+ void
+ SetProcessStopId (uint32_t stop_id);
+
+ bool
+ operator== (const KextImageInfo &rhs);
+
+ uint32_t
+ GetAddressByteSize (); // as determined by Mach-O header
lldb::ByteOrder
- GetByteOrder();
+ GetByteOrder(); // as determined by Mach-O header
lldb_private::ArchSpec
- GetArchitecture () const;
+ GetArchitecture () const; // as determined by Mach-O header
void
PutToLog (lldb_private::Log *log) const;
- typedef std::vector<OSKextLoadedKextSummary> collection;
+ typedef std::vector<KextImageInfo> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
+
+ private:
+ std::string m_name;
+ lldb::ModuleSP m_module_sp;
+ lldb::ModuleSP m_memory_module_sp;
+ uint32_t m_load_process_stop_id; // the stop-id when this module was added to the Target
+ lldb_private::UUID m_uuid; // UUID for this dylib if it has one, else all zeros
+ lldb::addr_t m_load_address;
+ uint64_t m_size;
+ bool m_kernel_image; // true if this is the kernel, false if this is a kext
+
};
struct OSKextLoadedKextSummaryHeader
@@ -257,7 +298,7 @@
default: break;
}
// Version 2 and above has version, entry_size, entry_count, and reserved
- return 16;
+ return 16;
}
void
@@ -290,31 +331,45 @@
bool
ReadKextSummaryHeader ();
-
+
bool
- ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
+ ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
uint32_t count);
-
- bool
- AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
-
+
void
- UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
- uint32_t infos_count,
+ UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
+ uint32_t infos_count,
bool update_executable);
uint32_t
ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
- uint32_t image_infos_count,
- OSKextLoadedKextSummary::collection &image_infos);
-
- OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
- lldb_private::Address m_kext_summary_header_ptr_addr;
- lldb_private::Address m_kext_summary_header_addr;
- OSKextLoadedKextSummaryHeader m_kext_summary_header;
- OSKextLoadedKextSummary::collection m_kext_summaries;
- mutable lldb_private::Mutex m_mutex;
- lldb::user_id_t m_break_id;
+ uint32_t image_infos_count,
+ KextImageInfo::collection &image_infos);
+
+ static lldb::addr_t
+ SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
+
+ static lldb::addr_t
+ SearchForKernelWithDebugHints (lldb_private::Process *process);
+
+ static lldb::addr_t
+ SearchForKernelNearPC (lldb_private::Process *process);
+
+ static lldb::addr_t
+ SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
+
+ static lldb_private::UUID
+ CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
+
+ lldb::addr_t m_kernel_load_address;
+ KextImageInfo m_kernel; // Info about the current kernel image being used
+
+ lldb_private::Address m_kext_summary_header_ptr_addr;
+ lldb_private::Address m_kext_summary_header_addr;
+ OSKextLoadedKextSummaryHeader m_kext_summary_header;
+ KextImageInfo::collection m_known_kexts;
+ mutable lldb_private::Mutex m_mutex;
+ lldb::user_id_t m_break_id;
private:
DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Index: aze/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/CMakeLists.txt 2013-03-03 09:35:50.207457352 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginDynamicLoaderMacOSXDYLD
+ DynamicLoaderMacOSXDYLD.cpp
+ )
Index: aze/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp 2013-03-03 09:35:50.211457353 +0100
@@ -139,7 +139,8 @@
m_break_id(LLDB_INVALID_BREAK_ID),
m_dyld_image_infos(),
m_dyld_image_infos_stop_id (UINT32_MAX),
- m_mutex(Mutex::eMutexTypeRecursive)
+ m_mutex(Mutex::eMutexTypeRecursive),
+ m_process_image_addr_is_all_images_infos (false)
{
}
@@ -179,6 +180,54 @@
SetNotificationBreakpoint ();
}
+bool
+DynamicLoaderMacOSXDYLD::ProcessDidExec ()
+{
+ if (m_process)
+ {
+ // If we are stopped after an exec, we will have only one thread...
+ if (m_process->GetThreadList().GetSize() == 1)
+ {
+ // We know if a process has exec'ed if our "m_dyld_all_image_infos_addr"
+ // value differs from the Process' image info address. When a process
+ // execs itself it might cause a change if ASLR is enabled.
+ const addr_t shlib_addr = m_process->GetImageInfoAddress ();
+ if (m_process_image_addr_is_all_images_infos == true && shlib_addr != m_dyld_all_image_infos_addr)
+ {
+ // The image info address from the process is the 'dyld_all_image_infos'
+ // address and it has changed.
+ return true;
+ }
+
+ if (m_process_image_addr_is_all_images_infos == false && shlib_addr == m_dyld.address)
+ {
+ // The image info address from the process is the mach_header
+ // address for dyld and it has changed.
+ return true;
+ }
+
+ // ASLR might be disabled and dyld could have ended up in the same
+ // location. We should try and detect if we are stopped at '_dyld_start'
+ ThreadSP thread_sp (m_process->GetThreadList().GetThreadAtIndex(0));
+ if (thread_sp)
+ {
+ lldb::StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex(0));
+ if (frame_sp)
+ {
+ const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+ if (symbol)
+ {
+ if (symbol->GetName() == ConstString("_dyld_start"))
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+
//----------------------------------------------------------------------
// Clear out the state of this class.
@@ -189,7 +238,7 @@
Mutex::Locker locker(m_mutex);
if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
+ m_process->GetTarget().RemoveBreakpointByID (m_break_id);
if (clear_process)
m_process = NULL;
@@ -224,29 +273,33 @@
// mach header for dyld, or it might point to the
// dyld_all_image_infos struct
const addr_t shlib_addr = m_process->GetImageInfoAddress ();
-
- ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint8_t buf[4];
- DataExtractor data (buf, sizeof(buf), byte_order, 4);
- Error error;
- if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
+ if (shlib_addr != LLDB_INVALID_ADDRESS)
{
- uint32_t offset = 0;
- uint32_t magic = data.GetU32 (&offset);
- switch (magic)
- {
- case llvm::MachO::HeaderMagic32:
- case llvm::MachO::HeaderMagic64:
- case llvm::MachO::HeaderMagic32Swapped:
- case llvm::MachO::HeaderMagic64Swapped:
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
-
- default:
- break;
+ ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
+ uint8_t buf[4];
+ DataExtractor data (buf, sizeof(buf), byte_order, 4);
+ Error error;
+ if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
+ {
+ lldb::offset_t offset = 0;
+ uint32_t magic = data.GetU32 (&offset);
+ switch (magic)
+ {
+ case llvm::MachO::HeaderMagic32:
+ case llvm::MachO::HeaderMagic64:
+ case llvm::MachO::HeaderMagic32Swapped:
+ case llvm::MachO::HeaderMagic64Swapped:
+ m_process_image_addr_is_all_images_infos = false;
+ return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+
+ default:
+ break;
+ }
}
+ // Maybe it points to the all image infos?
+ m_dyld_all_image_infos_addr = shlib_addr;
+ m_process_image_addr_is_all_images_infos = true;
}
- // Maybe it points to the all image infos?
- m_dyld_all_image_infos_addr = shlib_addr;
}
if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
@@ -283,13 +336,13 @@
}
ModuleSP
-DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
+DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
{
if (did_create_ptr)
*did_create_ptr = false;
-
- const ModuleList &target_images = m_process->GetTarget().GetImages();
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_images = target.GetImages();
ModuleSpec module_spec (image_info.file_spec, image_info.GetArchitecture ());
module_spec.GetUUID() = image_info.uuid;
ModuleSP module_sp (target_images.FindFirstModule (module_spec));
@@ -306,16 +359,9 @@
{
if (can_create)
{
- module_sp = m_process->GetTarget().GetSharedModule (module_spec);
+ module_sp = target.GetSharedModule (module_spec);
if (!module_sp || module_sp->GetObjectFile() == NULL)
- {
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = false;
- module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
- image_info.address,
- add_image_to_target,
- load_image_sections_in_target);
- }
+ module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
if (did_create_ptr)
*did_create_ptr = (bool) module_sp;
@@ -349,12 +395,14 @@
}
}
+ Target &target = m_process->GetTarget();
+
if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
{
static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
if (symbol)
- m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
+ m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&target);
}
// Update all image infos
@@ -365,9 +413,15 @@
// it again (since Target::SetExecutableModule() will clear the
// images). So append the dyld module back to the list if it is
/// unique!
- if (dyld_module_sp && m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+ if (dyld_module_sp)
+ {
+ target.GetImages().AppendIfNeeded (dyld_module_sp);
+ // At this point we should have read in dyld's module, and so we should set breakpoints in it:
+ ModuleList modules;
+ modules.Append(dyld_module_sp);
+ target.ModulesDidLoad(modules);
+ }
return true;
}
}
@@ -380,40 +434,6 @@
return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
}
-bool
-DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- uint32_t num_sections = section_list->GetSize();
- for (uint32_t i=0; i<num_sections; ++i)
- {
- SectionSP section_sp (section_list->GetSectionAtIndex (i));
- if (section_sp)
- {
- const addr_t new_section_load_addr = section_sp->GetFileAddress ();
- const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
- if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
- old_section_load_addr != new_section_load_addr)
- {
- if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress ()))
- changed = true;
- }
- }
- }
- }
- }
- }
- return changed;
-}
-
//----------------------------------------------------------------------
// Update the load addresses for all segments in MODULE using the
// updated INFO that is passed in.
@@ -433,8 +453,8 @@
std::vector<uint32_t> inaccessible_segment_indexes;
// We now know the slide amount, so go through all sections
// and update the load addresses with the correct values.
- uint32_t num_segments = info.segments.size();
- for (uint32_t i=0; i<num_segments; ++i)
+ const size_t num_segments = info.segments.size();
+ for (size_t i=0; i<num_segments; ++i)
{
// Only load a segment if it has protections. Things like
// __PAGEZERO don't have any protections, and they shouldn't
@@ -469,7 +489,7 @@
else
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
+ "warning: unable to find and load segment named '%s' at 0x%" PRIx64 " in '%s/%s' in macosx dynamic loader plug-in.\n",
info.segments[i].name.AsCString("<invalid>"),
(uint64_t)new_section_load_addr,
image_object_file->GetFileSpec().GetDirectory().AsCString(),
@@ -509,6 +529,14 @@
}
}
}
+ // We might have an in memory image that was loaded as soon as it was created
+ if (info.load_stop_id == m_process->GetStopID())
+ changed = true;
+ else if (changed)
+ {
+ // Update the stop ID when this library was updated
+ info.load_stop_id = m_process->GetStopID();
+ }
return changed;
}
@@ -528,8 +556,8 @@
SectionList *section_list = image_object_file->GetSectionList ();
if (section_list)
{
- uint32_t num_segments = info.segments.size();
- for (uint32_t i=0; i<num_segments; ++i)
+ const size_t num_segments = info.segments.size();
+ for (size_t i=0; i<num_segments; ++i)
{
SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
if (section_sp)
@@ -658,7 +686,7 @@
uint8_t buf[256];
DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
const size_t count_v2 = sizeof (uint32_t) + // version
sizeof (uint32_t) + // infoArrayCount
@@ -683,7 +711,6 @@
addr_size; // errorSymbol
assert (sizeof (buf) >= count_v11);
- int count;
Error error;
if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
{
@@ -710,10 +737,7 @@
return false;
}
- if (m_dyld_all_image_infos.version >= 11)
- count = count_v11;
- else
- count = count_v2;
+ const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
if (bytes_read == count)
@@ -790,12 +814,14 @@
// Now add these images to the main list.
ModuleList loaded_module_list;
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ ModuleList& target_images = target.GetImages();
for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
{
if (log)
{
- log->Printf ("Adding new image at address=0x%16.16llx.", image_infos[idx].address);
+ log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
image_infos[idx].PutToLog (log.get());
}
@@ -818,26 +844,31 @@
Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
if (commpage_section)
{
- const ModuleList& target_images = m_process->GetTarget().GetImages();
ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
module_spec.GetObjectName() = commpage_dbstr;
ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
if (!commpage_image_module_sp)
{
- module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset());
- commpage_image_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
+ module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
+ commpage_image_module_sp = target.GetSharedModule (module_spec);
if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
{
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = false;
commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
- image_infos[idx].address,
- add_image_to_target,
- load_image_sections_in_target);
+ image_infos[idx].address);
+ // Always load a memory image right away in the target in case
+ // we end up trying to read the symbol table from memory... The
+ // __LINKEDIT will need to be mapped so we can figure out where
+ // the symbol table bits are...
+ bool changed = false;
+ UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
+ target.GetImages().Append(commpage_image_module_sp);
+ if (changed)
+ {
+ image_infos[idx].load_stop_id = m_process->GetStopID();
+ loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
+ }
}
}
- if (commpage_image_module_sp)
- UpdateCommPageLoadAddress (commpage_image_module_sp.get());
}
}
}
@@ -849,6 +880,7 @@
// shared libraries each time.
if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
{
+ target_images.AppendIfNeeded(image_module_sp);
loaded_module_list.AppendIfNeeded (image_module_sp);
}
}
@@ -907,7 +939,7 @@
{
if (log)
{
- log->Printf ("Removing module at address=0x%16.16llx.", image_infos[idx].address);
+ log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
image_infos[idx].PutToLog (log.get());
}
@@ -992,7 +1024,7 @@
error);
if (bytes_read == count)
{
- uint32_t info_data_offset = 0;
+ lldb::offset_t info_data_offset = 0;
DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
{
@@ -1051,7 +1083,7 @@
if (!AddModulesUsingImageInfosAddress (m_dyld_all_image_infos.dylib_info_addr,
m_dyld_all_image_infos.dylib_info_count))
{
- DEBUG_PRINTF( "unable to read all data for all_dylib_infos.");
+ DEBUG_PRINTF("%s", "unable to read all data for all_dylib_infos.");
m_dyld_image_infos.clear();
}
}
@@ -1110,7 +1142,7 @@
error);
if (bytes_read == sizeof(llvm::MachO::mach_header))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
::memset (header, 0, sizeof(llvm::MachO::mach_header));
// Get the magic byte unswapped so we can figure out what we are dealing with
@@ -1172,7 +1204,7 @@
uint32_t
DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t cmd_idx;
Segment segment;
dylib_info.Clear (true);
@@ -1185,7 +1217,7 @@
if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
{
llvm::MachO::load_command load_cmd;
- uint32_t load_cmd_offset = offset;
+ lldb::offset_t load_cmd_offset = offset;
load_cmd.cmd = data.GetU32 (&offset);
load_cmd.cmdsize = data.GetU32 (&offset);
switch (load_cmd.cmd)
@@ -1219,7 +1251,7 @@
case llvm::MachO::LoadCommandDynamicLinkerIdent:
if (lc_id_dylinker)
{
- uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
+ const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset);
const char *path = data.PeekCStr (name_offset);
lc_id_dylinker->SetFile (path, true);
}
@@ -1290,32 +1322,18 @@
}
}
+ Target &target = m_process->GetTarget();
+
if (exe_idx < image_infos.size())
{
const bool can_create = true;
ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
- if (!exe_module_sp)
- {
- ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
- ModuleSpec module_spec (image_infos[exe_idx].file_spec,
- image_infos[exe_idx].GetArchitecture ());
- module_spec.GetUUID() = image_infos[exe_idx].uuid;
- exe_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
- {
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = false;
- exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
- image_infos[exe_idx].address,
- add_image_to_target,
- load_image_sections_in_target);
- }
- }
-
if (exe_module_sp)
{
- if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModulePointer())
+ UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
+
+ if (exe_module_sp.get() != target.GetExecutableModulePointer())
{
// Don't load dependent images since we are in dyld where we will know
// and find out about all images that are loaded
@@ -1376,12 +1394,12 @@
if (log)
{
if (slide == 0)
- log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)",
+ log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")",
name.AsCString(""),
vmaddr + slide,
vmaddr + slide + vmsize);
else
- log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx",
+ log->Printf ("\t\t%16s [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") slide = 0x%" PRIx64,
name.AsCString(""),
vmaddr + slide,
vmaddr + slide + vmsize,
@@ -1416,7 +1434,7 @@
{
if (u)
{
- log->Printf("\t modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s' (UNLOADED)",
+ log->Printf("\t modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s' (UNLOADED)",
mod_date,
u[ 0], u[ 1], u[ 2], u[ 3],
u[ 4], u[ 5], u[ 6], u[ 7],
@@ -1426,7 +1444,7 @@
file_spec.GetFilename().AsCString());
}
else
- log->Printf("\t modtime=0x%8.8llx path='%s/%s' (UNLOADED)",
+ log->Printf("\t modtime=0x%8.8" PRIx64 " path='%s/%s' (UNLOADED)",
mod_date,
file_spec.GetDirectory().AsCString(),
file_spec.GetFilename().AsCString());
@@ -1435,7 +1453,7 @@
{
if (u)
{
- log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s'",
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X path='%s/%s'",
address,
mod_date,
u[ 0], u[ 1], u[ 2], u[ 3],
@@ -1447,7 +1465,7 @@
}
else
{
- log->Printf("\taddress=0x%16.16llx modtime=0x%8.8llx path='%s/%s'",
+ log->Printf("\taddress=0x%16.16" PRIx64 " modtime=0x%8.8" PRIx64 " path='%s/%s'",
address,
mod_date,
file_spec.GetDirectory().AsCString(),
@@ -1470,7 +1488,7 @@
return;
Mutex::Locker locker(m_mutex);
- log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8llx, notify=0x%8.8llx }",
+ log->Printf("dyld_all_image_infos = { version=%d, count=%d, addr=0x%8.8" PRIx64 ", notify=0x%8.8" PRIx64 " }",
m_dyld_all_image_infos.version,
m_dyld_all_image_infos.dylib_info_count,
(uint64_t)m_dyld_all_image_infos.dylib_info_addr,
@@ -1512,6 +1530,7 @@
{
Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind ("shared-library-event");
m_break_id = dyld_break->GetID();
}
}
@@ -1555,9 +1574,6 @@
case eStateCrashed:
case eStateSuspended:
break;
-
- default:
- break;
}
}
Index: aze/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h 2013-03-03 09:35:50.211457353 +0100
@@ -62,6 +62,9 @@
virtual void
DidLaunch ();
+ virtual bool
+ ProcessDidExec ();
+
virtual lldb::ThreadPlanSP
GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
bool stop_others);
@@ -175,6 +178,7 @@
lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
llvm::MachO::mach_header header; // The mach header for this image
std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
+ uint32_t load_stop_id; // The process stop ID that the sections for this image were loadeded
DYLDImageInfo() :
address(LLDB_INVALID_ADDRESS),
@@ -183,7 +187,8 @@
file_spec(),
uuid(),
header(),
- segments()
+ segments(),
+ load_stop_id(0)
{
}
@@ -200,6 +205,7 @@
}
uuid.Clear();
segments.clear();
+ load_stop_id = 0;
}
bool
@@ -313,7 +319,7 @@
DYLDImageInfo& info);
lldb::ModuleSP
- FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info,
+ FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info,
bool can_create,
bool *did_create_ptr);
@@ -355,9 +361,6 @@
bool update_executable);
bool
- UpdateCommPageLoadAddress (lldb_private::Module *module);
-
- bool
ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
DYLDImageInfo::collection &image_infos);
@@ -372,6 +375,7 @@
uint32_t m_dyld_image_infos_stop_id; // The process stop ID that "m_dyld_image_infos" is valid for
mutable lldb_private::Mutex m_mutex;
lldb_private::Process::Notifications m_notification_callbacks;
+ bool m_process_image_addr_is_all_images_infos;
private:
DISALLOW_COPY_AND_ASSIGN (DynamicLoaderMacOSXDYLD);
Index: aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp 2013-03-03 09:35:50.211457353 +0100
@@ -26,21 +26,25 @@
static bool
GetMaxU64(DataExtractor &data,
- uint32_t *offset, uint64_t *value, unsigned int byte_size)
-{
- uint32_t saved_offset = *offset;
- *value = data.GetMaxU64(offset, byte_size);
- return *offset != saved_offset;
+ lldb::offset_t *offset_ptr,
+ uint64_t *value,
+ unsigned int byte_size)
+{
+ lldb::offset_t saved_offset = *offset_ptr;
+ *value = data.GetMaxU64(offset_ptr, byte_size);
+ return *offset_ptr != saved_offset;
}
static bool
-ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
- uint32_t *offset, unsigned int byte_size)
+ParseAuxvEntry(DataExtractor &data,
+ AuxVector::Entry &entry,
+ lldb::offset_t *offset_ptr,
+ unsigned int byte_size)
{
- if (!GetMaxU64(data, offset, &entry.type, byte_size))
+ if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
return false;
- if (!GetMaxU64(data, offset, &entry.value, byte_size))
+ if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
return false;
return true;
@@ -57,7 +61,7 @@
AuxVector::ParseAuxv(DataExtractor &data)
{
const unsigned int byte_size = m_process->GetAddressByteSize();
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
for (;;)
{
@@ -113,7 +117,7 @@
log->PutCString("AuxVector: ");
for (iterator I = begin(); I != end(); ++I)
{
- log->Printf(" %s [%llu]: %llx", GetEntryName(*I), I->type, I->value);
+ log->Printf(" %s [%" PRIu64 "]: %" PRIx64, GetEntryName(*I), I->type, I->value);
}
}
@@ -125,10 +129,6 @@
#define ENTRY_NAME(_type) _type: name = #_type
switch (type)
{
- default:
- name = "unkown";
- break;
-
case ENTRY_NAME(AT_NULL); break;
case ENTRY_NAME(AT_IGNORE); break;
case ENTRY_NAME(AT_EXECFD); break;
Index: aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt 2013-03-03 09:35:50.211457353 +0100
@@ -0,0 +1,7 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginDynamicLoaderPosixDYLD
+ AuxVector.cpp
+ DYLDRendezvous.cpp
+ DynamicLoaderPOSIXDYLD.cpp
+ )
Index: aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp 2013-03-03 09:35:50.211457353 +0100
@@ -303,11 +303,11 @@
return;
log->PutCString("DYLDRendezvous:");
- log->Printf(" Address: %llx", GetRendezvousAddress());
- log->Printf(" Version: %d", GetVersion());
- log->Printf(" Link : %llx", GetLinkMapAddress());
- log->Printf(" Break : %llx", GetBreakAddress());
- log->Printf(" LDBase : %llx", GetLDBase());
+ log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
+ log->Printf(" Version: %" PRIu64, GetVersion());
+ log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
+ log->Printf(" Break : %" PRIx64, GetBreakAddress());
+ log->Printf(" LDBase : %" PRIx64, GetLDBase());
log->Printf(" State : %s",
(state == eConsistent) ? "consistent" :
(state == eAdd) ? "add" :
@@ -322,10 +322,10 @@
for (int i = 1; I != E; ++I, ++i)
{
log->Printf("\n SOEntry [%d] %s", i, I->path.c_str());
- log->Printf(" Base : %llx", I->base_addr);
- log->Printf(" Path : %llx", I->path_addr);
- log->Printf(" Dyn : %llx", I->dyn_addr);
- log->Printf(" Next : %llx", I->next);
- log->Printf(" Prev : %llx", I->prev);
+ log->Printf(" Base : %" PRIx64, I->base_addr);
+ log->Printf(" Path : %" PRIx64, I->path_addr);
+ log->Printf(" Dyn : %" PRIx64, I->dyn_addr);
+ log->Printf(" Next : %" PRIx64, I->next);
+ log->Printf(" Prev : %" PRIx64, I->prev);
}
}
Index: aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h 2013-03-03 09:35:50.211457353 +0100
@@ -73,7 +73,7 @@
GetRendezvousAddress() const { return m_rendezvous_addr; }
/// @returns the version of the rendezvous protocol being used.
- int
+ uint64_t
GetVersion() const { return m_current.version; }
/// @returns address in the inferiors address space containing the linked
@@ -92,7 +92,7 @@
GetBreakAddress() const { return m_current.brk; }
/// Returns the current state of the rendezvous structure.
- int
+ uint64_t
GetState() const { return m_current.state; }
/// @returns the base address of the runtime linker in the inferiors address
Index: aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp 2013-03-03 09:35:50.211457353 +0100
@@ -202,6 +202,7 @@
entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
entry_break->SetCallback(EntryBreakpointHit, this, true);
+ entry_break->SetBreakpointKind("shared-library-event");
}
// The runtime linker has run and initialized the rendezvous structure once the
@@ -233,6 +234,7 @@
break_addr = m_rendezvous.GetBreakAddress();
dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind ("shared-library-event");
}
bool
Index: aze/lldb/source/Plugins/DynamicLoader/Static/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/DynamicLoader/Static/CMakeLists.txt 2013-03-03 09:35:50.211457353 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginDynamicLoaderStatic
+ DynamicLoaderStatic.cpp
+ )
Index: aze/lldb/source/Plugins/Instruction/ARM/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Instruction/ARM/CMakeLists.txt 2013-03-03 09:35:50.211457353 +0100
@@ -0,0 +1,6 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginInstructionARM
+ EmulateInstructionARM.cpp
+ EmulationStateARM.cpp
+ )
Index: aze/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp 2013-03-03 09:35:50.215457353 +0100
@@ -13001,7 +13001,6 @@
{
switch (m_opcode_mode)
{
- default:
case eModeInvalid:
break;
Index: aze/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h
===================================================================
--- aze.orig/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h 2013-03-03 09:35:50.215457353 +0100
@@ -89,9 +89,6 @@
case eInstructionTypeAll:
return false;
-
- default:
- break;
}
return false;
}
Index: aze/lldb/source/Plugins/Instruction/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Instruction/CMakeLists.txt 2013-03-03 09:35:50.215457353 +0100
@@ -0,0 +1 @@
+add_subdirectory(ARM)
Index: aze/lldb/source/Plugins/LanguageRuntime/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/LanguageRuntime/CMakeLists.txt 2013-03-03 09:35:50.215457353 +0100
@@ -0,0 +1,2 @@
+add_subdirectory(CPlusPlus)
+add_subdirectory(ObjC)
Index: aze/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt 2013-03-03 09:35:50.215457353 +0100
@@ -0,0 +1,2 @@
+add_subdirectory(ItaniumABI)
+#add_subdirectory(MicrosoftABI)
Index: aze/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt 2013-03-03 09:35:50.215457353 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginCXXItaniumABI
+ ItaniumABILanguageRuntime.cpp
+ )
Index: aze/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp 2013-03-03 09:35:50.215457353 +0100
@@ -59,6 +59,8 @@
// start of the value object which holds the dynamic type.
//
+ class_type_or_name.Clear();
+
// Only a pointer or reference type can have a different dynamic and static type:
if (CouldHaveDynamicValue (in_value))
{
@@ -88,10 +90,10 @@
return false;
}
- uint32_t offset_ptr = 0;
- lldb::addr_t vtable_address_point = data.GetAddress (&offset_ptr);
+ lldb::offset_t offset = 0;
+ lldb::addr_t vtable_address_point = data.GetAddress (&offset);
- if (offset_ptr == 0)
+ if (offset == 0)
return false;
// Now find the symbol that contains this address:
@@ -111,7 +113,7 @@
{
LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("0x%16.16llx: static-type = '%s' has vtable symbol '%s'\n",
+ log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
original_ptr,
in_value.GetTypeName().GetCString(),
name);
@@ -149,14 +151,14 @@
if (num_matches == 0)
{
if (log)
- log->Printf("0x%16.16llx: is not dynamic\n", original_ptr);
+ log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr);
return false;
}
if (num_matches == 1)
{
type_sp = class_types.GetTypeAtIndex(0);
if (log)
- log->Printf ("0x%16.16llx: static-type = '%s' has dynamic type: uid={0x%llx}, type-name='%s'\n",
+ log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 "}, type-name='%s'\n",
original_ptr,
in_value.GetTypeName().AsCString(),
type_sp->GetID(),
@@ -175,7 +177,7 @@
if (type_sp)
{
if (log)
- log->Printf ("0x%16.16llx: static-type = '%s' has multiple matching dynamic types: uid={0x%llx}, type-name='%s'\n",
+ log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types: uid={0x%" PRIx64 "}, type-name='%s'\n",
original_ptr,
in_value.GetTypeName().AsCString(),
type_sp->GetID(),
@@ -192,7 +194,7 @@
if (ClangASTContext::IsCXXClassType(type_sp->GetClangFullType()))
{
if (log)
- log->Printf ("0x%16.16llx: static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%llx}, type-name='%s'\n",
+ log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n",
original_ptr,
in_value.GetTypeName().AsCString(),
type_sp->GetID(),
@@ -206,7 +208,7 @@
if (i == num_matches)
{
if (log)
- log->Printf ("0x%16.16llx: static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n",
+ log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n",
original_ptr,
in_value.GetTypeName().AsCString());
return false;
@@ -253,8 +255,8 @@
return false;
}
- offset_ptr = 0;
- int64_t offset_to_top = data.GetMaxS64(&offset_ptr, process->GetAddressByteSize());
+ offset = 0;
+ int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize());
// So the dynamic type is a value that starts at offset_to_top
// above the original address.
@@ -271,7 +273,7 @@
}
}
- return false;
+ return class_type_or_name.IsEmpty() == false;
}
bool
@@ -411,11 +413,25 @@
if (!m_cxx_exception_bp_sp)
{
Target &target = m_process->GetTarget();
-
+ FileSpecList filter_modules;
+ // Limit the number of modules that are searched for these breakpoints for
+ // Apple binaries.
+ if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
+ {
+ filter_modules.Append(FileSpec("libc++abi.dylib", false));
+ filter_modules.Append(FileSpec("libSystem.B.dylib", false));
+ }
BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
- SearchFilterSP filter_sp = target.GetSearchFilterForModule(NULL);
+ SearchFilterSP filter_sp;
+
+ if (filter_modules.IsEmpty())
+ filter_sp = target.GetSearchFilterForModule(NULL);
+ else
+ filter_sp = target.GetSearchFilterForModuleList(&filter_modules);
m_cxx_exception_bp_sp = target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
+ if (m_cxx_exception_bp_sp)
+ m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
}
else
m_cxx_exception_bp_sp->SetEnabled (true);
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp 2013-03-03 09:35:50.215457353 +0100
@@ -134,9 +134,10 @@
lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
- bool unwind_on_error = true;
- bool try_all_threads = true;
- bool stop_others = true;
+ const bool unwind_on_error = true;
+ const bool try_all_threads = true;
+ const bool stop_others = true;
+ const bool ignore_breakpoints = true;
ExecutionResults results = func.ExecuteFunction (exe_ctx,
&wrapper_struct_addr,
@@ -144,7 +145,8 @@
stop_others,
0 /* no timeout */,
try_all_threads,
- unwind_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
ret);
if (results != eExecutionCompleted)
{
@@ -331,11 +333,15 @@
const bool is_internal = true;
if (!m_objc_exception_bp_sp)
+ {
m_objc_exception_bp_sp = LanguageRuntime::CreateExceptionBreakpoint (m_process->GetTarget(),
GetLanguageType(),
catch_bp,
throw_bp,
is_internal);
+ if (m_objc_exception_bp_sp)
+ m_objc_exception_bp_sp->SetBreakpointKind("ObjC exception");
+ }
else
m_objc_exception_bp_sp->SetEnabled(true);
}
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp 2013-03-03 09:35:50.215457353 +0100
@@ -9,6 +9,7 @@
#include "AppleObjCRuntimeV1.h"
#include "AppleObjCTrampolineHandler.h"
+#include "AppleObjCTypeVendor.h"
#include "llvm/Support/MachO.h"
#include "clang/AST/Type.h"
@@ -48,13 +49,26 @@
{
}
+// for V1 runtime we just try to return a class name as that is the minimum level of support
+// required for the data formatters to work
bool
AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
Address &address)
{
- return false;
+ class_type_or_name.Clear();
+ if (CouldHaveDynamicValue(in_value))
+ {
+ auto class_descriptor(GetClassDescriptor(in_value));
+ if (class_descriptor && class_descriptor->IsValid() && class_descriptor->GetClassName())
+ {
+ const addr_t object_ptr = in_value.GetPointerValue();
+ address.SetRawAddress(object_ptr);
+ class_type_or_name.SetName(class_descriptor->GetClassName());
+ }
+ }
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
@@ -294,6 +308,15 @@
return ObjCLanguageRuntime::ClassDescriptorSP(new AppleObjCRuntimeV1::ClassDescriptorV1(m_parent_isa,process_sp));
}
+bool
+AppleObjCRuntimeV1::ClassDescriptorV1::Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+ std::function <bool (const char *, const char *)> const &instance_method_func,
+ std::function <bool (const char *, const char *)> const &class_method_func,
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
+{
+ return false;
+}
+
lldb::addr_t
AppleObjCRuntimeV1::GetISAHashTablePointer ()
{
@@ -341,9 +364,8 @@
{
// Update the process stop ID that indicates the last time we updated the
// map, wether it was successful or not.
- m_isa_to_descriptor_cache_stop_id = process->GetStopID();
+ m_isa_to_descriptor_stop_id = process->GetStopID();
-
lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
ProcessSP process_sp = process->shared_from_this();
@@ -375,7 +397,7 @@
const uint32_t addr_size = m_process->GetAddressByteSize();
const ByteOrder byte_order = m_process->GetByteOrder();
DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
- uint32_t offset = addr_size; // Skip prototype
+ lldb::offset_t offset = addr_size; // Skip prototype
const uint32_t count = data.GetU32(&offset);
const uint32_t num_buckets = data.GetU32(&offset);
const addr_t buckets_ptr = data.GetPointer(&offset);
@@ -408,14 +430,14 @@
isa = bucket_data;
if (isa)
{
- if (m_isa_to_descriptor_cache.count(isa) == 0)
+ if (!ISAIsCached(isa))
{
ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%llx from _objc_debug_class_hash to isa->descriptor cache", isa);
+ log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
- m_isa_to_descriptor_cache[isa] = descriptor_sp;
+ AddClass (isa, descriptor_sp);
}
}
}
@@ -430,14 +452,14 @@
if (isa && isa != LLDB_INVALID_ADDRESS)
{
- if (m_isa_to_descriptor_cache.count(isa) == 0)
+ if (!ISAIsCached(isa))
{
ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%llx from _objc_debug_class_hash to isa->descriptor cache", isa);
+ log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
- m_isa_to_descriptor_cache[isa] = descriptor_sp;
+ AddClass (isa, descriptor_sp);
}
}
}
@@ -450,7 +472,15 @@
}
else
{
- m_isa_to_descriptor_cache_stop_id = UINT32_MAX;
+ m_isa_to_descriptor_stop_id = UINT32_MAX;
}
}
+TypeVendor *
+AppleObjCRuntimeV1::GetTypeVendor()
+{
+ if (!m_type_vendor_ap.get())
+ m_type_vendor_ap.reset(new AppleObjCTypeVendor(*this));
+
+ return m_type_vendor_ap.get();
+}
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h 2013-03-03 09:35:50.215457353 +0100
@@ -64,6 +64,12 @@
return m_isa;
}
+ virtual bool
+ Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
+ std::function <bool (const char *, const char *)> const &instance_method_func,
+ std::function <bool (const char *, const char *)> const &class_method_func,
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func);
+
virtual
~ClassDescriptorV1 ()
{}
@@ -125,6 +131,9 @@
virtual void
UpdateISAToDescriptorMapIfNeeded();
+
+ virtual TypeVendor *
+ GetTypeVendor();
protected:
virtual lldb::BreakpointResolverSP
@@ -173,6 +182,7 @@
HashTableSignature m_hash_signature;
lldb::addr_t m_isa_hash_table_ptr;
+ std::auto_ptr<TypeVendor> m_type_vendor_ap;
private:
AppleObjCRuntimeV1(Process *process);
};
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp 2013-03-03 09:35:50.219457353 +0100
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
#include <string>
#include <vector>
@@ -17,10 +18,8 @@
#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
@@ -28,7 +27,7 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/Timer.h"
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -49,206 +48,265 @@
using namespace lldb;
using namespace lldb_private;
-
static const char *pluginName = "AppleObjCRuntimeV2";
static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2";
static const char *pluginShort = "language.apple.objc.v2";
+// 2 second timeout when running utility functions
+#define UTILITY_FUNCTION_TIMEOUT_USEC 2*1000*1000
-const char *AppleObjCRuntimeV2::g_find_class_name_function_name = "__lldb_apple_objc_v2_find_class_name";
-const char *AppleObjCRuntimeV2::g_find_class_name_function_body = " \n\
-extern \"C\" \n\
-{ \n\
- extern void *gdb_class_getClass (void *objc_class); \n\
- extern void *class_getName(void *objc_class); \n\
- extern int printf(const char *format, ...); \n\
- extern unsigned char class_isMetaClass (void *objc_class); \n\
-} \n\
- \n\
-struct __lldb_objc_object { \n\
- void *isa; \n\
-}; \n\
- \n\
-extern \"C\" void *__lldb_apple_objc_v2_find_class_name ( \n\
- __lldb_objc_object *object_ptr, \n\
- int debug) \n\
-{ \n\
- void *name = 0; \n\
- if (debug) \n\
- printf (\"\\n*** Called in v2_find_class_name with object: 0x%p\\n\", object_ptr); \n\
- // Call gdb_class_getClass so we can tell if the class is good. \n\
- void *objc_class = gdb_class_getClass (object_ptr->isa); \n\
- if (objc_class) \n\
- { \n\
- void *actual_class = (void *) [(id) object_ptr class]; \n\
- if (actual_class != 0) \n\
- { \n\
- if (class_isMetaClass(actual_class) == 1) \n\
- { \n\
- if (debug) \n\
- printf (\"\\n*** Found metaclass.\\n\"); \n\
- } \n\
- else \n\
- { \n\
- name = class_getName((void *) actual_class); \n\
- } \n\
- } \n\
- if (debug) \n\
- printf (\"\\n*** Found name: %s\\n\", name ? name : \"<NOT FOUND>\"); \n\
- } \n\
- else if (debug) \n\
- printf (\"\\n*** gdb_class_getClass returned NULL\\n\"); \n\
- return name; \n\
-} \n\
-";
+static const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+// need to revert to the code above...
+static const char *g_get_dynamic_class_info_body = R"(
+
+extern "C"
+{
+ size_t strlen(const char *);
+ char *strncpy (char * s1, const char * s2, size_t n);
+ int printf(const char * format, ...);
+}
+//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
+#ifdef ENABLE_DEBUG_PRINTF
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+typedef struct _NXMapTable {
+ void *prototype;
+ unsigned num_classes;
+ unsigned num_buckets_minus_one;
+ void *buckets;
+} NXMapTable;
+
+#define NX_MAPNOTAKEY ((void *)(-1))
+
+typedef struct BucketInfo
+{
+ const char *name_ptr;
+ Class isa;
+} BucketInfo;
+
+struct ClassInfo
+{
+ Class isa;
+ uint32_t hash;
+} __attribute__((__packed__));
-AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
- const ModuleSP &objc_module_sp) :
- AppleObjCRuntime (process),
- m_get_class_name_function (),
- m_get_class_name_code (),
- m_get_class_name_args (LLDB_INVALID_ADDRESS),
- m_get_class_name_args_mutex (Mutex::eMutexTypeNormal),
- m_type_vendor_ap (),
- m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
- m_hash_signature (),
- m_has_object_getClass (false),
- m_loaded_objc_opt (false)
+uint32_t
+__lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,
+ void *class_infos_ptr,
+ uint32_t class_infos_byte_size)
+{
+ DEBUG_PRINTF ("gdb_objc_realized_classes_ptr = %p\n", gdb_objc_realized_classes_ptr);
+ DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
+ DEBUG_PRINTF ("class_infos_byte_size = %u\n", class_infos_byte_size);
+ const NXMapTable *grc = (const NXMapTable *)gdb_objc_realized_classes_ptr;
+ if (grc)
+ {
+ const unsigned num_classes = grc->num_classes;
+ if (class_infos_ptr)
+ {
+ const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+ ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+ BucketInfo *buckets = (BucketInfo *)grc->buckets;
+
+ uint32_t idx = 0;
+ for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)
+ {
+ if (buckets[i].name_ptr != NX_MAPNOTAKEY)
+ {
+ if (idx < max_class_infos)
+ {
+ const char *s = buckets[i].name_ptr;
+ uint32_t h = 5381;
+ for (unsigned char c = *s; c; c = *++s)
+ h = ((h << 5) + h) + c;
+ class_infos[idx].hash = h;
+ class_infos[idx].isa = buckets[i].isa;
+ }
+ ++idx;
+ }
+ }
+ if (idx < max_class_infos)
+ {
+ class_infos[idx].isa = NULL;
+ class_infos[idx].hash = 0;
+ }
+ }
+ return num_classes;
+ }
+ return 0;
+}
+
+)";
+
+static const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+// need to revert to the code above...
+static const char *g_get_shared_cache_class_info_body = R"(
+
+extern "C"
{
- static const ConstString g_gdb_object_getClass("gdb_object_getClass");
- m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
+ const char *class_getName(void *objc_class);
+ size_t strlen(const char *);
+ char *strncpy (char * s1, const char * s2, size_t n);
+ int printf(const char * format, ...);
}
-bool
-AppleObjCRuntimeV2::RunFunctionToFindClassName(addr_t object_addr, Thread *thread, char *name_dst, size_t max_name_len)
+//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN
+#ifdef ENABLE_DEBUG_PRINTF
+#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG_PRINTF(fmt, ...)
+#endif
+
+
+struct objc_classheader_t {
+ int32_t clsOffset;
+ int32_t hiOffset;
+};
+
+struct objc_clsopt_t {
+ uint32_t capacity;
+ uint32_t occupied;
+ uint32_t shift;
+ uint32_t mask;
+ uint32_t zero;
+ uint32_t unused;
+ uint64_t salt;
+ uint32_t scramble[256];
+ uint8_t tab[0]; // tab[mask+1]
+ // uint8_t checkbytes[capacity];
+ // int32_t offset[capacity];
+ // objc_classheader_t clsOffsets[capacity];
+ // uint32_t duplicateCount;
+ // objc_classheader_t duplicateOffsets[duplicateCount];
+};
+
+struct objc_opt_t {
+ uint32_t version;
+ int32_t selopt_offset;
+ int32_t headeropt_offset;
+ int32_t clsopt_offset;
+};
+
+struct ClassInfo
{
- // Since we are going to run code we have to make sure only one thread at a time gets to try this.
- Mutex::Locker locker(m_get_class_name_args_mutex);
-
- StreamString errors;
-
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); // FIXME - a more appropriate log channel?
-
- int32_t debug;
- if (log && log->GetVerbose())
- debug = 1;
- else
- debug = 0;
+ Class isa;
+ uint32_t hash;
+} __attribute__((__packed__));
- ValueList dispatch_values;
-
- Value void_ptr_value;
- ClangASTContext *clang_ast_context = m_process->GetTarget().GetScratchClangASTContext();
-
- clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
- void_ptr_value.SetValueType (Value::eValueTypeScalar);
- void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
- void_ptr_value.GetScalar() = object_addr;
-
- dispatch_values.PushValue (void_ptr_value);
-
- Value int_value;
- clang_type_t clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
- int_value.SetValueType (Value::eValueTypeScalar);
- int_value.SetContext (Value::eContextTypeClangType, clang_int_type);
- int_value.GetScalar() = debug;
-
- dispatch_values.PushValue (int_value);
-
- ExecutionContext exe_ctx;
- thread->CalculateExecutionContext(exe_ctx);
-
- Address find_class_name_address;
-
- if (!m_get_class_name_code.get())
- {
- m_get_class_name_code.reset (new ClangUtilityFunction (g_find_class_name_function_body,
- g_find_class_name_function_name));
-
- if (!m_get_class_name_code->Install(errors, exe_ctx))
- {
- if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
- m_get_class_name_code.reset();
- return false;
+uint32_t
+__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,
+ void *class_infos_ptr,
+ uint32_t class_infos_byte_size)
+{
+ uint32_t idx = 0;
+ DEBUG_PRINTF ("objc_opt_ro_ptr = %p\n", objc_opt_ro_ptr);
+ DEBUG_PRINTF ("class_infos_ptr = %p\n", class_infos_ptr);
+ DEBUG_PRINTF ("class_infos_byte_size = %u (%zu class infos)\n", class_infos_byte_size, (size_t)(class_infos_byte_size/sizeof(ClassInfo)));
+ if (objc_opt_ro_ptr)
+ {
+ const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;
+ DEBUG_PRINTF ("objc_opt->version = %u\n", objc_opt->version);
+ DEBUG_PRINTF ("objc_opt->selopt_offset = %d\n", objc_opt->selopt_offset);
+ DEBUG_PRINTF ("objc_opt->headeropt_offset = %d\n", objc_opt->headeropt_offset);
+ DEBUG_PRINTF ("objc_opt->clsopt_offset = %d\n", objc_opt->clsopt_offset);
+ if (objc_opt->version == 12)
+ {
+ const objc_clsopt_t* clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);
+ const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);
+ ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;
+ int32_t zeroOffset = 16;
+ const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];
+ const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);
+ const objc_classheader_t *classOffsets = (const objc_classheader_t *)(offsets + clsopt->capacity);
+ DEBUG_PRINTF ("clsopt->capacity = %u\n", clsopt->capacity);
+ DEBUG_PRINTF ("clsopt->mask = 0x%8.8x\n", clsopt->mask);
+ DEBUG_PRINTF ("classOffsets = %p\n", classOffsets);
+ for (uint32_t i=0; i<clsopt->capacity; ++i)
+ {
+ const int32_t clsOffset = classOffsets[i].clsOffset;
+ if (clsOffset & 1)
+ continue; // duplicate
+ else if (clsOffset == zeroOffset)
+ continue; // zero offset
+
+ if (class_infos && idx < max_class_infos)
+ {
+ class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
+ const char *name = class_getName (class_infos[idx].isa);
+ DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+ // Hash the class name so we don't have to read it
+ const char *s = name;
+ uint32_t h = 5381;
+ for (unsigned char c = *s; c; c = *++s)
+ h = ((h << 5) + h) + c;
+ class_infos[idx].hash = h;
+ }
+ ++idx;
+ }
+
+ const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];
+ const uint32_t duplicate_count = *duplicate_count_ptr;
+ const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);
+ DEBUG_PRINTF ("duplicate_count = %u\n", duplicate_count);
+ DEBUG_PRINTF ("duplicateClassOffsets = %p\n", duplicateClassOffsets);
+ for (uint32_t i=0; i<duplicate_count; ++i)
+ {
+ const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;
+ if (clsOffset & 1)
+ continue; // duplicate
+ else if (clsOffset == zeroOffset)
+ continue; // zero offset
+
+ if (class_infos && idx < max_class_infos)
+ {
+ class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);
+ const char *name = class_getName (class_infos[idx].isa);
+ DEBUG_PRINTF ("[%u] isa = %8p %s\n", idx, class_infos[idx].isa, name);
+ // Hash the class name so we don't have to read it
+ const char *s = name;
+ uint32_t h = 5381;
+ for (unsigned char c = *s; c; c = *++s)
+ h = ((h << 5) + h) + c;
+ class_infos[idx].hash = h;
+ }
+ ++idx;
+ }
}
- find_class_name_address.Clear();
- find_class_name_address.SetOffset(m_get_class_name_code->StartAddress());
- }
- else
- {
- find_class_name_address.Clear();
- find_class_name_address.SetOffset(m_get_class_name_code->StartAddress());
+ DEBUG_PRINTF ("%u class_infos\n", idx);
+ DEBUG_PRINTF ("done\n");
}
+ return idx;
+}
- // Next make the runner function for our implementation utility function.
- if (!m_get_class_name_function.get())
- {
- m_get_class_name_function.reset(new ClangFunction (*m_process,
- clang_ast_context,
- clang_void_ptr_type,
- find_class_name_address,
- dispatch_values));
-
- errors.Clear();
- unsigned num_errors = m_get_class_name_function->CompileFunction(errors);
- if (num_errors)
- {
- if (log)
- log->Printf ("Error compiling function: \"%s\".", errors.GetData());
- return false;
- }
-
- errors.Clear();
- if (!m_get_class_name_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
- return false;
- }
- }
- if (m_get_class_name_code.get() == NULL || m_get_class_name_function.get() == NULL)
- return false;
+)";
- // Finally, write down the arguments, and call the function. Note that we will re-use the same space in the target
- // for the args. We're locking this to ensure that only one thread at a time gets to call this function, so we don't
- // have to worry about overwriting the arguments.
-
- if (!m_get_class_name_function->WriteFunctionArguments (exe_ctx, m_get_class_name_args, find_class_name_address, dispatch_values, errors))
- return false;
-
- bool stop_others = true;
- bool try_all_threads = true;
- bool unwind_on_error = true;
-
- ExecutionResults results = m_get_class_name_function->ExecuteFunction (exe_ctx,
- &m_get_class_name_args,
- errors,
- stop_others,
- 100000,
- try_all_threads,
- unwind_on_error,
- void_ptr_value);
-
- if (results != eExecutionCompleted)
- {
- if (log)
- log->Printf("Error evaluating our find class name function: %d.\n", results);
- return false;
- }
-
- addr_t result_ptr = void_ptr_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- Error error;
- size_t chars_read = m_process->ReadCStringFromMemory (result_ptr, name_dst, max_name_len, error);
-
- // If we exhausted our buffer before finding a NULL we're probably off in the weeds somewhere...
- if (error.Fail() || chars_read == max_name_len)
- return false;
- else
- return true;
-
+
+AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
+ const ModuleSP &objc_module_sp) :
+ AppleObjCRuntime (process),
+ m_get_class_info_function(),
+ m_get_class_info_code(),
+ m_get_class_info_args (LLDB_INVALID_ADDRESS),
+ m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
+ m_get_shared_cache_class_info_function(),
+ m_get_shared_cache_class_info_code(),
+ m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
+ m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
+ m_type_vendor_ap (),
+ m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
+ m_hash_signature (),
+ m_has_object_getClass (false),
+ m_loaded_objc_opt (false)
+{
+ static const ConstString g_gdb_object_getClass("gdb_object_getClass");
+ m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_object_getClass, eSymbolTypeCode) != NULL);
}
bool
@@ -260,6 +318,8 @@
// The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
assert (in_value.GetProcessSP().get() == m_process);
assert (m_process != NULL);
+
+ class_type_or_name.Clear();
// Make sure we can have a dynamic value before starting...
if (CouldHaveDynamicValue (in_value))
@@ -285,12 +345,9 @@
class_type_or_name.SetTypeSP (type_sp);
}
}
-
- if (type_sp)
- return true;
}
}
- return false;
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
@@ -489,6 +546,15 @@
{
}
+ void
+ Dump ()
+ {
+ printf ("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
+ printf ("RemoteNXMapTable.m_count = %u\n", m_count);
+ printf ("RemoteNXMapTable.m_num_buckets_minus_one = %u\n", m_num_buckets_minus_one);
+ printf ("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
+ }
+
bool
ParseHeader (Process* process, lldb::addr_t load_addr)
{
@@ -669,6 +735,12 @@
{
return m_buckets_ptr;
}
+
+ lldb::addr_t
+ GetTableLoadAddress() const
+ {
+ return m_load_addr;
+ }
private:
// contents of _NXMapTable struct
@@ -720,235 +792,6 @@
return true;
}
-class RemoteObjCOpt
-{
-public:
- RemoteObjCOpt (Process* process,
- lldb::addr_t load_addr) :
- m_process(process),
- m_end_iterator(*this, -1ll),
- m_load_addr(load_addr)
- {
- lldb::addr_t cursor = load_addr;
-
- Error err;
-
- // uint32_t version;
- m_version = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- if (!IsValid())
- return;
-
- // int32_t selopt_offset;
- cursor += sizeof(int32_t);
-
- // int32_t headeropt_offset;
- cursor += sizeof(int32_t);
-
- // int32_t clsopt_offset;
- {
- Scalar clsopt_offset;
- m_process->ReadScalarIntegerFromMemory(cursor, sizeof(int32_t), /*is_signed*/ true, clsopt_offset, err);
- m_clsopt_offset = clsopt_offset.SInt();
- cursor += sizeof(int32_t);
- }
-
- m_clsopt_ptr = load_addr + m_clsopt_offset;
-
- cursor = m_clsopt_ptr;
-
- // uint32_t capacity;
- m_capacity = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- // uint32_t occupied;
- cursor += sizeof(uint32_t);
-
- // uint32_t shift;
- cursor += sizeof(uint32_t);
-
- // uint32_t mask;
- m_mask = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- // uint32_t zero;
- m_zero_offset = cursor - m_clsopt_ptr;
- cursor += sizeof(uint32_t);
-
- // uint32_t unused;
- cursor += sizeof(uint32_t);
-
- // uint64_t salt;
- cursor += sizeof(uint64_t);
-
- // uint32_t scramble[256];
- cursor += sizeof(uint32_t) * 256;
-
- // uint8_t tab[mask+1];
- cursor += sizeof(uint8_t) * (m_mask + 1);
-
- // uint8_t checkbytes[capacity];
- cursor += sizeof(uint8_t) * m_capacity;
-
- // int32_t offset[capacity];
- cursor += sizeof(int32_t) * m_capacity;
-
- // objc_classheader_t clsOffsets[capacity];
- m_clsOffsets_ptr = cursor;
- cursor += (m_classheader_size * m_capacity);
-
- // uint32_t duplicateCount;
- m_duplicateCount = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- // objc_classheader_t duplicateOffsets[duplicateCount];
- m_duplicateOffsets_ptr = cursor;
- }
-
- friend class const_iterator;
- class const_iterator
- {
- public:
- const_iterator (RemoteObjCOpt &parent, int64_t index) : m_parent(parent), m_index(index)
- {
- AdvanceToValidIndex();
- }
-
- const_iterator (const const_iterator &rhs) : m_parent(rhs.m_parent), m_index(rhs.m_index)
- {
- // AdvanceToValidIndex() has been called by rhs already
- }
-
- const_iterator &operator=(const const_iterator &rhs)
- {
- assert (&m_parent == &rhs.m_parent);
- m_index = rhs.m_index;
- return *this;
- }
-
- bool operator==(const const_iterator &rhs) const
- {
- if (&m_parent != &rhs.m_parent)
- return false;
- if (m_index != rhs.m_index)
- return false;
- return true;
- }
-
- bool operator!=(const const_iterator &rhs) const
- {
- return !(operator==(rhs));
- }
-
- const_iterator &operator++()
- {
- AdvanceToValidIndex();
- return *this;
- }
-
- const ObjCLanguageRuntime::ObjCISA operator*() const
- {
- if (m_index == -1)
- return 0;
-
- Error err;
- return isaForIndex(err);
- }
- private:
- ObjCLanguageRuntime::ObjCISA isaForIndex(Error &err) const
- {
- if (m_index >= m_parent.m_capacity + m_parent.m_duplicateCount)
- return 0; // index out of range
-
- lldb::addr_t classheader_ptr;
-
- if (m_index >= m_parent.m_capacity)
- {
- // index in the duplicate offsets
- uint32_t index = (uint32_t)((uint64_t)m_index - (uint64_t)m_parent.m_capacity);
- classheader_ptr = m_parent.m_duplicateOffsets_ptr + (index * m_parent.m_classheader_size);
- }
- else
- {
- // index in the offsets
- uint32_t index = (uint32_t)m_index;
- classheader_ptr = m_parent.m_clsOffsets_ptr + (index * m_parent.m_classheader_size);
- }
-
- Scalar clsOffset;
- m_parent.m_process->ReadScalarIntegerFromMemory(classheader_ptr, sizeof(int32_t), /*is_signed*/ true, clsOffset, err);
- if (!err.Success())
- return 0;
-
- int32_t clsOffset_int = clsOffset.SInt();
- if (clsOffset_int & 0x1)
- return 0; // not even
-
- if (clsOffset_int == m_parent.m_zero_offset)
- return 0; // == offsetof(objc_clsopt_t, zero)
-
- return m_parent.m_clsopt_ptr + (int64_t)clsOffset_int;
- }
-
- void AdvanceToValidIndex ()
- {
- if (m_index == -1)
- return;
-
- Error err;
-
- m_index--;
-
- while (m_index >= 0)
- {
- ObjCLanguageRuntime::ObjCISA objc_isa = isaForIndex(err);
- if (objc_isa)
- return;
- m_index--;
- }
- }
- RemoteObjCOpt &m_parent;
- int64_t m_index;
- };
-
- const_iterator begin ()
- {
- if (!IsValid())
- return m_end_iterator;
- else
- return const_iterator(*this, (int64_t)m_capacity + (int64_t)m_duplicateCount);
- }
-
- const_iterator end ()
- {
- return m_end_iterator;
- }
-
-private:
- bool IsValid()
- {
- return (m_version == 12);
- }
-
- // contents of objc_opt struct
- uint32_t m_version;
- int32_t m_clsopt_offset;
- lldb::addr_t m_clsopt_ptr;
-
- // contents of objc_clsopt struct
- uint32_t m_capacity;
- uint32_t m_mask;
- uint32_t m_duplicateCount;
- lldb::addr_t m_clsOffsets_ptr;
- lldb::addr_t m_duplicateOffsets_ptr;
- int32_t m_zero_offset;
- lldb_private::Process *m_process;
- const_iterator m_end_iterator;
- lldb::addr_t m_load_addr;
- const size_t m_classheader_size = (sizeof(int32_t) * 2);
-};
-
class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
{
public:
@@ -957,13 +800,13 @@
private:
// The constructor should only be invoked by the runtime as it builds its caches
// or populates them. A ClassDescriptorV2 should only ever exist in a cache.
- ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa) :
+ ClassDescriptorV2 (AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa, const char *name) :
m_runtime (runtime),
m_objc_class_ptr (isa),
- m_name ()
+ m_name (name)
{
}
-
+
public:
virtual ConstString
GetClassName ()
@@ -1047,8 +890,9 @@
virtual bool
Describe (std::function <void (ObjCLanguageRuntime::ObjCISA)> const &superclass_func,
- std::function <void (const char *, const char *)> const &instance_method_func,
- std::function <void (const char *, const char *)> const &class_method_func)
+ std::function <bool (const char *, const char *)> const &instance_method_func,
+ std::function <bool (const char *, const char *)> const &class_method_func,
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> const &ivar_func)
{
lldb_private::Process *process = m_runtime.GetProcess();
@@ -1084,32 +928,56 @@
{
method->Read(process, base_method_list->m_first_ptr + (i * base_method_list->m_entsize));
- instance_method_func(method->m_name.c_str(), method->m_types.c_str());
+ if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
+ break;
}
}
if (class_method_func)
{
- ClassDescriptorV2 metaclass(m_runtime, objc_class->m_isa); // The metaclass is not in the cache
+ ClassDescriptorV2 metaclass(m_runtime, objc_class->m_isa, NULL); // The metaclass is not in the cache
// We don't care about the metaclass's superclass, or its class methods. Its instance methods are
// our class methods.
metaclass.Describe(std::function <void (ObjCLanguageRuntime::ObjCISA)> (nullptr),
class_method_func,
- std::function <void (const char *, const char *)> (nullptr));
+ std::function <bool (const char *, const char *)> (nullptr),
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> (nullptr));
}
- while (0);
-
- return true;
- }
-
- virtual
- ~ClassDescriptorV2 ()
- {
- }
-private:
+ if (ivar_func)
+ {
+ std::auto_ptr <ivar_list_t> ivar_list;
+
+ ivar_list.reset(new ivar_list_t);
+ if (!ivar_list->Read(process, class_ro->m_ivars_ptr))
+ return false;
+
+ if (ivar_list->m_entsize != ivar_t::GetSize(process))
+ return false;
+
+ std::auto_ptr <ivar_t> ivar;
+ ivar.reset(new ivar_t);
+
+ for (uint32_t i = 0, e = ivar_list->m_count; i < e; ++i)
+ {
+ ivar->Read(process, ivar_list->m_first_ptr + (i * ivar_list->m_entsize));
+
+ if (ivar_func(ivar->m_name.c_str(), ivar->m_type.c_str(), ivar->m_offset_ptr, ivar->m_size))
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ virtual
+ ~ClassDescriptorV2 ()
+ {
+ }
+
+private:
static const uint32_t RW_REALIZED = (1 << 31);
struct objc_class_t {
@@ -1162,7 +1030,7 @@
DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_isa = extractor.GetAddress_unchecked(&cursor); // uintptr_t isa;
m_superclass = extractor.GetAddress_unchecked(&cursor); // Class superclass;
@@ -1221,7 +1089,7 @@
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_flags = extractor.GetU32_unchecked(&cursor);
m_instanceStart = extractor.GetU32_unchecked(&cursor);
@@ -1292,13 +1160,13 @@
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_flags = extractor.GetU32_unchecked(&cursor);
m_version = extractor.GetU32_unchecked(&cursor);
- m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
- m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
- m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
@@ -1328,7 +1196,7 @@
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
m_count = extractor.GetU32_unchecked(&cursor);
@@ -1371,7 +1239,7 @@
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_name_ptr = extractor.GetAddress_unchecked(&cursor);
m_types_ptr = extractor.GetAddress_unchecked(&cursor);
@@ -1392,6 +1260,98 @@
}
};
+ struct ivar_list_t
+ {
+ uint32_t m_entsize;
+ uint32_t m_count;
+ lldb::addr_t m_first_ptr;
+
+ bool Read(Process *process, lldb::addr_t addr)
+ {
+ size_t size = sizeof(uint32_t) // uint32_t entsize;
+ + sizeof(uint32_t); // uint32_t count;
+
+ DataBufferHeap buffer (size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail())
+ {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_entsize = extractor.GetU32_unchecked(&cursor);
+ m_count = extractor.GetU32_unchecked(&cursor);
+ m_first_ptr = addr + cursor;
+
+ return true;
+ }
+ };
+
+ struct ivar_t
+ {
+ lldb::addr_t m_offset_ptr;
+ lldb::addr_t m_name_ptr;
+ lldb::addr_t m_type_ptr;
+ uint32_t m_alignment;
+ uint32_t m_size;
+
+ std::string m_name;
+ std::string m_type;
+
+ static size_t GetSize(Process *process)
+ {
+ size_t ptr_size = process->GetAddressByteSize();
+
+ return ptr_size // uintptr_t *offset;
+ + ptr_size // const char *name;
+ + ptr_size // const char *type;
+ + sizeof(uint32_t) // uint32_t alignment;
+ + sizeof(uint32_t); // uint32_t size;
+ }
+
+ bool Read(Process *process, lldb::addr_t addr)
+ {
+ size_t size = GetSize(process);
+
+ DataBufferHeap buffer (size, '\0');
+ Error error;
+
+ process->ReadMemory(addr, buffer.GetBytes(), size, error);
+ if (error.Fail())
+ {
+ return false;
+ }
+
+ DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
+
+ lldb::offset_t cursor = 0;
+
+ m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_name_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_type_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_alignment = extractor.GetU32_unchecked(&cursor);
+ m_size = extractor.GetU32_unchecked(&cursor);
+
+ const size_t buffer_size = 1024;
+ size_t count;
+
+ DataBufferHeap string_buf(buffer_size, 0);
+
+ count = process->ReadCStringFromMemory(m_name_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+ m_name.assign((char*)string_buf.GetBytes(), count);
+
+ count = process->ReadCStringFromMemory(m_type_ptr, (char*)string_buf.GetBytes(), buffer_size, error);
+ m_type.assign((char*)string_buf.GetBytes(), count);
+
+ return true;
+ }
+ };
+
bool Read_objc_class (Process* process, std::auto_ptr<objc_class_t> &objc_class)
{
objc_class.reset(new objc_class_t);
@@ -1683,7 +1643,7 @@
{
lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf("0x%llx: AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%llx",
+ log->Printf("0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%" PRIx64,
isa_pointer,
isa);
}
@@ -1720,100 +1680,568 @@
return m_isa_hash_table_ptr;
}
-void
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table)
{
- // Else we need to check with our process to see when the map was updated.
Process *process = GetProcess();
-
- if (process)
+
+ if (process == NULL)
+ return false;
+
+ lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ ExecutionContext exe_ctx;
+
+ ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+
+ if (!thread_sp)
+ return false;
+
+ thread_sp->CalculateExecutionContext(exe_ctx);
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ if (!ast)
+ return false;
+
+ Address function_address;
+
+ StreamString errors;
+
+ const uint32_t addr_size = process->GetAddressByteSize();
+
+ Error err;
+
+ // Read the total number of classes from the hash table
+ const uint32_t num_classes = hash_table.GetCount();
+ if (num_classes == 0)
{
- // Update the process stop ID that indicates the last time we updated the
- // map, wether it was successful or not.
- m_isa_to_descriptor_cache_stop_id = process->GetStopID();
+ if (log)
+ log->Printf ("No dynamic classes found in gdb_objc_realized_classes.");
+ return false;
+ }
+
+ // Make some types for our arguments
+ clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+
+ if (!m_get_class_info_code.get())
+ {
+ m_get_class_info_code.reset (new ClangUtilityFunction (g_get_dynamic_class_info_body,
+ g_get_dynamic_class_info_name));
- RemoteNXMapTable hash_table;
+ errors.Clear();
- if (m_hash_signature.NeedsUpdate(process, this, hash_table))
+ if (!m_get_class_info_code->Install(errors, exe_ctx))
{
- // Update the hash table signature
- m_hash_signature.UpdateSignature (hash_table);
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_get_class_info_code.reset();
+ }
+ }
+
+ if (m_get_class_info_code.get())
+ function_address.SetOffset(m_get_class_info_code->StartAddress());
+ else
+ return false;
+
+ ValueList arguments;
+
+ // Next make the runner function for our implementation utility function.
+ if (!m_get_class_info_function.get())
+ {
+ Value value;
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ arguments.PushValue (value);
+
+ m_get_class_info_function.reset(new ClangFunction (*m_process,
+ ast,
+ clang_uint32_t_type,
+ function_address,
+ arguments));
+
+ if (m_get_class_info_function.get() == NULL)
+ return false;
+
+ errors.Clear();
+
+ unsigned num_errors = m_get_class_info_function->CompileFunction(errors);
+ if (num_errors)
+ {
+ if (log)
+ log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+ return false;
+ }
+
+ errors.Clear();
+
+ if (!m_get_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+ {
+ if (log)
+ log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ return false;
+ }
+ }
+ else
+ {
+ arguments = m_get_class_info_function->GetArgumentValues ();
+ }
+
+ const uint32_t class_info_byte_size = addr_size + 4;
+ const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+ lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
+ ePermissionsReadable | ePermissionsWritable,
+ err);
+
+ if (class_infos_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Mutex::Locker locker(m_get_class_info_args_mutex);
+
+ // Fill in our function argument values
+ arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
+ arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+
+ bool success = false;
+
+ errors.Clear();
+
+ // Write our function arguments into the process so we can run our function
+ if (m_get_class_info_function->WriteFunctionArguments (exe_ctx,
+ m_get_class_info_args,
+ function_address,
+ arguments,
+ errors))
+ {
+ bool stop_others = true;
+ bool try_all_threads = false;
+ bool unwind_on_error = true;
+ bool ignore_breakpoints = true;
+
+ Value return_value;
+ return_value.SetValueType (Value::eValueTypeScalar);
+ return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ return_value.GetScalar() = 0;
+
+ errors.Clear();
+
+ // Run the function
+ ExecutionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
+ &m_get_class_info_args,
+ errors,
+ stop_others,
+ UTILITY_FUNCTION_TIMEOUT_USEC,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ return_value);
+
+ if (results == eExecutionCompleted)
+ {
+ // The result is the number of ClassInfo structures that were filled in
+ uint32_t num_class_infos = return_value.GetScalar().ULong();
+ if (num_class_infos > 0)
+ {
+ // Read the ClassInfo structures
+ DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), buffer.GetByteSize(), err) == buffer.GetByteSize())
+ {
+ DataExtractor class_infos_data (buffer.GetBytes(),
+ buffer.GetByteSize(),
+ process->GetByteOrder(),
+ addr_size);
+ ParseClassInfoArray (class_infos_data, num_class_infos);
+ }
+ }
+ success = true;
+ }
+ else
+ {
+ if (log)
+ log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ }
+
+ // Deallocate the memory we allocated for the ClassInfo array
+ process->DeallocateMemory(class_infos_addr);
+
+ return success;
+}
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+void
+AppleObjCRuntimeV2::ParseClassInfoArray (const DataExtractor &data, uint32_t num_class_infos)
+{
+ // Parses an array of "num_class_infos" packed ClassInfo structures:
+ //
+ // struct ClassInfo
+ // {
+ // Class isa;
+ // uint32_t hash;
+ // } __attribute__((__packed__));
- uint32_t num_map_table_isas = 0;
- uint32_t num_objc_opt_ro_isas = 0;
+ lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (objc_module_sp)
- {
- for (RemoteNXMapTable::element elt : hash_table)
+ // Iterate through all ClassInfo structures
+ lldb::offset_t offset = 0;
+ for (uint32_t i=0; i<num_class_infos; ++i)
+ {
+ ObjCISA isa = data.GetPointer(&offset);
+
+ if (isa == 0)
+ {
+ if (log)
+ log->Printf("AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
+ continue;
+ }
+ // Check if we already know about this ISA, if we do, the info will
+ // never change, so we can just skip it.
+ if (ISAIsCached(isa))
+ {
+ offset += 4;
+ }
+ else
+ {
+ // Read the 32 bit hash for the class name
+ const uint32_t name_hash = data.GetU32(&offset);
+ ClassDescriptorSP descriptor_sp (new ClassDescriptorV2(*this, isa, NULL));
+ AddClass (isa, descriptor_sp, name_hash);
+ if (log && log->GetVerbose())
+ log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 ", hash=0x%8.8x", isa, name_hash);
+ }
+ }
+}
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
+{
+ Process *process = GetProcess();
+
+ if (process == NULL)
+ return false;
+
+ lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ ExecutionContext exe_ctx;
+
+ ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+
+ if (!thread_sp)
+ return false;
+
+ thread_sp->CalculateExecutionContext(exe_ctx);
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ if (!ast)
+ return false;
+
+ Address function_address;
+
+ StreamString errors;
+
+ const uint32_t addr_size = process->GetAddressByteSize();
+
+ Error err;
+
+ const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
+
+ if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ // Read the total number of classes from the hash table
+ const uint32_t num_classes = 16*1024;
+ if (num_classes == 0)
+ {
+ if (log)
+ log->Printf ("No dynamic classes found in gdb_objc_realized_classes_addr.");
+ return false;
+ }
+
+ // Make some types for our arguments
+ clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+
+ if (!m_get_shared_cache_class_info_code.get())
+ {
+ m_get_shared_cache_class_info_code.reset (new ClangUtilityFunction (g_get_shared_cache_class_info_body,
+ g_get_shared_cache_class_info_name));
+
+ errors.Clear();
+
+ if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_get_shared_cache_class_info_code.reset();
+ }
+ }
+
+ if (m_get_shared_cache_class_info_code.get())
+ function_address.SetOffset(m_get_shared_cache_class_info_code->StartAddress());
+ else
+ return false;
+
+ ValueList arguments;
+
+ // Next make the runner function for our implementation utility function.
+ if (!m_get_shared_cache_class_info_function.get())
+ {
+ Value value;
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ arguments.PushValue (value);
+
+ m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
+ ast,
+ clang_uint32_t_type,
+ function_address,
+ arguments));
+
+ if (m_get_shared_cache_class_info_function.get() == NULL)
+ return false;
+
+ errors.Clear();
+
+ unsigned num_errors = m_get_shared_cache_class_info_function->CompileFunction(errors);
+ if (num_errors)
+ {
+ if (log)
+ log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+ return false;
+ }
+
+ errors.Clear();
+
+ if (!m_get_shared_cache_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+ {
+ if (log)
+ log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ return false;
+ }
+ }
+ else
+ {
+ arguments = m_get_shared_cache_class_info_function->GetArgumentValues ();
+ }
+
+ const uint32_t class_info_byte_size = addr_size + 4;
+ const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+ lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
+ ePermissionsReadable | ePermissionsWritable,
+ err);
+
+ if (class_infos_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Mutex::Locker locker(m_get_shared_cache_class_info_args_mutex);
+
+ // Fill in our function argument values
+ arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
+ arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+
+ bool success = false;
+
+ errors.Clear();
+
+ // Write our function arguments into the process so we can run our function
+ if (m_get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
+ m_get_shared_cache_class_info_args,
+ function_address,
+ arguments,
+ errors))
+ {
+ bool stop_others = true;
+ bool try_all_threads = false;
+ bool unwind_on_error = true;
+ bool ignore_breakpoints = true;
+
+ Value return_value;
+ return_value.SetValueType (Value::eValueTypeScalar);
+ return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ return_value.GetScalar() = 0;
+
+ errors.Clear();
+
+ // Run the function
+ ExecutionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
+ &m_get_shared_cache_class_info_args,
+ errors,
+ stop_others,
+ UTILITY_FUNCTION_TIMEOUT_USEC,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ return_value);
+
+ if (results == eExecutionCompleted)
+ {
+ // The result is the number of ClassInfo structures that were filled in
+ uint32_t num_class_infos = return_value.GetScalar().ULong();
+ if (num_class_infos > 0)
+ {
+ // Read the ClassInfo structures
+ DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr,
+ buffer.GetBytes(),
+ buffer.GetByteSize(),
+ err) == buffer.GetByteSize())
{
- ++num_map_table_isas;
+ DataExtractor class_infos_data (buffer.GetBytes(),
+ buffer.GetByteSize(),
+ process->GetByteOrder(),
+ addr_size);
- if (m_isa_to_descriptor_cache.count(elt.second))
- continue;
-
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second));
-
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
-
- m_isa_to_descriptor_cache[elt.second] = descriptor_sp;
+ ParseClassInfoArray (class_infos_data, num_class_infos);
}
+ }
+ success = true;
+ }
+ else
+ {
+ if (log)
+ log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ }
+
+ // Deallocate the memory we allocated for the ClassInfo array
+ process->DeallocateMemory(class_infos_addr);
+
+ return success;
+}
+
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table)
+{
+ lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ Process *process = GetProcess();
+
+ if (process == NULL)
+ return false;
+
+ uint32_t num_map_table_isas = 0;
+
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (objc_module_sp)
+ {
+ for (RemoteNXMapTable::element elt : hash_table)
+ {
+ ++num_map_table_isas;
+
+ if (ISAIsCached(elt.second))
+ continue;
+
+ ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
+
+ if (log && log->GetVerbose())
+ log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
+
+ AddClass (elt.second, descriptor_sp, elt.first.AsCString());
+ }
+ }
+
+ return num_map_table_isas > 0;
+}
+
+lldb::addr_t
+AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
+{
+ Process *process = GetProcess();
+
+ if (process)
+ {
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (objc_module_sp)
+ {
+ ObjectFile *objc_object = objc_module_sp->GetObjectFile();
+
+ if (objc_object)
+ {
+ SectionList *section_list = objc_object->GetSectionList();
- if (!m_loaded_objc_opt)
+ if (section_list)
{
- m_loaded_objc_opt = true;
+ SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
- ObjectFile *objc_object = objc_module_sp->GetObjectFile();
-
- if (objc_object)
+ if (text_segment_sp)
{
- SectionList *section_list = objc_object->GetSectionList();
+ SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
- if (section_list)
+ if (objc_opt_section_sp)
{
- SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
-
- if (text_segment_sp)
- {
- SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
-
- if (objc_opt_section_sp)
- {
- lldb::addr_t objc_opt_ptr = objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
-
- if (objc_opt_ptr != LLDB_INVALID_ADDRESS)
- {
- RemoteObjCOpt objc_opt(process, objc_opt_ptr);
-
- for (ObjCLanguageRuntime::ObjCISA objc_isa : objc_opt)
- {
- ++num_objc_opt_ro_isas;
- if (m_isa_to_descriptor_cache.count(objc_isa))
- continue;
-
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, objc_isa));
-
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%llx (%s) from static table to isa->descriptor cache", objc_isa, descriptor_sp->GetClassName().AsCString());
-
- m_isa_to_descriptor_cache[objc_isa] = descriptor_sp;
- }
- }
- }
- }
+ return objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
}
}
}
}
}
}
+ return LLDB_INVALID_ADDRESS;
+}
+
+void
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+
+ // Else we need to check with our process to see when the map was updated.
+ Process *process = GetProcess();
+
+ if (process)
+ {
+ RemoteNXMapTable hash_table;
+
+ // Update the process stop ID that indicates the last time we updated the
+ // map, wether it was successful or not.
+ m_isa_to_descriptor_stop_id = process->GetStopID();
+
+ if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
+ return;
+
+ m_hash_signature.UpdateSignature (hash_table);
+
+ // Grab the dynamicly loaded objc classes from the hash table in memory
+ UpdateISAToDescriptorMapDynamic(hash_table);
+
+ // Now get the objc classes that are baked into the Objective C runtime
+ // in the shared cache, but only once per process as this data never
+ // changes
+ if (!m_loaded_objc_opt)
+ UpdateISAToDescriptorMapSharedCache();
+ }
else
{
- m_isa_to_descriptor_cache_stop_id = UINT32_MAX;
+ m_isa_to_descriptor_stop_id = UINT32_MAX;
}
}
@@ -1864,3 +2292,53 @@
return m_type_vendor_ap.get();
}
+
+lldb::addr_t
+AppleObjCRuntimeV2::LookupRuntimeSymbol (const ConstString &name)
+{
+ lldb::addr_t ret = LLDB_INVALID_ADDRESS;
+
+ const char *name_cstr = name.AsCString();
+
+ if (name_cstr)
+ {
+ llvm::StringRef name_strref(name_cstr);
+
+ static const llvm::StringRef ivar_prefix("OBJC_IVAR_$_");
+
+ if (name_strref.startswith(ivar_prefix))
+ {
+ llvm::StringRef ivar_skipped_prefix = name_strref.substr(ivar_prefix.size());
+ std::pair<llvm::StringRef, llvm::StringRef> class_and_ivar = ivar_skipped_prefix.split('.');
+
+ if (class_and_ivar.first.size() && class_and_ivar.second.size())
+ {
+ const ConstString class_name_cs(class_and_ivar.first);
+ ClassDescriptorSP descriptor = ObjCLanguageRuntime::GetClassDescriptor(class_name_cs);
+
+ if (descriptor)
+ {
+ const ConstString ivar_name_cs(class_and_ivar.second);
+ const char *ivar_name_cstr = ivar_name_cs.AsCString();
+
+ auto ivar_func = [&ret, ivar_name_cstr](const char *name, const char *type, lldb::addr_t offset_addr, uint64_t size) -> lldb::addr_t
+ {
+ if (!strcmp(name, ivar_name_cstr))
+ {
+ ret = offset_addr;
+ return true;
+ }
+ return false;
+ };
+
+ descriptor->Describe(std::function<void (ObjCISA)>(nullptr),
+ std::function<bool (const char *, const char *)>(nullptr),
+ std::function<bool (const char *, const char *)>(nullptr),
+ ivar_func);
+ }
+ }
+ }
+ }
+
+ return ret;
+}
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h 2013-03-03 09:35:50.219457353 +0100
@@ -83,7 +83,6 @@
// we report an actual type - otherwise, we just say tagged
// there is no connection between the values here and the tagged pointers map
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
-
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
@@ -99,6 +98,9 @@
virtual TypeVendor *
GetTypeVendor();
+ virtual lldb::addr_t
+ LookupRuntimeSymbol (const ConstString &name);
+
protected:
virtual lldb::BreakpointResolverSP
CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
@@ -132,20 +134,38 @@
lldb::addr_t
GetISAHashTablePointer ();
- bool RunFunctionToFindClassName (lldb::addr_t class_addr, Thread *thread, char *name_dst, size_t max_name_len);
+ bool
+ UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table);
+
+ bool
+ UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
+
+ void
+ ParseClassInfoArray (const lldb_private::DataExtractor &data,
+ uint32_t num_class_infos);
- std::auto_ptr<ClangFunction> m_get_class_name_function;
- std::auto_ptr<ClangUtilityFunction> m_get_class_name_code;
- lldb::addr_t m_get_class_name_args;
- Mutex m_get_class_name_args_mutex;
+ bool
+ UpdateISAToDescriptorMapSharedCache ();
+
+ lldb::addr_t
+ GetSharedCacheReadOnlyAddress();
+
+ std::auto_ptr<ClangFunction> m_get_class_info_function;
+ std::auto_ptr<ClangUtilityFunction> m_get_class_info_code;
+ lldb::addr_t m_get_class_info_args;
+ Mutex m_get_class_info_args_mutex;
+
+ std::auto_ptr<ClangFunction> m_get_shared_cache_class_info_function;
+ std::auto_ptr<ClangUtilityFunction> m_get_shared_cache_class_info_code;
+ lldb::addr_t m_get_shared_cache_class_info_args;
+ Mutex m_get_shared_cache_class_info_args_mutex;
+
std::auto_ptr<TypeVendor> m_type_vendor_ap;
lldb::addr_t m_isa_hash_table_ptr;
HashTableSignature m_hash_signature;
bool m_has_object_getClass;
bool m_loaded_objc_opt;
- static const char *g_find_class_name_function_name;
- static const char *g_find_class_name_function_body;
};
} // namespace lldb_private
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp 2013-03-03 09:35:50.219457353 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "AppleObjCTrampolineHandler.h"
// C Includes
@@ -41,7 +43,8 @@
using namespace lldb_private;
const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = " \n\
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL;
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\
extern \"C\" \n\
{ \n\
extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
@@ -150,6 +153,106 @@
return return_struct.impl_addr; \n\
} \n\
";
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code = " \n\
+extern \"C\" \n\
+{ \n\
+ extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
+ extern void * sel_getUid(char *name); \n\
+ extern int printf(const char *format, ...); \n\
+} \n\
+extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\
+ void *sel, \n\
+ int is_stret, \n\
+ int is_super, \n\
+ int is_super2, \n\
+ int is_fixup, \n\
+ int is_fixed, \n\
+ int debug) \n\
+{ \n\
+ struct __lldb_imp_return_struct \n\
+ { \n\
+ void *class_addr; \n\
+ void *sel_addr; \n\
+ void *impl_addr; \n\
+ }; \n\
+ \n\
+ struct __lldb_objc_class { \n\
+ void *isa; \n\
+ void *super_ptr; \n\
+ }; \n\
+ struct __lldb_objc_super { \n\
+ void *reciever; \n\
+ struct __lldb_objc_class *class_ptr; \n\
+ }; \n\
+ struct __lldb_msg_ref { \n\
+ void *dont_know; \n\
+ void *sel; \n\
+ }; \n\
+ \n\
+ struct __lldb_imp_return_struct return_struct; \n\
+ \n\
+ if (debug) \n\
+ printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\
+ \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\
+ object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\
+ if (is_super) \n\
+ { \n\
+ if (is_super2) \n\
+ { \n\
+ return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ void *class_ptr = (void *) [(id) object class]; \n\
+ if (class_ptr == object) \n\
+ { \n\
+ struct __lldb_objc_class *class_as_class_struct = (struct __lldb_objc_class *) class_ptr; \n\
+ if (debug) \n\
+ printf (\"Found a class object, need to return the meta class 0x%p -> 0x%p\\n\", \n\
+ class_ptr, class_as_class_struct->isa); \n\
+ return_struct.class_addr = class_as_class_struct->isa; \n\
+ } \n\
+ else \n\
+ { \n\
+ if (debug) \n\
+ printf (\"[object class] returned: 0x%p.\\n\", class_ptr); \n\
+ return_struct.class_addr = class_ptr; \n\
+ } \n\
+ } \n\
+ \n\
+ if (is_fixup) \n\
+ { \n\
+ if (is_fixed) \n\
+ { \n\
+ return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\
+ } \n\
+ else \n\
+ { \n\
+ char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\
+ return_struct.sel_addr = sel_getUid (sel_name); \n\
+ if (debug) \n\
+ printf (\"\\n*** Got fixed up selector: 0x%p for name %s.\\n\", \n\
+ return_struct.sel_addr, sel_name); \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.sel_addr = sel; \n\
+ } \n\
+ \n\
+ return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\
+ return_struct.sel_addr); \n\
+ if (debug) \n\
+ printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr); \n\
+ \n\
+ return return_struct.impl_addr; \n\
+} \n\
+";
AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr) :
m_valid (true),
@@ -192,12 +295,12 @@
return;
}
- uint32_t offset_ptr = 0;
- const uint16_t header_size = data.GetU16(&offset_ptr);
- const uint16_t descriptor_size = data.GetU16(&offset_ptr);
- const size_t num_descriptors = data.GetU32(&offset_ptr);
+ lldb::offset_t offset = 0;
+ const uint16_t header_size = data.GetU16(&offset);
+ const uint16_t descriptor_size = data.GetU16(&offset);
+ const size_t num_descriptors = data.GetU32(&offset);
- m_next_region = data.GetPointer(&offset_ptr);
+ m_next_region = data.GetPointer(&offset);
// If the header size is 0, that means we've come in too early before this data is set up.
// Set ourselves as not valid, and continue.
@@ -237,16 +340,16 @@
// The actual code for the vtables will be laid out consecutively, so I also
// compute the start and end of the whole code block.
- offset_ptr = 0;
+ offset = 0;
m_code_start_addr = 0;
m_code_end_addr = 0;
for (int i = 0; i < num_descriptors; i++)
{
- lldb::addr_t start_offset = offset_ptr;
- uint32_t offset = desc_extractor.GetU32 (&offset_ptr);
- uint32_t flags = desc_extractor.GetU32 (&offset_ptr);
- lldb::addr_t code_addr = desc_ptr + start_offset + offset;
+ lldb::addr_t start_offset = offset;
+ uint32_t voffset = desc_extractor.GetU32 (&offset);
+ uint32_t flags = desc_extractor.GetU32 (&offset);
+ lldb::addr_t code_addr = desc_ptr + start_offset + voffset;
m_descriptors.push_back (VTableDescriptor(flags, code_addr));
if (m_code_start_addr == 0 || code_addr < m_code_start_addr)
@@ -254,7 +357,7 @@
if (code_addr > m_code_end_addr)
m_code_end_addr = code_addr;
- offset_ptr = start_offset + descriptor_size;
+ offset = start_offset + descriptor_size;
}
// Finally, a little bird told me that all the vtable code blocks are the same size.
// Let's compute the blocks and if they are all the same add the size to the code end address:
@@ -301,13 +404,13 @@
void
AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::Dump (Stream &s)
{
- s.Printf ("Header addr: 0x%llx Code start: 0x%llx Code End: 0x%llx Next: 0x%llx\n",
+ s.Printf ("Header addr: 0x%" PRIx64 " Code start: 0x%" PRIx64 " Code End: 0x%" PRIx64 " Next: 0x%" PRIx64 "\n",
m_header_addr, m_code_start_addr, m_code_end_addr, m_next_region);
size_t num_elements = m_descriptors.size();
for (size_t i = 0; i < num_elements; i++)
{
s.Indent();
- s.Printf ("Code start: 0x%llx Flags: %d\n", m_descriptors[i].code_start, m_descriptors[i].flags);
+ s.Printf ("Code start: 0x%" PRIx64 " Flags: %d\n", m_descriptors[i].code_start, m_descriptors[i].flags);
}
}
@@ -380,6 +483,7 @@
{
m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID();
trampolines_changed_bp_sp->SetCallback (RefreshTrampolines, this, true);
+ trampolines_changed_bp_sp->SetBreakpointKind ("objc-trampolines-changed");
return true;
}
}
@@ -425,8 +529,8 @@
data,
0,
NULL);
- uint32_t offset_ptr = 0;
- lldb::addr_t region_addr = data.GetPointer(&offset_ptr);
+ lldb::offset_t offset = 0;
+ lldb::addr_t region_addr = data.GetPointer(&offset);
if (region_addr != 0)
vtable_handler->ReadRegions(region_addr);
@@ -553,8 +657,26 @@
m_msg_forward_stret_addr = msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target);
// FIXME: Do some kind of logging here.
- if (m_impl_fn_addr == LLDB_INVALID_ADDRESS || m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
+ if (m_impl_fn_addr == LLDB_INVALID_ADDRESS)
+ {
+ // If we can't even find the ordinary get method implementation function, then we aren't going to be able to
+ // step through any method dispatches. Warn to that effect and get out of here.
+ process_sp->GetTarget().GetDebugger().GetErrorStream().Printf("Could not find implementation lookup function \"%s\""
+ " step in through ObjC method dispatch will not work.\n",
+ get_impl_name.AsCString());
return;
+ }
+ else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
+ {
+ // It there is no stret return lookup function, assume that it is the same as the straight lookup:
+ m_impl_stret_fn_addr = m_impl_fn_addr;
+ // Also we will use the version of the lookup code that doesn't rely on the stret version of the function.
+ g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
+ }
+ else
+ {
+ g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
+ }
// Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol
// names dynamically to figure out how to dispatch to them. If it becomes more complicated than this we can
@@ -616,7 +738,7 @@
impl_code_address = sc.symbol->GetAddress();
//lldb::addr_t addr = impl_code_address.GetOpcodeLoadAddress (exe_ctx.GetTargetPtr());
- //printf ("Getting address for our_utility_function: 0x%llx.\n", addr);
+ //printf ("Getting address for our_utility_function: 0x%" PRIx64 ".\n", addr);
}
else
{
@@ -626,15 +748,26 @@
}
else if (!m_impl_code.get())
{
- m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
- g_lookup_implementation_function_name));
- if (!m_impl_code->Install(errors, exe_ctx))
+ if (g_lookup_implementation_function_code != NULL)
+ {
+ m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
+ g_lookup_implementation_function_name));
+ if (!m_impl_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_impl_code.reset();
+ return args_addr;
+ }
+ }
+ else
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
- m_impl_code.reset();
- return args_addr;
+ log->Printf("No method lookup implementation code.");
+ errors.Printf ("No method lookup implementation code found.");
+ return LLDB_INVALID_ADDRESS;
}
+
impl_code_address.Clear();
impl_code_address.SetOffset(m_impl_code->StartAddress());
}
@@ -882,7 +1015,7 @@
{
if (log)
{
- log->Printf("Resolving call for class - 0x%llx and selector - 0x%llx",
+ log->Printf("Resolving call for class - 0x%" PRIx64 " and selector - 0x%" PRIx64,
isa_addr, sel_addr);
}
ObjCLanguageRuntime *objc_runtime = m_process_sp->GetObjCLanguageRuntime ();
@@ -896,7 +1029,7 @@
// Yup, it was in the cache, so we can run to that address directly.
if (log)
- log->Printf ("Found implementation address in cache: 0x%llx", impl_addr);
+ log->Printf ("Found implementation address in cache: 0x%" PRIx64, impl_addr);
ret_plan_sp.reset (new ThreadPlanRunToAddress (thread, impl_addr, stop_others));
}
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h 2013-03-03 09:35:50.219457353 +0100
@@ -67,6 +67,8 @@
private:
static const char *g_lookup_implementation_function_name;
static const char *g_lookup_implementation_function_code;
+ static const char *g_lookup_implementation_with_stret_function_code;
+ static const char *g_lookup_implementation_no_stret_function_code;
class AppleObjCVTables
{
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp 2013-03-03 09:35:50.223457353 +0100
@@ -30,7 +30,7 @@
{
}
- clang::DeclContextLookupResult
+ bool
FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx,
clang::DeclarationName name)
{
@@ -60,12 +60,15 @@
if (!m_type_vendor.FinishDecl(non_const_interface_decl))
break;
-
- return non_const_interface_decl->lookup(name);
+
+ clang::DeclContext::lookup_const_result result = non_const_interface_decl->lookup(name);
+
+ return (result.size() != 0);
}
while(0);
- return clang::DeclContextLookupResult();
+ SetNoExternalVisibleDeclsForName(decl_ctx, name);
+ return false;
}
clang::ExternalLoadResult
@@ -126,6 +129,8 @@
ASTDumper dumper((clang::Decl*)interface_decl);
dumper.ToLog(log, " [CT] ");
}
+
+ m_type_vendor.FinishDecl(interface_decl);
if (log)
{
@@ -197,6 +202,7 @@
m_external_source->SetMetadata((uintptr_t)new_iface_decl, meta_data);
new_iface_decl->setHasExternalVisibleStorage();
+ new_iface_decl->setHasExternalLexicalStorage();
ast_ctx->getTranslationUnitDecl()->addDecl(new_iface_decl);
@@ -344,7 +350,7 @@
while (*name_cursor != '\0')
{
- char *colon_loc = strchr(name_cursor, ':');
+ const char *colon_loc = strchr(name_cursor, ':');
if (!colon_loc)
{
selector_components.push_back(&ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
@@ -422,6 +428,8 @@
clang::QualType target_type = BuildType(ast_ctx, type+1);
if (target_type.isNull())
return clang::QualType();
+ else if (target_type == ast_ctx.UnknownAnyTy)
+ return ast_ctx.UnknownAnyTy;
else
return ast_ctx.getConstType(target_type);
}
@@ -430,6 +438,8 @@
clang::QualType target_type = BuildType(ast_ctx, type+1);
if (target_type.isNull())
return clang::QualType();
+ else if (target_type == ast_ctx.UnknownAnyTy)
+ return ast_ctx.UnknownAnyTy;
else
return ast_ctx.getPointerType(target_type);
}
@@ -504,6 +514,7 @@
interface_decl->startDefinition();
interface_decl->setHasExternalVisibleStorage(false);
+ interface_decl->setHasExternalLexicalStorage(false);
ObjCLanguageRuntime::ClassDescriptorSP descriptor = m_runtime.GetClassDescriptor(objc_isa);
@@ -518,7 +529,7 @@
interface_decl->setSuperClass(superclass_decl);
};
- auto instance_method_func = [log, interface_decl, this](const char *name, const char *types)
+ auto instance_method_func = [log, interface_decl, this](const char *name, const char *types) -> bool
{
ObjCRuntimeMethodType method_type(types);
@@ -529,9 +540,11 @@
if (method_decl)
interface_decl->addDecl(method_decl);
+
+ return false;
};
- auto class_method_func = [log, interface_decl, this](const char *name, const char *types)
+ auto class_method_func = [log, interface_decl, this](const char *name, const char *types) -> bool
{
ObjCRuntimeMethodType method_type(types);
@@ -542,6 +555,8 @@
if (method_decl)
interface_decl->addDecl(method_decl);
+
+ return false;
};
if (log)
@@ -552,7 +567,10 @@
}
- if (!descriptor->Describe(superclass_func, instance_method_func, class_method_func))
+ if (!descriptor->Describe(superclass_func,
+ instance_method_func,
+ class_method_func,
+ std::function <bool (const char *, const char *, lldb::addr_t, uint64_t)> (nullptr)))
return false;
if (log)
@@ -601,9 +619,9 @@
clang::DeclContext::lookup_const_result lookup_result = ast_ctx->getTranslationUnitDecl()->lookup(decl_name);
- if (lookup_result.first != lookup_result.second)
+ if (!lookup_result.empty())
{
- if (const clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.first))
+ if (const clang::ObjCInterfaceDecl *result_iface_decl = llvm::dyn_cast<clang::ObjCInterfaceDecl>(lookup_result[0]))
{
clang::QualType result_iface_type = ast_ctx->getObjCInterfaceType(result_iface_decl);
@@ -616,7 +634,7 @@
if (metadata)
isa_value = metadata->GetISAPtr();
- log->Printf("AOCTV::FT [%u] Found %s (isa 0x%llx) in the ASTContext",
+ log->Printf("AOCTV::FT [%u] Found %s (isa 0x%" PRIx64 ") in the ASTContext",
current_id,
dumper.GetCString(),
isa_value);
@@ -659,7 +677,7 @@
if (!iface_decl)
{
if (log)
- log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for isa 0x%llx",
+ log->Printf("AOCTV::FT [%u] Couldn't get the Objective-C interface for isa 0x%" PRIx64,
current_id,
(uint64_t)isa);
@@ -671,7 +689,7 @@
if (log)
{
ASTDumper dumper(new_iface_type);
- log->Printf("AOCTV::FT [%u] Created %s (isa 0x%llx)",
+ log->Printf("AOCTV::FT [%u] Created %s (isa 0x%" PRIx64 ")",
current_id,
dumper.GetCString(),
(uint64_t)isa);
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.h 2013-03-03 09:35:50.223457353 +0100
@@ -38,6 +38,12 @@
uint32_t max_matches,
std::vector <ClangASTType> &types);
+ virtual clang::ASTContext *
+ GetClangASTContext ()
+ {
+ return m_ast_ctx.getASTContext();
+ }
+
friend class AppleObjCExternalASTSource;
private:
clang::ObjCInterfaceDecl *GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa);
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp 2013-03-03 09:35:50.223457353 +0100
@@ -84,9 +84,15 @@
}
m_impl_function = m_trampoline_handler->GetLookupImplementationWrapperFunction();
ExecutionContext exc_ctx;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
m_thread.CalculateExecutionContext(exc_ctx);
- m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx, m_args_addr, errors, m_stop_others));
- m_func_sp->SetPrivate(true);
+ m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx,
+ m_args_addr,
+ errors,
+ m_stop_others,
+ unwind_on_error,
+ ignore_breakpoints));
m_func_sp->SetOkayToDiscard(true);
m_thread.QueueThreadPlan (m_func_sp, false);
}
@@ -108,8 +114,8 @@
s->Printf("Step through ObjC trampoline");
else
{
- s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx, isa: 0x%llx, sel: 0x%llx",
- m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(), m_isa_addr, m_sel_addr);
+ s->Printf ("Stepping to implementation of ObjC method - obj: 0x%llx, isa: 0x%" PRIx64 ", sel: 0x%" PRIx64,
+ m_input_values.GetValueAtIndex(0)->GetScalar().ULongLong(), m_isa_addr, m_sel_addr);
}
}
@@ -120,7 +126,7 @@
}
bool
-AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop ()
+AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop (Event *event_ptr)
{
// If we get asked to explain the stop it will be because something went
// wrong (like the implementation for selector function crashed... We're going
@@ -178,7 +184,7 @@
if (m_trampoline_handler->AddrIsMsgForward(target_addr))
{
if (log)
- log->Printf ("Implementation lookup returned msgForward function: 0x%llx, stopping.", target_addr);
+ log->Printf ("Implementation lookup returned msgForward function: 0x%" PRIx64 ", stopping.", target_addr);
SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext(eSymbolContextEverything);
m_run_to_sp.reset(new ThreadPlanStepOut (m_thread,
@@ -194,13 +200,13 @@
}
if (log)
- log->Printf("Running to ObjC method implementation: 0x%llx", target_addr);
+ log->Printf("Running to ObjC method implementation: 0x%" PRIx64, target_addr);
ObjCLanguageRuntime *objc_runtime = GetThread().GetProcess()->GetObjCLanguageRuntime();
assert (objc_runtime != NULL);
objc_runtime->AddToMethodCache (m_isa_addr, m_sel_addr, target_addr);
if (log)
- log->Printf("Adding {isa-addr=0x%llx, sel-addr=0x%llx} = addr=0x%llx to cache.", m_isa_addr, m_sel_addr, target_addr);
+ log->Printf("Adding {isa-addr=0x%" PRIx64 ", sel-addr=0x%" PRIx64 "} = addr=0x%" PRIx64 " to cache.", m_isa_addr, m_sel_addr, target_addr);
// Extract the target address from the value:
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
===================================================================
--- aze.orig/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h 2013-03-03 09:35:50.223457353 +0100
@@ -46,7 +46,7 @@
ValidatePlan (Stream *error);
virtual bool
- PlanExplainsStop ();
+ PlanExplainsStop (Event *event_ptr);
virtual lldb::StateType
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1,10 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginAppleObjCRuntime
+ AppleObjCRuntime.cpp
+ AppleObjCRuntimeV1.cpp
+ AppleObjCRuntimeV2.cpp
+ AppleObjCTrampolineHandler.cpp
+ AppleObjCTypeVendor.cpp
+ AppleThreadPlanStepThroughObjCTrampoline.cpp
+ )
Index: aze/lldb/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1 @@
+add_subdirectory(AppleObjCRuntime)
Index: aze/lldb/source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginObjectContainerBSDArchive
+ ObjectContainerBSDArchive.cpp
+ )
Index: aze/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp 2013-03-03 09:35:50.223457353 +0100
@@ -49,8 +49,8 @@
ar_file_size = 0;
}
-uint32_t
-ObjectContainerBSDArchive::Object::Extract (const DataExtractor& data, uint32_t offset)
+lldb::offset_t
+ObjectContainerBSDArchive::Object::Extract (const DataExtractor& data, lldb::offset_t offset)
{
size_t ar_name_len = 0;
std::string str;
@@ -98,17 +98,19 @@
ar_file_size = ar_size - ar_name_len;
return offset;
}
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_OFFSET;
}
ObjectContainerBSDArchive::Archive::Archive
(
const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &time
+ const lldb_private::TimeValue &time,
+ lldb_private::DataExtractor &data
) :
m_arch (arch),
m_time (time),
- m_objects()
+ m_objects(),
+ m_data (data)
{
}
@@ -117,10 +119,11 @@
}
size_t
-ObjectContainerBSDArchive::Archive::ParseObjects (DataExtractor &data)
+ObjectContainerBSDArchive::Archive::ParseObjects ()
{
+ DataExtractor &data = m_data;
std::string str;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
if (str == ARMAG)
{
@@ -128,9 +131,9 @@
do
{
offset = obj.Extract (data, offset);
- if (offset == LLDB_INVALID_INDEX32)
+ if (offset == LLDB_INVALID_OFFSET)
break;
- uint32_t obj_idx = m_objects.size();
+ size_t obj_idx = m_objects.size();
m_objects.push_back(obj);
// Insert all of the C strings out of order for now...
m_object_name_to_index_map.Append (obj.ar_name.GetCString(), obj_idx);
@@ -147,7 +150,7 @@
ObjectContainerBSDArchive::Object *
ObjectContainerBSDArchive::Archive::FindObject (const ConstString &object_name)
{
- const UniqueCStringMap<uint32_t>::Entry *match = m_object_name_to_index_map.FindFirstValueForName (object_name.GetCString());
+ const ObjectNameToIndexMap::Entry *match = m_object_name_to_index_map.FindFirstValueForName (object_name.GetCString());
if (match)
return &m_objects[match->value];
return NULL;
@@ -165,7 +168,7 @@
// delete an archive entry...
while (pos != archive_map.end() && pos->first == file)
{
- if (pos->second->GetArchitecture() == arch)
+ if (pos->second->GetArchitecture().IsCompatibleMatch(arch))
{
if (pos->second->GetModificationTime() == time)
{
@@ -200,10 +203,10 @@
DataExtractor &data
)
{
- shared_ptr archive_sp(new Archive (arch, time));
+ shared_ptr archive_sp(new Archive (arch, time, data));
if (archive_sp)
{
- if (archive_sp->ParseObjects (data) > 0)
+ if (archive_sp->ParseObjects () > 0)
{
Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
@@ -264,34 +267,70 @@
(
const lldb::ModuleSP &module_sp,
DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length)
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- DataExtractor data;
- data.SetData (data_sp, offset, length);
- if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
+ ConstString object_name (module_sp->GetObjectName());
+ if (object_name)
{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%8.8llx, file_size = 0x%8.8llx)",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- file, (uint64_t) offset, (uint64_t) length);
-
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
-
- std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, file, offset, length));
-
- if (container_ap.get())
+ if (data_sp)
+ {
+ // We have data, which means this is the first 512 bytes of the file
+ // Check to see if the magic bytes match and if they do, read the entire
+ // table of contents for the archive and cache it
+ DataExtractor data;
+ data.SetData (data_sp, data_offset, length);
+ if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
+ {
+ Timer scoped_timer (__PRETTY_FUNCTION__,
+ "ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
+ module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp->GetFileSpec().GetFilename().AsCString(),
+ file, (uint64_t) file_offset, (uint64_t) length);
+
+ // Map the entire .a file to be sure that we don't lose any data if the file
+ // gets updated by a new build while this .a file is being used for debugging
+ DataBufferSP archive_data_sp (file->MemoryMapFileContents(file_offset, length));
+ lldb::offset_t archive_data_offset = 0;
+
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp,
+ archive_data_sp,
+ archive_data_offset,
+ file,
+ file_offset,
+ length));
+
+ if (container_ap.get())
+ {
+ if (archive_sp)
+ {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive (archive_sp);
+ return container_ap.release();
+ }
+ else if (container_ap->ParseHeader())
+ return container_ap.release();
+ }
+ }
+ }
+ else
{
+ // No data, just check for a cached archive
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
if (archive_sp)
{
- // We already have this archive in our cache, use it
- container_ap->SetArchive (archive_sp);
- return container_ap.release();
+ std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length));
+
+ if (container_ap.get())
+ {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive (archive_sp);
+ return container_ap.release();
+ }
}
- else if (container_ap->ParseHeader())
- return container_ap.release();
}
}
return NULL;
@@ -316,19 +355,20 @@
ObjectContainerBSDArchive::ObjectContainerBSDArchive
(
const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t size
+ lldb::offset_t file_offset,
+ lldb::offset_t size
) :
- ObjectContainer (module_sp, file, offset, size, dataSP),
+ ObjectContainer (module_sp, file, file_offset, size, data_sp, data_offset),
m_archive_sp ()
{
}
void
ObjectContainerBSDArchive::SetArchive (Archive::shared_ptr &archive_sp)
{
- m_archive_sp = archive_sp;
+ m_archive_sp = archive_sp;
}
@@ -352,6 +392,9 @@
module_sp->GetModificationTime(),
m_data);
}
+ // Clear the m_data that contains the entire archive
+ // data and let our m_archive_sp hold onto the data.
+ m_data.Clear();
}
}
return m_archive_sp.get() != NULL;
@@ -393,11 +436,15 @@
{
Object *object = m_archive_sp->FindObject (module_sp->GetObjectName());
if (object)
- return ObjectFile::FindPlugin (module_sp,
+ {
+ lldb::offset_t data_offset = m_offset + object->ar_file_offset;
+ return ObjectFile::FindPlugin (module_sp,
file,
- object->ar_file_offset,
- object->ar_file_size,
- m_data.GetSharedDataBuffer());
+ m_offset + object->ar_file_offset,
+ object->ar_file_size,
+ m_archive_sp->GetData().GetSharedDataBuffer(),
+ data_offset);
+ }
}
}
return ObjectFileSP();
Index: aze/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h 2013-03-03 09:35:50.223457353 +0100
@@ -40,10 +40,11 @@
static lldb_private::ObjectContainer *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static bool
MagicBytesMatch (const lldb_private::DataExtractor &data);
@@ -52,10 +53,11 @@
// Member Functions
//------------------------------------------------------------------
ObjectContainerBSDArchive (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
virtual
~ObjectContainerBSDArchive();
@@ -97,8 +99,8 @@
void
Clear();
- uint32_t
- Extract (const lldb_private::DataExtractor& data, uint32_t offset);
+ lldb::offset_t
+ Extract (const lldb_private::DataExtractor& data, lldb::offset_t offset);
lldb_private::ConstString ar_name; // name
uint32_t ar_date; // modification time
@@ -106,8 +108,8 @@
uint16_t ar_gid; // group id
uint16_t ar_mode; // octal file permissions
uint32_t ar_size; // size in bytes
- uint32_t ar_file_offset; // file offset in bytes from the beginning of the file of the object data
- uint32_t ar_file_size; // length of the object data
+ lldb::offset_t ar_file_offset; // file offset in bytes from the beginning of the file of the object data
+ lldb::offset_t ar_file_size; // length of the object data
typedef std::vector<Object> collection;
typedef collection::iterator iterator;
@@ -138,7 +140,8 @@
lldb_private::DataExtractor &data);
Archive (const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time);
+ const lldb_private::TimeValue &mod_time,
+ lldb_private::DataExtractor &data);
~Archive ();
@@ -149,7 +152,7 @@
}
size_t
- ParseObjects (lldb_private::DataExtractor &data);
+ ParseObjects ();
Object *
FindObject (const lldb_private::ConstString &object_name);
@@ -169,15 +172,22 @@
bool
HasNoExternalReferences() const;
- protected:
+ lldb_private::DataExtractor &
+ GetData ()
+ {
+ return m_data;
+ }
+ protected:
+ typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
//----------------------------------------------------------------------
// Member Variables
//----------------------------------------------------------------------
lldb_private::ArchSpec m_arch;
lldb_private::TimeValue m_time;
Object::collection m_objects;
- lldb_private::UniqueCStringMap<uint32_t> m_object_name_to_index_map;
+ ObjectNameToIndexMap m_object_name_to_index_map;
+ lldb_private::DataExtractor m_data; ///< The data for this object container so we don't lose data if the .a files gets modified
};
void
Index: aze/lldb/source/Plugins/ObjectContainer/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectContainer/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1,2 @@
+add_subdirectory(BSD-Archive)
+add_subdirectory(Universal-Mach-O)
Index: aze/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginObjectContainerMachOArchive
+ ObjectContainerUniversalMachO.cpp
+ )
Index: aze/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp 2013-03-03 09:35:50.223457353 +0100
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "ObjectContainerUniversalMachO.h"
-#include "lldb/Core/Stream.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
@@ -52,30 +53,34 @@
(
const lldb::ModuleSP &module_sp,
DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length
+ lldb::offset_t file_offset,
+ lldb::offset_t length
)
{
- DataExtractor data;
- data.SetData (data_sp, offset, length);
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
- {
- std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, file, offset, length));
- if (container_ap->ParseHeader())
+ // We get data when we aren't trying to look for cached container information,
+ // so only try and look for an architecture slice if we get data
+ if (data_sp)
+ {
+ DataExtractor data;
+ data.SetData (data_sp, data_offset, length);
+ if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
{
- return container_ap.release();
+ std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, data_offset, file, file_offset, length));
+ if (container_ap->ParseHeader())
+ {
+ return container_ap.release();
+ }
}
}
return NULL;
}
-
-
bool
ObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return magic == UniversalMagic || magic == UniversalMagicSwapped;
}
@@ -83,12 +88,13 @@
ObjectContainerUniversalMachO::ObjectContainerUniversalMachO
(
const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length
+ lldb::offset_t file_offset,
+ lldb::offset_t length
) :
- ObjectContainer (module_sp, file, offset, length, dataSP),
+ ObjectContainer (module_sp, file, file_offset, length, data_sp, data_offset),
m_header(),
m_fat_archs()
{
@@ -103,9 +109,10 @@
bool
ObjectContainerUniversalMachO::ParseHeader ()
{
+ bool success = false;
// Store the file offset for this universal file as we could have a universal .o file
// in a BSD archive, or be contained in another kind of object.
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
// Universal mach-o files always have their headers in big endian.
m_data.SetByteOrder (eByteOrderBig);
m_header.magic = m_data.GetU32(&offset);
@@ -130,14 +137,17 @@
}
}
}
- return true;
+ success = true;
}
else
{
memset(&m_header, 0, sizeof(m_header));
}
- return false;
+ // We no longer need any data, we parsed all we needed to parse
+ // and cached it in m_header and m_fat_archs
+ m_data.Clear();
+ return success;
}
void
@@ -206,35 +216,31 @@
// First, try to find an exact match for the Arch of the Target.
for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
{
- if (GetArchitectureAtIndex (arch_idx, curr_arch))
- {
- if (arch.IsExactMatch(curr_arch))
- {
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- m_data.GetSharedDataBuffer());
- }
- }
+ if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsExactMatch(curr_arch))
+ break;
}
// Failing an exact match, try to find a compatible Arch of the Target.
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
+ if (arch_idx >= m_header.nfat_arch)
{
- if (GetArchitectureAtIndex (arch_idx, curr_arch))
+ for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
{
- if (arch.IsCompatibleMatch(curr_arch))
- {
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- m_data.GetSharedDataBuffer());
- }
+ if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsCompatibleMatch(curr_arch))
+ break;
}
}
+ if (arch_idx < m_header.nfat_arch)
+ {
+ DataBufferSP data_sp;
+ lldb::offset_t data_offset = 0;
+ return ObjectFile::FindPlugin (module_sp,
+ file,
+ m_offset + m_fat_archs[arch_idx].offset,
+ m_fat_archs[arch_idx].size,
+ data_sp,
+ data_offset);
+ }
}
return ObjectFileSP();
}
Index: aze/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h 2013-03-03 09:35:50.223457353 +0100
@@ -36,10 +36,11 @@
static lldb_private::ObjectContainer *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static bool
MagicBytesMatch (const lldb_private::DataExtractor &data);
@@ -48,10 +49,11 @@
// Member Functions
//------------------------------------------------------------------
ObjectContainerUniversalMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
virtual
~ObjectContainerUniversalMachO();
Index: aze/lldb/source/Plugins/ObjectFile/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectFile/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1,3 @@
+add_subdirectory(ELF)
+add_subdirectory(Mach-O)
+add_subdirectory(PECOFF)
Index: aze/lldb/source/Plugins/ObjectFile/ELF/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectFile/ELF/CMakeLists.txt 2013-03-03 09:35:50.223457353 +0100
@@ -0,0 +1,6 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginObjectFileELF
+ ELFHeader.cpp
+ ObjectFileELF.cpp
+ )
Index: aze/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp 2013-03-03 09:35:50.223457353 +0100
@@ -23,20 +23,24 @@
// GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
// with error handling code and provide for parsing a sequence of values.
static bool
-GetMaxU64(const lldb_private::DataExtractor &data,
- uint32_t *offset, uint64_t *value, uint32_t byte_size)
+GetMaxU64(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset,
+ uint64_t *value,
+ uint32_t byte_size)
{
- const uint32_t saved_offset = *offset;
+ const lldb::offset_t saved_offset = *offset;
*value = data.GetMaxU64(offset, byte_size);
return *offset != saved_offset;
}
static bool
GetMaxU64(const lldb_private::DataExtractor &data,
- uint32_t *offset, uint64_t *value, uint32_t byte_size,
+ lldb::offset_t *offset,
+ uint64_t *value,
+ uint32_t byte_size,
uint32_t count)
{
- uint32_t saved_offset = *offset;
+ lldb::offset_t saved_offset = *offset;
for (uint32_t i = 0; i < count; ++i, ++value)
{
@@ -51,19 +55,23 @@
static bool
GetMaxS64(const lldb_private::DataExtractor &data,
- uint32_t *offset, int64_t *value, uint32_t byte_size)
+ lldb::offset_t *offset,
+ int64_t *value,
+ uint32_t byte_size)
{
- const uint32_t saved_offset = *offset;
+ const lldb::offset_t saved_offset = *offset;
*value = data.GetMaxS64(offset, byte_size);
return *offset != saved_offset;
}
static bool
GetMaxS64(const lldb_private::DataExtractor &data,
- uint32_t *offset, int64_t *value, uint32_t byte_size,
+ lldb::offset_t *offset,
+ int64_t *value,
+ uint32_t byte_size,
uint32_t count)
{
- uint32_t saved_offset = *offset;
+ lldb::offset_t saved_offset = *offset;
for (uint32_t i = 0; i < count; ++i, ++value)
{
@@ -95,7 +103,7 @@
}
bool
-ELFHeader::Parse(lldb_private::DataExtractor &data, uint32_t *offset)
+ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
// Read e_ident. This provides byte order and address size info.
if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
@@ -190,7 +198,7 @@
bool
ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
- uint32_t *offset)
+ lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
@@ -226,7 +234,7 @@
}
bool
-ELFSymbol::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
const bool parsing_32 = byte_size == 4;
@@ -276,7 +284,7 @@
bool
ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
- uint32_t *offset)
+ lldb::offset_t *offset)
{
const uint32_t byte_size = data.GetAddressByteSize();
const bool parsing_32 = byte_size == 4;
@@ -320,7 +328,7 @@
}
bool
-ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
return GetMaxS64(data, offset, &d_tag, byte_size, 2);
@@ -335,7 +343,7 @@
}
bool
-ELFRel::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
@@ -355,7 +363,7 @@
}
bool
-ELFRela::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
Index: aze/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.h 2013-03-03 09:35:50.223457353 +0100
@@ -123,7 +123,7 @@
/// True if the ELFSectionHeader was successfully read and false
/// otherwise.
bool
- Parse(lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
//--------------------------------------------------------------------------
/// Examines at most EI_NIDENT bytes starting from the given pointer and
@@ -181,7 +181,7 @@
/// True if the ELFSectionHeader was successfully read and false
/// otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -216,7 +216,7 @@
/// True if the ELFProgramHeader was successfully read and false
/// otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -259,7 +259,7 @@
/// @return
/// True if the ELFSymbol was successfully read and false otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -292,7 +292,7 @@
/// True if the ELFDynamic entry was successfully read and false
/// otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -320,7 +320,7 @@
/// @return
/// True if the ELFRel entry was successfully read and false otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
/// Returns the type when the given entry represents a 32-bit relocation.
static unsigned
@@ -379,7 +379,7 @@
/// @return
/// True if the ELFRela entry was successfully read and false otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
/// Returns the type when the given entry represents a 32-bit relocation.
static unsigned
Index: aze/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp 2013-03-03 09:35:50.227457352 +0100
@@ -53,7 +53,7 @@
~ELFRelocation();
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
static unsigned
RelocType32(const ELFRelocation &rel);
@@ -94,7 +94,7 @@
}
bool
-ELFRelocation::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
if (reloc.is<ELFRel*>())
return reloc.get<ELFRel*>()->Parse(data, offset);
@@ -173,19 +173,32 @@
ObjectFile *
ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
DataBufferSP &data_sp,
- const FileSpec *file,
- addr_t offset,
- addr_t length)
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset))
+ if (!data_sp)
{
- const uint8_t *magic = data_sp->GetBytes() + offset;
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
+ {
+ const uint8_t *magic = data_sp->GetBytes() + data_offset;
if (ELFHeader::MagicBytesMatch(magic))
{
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length) {
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ magic = data_sp->GetBytes();
+ }
unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
if (address_size == 4 || address_size == 8)
{
- std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, file, offset, length));
+ std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, data_offset, file, file_offset, length));
ArchSpec spec;
if (objfile_ap->GetArchitecture(spec) &&
objfile_ap->SetModulesArchitecture(spec))
@@ -232,11 +245,12 @@
//------------------------------------------------------------------
ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec* file,
- addr_t offset,
- addr_t length) :
- ObjectFile(module_sp, file, offset, length, dataSP),
+ lldb::offset_t file_offset,
+ lldb::offset_t length) :
+ ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
m_header(),
m_program_headers(),
m_section_headers(),
@@ -270,28 +284,28 @@
return eByteOrderInvalid;
}
-size_t
+uint32_t
ObjectFileELF::GetAddressByteSize() const
{
return m_data.GetAddressByteSize();
}
-unsigned
+size_t
ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
{
- return std::distance(m_section_headers.begin(), I) + 1;
+ return std::distance(m_section_headers.begin(), I) + 1u;
}
-unsigned
+size_t
ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
{
- return std::distance(m_section_headers.begin(), I) + 1;
+ return std::distance(m_section_headers.begin(), I) + 1u;
}
bool
ObjectFileELF::ParseHeader()
{
- uint32_t offset = GetOffset();
+ lldb::offset_t offset = GetFileOffset();
return m_header.Parse(m_data, &offset);
}
@@ -445,8 +459,8 @@
ReadSectionData(dynstr, dynstr_data))
{
ELFDynamic symbol;
- const unsigned section_size = dynsym_data.GetByteSize();
- unsigned offset = 0;
+ const lldb::offset_t section_size = dynsym_data.GetByteSize();
+ lldb::offset_t offset = 0;
// The only type of entries we are concerned with are tagged DT_NEEDED,
// yielding the name of a required library.
@@ -492,7 +506,7 @@
return 0;
uint32_t idx;
- uint32_t offset;
+ lldb::offset_t offset;
for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
{
if (m_program_headers[idx].Parse(data, &offset) == false)
@@ -530,7 +544,7 @@
return 0;
uint32_t idx;
- uint32_t offset;
+ lldb::offset_t offset;
for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
{
if (m_section_headers[idx].Parse(data, &offset) == false)
@@ -698,9 +712,8 @@
const DataExtractor &strtab_data)
{
ELFSymbol symbol;
- uint32_t offset = 0;
- const unsigned num_symbols =
- symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
+ lldb::offset_t offset = 0;
+ const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
static ConstString text_section_name(".text");
static ConstString init_section_name(".init");
@@ -737,37 +750,47 @@
break;
}
- switch (symbol.getType())
+ // If a symbol is undefined do not process it further even if it has a STT type
+ if (symbol_type != eSymbolTypeUndefined)
{
- default:
- case STT_NOTYPE:
- // The symbol's type is not specified.
- break;
+ switch (symbol.getType())
+ {
+ default:
+ case STT_NOTYPE:
+ // The symbol's type is not specified.
+ break;
- case STT_OBJECT:
- // The symbol is associated with a data object, such as a variable,
- // an array, etc.
- symbol_type = eSymbolTypeData;
- break;
+ case STT_OBJECT:
+ // The symbol is associated with a data object, such as a variable,
+ // an array, etc.
+ symbol_type = eSymbolTypeData;
+ break;
- case STT_FUNC:
- // The symbol is associated with a function or other executable code.
- symbol_type = eSymbolTypeCode;
- break;
+ case STT_FUNC:
+ // The symbol is associated with a function or other executable code.
+ symbol_type = eSymbolTypeCode;
+ break;
- case STT_SECTION:
- // The symbol is associated with a section. Symbol table entries of
- // this type exist primarily for relocation and normally have
- // STB_LOCAL binding.
- break;
+ case STT_SECTION:
+ // The symbol is associated with a section. Symbol table entries of
+ // this type exist primarily for relocation and normally have
+ // STB_LOCAL binding.
+ break;
- case STT_FILE:
- // Conventionally, the symbol's name gives the name of the source
- // file associated with the object file. A file symbol has STB_LOCAL
- // binding, its section index is SHN_ABS, and it precedes the other
- // STB_LOCAL symbols for the file, if it is present.
- symbol_type = eSymbolTypeObjectFile;
- break;
+ case STT_FILE:
+ // Conventionally, the symbol's name gives the name of the source
+ // file associated with the object file. A file symbol has STB_LOCAL
+ // binding, its section index is SHN_ABS, and it precedes the other
+ // STB_LOCAL symbols for the file, if it is present.
+ symbol_type = eSymbolTypeObjectFile;
+ break;
+
+ case STT_GNU_IFUNC:
+ // The symbol is associated with an indirect function. The actual
+ // function will be resolved if it is referenced.
+ symbol_type = eSymbolTypeResolver;
+ break;
+ }
}
if (symbol_type == eSymbolTypeInvalid)
@@ -877,8 +900,8 @@
DataExtractor dynsym_data;
if (ReadSectionData(dynsym, dynsym_data))
{
- const unsigned section_size = dynsym_data.GetByteSize();
- unsigned cursor = 0;
+ const lldb::offset_t section_size = dynsym_data.GetByteSize();
+ lldb::offset_t cursor = 0;
while (cursor < section_size)
{
@@ -956,15 +979,15 @@
{
ELFRelocation rel(rel_type);
ELFSymbol symbol;
- uint32_t offset = 0;
- const unsigned plt_entsize = plt_hdr->sh_entsize;
- const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
+ lldb::offset_t offset = 0;
+ const elf_xword plt_entsize = plt_hdr->sh_entsize;
+ const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
reloc_info_fn reloc_type;
reloc_info_fn reloc_symbol;
- if (hdr->Is32Bit() == 4)
+ if (hdr->Is32Bit())
{
reloc_type = ELFRelocation::RelocType32;
reloc_symbol = ELFRelocation::RelocSymbol32;
@@ -985,7 +1008,7 @@
if (reloc_type(rel) != slot_type)
continue;
- unsigned symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
+ lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
uint64_t plt_index = (i + 1) * plt_entsize;
if (!symbol.Parse(symtab_data, &symbol_offset))
@@ -1186,9 +1209,9 @@
DumpELFHeader_e_type(s, header.e_type);
s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
s->Printf("e_version = 0x%8.8x\n", header.e_version);
- s->Printf("e_entry = 0x%8.8llx\n", header.e_entry);
- s->Printf("e_phoff = 0x%8.8llx\n", header.e_phoff);
- s->Printf("e_shoff = 0x%8.8llx\n", header.e_shoff);
+ s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
+ s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
+ s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
@@ -1246,11 +1269,11 @@
ObjectFileELF::DumpELFProgramHeader(Stream *s, const ELFProgramHeader &ph)
{
DumpELFProgramHeader_p_type(s, ph.p_type);
- s->Printf(" %8.8llx %8.8llx %8.8llx", ph.p_offset, ph.p_vaddr, ph.p_paddr);
- s->Printf(" %8.8llx %8.8llx %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
+ s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, ph.p_vaddr, ph.p_paddr);
+ s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, ph.p_flags);
DumpELFProgramHeader_p_flags(s, ph.p_flags);
- s->Printf(") %8.8llx", ph.p_align);
+ s->Printf(") %8.8" PRIx64, ph.p_align);
}
//----------------------------------------------------------------------
@@ -1331,11 +1354,11 @@
{
s->Printf("%8.8x ", sh.sh_name);
DumpELFSectionHeader_sh_type(s, sh.sh_type);
- s->Printf(" %8.8llx (", sh.sh_flags);
+ s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
- s->Printf(") %8.8llx %8.8llx %8.8llx", sh.sh_addr, sh.sh_offset, sh.sh_size);
+ s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, sh.sh_offset, sh.sh_size);
s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
- s->Printf(" %8.8llx %8.8llx", sh.sh_addralign, sh.sh_entsize);
+ s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
}
//----------------------------------------------------------------------
@@ -1378,7 +1401,7 @@
// Dump an token value for the ELF section header member sh_flags
//----------------------------------------------------------------------
void
-ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags)
+ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
{
*s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
<< (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
Index: aze/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h 2013-03-03 09:35:50.227457352 +0100
@@ -46,10 +46,11 @@
static lldb_private::ObjectFile *
CreateInstance(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t file_offset,
+ lldb::offset_t length);
static lldb_private::ObjectFile *
CreateMemoryInstance (const lldb::ModuleSP &module_sp,
@@ -84,7 +85,7 @@
virtual bool
IsExecutable () const;
- virtual size_t
+ virtual uint32_t
GetAddressByteSize() const;
virtual lldb_private::Symtab *
@@ -119,10 +120,11 @@
private:
ObjectFileELF(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl;
typedef ProgramHeaderColl::iterator ProgramHeaderCollIter;
@@ -168,11 +170,11 @@
lldb_private::Address m_entry_point_address;
/// Returns a 1 based index of the given section header.
- unsigned
+ size_t
SectionIndex(const SectionHeaderCollIter &I);
/// Returns a 1 based index of the given section header.
- unsigned
+ size_t
SectionIndex(const SectionHeaderCollConstIter &I) const;
/// Parses all section headers present in this object file and populates
@@ -282,7 +284,7 @@
static void
DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
- elf::elf_word sh_flags);
+ elf::elf_xword sh_flags);
//@}
/// ELF dependent module dump routine.
Index: aze/lldb/source/Plugins/ObjectFile/Mach-O/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectFile/Mach-O/CMakeLists.txt 2013-03-03 09:35:50.227457352 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginObjectFileMachO
+ ObjectFileMachO.cpp
+ )
Index: aze/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp 2013-03-03 09:35:50.227457352 +0100
@@ -58,7 +58,7 @@
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
@@ -166,7 +166,7 @@
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
@@ -273,7 +273,7 @@
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
@@ -378,13 +378,29 @@
return "Mach-o object file reader (32 and 64 bit)";
}
-
ObjectFile *
-ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length)
+ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
+ if (!data_sp)
+ {
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
{
- std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length));
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length)
+ {
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+ std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
}
@@ -472,14 +488,19 @@
{
DataExtractor data;
data.SetData (data_sp, data_offset, data_length);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return MachHeaderSizeFromMagic(magic) != 0;
}
-ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
- ObjectFile(module_sp, file, offset, length, data_sp),
+ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length) :
+ ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
m_sections_ap(),
m_symtab_ap(),
m_mach_segments(),
@@ -522,7 +543,7 @@
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
bool can_parse = false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
// Leave magic in the original byte order
m_header.magic = m_data.GetU32(&offset);
@@ -562,6 +583,11 @@
ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
+ // Check if the module has a required architecture
+ const ArchSpec &module_arch = module_sp->GetArchitecture();
+ if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
+ return false;
+
if (SetModulesArchitecture (mach_arch))
{
const size_t header_and_lc_size = m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic);
@@ -571,12 +597,12 @@
ProcessSP process_sp (m_process_wp.lock());
if (process_sp)
{
- data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
+ data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
}
else
{
// Read in all only the load command data from the file on disk
- data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
+ data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
if (data_sp->GetByteSize() != header_and_lc_size)
return false;
}
@@ -607,7 +633,7 @@
return m_header.filetype == HeaderFileTypeExecutable;
}
-size_t
+uint32_t
ObjectFileMachO::GetAddressByteSize () const
{
return m_data.GetAddressByteSize ();
@@ -685,6 +711,7 @@
case eSymbolTypeCode:
case eSymbolTypeTrampoline:
+ case eSymbolTypeResolver:
if (m_header.cputype == llvm::MachO::CPUTypeARM)
{
// For ARM we have a bit in the n_desc field of the symbol
@@ -764,7 +791,7 @@
{
lldb::user_id_t segID = 0;
lldb::user_id_t sectID = 0;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
const bool is_core = GetType() == eTypeCoreFile;
//bool dump_sections = false;
@@ -775,7 +802,7 @@
encryption_info_command encryption_cmd;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t load_cmd_offset = offset;
+ const lldb::offset_t load_cmd_offset = offset;
if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
break;
@@ -800,7 +827,7 @@
struct segment_command_64 load_cmd;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t load_cmd_offset = offset;
+ const lldb::offset_t load_cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
@@ -821,7 +848,7 @@
// get at data that isn't stored in the abstracted Sections.
m_mach_segments.push_back (load_cmd);
- ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
+ ConstString segment_name (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
// Use a segment ID of the segment index shifted left by 8 so they
// never conflict with any of the sections.
SectionSP segment_sp;
@@ -1204,14 +1231,14 @@
struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
FunctionStarts function_starts;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
// Read in the load command and load command size
struct load_command lc;
if (m_data.GetU32(&offset, &lc, 2) == NULL)
@@ -1277,13 +1304,15 @@
ProcessSP process_sp (m_process_wp.lock());
Process *process = process_sp.get();
- const size_t addr_byte_size = m_data.GetAddressByteSize();
+ const uint32_t addr_byte_size = m_data.GetAddressByteSize();
+ const ByteOrder byte_order = m_data.GetByteOrder();
bool bit_width_32 = addr_byte_size == 4;
const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
- DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
- DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
- DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
+ DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
+ DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
+ DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
const addr_t strtab_data_byte_size = symtab_load_command.strsize;
@@ -1343,6 +1372,13 @@
//DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
//if (strtab_data_sp)
// strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ if (m_dysymtab.nindirectsyms != 0)
+ {
+ const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
+ DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
+ if (indirect_syms_data_sp)
+ indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
+ }
if (function_starts_load_command.cmd)
{
const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
@@ -1361,6 +1397,12 @@
strtab_data.SetData (m_data,
symtab_load_command.stroff,
strtab_data_byte_size);
+ if (m_dysymtab.nindirectsyms != 0)
+ {
+ indirect_symbol_index_data.SetData (m_data,
+ m_dysymtab.indirectsymoff,
+ m_dysymtab.nindirectsyms * 4);
+ }
if (function_starts_load_command.cmd)
{
function_starts_data.SetData (m_data,
@@ -1415,7 +1457,7 @@
{
FunctionStarts::Entry function_start_entry;
function_start_entry.data = false;
- uint32_t function_start_offset = 0;
+ lldb::offset_t function_start_offset = 0;
function_start_entry.addr = text_section_sp->GetFileAddress();
uint64_t delta;
while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
@@ -1426,11 +1468,11 @@
}
}
- const uint32_t function_starts_count = function_starts.GetSize();
+ const size_t function_starts_count = function_starts.GetSize();
- uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
+ const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
- uint32_t nlist_data_offset = 0;
+ lldb::offset_t nlist_data_offset = 0;
uint32_t N_SO_index = UINT32_MAX;
@@ -1452,7 +1494,7 @@
uint32_t sym_idx = 0;
Symbol *sym = NULL;
- uint32_t num_syms = 0;
+ size_t num_syms = 0;
std::string memory_symbol_name;
uint32_t unmapped_local_symbols_found = 0;
@@ -1542,9 +1584,9 @@
if (DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header)))
{
- DataExtractor dsc_header_data(dsc_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
- uint32_t offset = offsetof (struct lldb_copy_dyld_cache_header, mappingOffset);
+ lldb::offset_t offset = offsetof (struct lldb_copy_dyld_cache_header, mappingOffset);
uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
// If the mappingOffset points to a location inside the header, we've
@@ -1561,7 +1603,7 @@
// Map the local symbols
if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
{
- DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
offset = 0;
@@ -1636,6 +1678,7 @@
uint32_t symbol_byte_size = 0;
bool add_nlist = true;
bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
+ bool demangled_is_synthesized = false;
assert (sym_idx < num_syms);
@@ -2030,68 +2073,67 @@
break;
case NListTypeSection: // N_SECT
- {
- symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
- if (symbol_section == NULL)
{
- // TODO: warn about this?
- add_nlist = false;
- break;
- }
+ symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
- if (TEXT_eh_frame_sectID == nlist.n_sect)
- {
- type = eSymbolTypeException;
- }
- else
- {
- uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
-
- switch (section_type)
+ if (symbol_section == NULL)
{
- case SectionTypeRegular: break; // regular section
- //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
- case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
- case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
- case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
- case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
- case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
- case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
- case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
- case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
- case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
- //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
- //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
- case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
- case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
- case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
- case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
- default: break;
+ // TODO: warn about this?
+ add_nlist = false;
+ break;
}
-
- if (type == eSymbolTypeInvalid)
+
+ if (TEXT_eh_frame_sectID == nlist.n_sect)
+ {
+ type = eSymbolTypeException;
+ }
+ else
{
- const char *symbol_sect_name = symbol_section->GetName().AsCString();
- if (symbol_section->IsDescendant (text_section_sp.get()))
+ uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
+
+ switch (section_type)
{
- if (symbol_section->IsClear(SectionAttrUserPureInstructions |
- SectionAttrUserSelfModifyingCode |
- SectionAttrSytemSomeInstructions))
- type = eSymbolTypeData;
- else
- type = eSymbolTypeCode;
+ case SectionTypeRegular: break; // regular section
+ //case SectionTypeZeroFill: type = eSymbolTypeData; break; // zero fill on demand section
+ case SectionTypeCStringLiterals: type = eSymbolTypeData; break; // section with only literal C strings
+ case SectionType4ByteLiterals: type = eSymbolTypeData; break; // section with only 4 byte literals
+ case SectionType8ByteLiterals: type = eSymbolTypeData; break; // section with only 8 byte literals
+ case SectionTypeLiteralPointers: type = eSymbolTypeTrampoline; break; // section with only pointers to literals
+ case SectionTypeNonLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only non-lazy symbol pointers
+ case SectionTypeLazySymbolPointers: type = eSymbolTypeTrampoline; break; // section with only lazy symbol pointers
+ case SectionTypeSymbolStubs: type = eSymbolTypeTrampoline; break; // section with only symbol stubs, byte size of stub in the reserved2 field
+ case SectionTypeModuleInitFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for initialization
+ case SectionTypeModuleTermFunctionPointers: type = eSymbolTypeCode; break; // section with only function pointers for termination
+ //case SectionTypeCoalesced: type = eSymbolType; break; // section contains symbols that are to be coalesced
+ //case SectionTypeZeroFillLarge: type = eSymbolTypeData; break; // zero fill on demand section (that can be larger than 4 gigabytes)
+ case SectionTypeInterposing: type = eSymbolTypeTrampoline; break; // section with only pairs of function pointers for interposing
+ case SectionType16ByteLiterals: type = eSymbolTypeData; break; // section with only 16 byte literals
+ case SectionTypeDTraceObjectFormat: type = eSymbolTypeInstrumentation; break;
+ case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
+ default: break;
}
- else
- if (symbol_section->IsDescendant(data_section_sp.get()))
+
+ if (type == eSymbolTypeInvalid)
+ {
+ const char *symbol_sect_name = symbol_section->GetName().AsCString();
+ if (symbol_section->IsDescendant (text_section_sp.get()))
+ {
+ if (symbol_section->IsClear(SectionAttrUserPureInstructions |
+ SectionAttrUserSelfModifyingCode |
+ SectionAttrSytemSomeInstructions))
+ type = eSymbolTypeData;
+ else
+ type = eSymbolTypeCode;
+ }
+ else if (symbol_section->IsDescendant(data_section_sp.get()))
{
if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
{
type = eSymbolTypeRuntime;
- if (symbol_name &&
- symbol_name[0] == '_' &&
- symbol_name[1] == 'O' &&
+ if (symbol_name &&
+ symbol_name[0] == '_' &&
+ symbol_name[1] == 'O' &&
symbol_name[2] == 'B')
{
llvm::StringRef symbol_name_ref(symbol_name);
@@ -2103,55 +2145,56 @@
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name = symbol_name + g_objc_v2_prefix_class.size();
type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
}
else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
{
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
}
else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
{
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
}
}
}
- else
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
- {
- type = eSymbolTypeException;
- }
- else
- {
- type = eSymbolTypeData;
- }
- }
- else
- if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
+ else if (symbol_sect_name && ::strstr (symbol_sect_name, "__gcc_except_tab") == symbol_sect_name)
{
- type = eSymbolTypeTrampoline;
+ type = eSymbolTypeException;
}
else
- if (symbol_section->IsDescendant(objc_section_sp.get()))
+ {
+ type = eSymbolTypeData;
+ }
+ }
+ else if (symbol_sect_name && ::strstr (symbol_sect_name, "__IMPORT") == symbol_sect_name)
+ {
+ type = eSymbolTypeTrampoline;
+ }
+ else if (symbol_section->IsDescendant(objc_section_sp.get()))
+ {
+ type = eSymbolTypeRuntime;
+ if (symbol_name && symbol_name[0] == '.')
+ {
+ llvm::StringRef symbol_name_ref(symbol_name);
+ static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
+ if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
{
- type = eSymbolTypeRuntime;
- if (symbol_name && symbol_name[0] == '.')
- {
- llvm::StringRef symbol_name_ref(symbol_name);
- static const llvm::StringRef g_objc_v1_prefix_class (".objc_class_name_");
- if (symbol_name_ref.startswith(g_objc_v1_prefix_class))
- {
- symbol_name_non_abi_mangled = symbol_name;
- symbol_name = symbol_name + g_objc_v1_prefix_class.size();
- type = eSymbolTypeObjCClass;
- }
- }
+ symbol_name_non_abi_mangled = symbol_name;
+ symbol_name = symbol_name + g_objc_v1_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
}
+ }
+ }
+ }
}
}
- }
break;
}
}
@@ -2287,6 +2330,8 @@
if (symbol_byte_size > 0)
sym[sym_idx].SetByteSize(symbol_byte_size);
+ if (demangled_is_synthesized)
+ sym[sym_idx].SetDemangledNameIsSynthesized(true);
++sym_idx;
}
else
@@ -2374,9 +2419,10 @@
const char *symbol_name_non_abi_mangled = NULL;
SectionSP symbol_section;
- uint32_t symbol_byte_size = 0;
+ lldb::addr_t symbol_byte_size = 0;
bool add_nlist = true;
bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
+ bool demangled_is_synthesized = false;
assert (sym_idx < num_syms);
@@ -2845,18 +2891,21 @@
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name = symbol_name + g_objc_v2_prefix_class.size();
type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
}
else if (symbol_name_ref.startswith(g_objc_v2_prefix_metaclass))
{
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
}
else if (symbol_name_ref.startswith(g_objc_v2_prefix_ivar))
{
symbol_name_non_abi_mangled = symbol_name + 1;
symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
}
}
}
@@ -2888,6 +2937,7 @@
symbol_name_non_abi_mangled = symbol_name;
symbol_name = symbol_name + g_objc_v1_prefix_class.size();
type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
}
}
}
@@ -3024,6 +3074,9 @@
if (symbol_byte_size > 0)
sym[sym_idx].SetByteSize(symbol_byte_size);
+ if (demangled_is_synthesized)
+ sym[sym_idx].SetDemangledNameIsSynthesized(true);
+
++sym_idx;
}
else
@@ -3151,8 +3204,6 @@
// Now synthesize indirect symbols
if (m_dysymtab.nindirectsyms != 0)
{
- DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
-
if (indirect_symbol_index_data.GetByteSize())
{
NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
@@ -3175,7 +3226,7 @@
{
const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
- uint32_t symbol_stub_offset = symbol_stub_index * 4;
+ lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
{
const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
@@ -3283,11 +3334,11 @@
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct uuid_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
@@ -3330,7 +3381,7 @@
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct load_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
uint32_t i;
for (i=0; i<m_header.ncmds; ++i)
@@ -3403,14 +3454,14 @@
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct load_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
bool done = false;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
@@ -3547,7 +3598,7 @@
if (!m_thread_context_offsets_valid)
{
m_thread_context_offsets_valid = true;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
FileRangeArray::Entry file_range;
thread_command thread_cmd;
for (uint32_t i=0; i<m_header.ncmds; ++i)
@@ -3713,13 +3764,13 @@
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct dylib_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t version_cmd = 0;
uint64_t version = 0;
uint32_t i;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
Index: aze/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h 2013-03-03 09:35:50.227457352 +0100
@@ -43,10 +43,11 @@
static lldb_private::ObjectFile *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t file_offset,
+ lldb::offset_t length);
static lldb_private::ObjectFile *
CreateMemoryInstance (const lldb::ModuleSP &module_sp,
@@ -55,7 +56,7 @@
lldb::addr_t header_addr);
static bool
- MagicBytesMatch (lldb::DataBufferSP& dataSP,
+ MagicBytesMatch (lldb::DataBufferSP& data_sp,
lldb::addr_t offset,
lldb::addr_t length);
@@ -63,13 +64,14 @@
// Member Functions
//------------------------------------------------------------------
ObjectFileMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
ObjectFileMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr);
@@ -85,7 +87,7 @@
virtual bool
IsExecutable () const;
- virtual size_t
+ virtual uint32_t
GetAddressByteSize () const;
virtual lldb::AddressClass
Index: aze/lldb/source/Plugins/ObjectFile/PECOFF/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/ObjectFile/PECOFF/CMakeLists.txt 2013-03-03 09:35:50.227457352 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginObjectFilePECOFF
+ ObjectFilePECOFF.cpp
+ )
Index: aze/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp 2013-03-03 09:35:50.227457352 +0100
@@ -145,11 +145,25 @@
ObjectFile *
-ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length)
+ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- if (ObjectFilePECOFF::MagicBytesMatch(dataSP))
+ if (!data_sp)
{
- std::auto_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, dataSP, file, offset, length));
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
+ {
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length)
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ std::auto_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length));
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
}
@@ -166,21 +180,22 @@
}
bool
-ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP)
+ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp)
{
- DataExtractor data(dataSP, eByteOrderLittle, 4);
- uint32_t offset = 0;
+ DataExtractor data(data_sp, eByteOrderLittle, 4);
+ lldb::offset_t offset = 0;
uint16_t magic = data.GetU16 (&offset);
return magic == IMAGE_DOS_SIGNATURE;
}
ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec* file,
- addr_t offset,
- addr_t length) :
- ObjectFile (module_sp, file, offset, length, dataSP),
+ lldb::offset_t file_offset,
+ lldb::offset_t length) :
+ ObjectFile (module_sp, file, file_offset, length, data_sp, data_offset),
m_dos_header (),
m_coff_header (),
m_coff_header_opt (),
@@ -206,7 +221,7 @@
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
m_sect_headers.clear();
m_data.SetByteOrder (eByteOrderLittle);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (ParseDOSHeader())
{
@@ -239,7 +254,7 @@
return (m_coff_header.flags & IMAGE_FILE_DLL) == 0;
}
-size_t
+uint32_t
ObjectFilePECOFF::GetAddressByteSize () const
{
if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
@@ -271,7 +286,7 @@
ObjectFilePECOFF::ParseDOSHeader ()
{
bool success = false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
success = m_data.ValidOffsetForDataOfSize(0, sizeof(m_dos_header));
if (success)
@@ -326,7 +341,7 @@
// ParserCOFFHeader
//----------------------------------------------------------------------
bool
-ObjectFilePECOFF::ParseCOFFHeader(uint32_t* offset_ptr)
+ObjectFilePECOFF::ParseCOFFHeader(lldb::offset_t *offset_ptr)
{
bool success = m_data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(m_coff_header));
if (success)
@@ -345,10 +360,10 @@
}
bool
-ObjectFilePECOFF::ParseCOFFOptionalHeader(uint32_t* offset_ptr)
+ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr)
{
bool success = false;
- const uint32_t end_offset = *offset_ptr + m_coff_header.hdrsize;
+ const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
if (*offset_ptr < end_offset)
{
success = true;
@@ -429,7 +444,7 @@
DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size));
DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size))
{
m_sect_headers.resize(nsects);
@@ -462,8 +477,8 @@
{
if (sect.name[0] == '/')
{
- uint32_t stroff = strtoul(&sect.name[1], NULL, 10);
- uint32_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
+ lldb::offset_t stroff = strtoul(&sect.name[1], NULL, 10);
+ lldb::offset_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
const char *name = m_data.GetCStr (&string_file_offset);
if (name)
{
@@ -503,7 +518,7 @@
// Include the 4 bytes string table size at the end of the symbols
DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4));
DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size);
- uint32_t offset = symbol_data_size;
+ lldb::offset_t offset = symbol_data_size;
const uint32_t strtab_size = symtab_data.GetU32 (&offset);
DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size + 4, strtab_size));
DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size);
@@ -787,7 +802,7 @@
s->Printf (" entry = 0x%8.8x\n", header.entry);
s->Printf (" code_offset = 0x%8.8x\n", header.code_offset);
s->Printf (" data_offset = 0x%8.8x\n", header.data_offset);
- s->Printf (" image_base = 0x%16.16llx\n", header.image_base);
+ s->Printf (" image_base = 0x%16.16" PRIx64 "\n", header.image_base);
s->Printf (" sect_alignment = 0x%8.8x\n", header.sect_alignment);
s->Printf (" file_alignment = 0x%8.8x\n", header.file_alignment);
s->Printf (" major_os_system_version = 0x%4.4x\n", header.major_os_system_version);
@@ -802,10 +817,10 @@
s->Printf (" checksum = 0x%8.8x\n", header.checksum);
s->Printf (" subsystem = 0x%4.4x\n", header.subsystem);
s->Printf (" dll_flags = 0x%4.4x\n", header.dll_flags);
- s->Printf (" stack_reserve_size = 0x%16.16llx\n", header.stack_reserve_size);
- s->Printf (" stack_commit_size = 0x%16.16llx\n", header.stack_commit_size);
- s->Printf (" heap_reserve_size = 0x%16.16llx\n", header.heap_reserve_size);
- s->Printf (" heap_commit_size = 0x%16.16llx\n", header.heap_commit_size);
+ s->Printf (" stack_reserve_size = 0x%16.16" PRIx64 "\n", header.stack_reserve_size);
+ s->Printf (" stack_commit_size = 0x%16.16" PRIx64 "\n", header.stack_commit_size);
+ s->Printf (" heap_reserve_size = 0x%16.16" PRIx64 "\n", header.heap_reserve_size);
+ s->Printf (" heap_commit_size = 0x%16.16" PRIx64 "\n", header.heap_commit_size);
s->Printf (" loader_flags = 0x%8.8x\n", header.loader_flags);
s->Printf (" num_data_dir_entries = 0x%8.8zx\n", header.data_dirs.size());
uint32_t i;
Index: aze/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
===================================================================
--- aze.orig/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h 2013-03-03 09:35:50.227457352 +0100
@@ -36,10 +36,11 @@
static ObjectFile *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static lldb_private::ObjectFile *
CreateMemoryInstance (const lldb::ModuleSP &module_sp,
@@ -47,14 +48,15 @@
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr);
static bool
- MagicBytesMatch (lldb::DataBufferSP& dataSP);
+ MagicBytesMatch (lldb::DataBufferSP& data_sp);
ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t file_offset,
+ lldb::offset_t length);
virtual
~ObjectFilePECOFF();
@@ -68,7 +70,7 @@
virtual bool
IsExecutable () const;
- virtual size_t
+ virtual uint32_t
GetAddressByteSize () const;
// virtual lldb_private::AddressClass
@@ -212,8 +214,8 @@
} coff_symbol_t;
bool ParseDOSHeader ();
- bool ParseCOFFHeader (uint32_t* offset_ptr);
- bool ParseCOFFOptionalHeader (uint32_t* offset_ptr);
+ bool ParseCOFFHeader (lldb::offset_t *offset_ptr);
+ bool ParseCOFFOptionalHeader (lldb::offset_t *offset_ptr);
bool ParseSectionHeaders (uint32_t offset);
static void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t& header);
Index: aze/lldb/source/Plugins/OperatingSystem/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/OperatingSystem/CMakeLists.txt 2013-03-03 09:35:50.227457352 +0100
@@ -0,0 +1,2 @@
+#add_subdirectory(Darwin-Kernel)
+add_subdirectory(Python)
Index: aze/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/CMakeLists.txt 2013-03-03 09:35:50.227457352 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginOSDarwinKernel
+ OperatingSystemDarwinKernel.cpp
+ )
Index: aze/lldb/source/Plugins/OperatingSystem/Python/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/OperatingSystem/Python/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginOSPython
+ OperatingSystemPython.cpp
+ )
Index: aze/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp 2013-03-03 09:35:50.231457351 +0100
@@ -6,6 +6,9 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
+#include "lldb/lldb-python.h"
+
#ifndef LLDB_DISABLE_PYTHON
#include "OperatingSystemPython.h"
@@ -17,7 +20,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -84,11 +86,11 @@
m_thread_list_valobj_sp (),
m_register_info_ap (),
m_interpreter (NULL),
- m_python_object (NULL)
+ m_python_object_sp ()
{
if (!process)
return;
- lldb::TargetSP target_sp = process->CalculateTarget();
+ TargetSP target_sp = process->CalculateTarget();
if (!target_sp)
return;
m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
@@ -111,9 +113,9 @@
os_plugin_class_name.erase (py_extension_pos);
// Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn"
os_plugin_class_name += ".OperatingSystemPlugIn";
- auto object_sp = m_interpreter->CreateOSPlugin(os_plugin_class_name.c_str(), process->CalculateProcess());
- if (object_sp)
- m_python_object = object_sp->GetObject();
+ ScriptInterpreterObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess());
+ if (object_sp && object_sp->GetObject())
+ m_python_object_sp = object_sp;
}
}
}
@@ -128,18 +130,14 @@
{
if (m_register_info_ap.get() == NULL)
{
- if (!m_interpreter || !m_python_object)
+ if (!m_interpreter || !m_python_object_sp)
return NULL;
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %llu", m_process->GetID());
+ log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID());
- auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
- if (!object_sp)
- return NULL;
- PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
- PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
+ PythonDictionary dictionary(m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp));
if (!dictionary)
return NULL;
@@ -174,58 +172,32 @@
bool
OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- if (!m_interpreter || !m_python_object)
- return NULL;
+ if (!m_interpreter || !m_python_object_sp)
+ return false;
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ // First thing we have to do is get the API lock, and the run lock. We're going to change the thread
+ // content of the process, and we're going to use python, which requires the API lock to do it.
+ // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
+ Target &target = m_process->GetTarget();
+ Mutex::Locker api_locker (target.GetAPIMutex());
+
if (log)
- log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %llu", m_process->GetID());
+ log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID());
- auto object_sp = m_interpreter->OSPlugin_QueryForThreadsInfo(m_interpreter->MakeScriptObject(m_python_object));
- if (!object_sp)
- return NULL;
- PythonDataObject pyobj((PyObject*)object_sp->GetObject());
- PythonDataArray threads_array (pyobj.GetArrayObject());
- if (threads_array)
+ PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp));
+ if (threads_list)
{
-// const uint32_t num_old_threads = old_thread_list.GetSize(false);
-// for (uint32_t i=0; i<num_old_threads; ++i)
-// {
-// ThreadSP old_thread_sp(old_thread_list.GetThreadAtIndex(i, false));
-// if (old_thread_sp->GetID() < 0x10000)
-// new_thread_list.AddThread (old_thread_sp);
-// }
-
- PythonDataString tid_pystr("tid");
- PythonDataString name_pystr("name");
- PythonDataString queue_pystr("queue");
- PythonDataString state_pystr("state");
- PythonDataString stop_reason_pystr("stop_reason");
- PythonDataString reg_data_addr_pystr ("register_data_addr");
-
- const uint32_t num_threads = threads_array.GetSize();
+ const uint32_t num_threads = threads_list.GetSize();
for (uint32_t i=0; i<num_threads; ++i)
{
- PythonDataDictionary thread_dict(threads_array.GetItemAtIndex(i).GetDictionaryObject());
+ PythonDictionary thread_dict(threads_list.GetItemAtIndex(i));
if (thread_dict)
{
- const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID);
- const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS);
- const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
- const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
- //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
- //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
-
- ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
- if (!thread_sp)
- thread_sp.reset (new ThreadMemory (*m_process,
- tid,
- name,
- queue,
- reg_data_addr));
- new_thread_list.AddThread(thread_sp);
-
+ ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, &old_thread_list, NULL));
+ if (thread_sp)
+ new_thread_list.AddThread(thread_sp);
}
}
}
@@ -236,18 +208,65 @@
return new_thread_list.GetSize(false) > 0;
}
+ThreadSP
+OperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict, ThreadList *old_thread_list_ptr, bool *did_create_ptr)
+{
+ ThreadSP thread_sp;
+ if (thread_dict)
+ {
+ PythonString tid_pystr("tid");
+ const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID);
+ if (tid != LLDB_INVALID_THREAD_ID)
+ {
+ PythonString name_pystr("name");
+ PythonString queue_pystr("queue");
+ PythonString state_pystr("state");
+ PythonString stop_reason_pystr("stop_reason");
+ PythonString reg_data_addr_pystr ("register_data_addr");
+
+ const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS);
+ const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
+ const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
+ //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
+ //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
+
+ if (old_thread_list_ptr)
+ thread_sp = old_thread_list_ptr->FindThreadByID (tid, false);
+ if (!thread_sp)
+ {
+ if (did_create_ptr)
+ *did_create_ptr = true;
+ thread_sp.reset (new ThreadMemory (*m_process,
+ tid,
+ name,
+ queue,
+ reg_data_addr));
+ }
+ }
+ }
+ return thread_sp;
+}
+
+
+
void
OperatingSystemPython::ThreadWasSelected (Thread *thread)
{
}
RegisterContextSP
-OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr)
+OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr)
{
RegisterContextSP reg_ctx_sp;
- if (!m_interpreter || !m_python_object || !thread)
+ if (!m_interpreter || !m_python_object_sp || !thread)
return RegisterContextSP();
+ // First thing we have to do is get the API lock, and the run lock. We're going to change the thread
+ // content of the process, and we're going to use python, which requires the API lock to do it.
+ // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
+ Target &target = m_process->GetTarget();
+ Mutex::Locker api_locker (target.GetAPIMutex());
+
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
if (reg_data_addr != LLDB_INVALID_ADDRESS)
@@ -255,7 +274,7 @@
// The registers data is in contiguous memory, just create the register
// context using the address provided
if (log)
- log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%llx, reg_data_addr = 0x%llx) creating memory register context", thread->GetID(), reg_data_addr);
+ log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ", reg_data_addr = 0x%" PRIx64 ") creating memory register context", thread->GetID(), reg_data_addr);
reg_ctx_sp.reset (new RegisterContextMemory (*thread, 0, *GetDynamicRegisterInfo (), reg_data_addr));
}
else
@@ -263,15 +282,9 @@
// No register data address is provided, query the python plug-in to let
// it make up the data as it sees fit
if (log)
- log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%llx) fetching register data from python", thread->GetID());
+ log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") fetching register data from python", thread->GetID());
- auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
- thread->GetID());
-
- if (!object_sp)
- return RegisterContextSP();
-
- PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
+ PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID()));
if (reg_context_data)
{
DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(),
@@ -300,5 +313,36 @@
return stop_info_sp;
}
+lldb::ThreadSP
+OperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+
+ if (log)
+ log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context);
+
+ if (m_interpreter && m_python_object_sp)
+ {
+ // First thing we have to do is get the API lock, and the run lock. We're going to change the thread
+ // content of the process, and we're going to use python, which requires the API lock to do it.
+ // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
+ Target &target = m_process->GetTarget();
+ Mutex::Locker api_locker (target.GetAPIMutex());
+
+ PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context));
+ if (thread_info_dict)
+ {
+ ThreadList &thread_list = m_process->GetThreadList();
+ bool did_create = false;
+ ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, &thread_list, &did_create));
+ if (did_create)
+ thread_list.AddThread(thread_sp);
+ return thread_sp;
+ }
+ }
+ return ThreadSP();
+}
+
+
#endif // #ifndef LLDB_DISABLE_PYTHON
Index: aze/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
===================================================================
--- aze.orig/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h 2013-03-03 09:35:50.231457351 +0100
@@ -78,19 +78,31 @@
virtual lldb::StopInfoSP
CreateThreadStopReason (lldb_private::Thread *thread);
+ //------------------------------------------------------------------
+ // Method for lazy creation of threads on demand
+ //------------------------------------------------------------------
+ virtual lldb::ThreadSP
+ CreateThread (lldb::tid_t tid, lldb::addr_t context);
+
protected:
bool IsValid() const
{
- return m_python_object != NULL;
+ return m_python_object_sp && m_python_object_sp->GetObject() != NULL;
}
+
+ lldb::ThreadSP
+ CreateThreadFromThreadInfo (lldb_private::PythonDictionary &thread_dict,
+ lldb_private::ThreadList *old_thread_list_ptr,
+ bool *did_create_ptr);
+
DynamicRegisterInfo *
GetDynamicRegisterInfo ();
lldb::ValueObjectSP m_thread_list_valobj_sp;
std::auto_ptr<DynamicRegisterInfo> m_register_info_ap;
lldb_private::ScriptInterpreter *m_interpreter;
- void* m_python_object;
+ lldb::ScriptInterpreterObjectSP m_python_object_sp;
};
Index: aze/lldb/source/Plugins/Platform/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Platform/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,5 @@
+add_subdirectory(FreeBSD)
+add_subdirectory(gdb-server)
+add_subdirectory(Linux)
+add_subdirectory(MacOSX)
+#add_subdirectory(Windows)
Index: aze/lldb/source/Plugins/Platform/FreeBSD/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Platform/FreeBSD/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginPlatformFreeBSD
+ PlatformFreeBSD.cpp
+ )
Index: aze/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp 2013-03-03 09:35:50.231457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "PlatformFreeBSD.h"
// C Includes
@@ -628,7 +630,7 @@
{
ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture));
ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64));
- if (platform_arch == platform_arch64)
+ if (platform_arch.IsExactMatch(platform_arch64))
{
// This freebsd platform supports both 32 and 64 bit. Since we already
// returned the 64 bit arch for idx == 0, return the 32 bit arch
Index: aze/lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Platform/gdb-server/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginPlatformGDB
+ PlatformRemoteGDBServer.cpp
+ )
Index: aze/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp 2013-03-03 09:35:50.231457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "PlatformRemoteGDBServer.h"
// C Includes
Index: aze/lldb/source/Plugins/Platform/Linux/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Platform/Linux/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginPlatformLinux
+ PlatformLinux.cpp
+ )
Index: aze/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp 2013-03-03 09:35:50.231457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "PlatformLinux.h"
// C Includes
Index: aze/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Platform/MacOSX/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,8 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginPlatformMacOSX
+ PlatformDarwin.cpp
+ PlatformiOSSimulator.cpp
+ PlatformMacOSX.cpp
+ PlatformRemoteiOS.cpp
+ )
Index: aze/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp 2013-03-03 09:35:50.231457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "PlatformDarwin.h"
// C Includes
@@ -22,6 +24,8 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/Target.h"
using namespace lldb;
@@ -48,57 +52,74 @@
{
}
-FileSpec
-PlatformDarwin::LocateExecutableScriptingResource (const ModuleSpec &module_spec)
-{
- const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
- const UUID *uuid = module_spec.GetUUIDPtr();
-
- const char* module_directory = exec_fspec->GetDirectory().GetCString();
- const char* module_basename = exec_fspec->GetFileNameStrippingExtension().GetCString();
-
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "LocateExecutableScriptingResource (file = %s, arch = %s, uuid = %p)",
- exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
- arch ? arch->GetArchitectureName() : "<NULL>",
- uuid);
-
-
- FileSpec symbol_fspec (Symbols::LocateExecutableSymbolFile(module_spec));
-
- FileSpec script_fspec;
-
- StreamString path_string;
-
- if (symbol_fspec && symbol_fspec.Exists())
- {
- // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
- // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
- path_string.Printf("%s/../Python/%s.py",symbol_fspec.GetDirectory().GetCString(),module_basename);
- script_fspec.SetFile(path_string.GetData(), true);
- if (!script_fspec.Exists())
- script_fspec.Clear();
- }
-
- // no symbols or symbols did not have a scripting resource
- if (!symbol_fspec || !script_fspec)
- {
- path_string.Clear();
- path_string.Printf("%s.framework",module_basename);
- if (module_directory && strstr(module_directory, path_string.GetData()))
+FileSpecList
+PlatformDarwin::LocateExecutableScriptingResources (Target *target,
+ Module &module)
+{
+ FileSpecList file_list;
+ if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython)
+ {
+ // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
+ // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
+ // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
+ // which should be stripped while leaving "this.binary.file" as-is.
+ FileSpec module_spec = module.GetFileSpec();
+
+ if (module_spec)
{
- // we are going to be in foo.framework/Versions/X/foo
- path_string.Clear();
- // let's go to foo.framework/Versions/X/Resources/Python/foo.py
- path_string.Printf("%s/Resources/Python/%s.py",module_directory,module_basename);
- script_fspec.SetFile(path_string.GetData(), true);
- if (!script_fspec.Exists())
- script_fspec.Clear();
+ SymbolVendor *symbols = module.GetSymbolVendor ();
+ if (symbols)
+ {
+ SymbolFile *symfile = symbols->GetSymbolFile();
+ if (symfile)
+ {
+ ObjectFile *objfile = symfile->GetObjectFile();
+ if (objfile)
+ {
+ FileSpec symfile_spec (objfile->GetFileSpec());
+ if (symfile_spec && symfile_spec.Exists())
+ {
+ while (module_spec.GetFilename())
+ {
+ std::string module_basename (module_spec.GetFilename().GetCString());
+
+ // FIXME: for Python, we cannot allow certain characters in module
+ // filenames we import. Theoretically, different scripting languages may
+ // have different sets of forbidden tokens in filenames, and that should
+ // be dealt with by each ScriptInterpreter. For now, we just replace dots
+ // with underscores, but if we ever support anything other than Python
+ // we will need to rework this
+ std::replace(module_basename.begin(), module_basename.end(), '.', '_');
+ std::replace(module_basename.begin(), module_basename.end(), ' ', '_');
+ std::replace(module_basename.begin(), module_basename.end(), '-', '_');
+
+
+ StreamString path_string;
+ // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
+ // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
+ path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str());
+ FileSpec script_fspec(path_string.GetData(), true);
+ if (script_fspec.Exists())
+ {
+ file_list.Append (script_fspec);
+ break;
+ }
+
+ // If we didn't find the python file, then keep
+ // stripping the extensions and try again
+ ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension());
+ if (module_spec.GetFilename() == filename_no_extension)
+ break;
+
+ module_spec.GetFilename() = filename_no_extension;
+ }
+ }
+ }
+ }
+ }
}
}
-
- return script_fspec;
+ return file_list;
}
Error
@@ -294,33 +315,52 @@
FileSpec bundle_directory;
if (Host::GetBundleDirectory (platform_file, bundle_directory))
{
- char platform_path[PATH_MAX];
- char bundle_dir[PATH_MAX];
- platform_file.GetPath (platform_path, sizeof(platform_path));
- const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
- char new_path[PATH_MAX];
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i=0; i<num_module_search_paths; ++i)
+ if (platform_file == bundle_directory)
+ {
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = bundle_directory;
+ if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
+ {
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ return new_error;
+ }
+ }
+ else
{
- const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
- if (search_path_len < sizeof(new_path))
+ char platform_path[PATH_MAX];
+ char bundle_dir[PATH_MAX];
+ platform_file.GetPath (platform_path, sizeof(platform_path));
+ const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
+ char new_path[PATH_MAX];
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i=0; i<num_module_search_paths; ++i)
{
- snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
- FileSpec new_file_spec (new_path, false);
- if (new_file_spec.Exists())
+ const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
+ if (search_path_len < sizeof(new_path))
{
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = new_file_spec;
- Error new_error (Platform::GetSharedModule (new_module_spec,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
+ snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
+ FileSpec new_file_spec (new_path, false);
+ if (new_file_spec.Exists())
{
- module_sp->SetPlatformFileSpec(new_file_spec);
- return new_error;
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = new_file_spec;
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ {
+ module_sp->SetPlatformFileSpec(new_file_spec);
+ return new_error;
+ }
}
}
}
@@ -673,7 +713,7 @@
{
ArchSpec platform_arch (Host::GetArchitecture (Host::eSystemDefaultArchitecture));
ArchSpec platform_arch64 (Host::GetArchitecture (Host::eSystemDefaultArchitecture64));
- if (platform_arch == platform_arch64)
+ if (platform_arch.IsExactMatch(platform_arch64))
{
// This macosx platform supports both 32 and 64 bit. Since we already
// returned the 64 bit arch for idx == 0, return the 32 bit arch
@@ -943,6 +983,7 @@
eFunctionNameTypeFull,
skip_prologue,
internal);
+ bp_sp->SetBreakpointKind("thread-creation");
return bp_sp;
}
Index: aze/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
===================================================================
--- aze.orig/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h 2013-03-03 09:35:50.231457351 +0100
@@ -38,8 +38,9 @@
const lldb_private::ModuleSpec &sym_spec,
lldb_private::FileSpec &sym_file);
- lldb_private::FileSpec
- LocateExecutableScriptingResource (const lldb_private::ModuleSpec &module_spec);
+ lldb_private::FileSpecList
+ LocateExecutableScriptingResources (lldb_private::Target *target,
+ lldb_private::Module &module);
virtual lldb_private::Error
GetSharedModule (const lldb_private::ModuleSpec &module_spec,
Index: aze/lldb/source/Plugins/Process/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,7 @@
+#add_subdirectory(FreeBSD)
+add_subdirectory(gdb-remote)
+add_subdirectory(Linux)
+#add_subdirectory(mach-core)
+#add_subdirectory(MacOSx-Kernel)
+add_subdirectory(POSIX)
+add_subdirectory(Utility)
Index: aze/lldb/source/Plugins/Process/FreeBSD/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/FreeBSD/CMakeLists.txt 2013-03-03 09:35:50.231457351 +0100
@@ -0,0 +1,6 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginProcessFreeBSD
+ ProcessFreeBSD.cpp
+ ProcessMonitor.cpp
+ )
Index: aze/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp 2013-03-03 09:35:50.231457351 +0100
@@ -502,8 +502,8 @@
class SiginfoOperation : public Operation
{
public:
- SiginfoOperation(lldb::tid_t tid, void *info, bool &result)
- : m_tid(tid), m_info(info), m_result(result) { }
+ SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
+ : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }
void Execute(ProcessMonitor *monitor);
@@ -511,6 +511,7 @@
lldb::tid_t m_tid;
void *m_info;
bool &m_result;
+ int &m_err;
};
void
@@ -518,9 +519,10 @@
{
struct ptrace_lwpinfo plwp;
- if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
+ if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
m_result = false;
- else {
+ m_err = errno;
+ } else {
memcpy(m_info, &plwp.pl_siginfo, sizeof(siginfo_t));
m_result = true;
}
@@ -625,14 +627,16 @@
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path)
+ const char *stderr_path,
+ const char *working_dir)
: OperationArgs(monitor),
m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
- m_stderr_path(stderr_path) { }
+ m_stderr_path(stderr_path),
+ m_working_dir(working_dir) { }
ProcessMonitor::LaunchArgs::~LaunchArgs()
{ }
@@ -663,6 +667,7 @@
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
@@ -676,7 +681,7 @@
std::auto_ptr<LaunchArgs> args;
args.reset(new LaunchArgs(this, module, argv, envp,
- stdin_path, stdout_path, stderr_path));
+ stdin_path, stdout_path, stderr_path, working_dir));
// Server/client descriptors.
@@ -837,6 +842,7 @@
const char *stdin_path = args->m_stdin_path;
const char *stdout_path = args->m_stdout_path;
const char *stderr_path = args->m_stderr_path;
+ const char *working_dir = args->m_working_dir;
lldb::pid_t pid;
lldb::ThreadSP inferior;
@@ -851,6 +857,7 @@
eDupStdinFailed,
eDupStdoutFailed,
eDupStderrFailed,
+ eChdirFailed,
eExecFailed
};
@@ -885,6 +892,11 @@
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
exit(eDupStderrFailed);
+ // Change working directory
+ if (working_dir != NULL && working_dir[0])
+ if (0 != ::chdir(working_dir))
+ exit(eChdirFailed);
+
// Execute. We should never return.
execve(argv[0],
const_cast<char *const *>(argv),
@@ -918,6 +930,9 @@
case eDupStderrFailed:
args->m_error.SetErrorString("Child open stderr failed.");
break;
+ case eChdirFailed:
+ args->m_error.SetErrorString("Child failed to set working directory.");
+ break;
case eExecFailed:
args->m_error.SetErrorString("Child exec failed.");
break;
@@ -1060,8 +1075,9 @@
ProcessFreeBSD *process = monitor->m_process;
bool stop_monitoring;
siginfo_t info;
+ int ptrace_err;
- if (!monitor->GetSignalInfo(pid, &info))
+ if (!monitor->GetSignalInfo(pid, &info, ptrace_err))
stop_monitoring = true; // pid is gone. Bail.
else {
switch (info.si_signo)
@@ -1407,7 +1423,8 @@
}
bool
-ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value)
+ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
+ unsigned size, RegisterValue &value)
{
bool result;
ReadRegOperation op(offset, size, value, result);
@@ -1416,7 +1433,8 @@
}
bool
-ProcessMonitor::WriteRegisterValue(unsigned offset, const RegisterValue &value)
+ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value)
{
bool result;
WriteRegOperation op(offset, value, result);
@@ -1425,7 +1443,7 @@
}
bool
-ProcessMonitor::ReadGPR(void *buf)
+ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
{
bool result;
ReadGPROperation op(buf, result);
@@ -1434,7 +1452,7 @@
}
bool
-ProcessMonitor::ReadFPR(void *buf)
+ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
{
bool result;
ReadFPROperation op(buf, result);
@@ -1443,7 +1461,7 @@
}
bool
-ProcessMonitor::WriteGPR(void *buf)
+ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
{
bool result;
WriteGPROperation op(buf, result);
@@ -1452,7 +1470,7 @@
}
bool
-ProcessMonitor::WriteFPR(void *buf)
+ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf)
{
bool result;
WriteFPROperation op(buf, result);
@@ -1488,10 +1506,10 @@
}
bool
-ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo)
+ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err)
{
bool result;
- SiginfoOperation op(tid, siginfo, result);
+ SiginfoOperation op(tid, siginfo, result, ptrace_err);
DoOperation(&op);
return result;
}
Index: aze/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h 2013-03-03 09:35:50.231457351 +0100
@@ -54,6 +54,7 @@
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error);
ProcessMonitor(ProcessPOSIX *process,
@@ -103,36 +104,50 @@
/// dependent) offset.
///
/// This method is provided for use by RegisterContextFreeBSD derivatives.
+ /// FIXME: The FreeBSD implementation of this function should use tid in order
+ /// to enable support for debugging threaded programs.
bool
- ReadRegisterValue(unsigned offset, unsigned size, lldb_private::RegisterValue &value);
+ ReadRegisterValue(lldb::tid_t tid, unsigned offset,
+ unsigned size, lldb_private::RegisterValue &value);
/// Writes the given value to the register identified by the given
/// (architecture dependent) offset.
///
/// This method is provided for use by RegisterContextFreeBSD derivatives.
+ /// FIXME: The FreeBSD implementation of this function should use tid in order
+ /// to enable support for debugging threaded programs.
bool
- WriteRegisterValue(unsigned offset, const lldb_private::RegisterValue &value);
+ WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const lldb_private::RegisterValue &value);
/// Reads all general purpose registers into the specified buffer.
+ /// FIXME: The FreeBSD implementation of this function should use tid in order
+ /// to enable support for debugging threaded programs.
bool
- ReadGPR(void *buf);
+ ReadGPR(lldb::tid_t tid, void *buf);
/// Reads all floating point registers into the specified buffer.
+ /// FIXME: The FreeBSD implementation of this function should use tid in order
+ /// to enable support for debugging threaded programs.
bool
- ReadFPR(void *buf);
+ ReadFPR(lldb::tid_t tid, void *buf);
/// Writes all general purpose registers into the specified buffer.
+ /// FIXME: The FreeBSD implementation of this function should use tid in order
+ /// to enable support for debugging threaded programs.
bool
- WriteGPR(void *buf);
+ WriteGPR(lldb::tid_t tid, void *buf);
/// Writes all floating point registers into the specified buffer.
+ /// FIXME: The FreeBSD implementation of this function should use tid in order
+ /// to enable support for debugging threaded programs.
bool
- WriteFPR(void *buf);
+ WriteFPR(lldb::tid_t tid, void *buf);
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
bool
- GetSignalInfo(lldb::tid_t tid, void *siginfo);
+ GetSignalInfo(lldb::tid_t tid, void *siginfo, int &errno);
/// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
/// corresponding to the given thread IDto the memory pointed to by @p
@@ -196,7 +211,8 @@
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path);
+ const char *stderr_path,
+ const char *working_dir);
~LaunchArgs();
@@ -206,6 +222,7 @@
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
+ const char *m_working_dir; // Working directory or NULL.
};
void
Index: aze/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt 2013-03-03 09:35:50.235457350 +0100
@@ -0,0 +1,11 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginProcessGDBRemote
+ GDBRemoteCommunication.cpp
+ GDBRemoteCommunicationClient.cpp
+ GDBRemoteCommunicationServer.cpp
+ GDBRemoteRegisterContext.cpp
+ ProcessGDBRemote.cpp
+ ProcessGDBRemoteLog.cpp
+ ThreadGDBRemote.cpp
+ )
\ No newline at end of file
Index: aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 2013-03-03 09:35:50.235457350 +0100
@@ -12,6 +12,8 @@
// C Includes
// C++ Includes
+#include <sstream>
+
// Other libraries and framework includes
#include "llvm/ADT/Triple.h"
#include "lldb/Interpreter/Args.h"
@@ -46,6 +48,7 @@
m_supports_vCont_s (eLazyBoolCalculate),
m_supports_vCont_S (eLazyBoolCalculate),
m_qHostInfo_is_valid (eLazyBoolCalculate),
+ m_qProcessInfo_is_valid (eLazyBoolCalculate),
m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
m_supports_memory_region_info (eLazyBoolCalculate),
m_supports_watchpoint_support_info (eLazyBoolCalculate),
@@ -70,7 +73,9 @@
m_async_packet (),
m_async_response (),
m_async_signal (-1),
+ m_thread_id_to_used_usec_map (),
m_host_arch(),
+ m_process_arch(),
m_os_version_major (UINT32_MAX),
m_os_version_minor (UINT32_MAX),
m_os_version_update (UINT32_MAX)
@@ -187,6 +192,7 @@
m_supports_vCont_s = eLazyBoolCalculate;
m_supports_vCont_S = eLazyBoolCalculate;
m_qHostInfo_is_valid = eLazyBoolCalculate;
+ m_qProcessInfo_is_valid = eLazyBoolCalculate;
m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
m_supports_memory_region_info = eLazyBoolCalculate;
m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
@@ -203,6 +209,7 @@
m_supports_z3 = true;
m_supports_z4 = true;
m_host_arch.Clear();
+ m_process_arch.Clear();
}
@@ -417,6 +424,99 @@
return response_len;
}
+static const char *end_delimiter = "--end--;";
+static const int end_delimiter_len = 8;
+
+std::string
+GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
+( ProcessGDBRemote *process,
+ StringExtractorGDBRemote& profileDataExtractor
+)
+{
+ std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
+ std::stringstream final_output;
+ std::string name, value;
+
+ // Going to assuming thread_used_usec comes first, else bail out.
+ while (profileDataExtractor.GetNameColonValue(name, value))
+ {
+ if (name.compare("thread_used_id") == 0)
+ {
+ StringExtractor threadIDHexExtractor(value.c_str());
+ uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
+
+ bool has_used_usec = false;
+ uint32_t curr_used_usec = 0;
+ std::string usec_name, usec_value;
+ uint32_t input_file_pos = profileDataExtractor.GetFilePos();
+ if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
+ {
+ if (usec_name.compare("thread_used_usec") == 0)
+ {
+ has_used_usec = true;
+ curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
+ }
+ else
+ {
+ // We didn't find what we want, it is probably
+ // an older version. Bail out.
+ profileDataExtractor.SetFilePos(input_file_pos);
+ }
+ }
+
+ if (has_used_usec)
+ {
+ uint32_t prev_used_usec = 0;
+ std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
+ if (iterator != m_thread_id_to_used_usec_map.end())
+ {
+ prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
+ }
+
+ uint32_t real_used_usec = curr_used_usec - prev_used_usec;
+ // A good first time record is one that runs for at least 0.25 sec
+ bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
+ bool good_subsequent_time = (prev_used_usec > 0) &&
+ ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
+
+ if (good_first_time || good_subsequent_time)
+ {
+ // We try to avoid doing too many index id reservation,
+ // resulting in fast increase of index ids.
+
+ final_output << name << ":";
+ int32_t index_id = process->AssignIndexIDToThread(thread_id);
+ final_output << index_id << ";";
+
+ final_output << usec_name << ":" << usec_value << ";";
+ }
+ else
+ {
+ // Skip past 'thread_used_name'.
+ std::string local_name, local_value;
+ profileDataExtractor.GetNameColonValue(local_name, local_value);
+ }
+
+ // Store current time as previous time so that they can be compared later.
+ new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
+ }
+ else
+ {
+ // Bail out and use old string.
+ final_output << name << ":" << value << ";";
+ }
+ }
+ else
+ {
+ final_output << name << ":" << value << ";";
+ }
+ }
+ final_output << end_delimiter;
+ m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
+
+ return final_output.str();
+}
+
StateType
GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
(
@@ -440,11 +540,11 @@
// may change if we are interrupted and we continue after an async packet...
std::string continue_packet(payload, packet_length);
- bool got_stdout = false;
+ bool got_async_packet = false;
while (state == eStateRunning)
{
- if (!got_stdout)
+ if (!got_async_packet)
{
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
@@ -454,7 +554,7 @@
m_private_is_running.SetValue (true, eBroadcastAlways);
}
- got_stdout = false;
+ got_async_packet = false;
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
@@ -637,7 +737,7 @@
case 'O':
// STDOUT
{
- got_stdout = true;
+ got_async_packet = true;
std::string inferior_stdout;
inferior_stdout.reserve(response.GetBytesLeft () / 2);
char ch;
@@ -647,6 +747,36 @@
}
break;
+ case 'A':
+ // Async miscellaneous reply. Right now, only profile data is coming through this channel.
+ {
+ got_async_packet = true;
+ std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
+ if (m_partial_profile_data.length() > 0)
+ {
+ m_partial_profile_data.append(input);
+ input = m_partial_profile_data;
+ m_partial_profile_data.clear();
+ }
+
+ size_t found, pos = 0, len = input.length();
+ while ((found = input.find(end_delimiter, pos)) != std::string::npos)
+ {
+ StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
+ const std::string& profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
+ process->BroadcastAsyncProfileData (profile_data.c_str(), profile_data.length());
+
+ pos = found + end_delimiter_len;
+ }
+
+ if (pos < len)
+ {
+ // Last incomplete chunk.
+ m_partial_profile_data = input.substr(pos);
+ }
+ }
+ break;
+
case 'E':
// ERROR
state = eStateInvalid;
@@ -953,6 +1083,14 @@
return ArchSpec();
}
+const lldb_private::ArchSpec &
+GDBRemoteCommunicationClient::GetProcessArchitecture ()
+{
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo ();
+ return m_process_arch;
+}
+
bool
GDBRemoteCommunicationClient::GetHostInfo (bool force)
@@ -1188,7 +1326,7 @@
if (pid != LLDB_INVALID_PROCESS_ID)
{
char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", pid);
+ const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
assert (packet_len < sizeof(packet));
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
{
@@ -1215,7 +1353,7 @@
{
m_supports_alloc_dealloc_memory = eLazyBoolYes;
char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "_M%llx,%s%s%s",
+ const int packet_len = ::snprintf (packet, sizeof(packet), "_M%" PRIx64 ",%s%s%s",
(uint64_t)size,
permissions & lldb::ePermissionsReadable ? "r" : "",
permissions & lldb::ePermissionsWritable ? "w" : "",
@@ -1242,7 +1380,7 @@
{
m_supports_alloc_dealloc_memory = eLazyBoolYes;
char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
+ const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
@@ -1275,7 +1413,7 @@
{
m_supports_memory_region_info = eLazyBoolYes;
char packet[64];
- const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%llx", (uint64_t)addr);
+ const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
@@ -1608,7 +1746,7 @@
if (m_supports_qProcessInfoPID)
{
char packet[32];
- const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%llu", pid);
+ const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
@@ -1624,6 +1762,100 @@
return false;
}
+bool
+GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
+{
+ if (m_qProcessInfo_is_valid == eLazyBoolYes)
+ return true;
+ if (m_qProcessInfo_is_valid == eLazyBoolNo)
+ return false;
+
+ GetHostInfo ();
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse ("qProcessInfo", response, false))
+ {
+ if (response.IsNormalResponse())
+ {
+ std::string name;
+ std::string value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ std::string triple;
+ uint32_t pointer_byte_size = 0;
+ StringExtractor extractor;
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t num_keys_decoded = 0;
+ while (response.GetNameColonValue(name, value))
+ {
+ if (name.compare("cputype") == 0)
+ {
+ cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ ++num_keys_decoded;
+ }
+ else if (name.compare("cpusubtype") == 0)
+ {
+ sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ if (sub != 0)
+ ++num_keys_decoded;
+ }
+ else if (name.compare("ostype") == 0)
+ {
+ os_name.swap (value);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("vendor") == 0)
+ {
+ vendor_name.swap(value);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("endian") == 0)
+ {
+ ++num_keys_decoded;
+ if (value.compare("little") == 0)
+ byte_order = eByteOrderLittle;
+ else if (value.compare("big") == 0)
+ byte_order = eByteOrderBig;
+ else if (value.compare("pdp") == 0)
+ byte_order = eByteOrderPDP;
+ else
+ --num_keys_decoded;
+ }
+ else if (name.compare("ptrsize") == 0)
+ {
+ pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
+ if (pointer_byte_size != 0)
+ ++num_keys_decoded;
+ }
+ }
+ if (num_keys_decoded > 0)
+ m_qProcessInfo_is_valid = eLazyBoolYes;
+ if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
+ {
+ m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
+ if (pointer_byte_size)
+ {
+ assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
+ }
+ m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
+ m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
+ return true;
+ }
+ }
+ }
+ else
+ {
+ m_qProcessInfo_is_valid = eLazyBoolNo;
+ }
+
+ return false;
+}
+
+
uint32_t
GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos)
@@ -1678,9 +1910,9 @@
}
if (match_info.GetProcessInfo().ProcessIDIsValid())
- packet.Printf("pid:%llu;",match_info.GetProcessInfo().GetProcessID());
+ packet.Printf("pid:%" PRIu64 ";",match_info.GetProcessInfo().GetProcessID());
if (match_info.GetProcessInfo().ParentProcessIDIsValid())
- packet.Printf("parent_pid:%llu;",match_info.GetProcessInfo().GetParentProcessID());
+ packet.Printf("parent_pid:%" PRIu64 ";",match_info.GetProcessInfo().GetParentProcessID());
if (match_info.GetProcessInfo().UserIDIsValid())
packet.Printf("uid:%u;",match_info.GetProcessInfo().GetUserID());
if (match_info.GetProcessInfo().GroupIDIsValid())
@@ -1803,7 +2035,7 @@
end_time = TimeValue::Now();
total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
- printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %llu.%9.9llu sec for %f packets/sec.\n",
+ printf ("%u qSpeedTest(send=%-5u, recv=%-5u) in %" PRIu64 ".%9.9" PRIu64 " sec for %f packets/sec.\n",
num_packets,
send_size,
recv_size,
@@ -1827,7 +2059,7 @@
end_time = TimeValue::Now();
total_time_nsec = end_time.GetAsNanoSecondsSinceJan1_1970() - start_time.GetAsNanoSecondsSinceJan1_1970();
packets_per_second = (((float)num_packets)/(float)total_time_nsec) * (float)TimeValue::NanoSecPerSec;
- printf ("%u 'qC' packets packets in 0x%llu%9.9llu sec for %f packets/sec.\n",
+ printf ("%u 'qC' packets packets in 0x%" PRIu64 "%9.9" PRIu64 " sec for %f packets/sec.\n",
num_packets,
total_time_nsec / TimeValue::NanoSecPerSec,
total_time_nsec % TimeValue::NanoSecPerSec,
@@ -1883,17 +2115,17 @@
}
bool
-GDBRemoteCommunicationClient::SetCurrentThread (int tid)
+GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
{
if (m_curr_tid == tid)
return true;
-
+
char packet[32];
int packet_len;
- if (tid <= 0)
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
else
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
+ packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
assert (packet_len + 1 < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
@@ -1908,18 +2140,18 @@
}
bool
-GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
+GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
{
if (m_curr_tid_run == tid)
return true;
-
+
char packet[32];
int packet_len;
- if (tid <= 0)
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
else
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
-
+ packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
+
assert (packet_len + 1 < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
@@ -1947,7 +2179,7 @@
if (m_supports_qThreadStopInfo)
{
char packet[256];
- int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%llx", tid);
+ int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
assert (packet_len < sizeof(packet));
if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
{
@@ -1977,13 +2209,12 @@
case eWatchpointWrite: if (!m_supports_z2) return UINT8_MAX; break;
case eWatchpointRead: if (!m_supports_z3) return UINT8_MAX; break;
case eWatchpointReadWrite: if (!m_supports_z4) return UINT8_MAX; break;
- default: return UINT8_MAX;
}
char packet[64];
const int packet_len = ::snprintf (packet,
sizeof(packet),
- "%c%i,%llx,%x",
+ "%c%i,%" PRIx64 ",%x",
insert ? 'Z' : 'z',
type,
addr,
@@ -2007,7 +2238,6 @@
case eWatchpointWrite: m_supports_z2 = false; break;
case eWatchpointRead: m_supports_z3 = false; break;
case eWatchpointReadWrite: m_supports_z4 = false; break;
- default: break;
}
}
@@ -2037,7 +2267,7 @@
{
do
{
- tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
if (tid != LLDB_INVALID_THREAD_ID)
{
Index: aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h 2013-03-03 09:35:50.235457350 +0100
@@ -217,7 +217,10 @@
const lldb_private::ArchSpec &
GetHostArchitecture ();
-
+
+ const lldb_private::ArchSpec &
+ GetProcessArchitecture ();
+
bool
GetVContSupported (char flavor);
@@ -307,7 +310,6 @@
case eWatchpointWrite: return m_supports_z2;
case eWatchpointRead: return m_supports_z3;
case eWatchpointReadWrite: return m_supports_z4;
- default: break;
}
return false;
}
@@ -330,10 +332,10 @@
uint32_t recv_size);
bool
- SetCurrentThread (int tid);
+ SetCurrentThread (uint64_t tid);
bool
- SetCurrentThreadForRun (int tid);
+ SetCurrentThreadForRun (uint64_t tid);
lldb_private::LazyBool
SupportsAllocDeallocMemory () // const
@@ -352,8 +354,16 @@
{
return m_interrupt_sent;
}
+
+ std::string
+ HarmonizeThreadIdsForProfileData (ProcessGDBRemote *process,
+ StringExtractorGDBRemote &inputStringExtractor);
+
protected:
+ bool
+ GetCurrentProcessInfo ();
+
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteCommunicationClient can see and modify these
//------------------------------------------------------------------
@@ -367,6 +377,7 @@
lldb_private::LazyBool m_supports_vCont_s;
lldb_private::LazyBool m_supports_vCont_S;
lldb_private::LazyBool m_qHostInfo_is_valid;
+ lldb_private::LazyBool m_qProcessInfo_is_valid;
lldb_private::LazyBool m_supports_alloc_dealloc_memory;
lldb_private::LazyBool m_supports_memory_region_info;
lldb_private::LazyBool m_supports_watchpoint_support_info;
@@ -401,8 +412,11 @@
StringExtractorGDBRemote m_async_response;
int m_async_signal; // We were asked to deliver a signal to the inferior process.
bool m_interrupt_sent;
+ std::string m_partial_profile_data;
+ std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
lldb_private::ArchSpec m_host_arch;
+ lldb_private::ArchSpec m_process_arch;
uint32_t m_os_version_major;
uint32_t m_os_version_minor;
uint32_t m_os_version_update;
Index: aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp 2013-03-03 09:35:50.235457350 +0100
@@ -92,7 +92,7 @@
const Entry &entry = m_packets[idx];
if (entry.type == ePacketTypeInvalid || entry.packet.empty())
break;
- strm.Printf ("history[%u] tid=0x%4.4llx <%4u> %s packet: %s\n",
+ strm.Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n",
entry.packet_idx,
entry.tid,
entry.bytes_transmitted,
@@ -116,7 +116,7 @@
const Entry &entry = m_packets[idx];
if (entry.type == ePacketTypeInvalid || entry.packet.empty())
break;
- log->Printf ("history[%u] tid=0x%4.4llx <%4u> %s packet: %s",
+ log->Printf ("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s",
entry.packet_idx,
entry.tid,
entry.bytes_transmitted,
@@ -298,7 +298,7 @@
size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
if (log)
- log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %llu",
+ log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
__PRETTY_FUNCTION__,
timeout_usec,
Communication::ConnectionStatusAsCString (status),
Index: aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp 2013-03-03 09:35:50.235457350 +0100
@@ -280,7 +280,7 @@
static void
CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &response)
{
- response.Printf ("pid:%llu;ppid:%llu;uid:%i;gid:%i;euid:%i;egid:%i;",
+ response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;",
proc_info.GetProcessID(),
proc_info.GetParentProcessID(),
proc_info.GetUserID(),
@@ -646,7 +646,7 @@
{
lldb::pid_t pid = m_process_launch_info.GetProcessID();
StreamString response;
- response.Printf("QC%llx", pid);
+ response.Printf("QC%" PRIx64, pid);
if (m_is_platform)
{
// If we launch a process and this GDB server is acting as a platform,
@@ -712,7 +712,7 @@
{
uint16_t port = (intptr_t)accept_thread_result;
char response[256];
- const int response_len = ::snprintf (response, sizeof(response), "pid:%llu;port:%u;", debugserver_pid, port);
+ const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port);
assert (response_len < sizeof(response));
//m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID();
success = SendPacketNoLock (response, response_len) > 0;
Index: aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp 2013-03-03 09:35:50.235457350 +0100
@@ -85,7 +85,7 @@
}
const RegisterInfo *
-GDBRemoteRegisterContext::GetRegisterInfoAtIndex (uint32_t reg)
+GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg)
{
return m_reg_info.GetRegisterInfoAtIndex (reg);
}
@@ -99,7 +99,7 @@
const RegisterSet *
-GDBRemoteRegisterContext::GetRegisterSet (uint32_t reg_set)
+GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set)
{
return m_reg_info.GetRegisterSet (reg_set);
}
@@ -134,13 +134,13 @@
bool success = bytes_copied == reg_byte_size;
if (success)
{
- m_reg_valid[reg] = true;
+ SetRegisterIsValid(reg, true);
}
else if (bytes_copied > 0)
{
// Only set register is valid to false if we copied some bytes, else
// leave it as it was.
- m_reg_valid[reg] = false;
+ SetRegisterIsValid(reg, false);
}
return success;
}
@@ -155,7 +155,7 @@
int packet_len = 0;
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
if (gdb_comm.GetThreadSuffixSupported())
- packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4llx;", reg, m_thread.GetID());
+ packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, m_thread.GetID());
else
packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
assert (packet_len < (sizeof(packet) - 1));
@@ -180,7 +180,7 @@
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (!m_reg_valid[reg])
+ if (!GetRegisterIsValid(reg))
{
Mutex::Locker locker;
if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read register."))
@@ -196,7 +196,7 @@
{
// Get all registers in one packet
if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4llx;", m_thread.GetID());
+ packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", m_thread.GetID());
else
packet_len = ::snprintf (packet, sizeof(packet), "g");
assert (packet_len < (sizeof(packet) - 1));
@@ -207,40 +207,43 @@
SetAllRegisterValid (true);
}
}
- else if (!reg_info->value_regs)
- {
- // Get each register individually
- GetPrimordialRegister(reg_info, gdb_comm);
- }
- else
+ else if (reg_info->value_regs)
{
// Process this composite register request by delegating to the constituent
// primordial registers.
-
+
// Index of the primordial register.
- uint32_t prim_reg_idx;
bool success = true;
- for (uint32_t idx = 0;
- (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM;
- ++idx)
+ for (uint32_t idx = 0; success; ++idx)
{
+ const uint32_t prim_reg = reg_info->value_regs[idx];
+ if (prim_reg == LLDB_INVALID_REGNUM)
+ break;
// We have a valid primordial regsiter as our constituent.
// Grab the corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
- if (!GetPrimordialRegister(prim_reg_info, gdb_comm))
- {
+ const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+ if (prim_reg_info == NULL)
success = false;
- // Some failure occurred. Let's break out of the for loop.
- break;
+ else
+ {
+ // Read the containing register if it hasn't already been read
+ if (!GetRegisterIsValid(prim_reg))
+ success = GetPrimordialRegister(prim_reg_info, gdb_comm);
}
}
+
if (success)
{
// If we reach this point, all primordial register requests have succeeded.
// Validate this composite register.
- m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = true;
+ SetRegisterIsValid (reg_info, true);
}
}
+ else
+ {
+ // Get each register individually
+ GetPrimordialRegister(reg_info, gdb_comm);
+ }
}
}
else
@@ -269,7 +272,7 @@
}
// Make sure we got a valid register value after reading it
- if (!m_reg_valid[reg])
+ if (!GetRegisterIsValid(reg))
return false;
}
@@ -311,10 +314,10 @@
lldb::endian::InlHostByteOrder());
if (gdb_comm.GetThreadSuffixSupported())
- packet.Printf (";thread:%4.4llx;", m_thread.GetID());
+ packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
// Invalidate just this register
- m_reg_valid[reg] = false;
+ SetRegisterIsValid(reg, false);
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
@@ -337,7 +340,7 @@
StreamString packet;
StringExtractorGDBRemote response;
- packet.Printf ("QSyncThreadState:%4.4llx;", m_thread.GetID());
+ packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetID());
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
@@ -387,6 +390,7 @@
{
StreamString packet;
StringExtractorGDBRemote response;
+
if (m_read_all_at_once)
{
// Set all registers in one packet
@@ -397,7 +401,7 @@
lldb::endian::InlHostByteOrder());
if (thread_suffix_supported)
- packet.Printf (";thread:%4.4llx;", m_thread.GetID());
+ packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
// Invalidate all register values
InvalidateIfNeeded (true);
@@ -414,52 +418,50 @@
}
}
}
- else if (!reg_info->value_regs)
- {
- // Set each register individually
- return SetPrimordialRegister(reg_info, gdb_comm);
- }
else
{
- // Process this composite register request by delegating to the constituent
- // primordial registers.
-
- // Invalidate this composite register first.
- m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = false;
-
- // Index of the primordial register.
- uint32_t prim_reg_idx;
- // For loop index.
- uint32_t idx;
+ bool success = true;
- // Invalidate the invalidate_regs, if present.
- if (reg_info->invalidate_regs)
+ if (reg_info->value_regs)
{
- for (idx = 0;
- (prim_reg_idx = reg_info->invalidate_regs[idx]) != LLDB_INVALID_REGNUM;
- ++idx)
+ // This register is part of another register. In this case we read the actual
+ // register data for any "value_regs", and once all that data is read, we will
+ // have enough data in our register context bytes for the value of this register
+
+ // Invalidate this composite register first.
+
+ for (uint32_t idx = 0; success; ++idx)
{
- // Grab the invalidate register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
- m_reg_valid[prim_reg_info->kinds[eRegisterKindLLDB]] = false;
+ const uint32_t reg = reg_info->value_regs[idx];
+ if (reg == LLDB_INVALID_REGNUM)
+ break;
+ // We have a valid primordial regsiter as our constituent.
+ // Grab the corresponding register info.
+ const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+ if (value_reg_info == NULL)
+ success = false;
+ else
+ success = SetPrimordialRegister(value_reg_info, gdb_comm);
}
}
+ else
+ {
+ // This is an actual register, write it
+ success = SetPrimordialRegister(reg_info, gdb_comm);
+ }
- bool success = true;
- for (idx = 0;
- (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM;
- ++idx)
+ // Check if writing this register will invalidate any other register values?
+ // If so, invalidate them
+ if (reg_info->invalidate_regs)
{
- // We have a valid primordial regsiter as our constituent.
- // Grab the corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
- if (!SetPrimordialRegister(prim_reg_info, gdb_comm))
+ for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
+ reg != LLDB_INVALID_REGNUM;
+ reg = reg_info->invalidate_regs[++idx])
{
- success = false;
- // Some failure occurred. Let's break out of the for loop.
- break;
+ SetRegisterIsValid(reg, false);
}
}
+
return success;
}
}
@@ -510,7 +512,7 @@
{
int packet_len = 0;
if (thread_suffix_supported)
- packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4llx", m_thread.GetID());
+ packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetID());
else
packet_len = ::snprintf (packet, sizeof(packet), "g");
assert (packet_len < (sizeof(packet) - 1));
@@ -527,7 +529,7 @@
if (thread_suffix_supported)
{
char thread_id_cstr[64];
- ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4llx;", m_thread.GetID());
+ ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetID());
response_str.append (thread_id_cstr);
}
data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size()));
@@ -633,7 +635,7 @@
const char *restore_src = (const char *)restore_data.PeekData(reg_byte_offset, reg_byte_size);
if (restore_src)
{
- if (m_reg_valid[reg])
+ if (GetRegisterIsValid(reg))
{
const char *current_src = (const char *)m_reg_data.PeekData(reg_byte_offset, reg_byte_size);
if (current_src)
@@ -650,9 +652,9 @@
lldb::endian::InlHostByteOrder());
if (thread_suffix_supported)
- packet.Printf (";thread:%4.4llx;", m_thread.GetID());
+ packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
- m_reg_valid[reg] = false;
+ SetRegisterIsValid(reg, false);
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
@@ -855,7 +857,7 @@
static ConstString gpr_reg_set ("General Purpose Registers");
static ConstString sfp_reg_set ("Software Floating Point Registers");
static ConstString vfp_reg_set ("Floating Point Registers");
- uint32_t i;
+ size_t i;
if (from_scratch)
{
// Calculate the offsets of the registers
@@ -903,8 +905,8 @@
else
{
// Add composite registers to our primordial registers, then.
- const uint32_t num_composites = llvm::array_lengthof(g_composites);
- const uint32_t num_primordials = GetNumRegisters();
+ const size_t num_composites = llvm::array_lengthof(g_composites);
+ const size_t num_primordials = GetNumRegisters();
RegisterInfo *g_comp_register_infos = g_register_infos + (num_registers - num_composites);
for (i=0; i<num_composites; ++i)
{
@@ -931,93 +933,3 @@
}
}
}
-
-void
-GDBRemoteDynamicRegisterInfo::Addx86_64ConvenienceRegisters()
-{
- // For eax, ebx, ecx, edx, esi, edi, ebp, esp register mapping.
- static const char* g_mapped_names[] = {
- "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp",
- "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp",
- "rax", "rbx", "rcx", "rdx",
- "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp"
- };
-
- // These value regs are to be populated with the corresponding primordial register index.
- // For example,
- static uint32_t g_eax_regs[] = { 0, LLDB_INVALID_REGNUM }; // 0 is to be replaced with rax's index.
- static uint32_t g_ebx_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_ecx_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_edx_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_edi_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_esi_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_ebp_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_esp_regs[] = { 0, LLDB_INVALID_REGNUM };
-
- static RegisterInfo g_conv_register_infos[] =
- {
-// NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB NATIVE VALUE REGS INVALIDATE REGS
-// ====== ======= == === ============= ============ ===================== ===================== ============================ ==================== ====================== ========== ===============
- { "eax" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "ebx" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "ecx" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "edx" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "edi" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs, NULL},
- { "esi" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs, NULL},
- { "ebp" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs, NULL},
- { "esp" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs, NULL},
- { "ax" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "bx" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "cx" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "dx" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "di" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs, NULL},
- { "si" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs, NULL},
- { "bp" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs, NULL},
- { "sp" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs, NULL},
- { "ah" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "bh" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "ch" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "dh" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "al" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "bl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "cl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "dl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "dil" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs, NULL},
- { "sil" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs, NULL},
- { "bpl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs, NULL},
- { "spl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs, NULL}
- };
-
- static const uint32_t num_conv_regs = llvm::array_lengthof(g_mapped_names);
- static ConstString gpr_reg_set ("General Purpose Registers");
-
- // Add convenience registers to our primordial registers.
- const uint32_t num_primordials = GetNumRegisters();
- uint32_t reg_kind = num_primordials;
- for (uint32_t i=0; i<num_conv_regs; ++i)
- {
- ConstString name;
- ConstString alt_name;
- const char *prim_reg_name = g_mapped_names[i];
- if (prim_reg_name && prim_reg_name[0])
- {
- for (uint32_t j = 0; j < num_primordials; ++j)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
- // Find a matching primordial register info entry.
- if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, prim_reg_name) == 0)
- {
- // The name matches the existing primordial entry.
- // Find and assign the offset, and then add this composite register entry.
- g_conv_register_infos[i].byte_offset = reg_info->byte_offset + g_conv_register_infos[i].byte_offset;
- // Update the value_regs and the kinds fields in order to delegate to the primordial register.
- g_conv_register_infos[i].value_regs[0] = j;
- g_conv_register_infos[i].kinds[eRegisterKindLLDB] = ++reg_kind;
- name.SetCString(g_conv_register_infos[i].name);
- AddRegister(g_conv_register_infos[i], name, alt_name, gpr_reg_set);
- }
- }
- }
- }
-}
-
Index: aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h 2013-03-03 09:35:50.235457350 +0100
@@ -46,19 +46,34 @@
}
void
- AddRegister (lldb_private::RegisterInfo &reg_info,
+ AddRegister (lldb_private::RegisterInfo reg_info,
lldb_private::ConstString &reg_name,
lldb_private::ConstString &reg_alt_name,
lldb_private::ConstString &set_name)
{
- const uint32_t reg_num = m_regs.size();
+ const uint32_t reg_num = (uint32_t)m_regs.size();
m_reg_names.push_back (reg_name);
m_reg_alt_names.push_back (reg_alt_name);
reg_info.name = reg_name.AsCString();
assert (reg_info.name);
reg_info.alt_name = reg_alt_name.AsCString(NULL);
+ uint32_t i;
+ if (reg_info.value_regs)
+ {
+ for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
+ m_value_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = m_value_regs_map[reg_num].data();
+ }
+ if (reg_info.invalidate_regs)
+ {
+ for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
+ m_invalidate_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = m_invalidate_regs_map[reg_num].data();
+ }
m_regs.push_back (reg_info);
- uint32_t set = GetRegisterSetIndexByName (set_name, true);
+ uint32_t set = GetRegisterSetIndexByName (set_name);
assert (set < m_sets.size());
assert (set < m_set_reg_nums.size());
assert (set < m_set_names.size());
@@ -114,20 +129,20 @@
}
uint32_t
- GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create)
+ GetRegisterSetIndexByName (lldb_private::ConstString &set_name)
{
name_collection::iterator pos, end = m_set_names.end();
for (pos = m_set_names.begin(); pos != end; ++pos)
{
if (*pos == set_name)
- return std::distance (m_set_names.begin(), pos);
+ return static_cast<uint32_t>(std::distance (m_set_names.begin(), pos));
}
m_set_names.push_back(set_name);
m_set_reg_nums.resize(m_set_reg_nums.size()+1);
lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
m_sets.push_back (new_set);
- return m_sets.size() - 1;
+ return static_cast<uint32_t>(m_sets.size() - 1);
}
uint32_t
@@ -137,7 +152,7 @@
for (pos = m_regs.begin(); pos != end; ++pos)
{
if (pos->kinds[kind] == num)
- return std::distance (m_regs.begin(), pos);
+ return static_cast<uint32_t>(std::distance (m_regs.begin(), pos));
}
return LLDB_INVALID_REGNUM;
@@ -156,9 +171,6 @@
void
HardcodeARMRegisters(bool from_scratch);
- void
- Addx86_64ConvenienceRegisters();
-
protected:
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteRegisterContext can see and modify these
@@ -168,6 +180,7 @@
typedef std::vector <uint32_t> reg_num_collection;
typedef std::vector <reg_num_collection> set_reg_num_collection;
typedef std::vector <lldb_private::ConstString> name_collection;
+ typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
reg_collection m_regs;
set_collection m_sets;
@@ -175,6 +188,8 @@
name_collection m_reg_names;
name_collection m_reg_alt_names;
name_collection m_set_names;
+ reg_to_regs_map m_value_regs_map;
+ reg_to_regs_map m_invalidate_regs_map;
size_t m_reg_data_byte_size; // The number of bytes required to store all registers
};
@@ -202,13 +217,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
@@ -243,6 +258,34 @@
void
SetAllRegisterValid (bool b);
+ bool
+ GetRegisterIsValid (uint32_t reg) const
+ {
+#if defined (LLDB_CONFIGURATION_DEBUG)
+ assert (reg < m_reg_valid.size());
+#endif
+ if (reg < m_reg_valid.size())
+ return m_reg_valid[reg];
+ return false;
+ }
+
+ void
+ SetRegisterIsValid (const lldb_private::RegisterInfo *reg_info, bool valid)
+ {
+ if (reg_info)
+ return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
+ }
+
+ void
+ SetRegisterIsValid (uint32_t reg, bool valid)
+ {
+#if defined (LLDB_CONFIGURATION_DEBUG)
+ assert (reg < m_reg_valid.size());
+#endif
+ if (reg < m_reg_valid.size())
+ m_reg_valid[reg] = valid;
+ }
+
void
SyncThreadState(lldb_private::Process *process); // Assumes the sequence mutex has already been acquired.
Index: aze/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 2013-03-03 09:35:50.239457350 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <errno.h>
#include <spawn.h>
@@ -62,7 +64,6 @@
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
namespace lldb
{
@@ -202,7 +203,6 @@
m_waiting_for_attach (false),
m_destroy_tried_resuming (false),
m_dyld_plugin_name(),
- m_kernel_load_addr (LLDB_INVALID_ADDRESS),
m_command_sp ()
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
@@ -278,6 +278,8 @@
ConstString reg_name;
ConstString alt_name;
ConstString set_name;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
RegisterInfo reg_info = { NULL, // Name
NULL, // Alt name
0, // byte size
@@ -369,11 +371,52 @@
{
reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str());
}
+ else if (name.compare("container-regs") == 0)
+ {
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = value;
+ do
+ {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty())
+ {
+ uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ if (reg != LLDB_INVALID_REGNUM)
+ value_regs.push_back (reg);
+ }
+ } while (!value_pair.second.empty());
+ }
+ else if (name.compare("invalidate-regs") == 0)
+ {
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = value;
+ do
+ {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty())
+ {
+ uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ if (reg != LLDB_INVALID_REGNUM)
+ invalidate_regs.push_back (reg);
+ }
+ } while (!value_pair.second.empty());
+ }
}
reg_info.byte_offset = reg_offset;
assert (reg_info.byte_size != 0);
reg_offset += reg_info.byte_size;
+ if (!value_regs.empty())
+ {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
+ }
+ if (!invalidate_regs.empty())
+ {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
+ }
+
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
}
}
@@ -391,7 +434,16 @@
bool from_scratch = (reg_num == 0);
const ArchSpec &target_arch = GetTarget().GetArchitecture();
- const ArchSpec &remote_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ // Use the process' architecture instead of the host arch, if available
+ ArchSpec remote_arch;
+ if (remote_process_arch.IsValid ())
+ remote_arch = remote_process_arch;
+ else
+ remote_arch = remote_host_arch;
+
if (!target_arch.IsValid())
{
if (remote_arch.IsValid()
@@ -404,11 +456,6 @@
m_register_info.HardcodeARMRegisters(from_scratch);
}
- // Add some convenience registers (eax, ebx, ecx, edx, esi, edi, ebp, esp) to x86_64.
- if ((target_arch.IsValid() && target_arch.GetMachine() == llvm::Triple::x86_64)
- || (remote_arch.IsValid() && remote_arch.GetMachine() == llvm::Triple::x86_64))
- m_register_info.Addx86_64ConvenienceRegisters();
-
// At this point, we can finalize our register info.
m_register_info.Finalize ();
}
@@ -445,8 +492,6 @@
return error;
StartAsyncThread ();
- CheckForKernel (strm);
-
lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
if (pid == LLDB_INVALID_PROCESS_ID)
{
@@ -468,126 +513,26 @@
SetPrivateState (state);
}
else
- error.SetErrorStringWithFormat ("Process %llu was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
+ error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but state was not stopped: %s", pid, remote_url, StateAsCString (state));
}
else
- error.SetErrorStringWithFormat ("Process %llu was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
+ error.SetErrorStringWithFormat ("Process %" PRIu64 " was reported after connecting to '%s', but no stop reply packet was received", pid, remote_url);
}
if (error.Success()
&& !GetTarget().GetArchitecture().IsValid()
&& m_gdb_comm.GetHostArchitecture().IsValid())
{
- GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ // Prefer the *process'* architecture over that of the *host*, if available.
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ else
+ GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
return error;
}
-// When we are establishing a connection to a remote system and we have no executable specified,
-// or the executable is a kernel, we may be looking at a KASLR situation (where the kernel has been
-// slid in memory.)
-//
-// This function tries to locate the kernel in memory if this is possibly a kernel debug session.
-//
-// If a kernel is found, return the address of the kernel in GetImageInfoAddress() -- the
-// DynamicLoaderDarwinKernel plugin uses this address as the kernel load address and will load the
-// binary, if needed, along with all the kexts.
-
-void
-ProcessGDBRemote::CheckForKernel (Stream *strm)
-{
- // early return if this isn't an "unknown" system (kernel debugging doesn't have a system type)
- const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
- if (!gdb_remote_arch.IsValid() || gdb_remote_arch.GetTriple().getVendor() != llvm::Triple::UnknownVendor)
- return;
-
- Module *exe_module = GetTarget().GetExecutableModulePointer();
- ObjectFile *exe_objfile = NULL;
- if (exe_module)
- exe_objfile = exe_module->GetObjectFile();
-
- // early return if we have an executable and it is not a kernel--this is very unlikely to be a kernel debug session.
- if (exe_objfile
- && (exe_objfile->GetType() != ObjectFile::eTypeExecutable
- || exe_objfile->GetStrata() != ObjectFile::eStrataKernel))
- return;
-
- // See if the kernel is in memory at the File address (slide == 0) -- no work needed, if so.
- if (exe_objfile && exe_objfile->GetHeaderAddress().IsValid())
- {
- ModuleSP memory_module_sp;
- memory_module_sp = ReadModuleFromMemory (exe_module->GetFileSpec(), exe_objfile->GetHeaderAddress().GetFileAddress(), false, false);
- if (memory_module_sp.get()
- && memory_module_sp->GetUUID().IsValid()
- && memory_module_sp->GetUUID() == exe_module->GetUUID())
- {
- m_kernel_load_addr = exe_objfile->GetHeaderAddress().GetFileAddress();
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- SetCanJIT(false);
- return;
- }
- }
-
- // See if the kernel's load address is stored in the kernel's low globals page; this is
- // done when a debug boot-arg has been set.
-
- Error error;
- uint8_t buf[24];
- ModuleSP memory_module_sp;
- addr_t kernel_addr = LLDB_INVALID_ADDRESS;
-
- // First try the 32-bit
- if (memory_module_sp.get() == NULL)
- {
- DataExtractor data4 (buf, sizeof(buf), gdb_remote_arch.GetByteOrder(), 4);
- if (DoReadMemory (0xffff0110, buf, 4, error) == 4)
- {
- uint32_t offset = 0;
- kernel_addr = data4.GetU32(&offset);
- memory_module_sp = ReadModuleFromMemory (FileSpec("mach_kernel", false), kernel_addr, false, false);
- if (!memory_module_sp.get()
- || !memory_module_sp->GetUUID().IsValid()
- || memory_module_sp->GetObjectFile() == NULL
- || memory_module_sp->GetObjectFile()->GetType() != ObjectFile::eTypeExecutable
- || memory_module_sp->GetObjectFile()->GetStrata() != ObjectFile::eStrataKernel)
- {
- memory_module_sp.reset();
- }
- }
- }
-
- // Now try the 64-bit location
- if (memory_module_sp.get() == NULL)
- {
- DataExtractor data8 (buf, sizeof(buf), gdb_remote_arch.GetByteOrder(), 8);
- if (DoReadMemory (0xffffff8000002010ULL, buf, 8, error) == 8)
- {
- uint32_t offset = 0;
- kernel_addr = data8.GetU32(&offset);
- memory_module_sp = ReadModuleFromMemory (FileSpec("mach_kernel", false), kernel_addr, false, false);
- if (!memory_module_sp.get()
- || !memory_module_sp->GetUUID().IsValid()
- || memory_module_sp->GetObjectFile() == NULL
- || memory_module_sp->GetObjectFile()->GetType() != ObjectFile::eTypeExecutable
- || memory_module_sp->GetObjectFile()->GetStrata() != ObjectFile::eStrataKernel)
- {
- memory_module_sp.reset();
- }
- }
- }
-
- if (memory_module_sp.get()
- && memory_module_sp->GetArchitecture().IsValid()
- && memory_module_sp->GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
- {
- m_kernel_load_addr = kernel_addr;
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- SetCanJIT(false);
- return;
- }
-}
-
Error
ProcessGDBRemote::WillLaunchOrAttach ()
{
@@ -864,7 +809,15 @@
// See if the GDB server supports the qHostInfo information
- const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+ ArchSpec gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+
+ // See if the GDB server supports the qProcessInfo packet, if so
+ // prefer that over the Host information as it will be more specific
+ // to our process.
+
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ gdb_remote_arch = m_gdb_comm.GetProcessArchitecture();
+
if (gdb_remote_arch.IsValid())
{
ArchSpec &target_arch = GetTarget().GetArchitecture();
@@ -960,7 +913,7 @@
if (error.Success())
{
char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%llx", attach_pid);
+ const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, attach_pid);
SetID (attach_pid);
m_async_broadcaster.BroadcastEvent (eBroadcastBitAsyncContinue, new EventDataBytes (packet, packet_len));
}
@@ -1058,6 +1011,17 @@
DidLaunchOrAttach ();
}
+void
+ProcessGDBRemote::DoDidExec ()
+{
+ // The process exec'ed itself, figure out the dynamic loader, etc...
+ BuildDynamicRegisterInfo (true);
+ m_gdb_comm.ResetDiscoverableSettings();
+ DidLaunchOrAttach ();
+}
+
+
+
Error
ProcessGDBRemote::WillResume ()
{
@@ -1092,7 +1056,7 @@
if (m_gdb_comm.GetVContSupported ('c'))
{
for (tid_collection::const_iterator t_pos = m_continue_c_tids.begin(), t_end = m_continue_c_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";c:%4.4llx", *t_pos);
+ continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
}
else
continue_packet_error = true;
@@ -1103,7 +1067,7 @@
if (m_gdb_comm.GetVContSupported ('C'))
{
for (tid_sig_collection::const_iterator s_pos = m_continue_C_tids.begin(), s_end = m_continue_C_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";C%2.2x:%4.4llx", s_pos->second, s_pos->first);
+ continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
}
else
continue_packet_error = true;
@@ -1114,7 +1078,7 @@
if (m_gdb_comm.GetVContSupported ('s'))
{
for (tid_collection::const_iterator t_pos = m_continue_s_tids.begin(), t_end = m_continue_s_tids.end(); t_pos != t_end; ++t_pos)
- continue_packet.Printf(";s:%4.4llx", *t_pos);
+ continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
}
else
continue_packet_error = true;
@@ -1125,7 +1089,7 @@
if (m_gdb_comm.GetVContSupported ('S'))
{
for (tid_sig_collection::const_iterator s_pos = m_continue_S_tids.begin(), s_end = m_continue_S_tids.end(); s_pos != s_end; ++s_pos)
- continue_packet.Printf(";S%2.2x:%4.4llx", s_pos->second, s_pos->first);
+ continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second, s_pos->first);
}
else
continue_packet_error = true;
@@ -1331,7 +1295,7 @@
// locker will keep a mutex locked until it goes out of scope
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf ("ProcessGDBRemote::%s (pid = %llu)", __FUNCTION__, GetID());
+ log->Printf ("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
size_t num_thread_ids = m_thread_ids.size();
// The "m_thread_ids" thread ID list should always be updated after each stop
@@ -1343,18 +1307,32 @@
num_thread_ids = m_thread_ids.size();
}
+ ThreadList old_thread_list_copy(old_thread_list);
if (num_thread_ids > 0)
{
for (size_t i=0; i<num_thread_ids; ++i)
{
tid_t tid = m_thread_ids[i];
- ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
+ ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID (tid, false));
if (!thread_sp)
thread_sp.reset (new ThreadGDBRemote (*this, tid));
new_thread_list.AddThread(thread_sp);
}
}
-
+
+ // Whatever that is left in old_thread_list_copy are not
+ // present in new_thread_list. Remove non-existent threads from internal id table.
+ size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
+ for (size_t i=0; i<old_num_thread_ids; i++)
+ {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
+ if (old_thread_sp)
+ {
+ lldb::tid_t old_thread_id = old_thread_sp->GetID();
+ m_thread_id_to_index_id_map.erase(old_thread_id);
+ }
+ }
+
return true;
}
@@ -1880,7 +1858,7 @@
|| reason == eStopReasonException)
{
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - thread: %lld stopped with reason: %s.",
+ log->Printf ("ProcessGDBRemote::DoDestroy() - thread: %" PRId64 " stopped with reason: %s.",
thread_sp->GetID(),
stop_info_sp->GetDescription());
stop_looks_like_crash = true;
@@ -1915,7 +1893,7 @@
&& reason != eStopReasonException)
{
if (log)
- log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: %lld before running.",
+ log->Printf ("ProcessGDBRemote::DoDestroy() - Suspending thread: %" PRId64 " before running.",
thread_sp->GetID());
thread_sp->SetResumeState(eStateSuspended);
}
@@ -1999,16 +1977,10 @@
return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
}
-// For kernel debugging, we return the load address of the kernel binary as the
-// ImageInfoAddress and we return the DynamicLoaderDarwinKernel as the GetDynamicLoader()
-// name so the correct DynamicLoader plugin is chosen.
addr_t
ProcessGDBRemote::GetImageInfoAddress()
{
- if (m_kernel_load_addr != LLDB_INVALID_ADDRESS)
- return m_kernel_load_addr;
- else
- return m_gdb_comm.GetShlibInfoAddr();
+ return m_gdb_comm.GetShlibInfoAddr();
}
//------------------------------------------------------------------
@@ -2026,7 +1998,7 @@
}
char packet[64];
- const int packet_len = ::snprintf (packet, sizeof(packet), "m%llx,%llx", (uint64_t)addr, (uint64_t)size);
+ const int packet_len = ::snprintf (packet, sizeof(packet), "m%" PRIx64 ",%" PRIx64, (uint64_t)addr, (uint64_t)size);
assert (packet_len + 1 < sizeof(packet));
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
@@ -2037,7 +2009,7 @@
return response.GetHexBytes(buf, size, '\xdd');
}
else if (response.IsErrorResponse())
- error.SetErrorString("memory read failed");
+ error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
else if (response.IsUnsupportedResponse())
error.SetErrorStringWithFormat("GDB server does not support reading memory");
else
@@ -2062,7 +2034,7 @@
}
StreamString packet;
- packet.Printf("M%llx,%llx:", addr, (uint64_t)size);
+ packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
@@ -2073,7 +2045,7 @@
return size;
}
else if (response.IsErrorResponse())
- error.SetErrorString("memory write failed");
+ error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64, addr);
else if (response.IsUnsupportedResponse())
error.SetErrorStringWithFormat("GDB server does not support writing memory");
else
@@ -2119,7 +2091,7 @@
}
if (allocated_addr == LLDB_INVALID_ADDRESS)
- error.SetErrorStringWithFormat("unable to allocate %llu bytes of memory with permissions %s", (uint64_t)size, GetPermissionsAsCString (permissions));
+ error.SetErrorStringWithFormat("unable to allocate %" PRIu64 " bytes of memory with permissions %s", (uint64_t)size, GetPermissionsAsCString (permissions));
else
error.Clear();
return allocated_addr;
@@ -2165,7 +2137,7 @@
case eLazyBoolYes:
if (!m_gdb_comm.DeallocateMemory (addr))
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
break;
case eLazyBoolNo:
@@ -2176,7 +2148,7 @@
InferiorCallMunmap(this, addr, pos->second))
m_addr_to_mmap_size.erase (pos);
else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
}
break;
}
@@ -2200,7 +2172,7 @@
}
Error
-ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
+ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
assert (bp_site != NULL);
@@ -2209,12 +2181,12 @@
user_id_t site_id = bp_site->GetID();
const addr_t addr = bp_site->GetLoadAddress();
if (log)
- log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %llu) address = 0x%llx", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
if (bp_site->IsEnabled())
{
if (log)
- log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %llu) address = 0x%llx -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
return error;
}
else
@@ -2252,7 +2224,7 @@
if (log)
{
const char *err_string = error.AsCString();
- log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8llx: %s",
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite () error for breakpoint at 0x%8.8" PRIx64 ": %s",
bp_site->GetLoadAddress(),
err_string ? err_string : "NULL");
}
@@ -2263,7 +2235,7 @@
}
Error
-ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
+ProcessGDBRemote::DisableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
assert (bp_site != NULL);
@@ -2271,7 +2243,7 @@
user_id_t site_id = bp_site->GetID();
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %llu) addr = 0x%8.8llx", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
if (bp_site->IsEnabled())
{
@@ -2300,7 +2272,7 @@
else
{
if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
return error;
}
@@ -2328,7 +2300,7 @@
}
Error
-ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp)
+ProcessGDBRemote::EnableWatchpoint (Watchpoint *wp, bool notify)
{
Error error;
if (wp)
@@ -2337,11 +2309,11 @@
addr_t addr = wp->GetLoadAddress();
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
if (log)
- log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %llu)", watchID);
+ log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", watchID);
if (wp->IsEnabled())
{
if (log)
- log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %llu) addr = 0x%8.8llx: watchpoint already enabled.", watchID, (uint64_t)addr);
+ log->Printf("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 ": watchpoint already enabled.", watchID, (uint64_t)addr);
return error;
}
@@ -2351,7 +2323,7 @@
{
if (m_gdb_comm.SendGDBStoppointTypePacket(type, true, addr, wp->GetByteSize()) == 0)
{
- wp->SetEnabled(true);
+ wp->SetEnabled(true, notify);
return error;
}
else
@@ -2370,7 +2342,7 @@
}
Error
-ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp)
+ProcessGDBRemote::DisableWatchpoint (Watchpoint *wp, bool notify)
{
Error error;
if (wp)
@@ -2380,17 +2352,18 @@
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
addr_t addr = wp->GetLoadAddress();
+
if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx", watchID, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64, watchID, (uint64_t)addr);
if (!wp->IsEnabled())
{
if (log)
- log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
// See also 'class WatchpointSentry' within StopInfo.cpp.
// This disabling attempt might come from the user-supplied actions, we'll route it in order for
// the watchpoint object to intelligently process this action.
- wp->SetEnabled(false);
+ wp->SetEnabled(false, notify);
return error;
}
@@ -2400,7 +2373,7 @@
// Pass down an appropriate z/Z packet...
if (m_gdb_comm.SendGDBStoppointTypePacket(type, false, addr, wp->GetByteSize()) == 0)
{
- wp->SetEnabled(false);
+ wp->SetEnabled(false, notify);
return error;
}
else
@@ -2580,7 +2553,7 @@
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
if (error.Fail() || log)
- error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%llu, path='%s'", m_debugserver_pid, debugserver_path);
+ error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%" PRIu64 ", path='%s'", m_debugserver_pid, debugserver_path);
}
else
{
@@ -2625,7 +2598,7 @@
TargetSP target_sp (Debugger::FindTargetWithProcess(process));
if (log)
- log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%llu, signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
+ log->Printf ("ProcessGDBRemote::MonitorDebugserverProcess (baton=%p, pid=%" PRIu64 ", signo=%i (0x%x), exit_status=%i)", callback_baton, debugserver_pid, signo, signo, exit_status);
if (target_sp)
{
@@ -2786,7 +2759,7 @@
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, arg, process->GetID());
Listener listener ("ProcessGDBRemote::AsyncThread");
EventSP event_sp;
@@ -2801,14 +2774,14 @@
while (!done)
{
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...", __FUNCTION__, arg, process->GetID());
if (listener.WaitForEvent (NULL, event_sp))
{
const uint32_t event_type = event_sp->GetType();
if (event_sp->BroadcasterIs (&process->m_async_broadcaster))
{
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") Got an event of type: %d...", __FUNCTION__, arg, process->GetID(), event_type);
switch (event_type)
{
@@ -2821,7 +2794,7 @@
const char *continue_cstr = (const char *)continue_packet->GetBytes ();
const size_t continue_cstr_len = continue_packet->GetByteSize ();
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncContinue: %s", __FUNCTION__, arg, process->GetID(), continue_cstr);
if (::strstr (continue_cstr, "vAttach") == NULL)
process->SetPrivateState(eStateRunning);
@@ -2865,13 +2838,13 @@
case eBroadcastBitAsyncThreadShouldExit:
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...", __FUNCTION__, arg, process->GetID());
done = true;
break;
default:
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") got unknown event 0x%8.8x", __FUNCTION__, arg, process->GetID(), event_type);
done = true;
break;
}
@@ -2888,14 +2861,14 @@
else
{
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false", __FUNCTION__, arg, process->GetID());
done = true;
}
}
}
if (log)
- log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, arg, process->GetID());
+ log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, arg, process->GetID());
process->m_async_thread = LLDB_INVALID_HOST_THREAD;
return NULL;
@@ -2954,7 +2927,7 @@
Error error;
if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
{
- uint32_t data_offset = 0;
+ lldb::offset_t data_offset = 0;
if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
{
if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
@@ -3150,33 +3123,80 @@
ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
if (process)
{
- const StateType state = process->GetState();
-
- if (StateIsStoppedState (state, true))
+ for (size_t i=0; i<argc; ++ i)
{
- for (size_t i=0; i<argc; ++ i)
+ const char *packet_cstr = command.GetArgumentAtIndex(0);
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf (" packet: %s\n", packet_cstr);
+ std::string &response_str = response.GetStringRef();
+
+ if (strcmp(packet_cstr, "qGetProfileData") == 0)
{
- const char *packet_cstr = command.GetArgumentAtIndex(0);
- bool send_async = false;
- StringExtractorGDBRemote response;
- process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
- result.SetStatus (eReturnStatusSuccessFinishResult);
- Stream &output_strm = result.GetOutputStream();
- output_strm.Printf (" packet: %s\n", packet_cstr);
- const std::string &response_str = response.GetStringRef();
- if (response_str.empty())
- output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
- else
- output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
+ response_str = process->GetGDBRemote().HarmonizeThreadIdsForProfileData(process, response);
}
+
+ if (response_str.empty())
+ output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
}
- else
- {
- result.AppendErrorWithFormat ("process must be stopped in order to send GDB remote packets, state is %s", StateAsCString (state));
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ }
+ return true;
+ }
+};
+class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw
+{
+private:
+
+public:
+ CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter) :
+ CommandObjectRaw (interpreter,
+ "process plugin packet monitor",
+ "Send a qRcmd packet through the GDB remote protocol and print the response."
+ "The argument passed to this command will be hex encoded into a valid 'qRcmd' packet, sent and the response will be printed.",
+ NULL)
+ {
+ }
+
+ ~CommandObjectProcessGDBRemotePacketMonitor ()
+ {
+ }
+
+ bool
+ DoExecute (const char *command, CommandReturnObject &result)
+ {
+ if (command == NULL || command[0] == '\0')
+ {
+ result.AppendErrorWithFormat ("'%s' takes a command string argument", m_cmd_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ {
+ StreamString packet;
+ packet.PutCString("qRcmd,");
+ packet.PutBytesAsRawHex8(command, strlen(command));
+ const char *packet_cstr = packet.GetString().c_str();
+
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf (" packet: %s\n", packet_cstr);
+ const std::string &response_str = response.GetStringRef();
+
+ if (response_str.empty())
+ output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
}
return true;
}
@@ -3195,6 +3215,7 @@
{
LoadSubCommand ("history", CommandObjectSP (new CommandObjectProcessGDBRemotePacketHistory (interpreter)));
LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
+ LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
}
~CommandObjectProcessGDBRemotePacket ()
Index: aze/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h 2013-03-03 09:35:50.239457350 +0100
@@ -113,6 +113,9 @@
virtual void
DidAttach ();
+ virtual void
+ DoDidExec ();
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -190,19 +193,19 @@
// Process Breakpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
//----------------------------------------------------------------------
// Process Watchpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableWatchpoint (lldb_private::Watchpoint *wp);
+ EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
virtual lldb_private::Error
- DisableWatchpoint (lldb_private::Watchpoint *wp);
+ DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
virtual lldb_private::Error
GetWatchpointSupportInfo (uint32_t &num);
@@ -294,9 +297,6 @@
m_last_stop_packet = response;
}
- void
- CheckForKernel (lldb_private::Stream *strm);
-
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------
@@ -339,7 +339,6 @@
bool m_waiting_for_attach;
bool m_destroy_tried_resuming;
std::string m_dyld_plugin_name;
- lldb::addr_t m_kernel_load_addr;
lldb::CommandObjectSP m_command_sp;
bool
Index: aze/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp 2013-03-03 09:35:50.239457350 +0100
@@ -97,7 +97,7 @@
int signo = GetResumeSignal();
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
if (log)
- log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state));
+ log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", GetID(), StateAsCString(resume_state));
ProcessSP process_sp (GetProcess());
if (process_sp)
Index: aze/lldb/source/Plugins/Process/Linux/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/Linux/CMakeLists.txt 2013-03-03 09:35:50.239457350 +0100
@@ -0,0 +1,11 @@
+set(LLVM_NO_RTTI 1)
+
+include_directories(.)
+include_directories(../POSIX)
+
+add_lldb_library(lldbPluginProcessLinux
+ ProcessLinux.cpp
+ ProcessMonitor.cpp
+ LinuxSignals.cpp
+ )
+
Index: aze/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp 2013-03-03 09:35:50.239457350 +0100
@@ -97,22 +97,7 @@
bool
ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessLinux::%s() (pid = %i)", __FUNCTION__, GetID());
-
- // Update the process thread list with this new thread.
- // FIXME: We should be using tid, not pid.
- assert(m_monitor);
- ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
- if (!thread_sp) {
- thread_sp.reset(new POSIXThread(*this, GetID()));
- }
-
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessLinux::%s() updated pid = %i", __FUNCTION__, GetID());
- new_thread_list.AddThread(thread_sp);
-
+ new_thread_list = old_thread_list;
return new_thread_list.GetSize(false) > 0;
}
Index: aze/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp 2013-03-03 09:35:50.239457350 +0100
@@ -7,10 +7,13 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <errno.h>
#include <poll.h>
#include <string.h>
+#include <stdint.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
@@ -177,7 +180,7 @@
if (log)
ProcessPOSIXLog::IncNestLevel();
if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
- log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__,
+ log->Printf ("ProcessMonitor::%s(%" PRIu64 ", %d, %p, %p, %zd, _)", __FUNCTION__,
pid, word_size, (void*)vm_addr, buf, size);
assert(sizeof(data) >= word_size);
@@ -197,8 +200,6 @@
remainder = remainder > word_size ? word_size : remainder;
// Copy the data into our buffer
- if (log)
- memset(dst, 0, sizeof(dst));
for (unsigned i = 0; i < remainder; ++i)
dst[i] = ((data >> i*8) & 0xFF);
@@ -206,8 +207,14 @@
(log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
(log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
- log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
- (void*)vm_addr, *(unsigned long*)dst, (unsigned long)data);
+ {
+ uintptr_t print_dst = 0;
+ // Format bytes from data by moving into print_dst for log output
+ for (unsigned i = 0; i < remainder; ++i)
+ print_dst |= (((data >> i*8) & 0xFF) << i*8);
+ log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+ (void*)vm_addr, print_dst, (unsigned long)data);
+ }
vm_addr += word_size;
dst += word_size;
@@ -232,7 +239,7 @@
if (log)
ProcessPOSIXLog::IncNestLevel();
if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
- log->Printf ("ProcessMonitor::%s(%d, %d, %p, %p, %d, _)", __FUNCTION__,
+ log->Printf ("ProcessMonitor::%s(%" PRIu64 ", %d, %p, %p, %zd, _)", __FUNCTION__,
pid, word_size, (void*)vm_addr, buf, size);
for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
@@ -405,14 +412,17 @@
class ReadRegOperation : public Operation
{
public:
- ReadRegOperation(unsigned offset, RegisterValue &value, bool &result)
- : m_offset(offset), m_value(value), m_result(result)
+ ReadRegOperation(lldb::tid_t tid, unsigned offset,
+ RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset),
+ m_value(value), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
- unsigned m_offset;
+ lldb::tid_t m_tid;
+ uintptr_t m_offset;
RegisterValue &m_value;
bool &m_result;
};
@@ -420,12 +430,11 @@
void
ReadRegOperation::Execute(ProcessMonitor *monitor)
{
- lldb::pid_t pid = monitor->GetPID();
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
// Set errno to zero so that we can detect a failed peek.
errno = 0;
- lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, pid, (void*)m_offset, NULL);
+ lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL);
if (data == -1UL && errno)
m_result = false;
else
@@ -434,7 +443,7 @@
m_result = true;
}
if (log)
- log->Printf ("ProcessMonitor::%s() reg %s: 0x%x", __FUNCTION__,
+ log->Printf ("ProcessMonitor::%s() reg %s: 0x%" PRIx64, __FUNCTION__,
POSIXThread::GetRegisterNameFromOffset(m_offset), data);
}
@@ -444,14 +453,17 @@
class WriteRegOperation : public Operation
{
public:
- WriteRegOperation(unsigned offset, const RegisterValue &value, bool &result)
- : m_offset(offset), m_value(value), m_result(result)
+ WriteRegOperation(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value, bool &result)
+ : m_tid(tid), m_offset(offset),
+ m_value(value), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
- unsigned m_offset;
+ lldb::tid_t m_tid;
+ uintptr_t m_offset;
const RegisterValue &m_value;
bool &m_result;
};
@@ -460,21 +472,18 @@
WriteRegOperation::Execute(ProcessMonitor *monitor)
{
void* buf;
- lldb::pid_t pid = monitor->GetPID();
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
- if (sizeof(void*) == sizeof(uint64_t))
- buf = (void*) m_value.GetAsUInt64();
- else
- {
- assert(sizeof(void*) == sizeof(uint32_t));
- buf = (void*) m_value.GetAsUInt32();
- }
+#if __WORDSIZE == 32
+ buf = (void*) m_value.GetAsUInt32();
+#else
+ buf = (void*) m_value.GetAsUInt64();
+#endif
if (log)
log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__,
POSIXThread::GetRegisterNameFromOffset(m_offset), buf);
- if (PTRACE(PTRACE_POKEUSER, pid, (void*)m_offset, buf))
+ if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf))
m_result = false;
else
m_result = true;
@@ -486,13 +495,14 @@
class ReadGPROperation : public Operation
{
public:
- ReadGPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -500,7 +510,7 @@
void
ReadGPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETREGS, monitor->GetPID(), NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf) < 0)
m_result = false;
else
m_result = true;
@@ -512,13 +522,14 @@
class ReadFPROperation : public Operation
{
public:
- ReadFPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -526,7 +537,7 @@
void
ReadFPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETFPREGS, monitor->GetPID(), NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf) < 0)
m_result = false;
else
m_result = true;
@@ -538,13 +549,14 @@
class WriteGPROperation : public Operation
{
public:
- WriteGPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -552,7 +564,7 @@
void
WriteGPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_SETREGS, monitor->GetPID(), NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf) < 0)
m_result = false;
else
m_result = true;
@@ -564,13 +576,14 @@
class WriteFPROperation : public Operation
{
public:
- WriteFPROperation(void *buf, bool &result)
- : m_buf(buf), m_result(result)
+ WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
+ : m_tid(tid), m_buf(buf), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
private:
+ lldb::tid_t m_tid;
void *m_buf;
bool &m_result;
};
@@ -578,7 +591,7 @@
void
WriteFPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_SETFPREGS, monitor->GetPID(), NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf) < 0)
m_result = false;
else
m_result = true;
@@ -604,7 +617,7 @@
void
ResumeOperation::Execute(ProcessMonitor *monitor)
{
- int data = 0;
+ intptr_t data = 0;
if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
data = m_signo;
@@ -635,7 +648,7 @@
void
SingleStepOperation::Execute(ProcessMonitor *monitor)
{
- int data = 0;
+ intptr_t data = 0;
if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
data = m_signo;
@@ -652,8 +665,8 @@
class SiginfoOperation : public Operation
{
public:
- SiginfoOperation(lldb::tid_t tid, void *info, bool &result)
- : m_tid(tid), m_info(info), m_result(result) { }
+ SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
+ : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }
void Execute(ProcessMonitor *monitor);
@@ -661,13 +674,16 @@
lldb::tid_t m_tid;
void *m_info;
bool &m_result;
+ int &m_err;
};
void
SiginfoOperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info))
+ if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info)) {
m_result = false;
+ m_err = errno;
+ }
else
m_result = true;
}
@@ -764,14 +780,16 @@
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path)
+ const char *stderr_path,
+ const char *working_dir)
: OperationArgs(monitor),
m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
- m_stderr_path(stderr_path) { }
+ m_stderr_path(stderr_path),
+ m_working_dir(working_dir) { }
ProcessMonitor::LaunchArgs::~LaunchArgs()
{ }
@@ -802,6 +820,7 @@
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error)
: m_process(static_cast<ProcessLinux *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
@@ -814,7 +833,7 @@
std::auto_ptr<LaunchArgs> args;
args.reset(new LaunchArgs(this, module, argv, envp,
- stdin_path, stdout_path, stderr_path));
+ stdin_path, stdout_path, stderr_path, working_dir));
// Server/client descriptors.
if (!EnableIPC())
@@ -960,11 +979,13 @@
const char *stdin_path = args->m_stdin_path;
const char *stdout_path = args->m_stdout_path;
const char *stderr_path = args->m_stderr_path;
+ const char *working_dir = args->m_working_dir;
lldb_utility::PseudoTerminal terminal;
const size_t err_len = 1024;
char err_str[err_len];
lldb::pid_t pid;
+ long ptrace_opts = 0;
lldb::ThreadSP inferior;
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
@@ -981,7 +1002,7 @@
goto FINISH;
}
- if ((pid = terminal.Fork(err_str, err_len)) < 0)
+ if ((pid = terminal.Fork(err_str, err_len)) == -1)
{
args->m_error.SetErrorToGenericError();
args->m_error.SetErrorString("Process fork failed.");
@@ -994,6 +1015,7 @@
eDupStdinFailed,
eDupStdoutFailed,
eDupStderrFailed,
+ eChdirFailed,
eExecFailed
};
@@ -1026,6 +1048,11 @@
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
exit(eDupStderrFailed);
+ // Change working directory
+ if (working_dir != NULL && working_dir[0])
+ if (0 != ::chdir(working_dir))
+ exit(eChdirFailed);
+
// Execute. We should never return.
execve(argv[0],
const_cast<char *const *>(argv),
@@ -1059,6 +1086,9 @@
case eDupStderrFailed:
args->m_error.SetErrorString("Child open stderr failed.");
break;
+ case eChdirFailed:
+ args->m_error.SetErrorString("Child failed to set working directory.");
+ break;
case eExecFailed:
args->m_error.SetErrorString("Child exec failed.");
break;
@@ -1073,7 +1103,12 @@
// Have the child raise an event on exit. This is used to keep the child in
// limbo until it is destroyed.
- if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)PTRACE_O_TRACEEXIT) < 0)
+ ptrace_opts |= PTRACE_O_TRACEEXIT;
+
+ // Have the tracer trace threads which spawn in the inferior process.
+ ptrace_opts |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE;
+
+ if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts) < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
@@ -1095,7 +1130,7 @@
// FIXME: by using pids instead of tids, we can only support one thread.
inferior.reset(new POSIXThread(process, pid));
if (log)
- log->Printf ("ProcessMonitor::%s() adding pid = %i", __FUNCTION__, pid);
+ log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
process.GetThreadList().AddThread(inferior);
// Let our process instance know the thread has stopped.
@@ -1180,7 +1215,7 @@
// Update the process thread list with the attached thread.
inferior.reset(new POSIXThread(process, pid));
if (log)
- log->Printf ("ProcessMonitor::%s() adding tid = %i", __FUNCTION__, pid);
+ log->Printf ("ProcessMonitor::%s() adding tid = %" PRIu64, __FUNCTION__, pid);
process.GetThreadList().AddThread(inferior);
// Let our process instance know the thread has stopped.
@@ -1203,9 +1238,22 @@
assert(process);
bool stop_monitoring;
siginfo_t info;
+ int ptrace_err;
- if (!monitor->GetSignalInfo(pid, &info))
- stop_monitoring = true; // pid is gone. Bail.
+ if (!monitor->GetSignalInfo(pid, &info, ptrace_err)) {
+ if (ptrace_err == EINVAL) {
+ // inferior process is in 'group-stop', so deliver SIGSTOP signal
+ if (!monitor->Resume(pid, SIGSTOP)) {
+ assert(0 && "SIGSTOP delivery failed while in 'group-stop' state");
+ }
+ stop_monitoring = false;
+ } else {
+ // ptrace(GETSIGINFO) failed (but not due to group-stop). Most likely,
+ // this means the child pid is gone (or not being debugged) therefore
+ // stop the monitor thread.
+ stop_monitoring = true;
+ }
+ }
else {
switch (info.si_signo)
{
@@ -1219,7 +1267,7 @@
}
process->SendMessage(message);
- stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
+ stop_monitoring = !process->IsAlive();
}
return stop_monitoring;
@@ -1240,6 +1288,17 @@
assert(false && "Unexpected SIGTRAP code!");
break;
+ case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+ case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
+ {
+ unsigned long tid = 0;
+ if (!monitor->GetEventMessage(pid, &tid))
+ tid = -1;
+ message = ProcessMessage::NewThread(pid, tid);
+ break;
+ }
+
case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
{
// The inferior process is about to exit. Maintain the process in a
@@ -1551,55 +1610,55 @@
}
bool
-ProcessMonitor::ReadRegisterValue(unsigned offset, unsigned size, RegisterValue &value)
+ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, unsigned size, RegisterValue &value)
{
bool result;
- ReadRegOperation op(offset, value, result);
+ ReadRegOperation op(tid, offset, value, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::WriteRegisterValue(unsigned offset, const RegisterValue &value)
+ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset, const RegisterValue &value)
{
bool result;
- WriteRegOperation op(offset, value, result);
+ WriteRegOperation op(tid, offset, value, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::ReadGPR(void *buf)
+ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
{
bool result;
- ReadGPROperation op(buf, result);
+ ReadGPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::ReadFPR(void *buf)
+ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
{
bool result;
- ReadFPROperation op(buf, result);
+ ReadFPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::WriteGPR(void *buf)
+ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
{
bool result;
- WriteGPROperation op(buf, result);
+ WriteGPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::WriteFPR(void *buf)
+ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf)
{
bool result;
- WriteFPROperation op(buf, result);
+ WriteFPROperation op(tid, buf, result);
DoOperation(&op);
return result;
}
@@ -1632,10 +1691,10 @@
}
bool
-ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo)
+ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err)
{
bool result;
- SiginfoOperation op(tid, siginfo, result);
+ SiginfoOperation op(tid, siginfo, result, ptrace_err);
DoOperation(&op);
return result;
}
@@ -1657,7 +1716,6 @@
DetachOperation op(error);
DoOperation(&op);
}
- StopMonitor();
return error;
}
@@ -1705,6 +1763,7 @@
Host::ThreadCancel(m_operation_thread, NULL);
Host::ThreadJoin(m_operation_thread, &result, NULL);
+ m_operation_thread = LLDB_INVALID_HOST_THREAD;
}
void
Index: aze/lldb/source/Plugins/Process/Linux/ProcessMonitor.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Linux/ProcessMonitor.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Linux/ProcessMonitor.h 2013-03-03 09:35:50.239457350 +0100
@@ -56,6 +56,7 @@
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error);
ProcessMonitor(ProcessPOSIX *process,
@@ -106,35 +107,37 @@
///
/// This method is provided for use by RegisterContextLinux derivatives.
bool
- ReadRegisterValue(unsigned offset, unsigned size, lldb_private::RegisterValue &value);
+ ReadRegisterValue(lldb::tid_t tid, unsigned offset,
+ unsigned size, lldb_private::RegisterValue &value);
/// Writes the given value to the register identified by the given
/// (architecture dependent) offset.
///
/// This method is provided for use by RegisterContextLinux derivatives.
bool
- WriteRegisterValue(unsigned offset, const lldb_private::RegisterValue &value);
+ WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const lldb_private::RegisterValue &value);
/// Reads all general purpose registers into the specified buffer.
bool
- ReadGPR(void *buf);
+ ReadGPR(lldb::tid_t tid, void *buf);
/// Reads all floating point registers into the specified buffer.
bool
- ReadFPR(void *buf);
+ ReadFPR(lldb::tid_t tid, void *buf);
/// Writes all general purpose registers into the specified buffer.
bool
- WriteGPR(void *buf);
+ WriteGPR(lldb::tid_t tid, void *buf);
/// Writes all floating point registers into the specified buffer.
bool
- WriteFPR(void *buf);
+ WriteFPR(lldb::tid_t tid, void *buf);
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
bool
- GetSignalInfo(lldb::tid_t tid, void *siginfo);
+ GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err);
/// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
/// corresponding to the given thread IDto the memory pointed to by @p
@@ -198,7 +201,8 @@
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path);
+ const char *stderr_path,
+ const char *working_dir);
~LaunchArgs();
@@ -208,6 +212,7 @@
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
+ const char *m_working_dir; // Working directory or NULL.
};
void
Index: aze/lldb/source/Plugins/Process/mach-core/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/mach-core/CMakeLists.txt 2013-03-03 09:35:50.239457350 +0100
@@ -0,0 +1,6 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginProcessMachCore
+ ProcessMachCore.cpp
+ ThreadMachCore.cpp
+ )
Index: aze/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp 2013-03-03 09:35:50.239457350 +0100
@@ -163,7 +163,7 @@
}
// TODO: swap header if needed...
- //printf("0x%16.16llx: magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
+ //printf("0x%16.16" PRIx64 ": magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
if (header.magic == llvm::MachO::HeaderMagic32 ||
header.magic == llvm::MachO::HeaderMagic64)
{
@@ -175,14 +175,14 @@
switch (header.filetype)
{
case llvm::MachO::HeaderFileTypeDynamicLinkEditor:
- //printf("0x%16.16llx: file_type = MH_DYLINKER\n", vaddr);
+ //printf("0x%16.16" PRIx64 ": file_type = MH_DYLINKER\n", vaddr);
// Address of dyld "struct mach_header" in the core file
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
m_dyld_addr = addr;
return true;
case llvm::MachO::HeaderFileTypeExecutable:
- //printf("0x%16.16llx: file_type = MH_EXECUTE\n", vaddr);
+ //printf("0x%16.16" PRIx64 ": file_type = MH_EXECUTE\n", vaddr);
// Check MH_EXECUTABLE file types to see if the dynamic link object flag
// is NOT set. If it isn't, then we have a mach_kernel.
if ((header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
@@ -256,7 +256,7 @@
ranges_are_sorted = false;
vm_addr = section->GetFileAddress();
VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
-// printf ("LC_SEGMENT[%u] arange=[0x%16.16llx - 0x%16.16llx), frange=[0x%8.8x - 0x%8.8x)\n",
+// printf ("LC_SEGMENT[%u] arange=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), frange=[0x%8.8x - 0x%8.8x)\n",
// i,
// range_entry.GetRangeBase(),
// range_entry.GetRangeEnd(),
@@ -301,24 +301,12 @@
if (m_dyld_addr == LLDB_INVALID_ADDRESS)
{
- // Check the magic kernel address for the mach image header address in case
- // it is there.
- if (arch.GetAddressByteSize() == 8)
+ addr_t kernel_load_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);
+ if (kernel_load_address != LLDB_INVALID_ADDRESS)
{
- Error header_addr_error;
- addr_t header_addr = ReadPointerFromMemory (0xffffff8000002010ull, header_addr_error);
- if (header_addr != LLDB_INVALID_ADDRESS)
- GetDynamicLoaderAddress (header_addr);
- }
- else
- {
- Error header_addr_error;
- addr_t header_addr = ReadPointerFromMemory (0xffff0110, header_addr_error);
- if (header_addr != LLDB_INVALID_ADDRESS)
- GetDynamicLoaderAddress (header_addr);
+ GetDynamicLoaderAddress (kernel_load_address);
}
}
-
return error;
}
@@ -413,7 +401,7 @@
}
else
{
- error.SetErrorStringWithFormat ("core file does not contain 0x%llx", addr);
+ error.SetErrorStringWithFormat ("core file does not contain 0x%" PRIx64, addr);
}
}
return 0;
Index: aze/lldb/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/MacOSX-Kernel/CMakeLists.txt 2013-03-03 09:35:50.239457350 +0100
@@ -0,0 +1,11 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginProcessMacOSXKernel
+ CommunicationKDP.cpp
+ ProcessKDP.cpp
+ ProcessKDPLog.cpp
+ RegisterContextKDP_arm.cpp
+ RegisterContextKDP_i386.cpp
+ RegisterContextKDP_x86_64.cpp
+ ThreadKDP.cpp
+ )
Index: aze/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp 2013-03-03 09:35:50.239457350 +0100
@@ -97,8 +97,7 @@
bool
CommunicationKDP::SendRequestAndGetReply (const CommandType command,
- const uint8_t request_sequence_id,
- const PacketStreamType &request_packet,
+ const PacketStreamType &request_packet,
DataExtractor &reply_packet)
{
if (IsRunning())
@@ -118,20 +117,26 @@
// NOTE: this only works for packets that are in native endian byte order
assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
#endif
- if (SendRequestPacketNoLock(request_packet))
+ lldb::offset_t offset = 1;
+ const uint32_t num_retries = 3;
+ for (uint32_t i=0; i<num_retries; ++i)
{
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
+ if (SendRequestPacketNoLock(request_packet))
{
- uint32_t offset = 0;
- const uint8_t reply_command = reply_packet.GetU8 (&offset);
- const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
- if ((reply_command & eCommandTypeMask) == command)
+ const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
{
- if (request_sequence_id == reply_sequence_id)
+ offset = 0;
+ const uint8_t reply_command = reply_packet.GetU8 (&offset);
+ const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
+ if ((reply_command & eCommandTypeMask) == command)
{
- if (command == KDP_RESUMECPUS)
- m_is_running.SetValue(true, eBroadcastAlways);
- return true;
+ if (request_sequence_id == reply_sequence_id)
+ {
+ if (command == KDP_RESUMECPUS)
+ m_is_running.SetValue(true, eBroadcastAlways);
+ return true;
+ }
}
}
}
@@ -166,7 +171,7 @@
return true;
if (log)
- log->Printf ("error: failed to send packet entire packet %llu of %llu bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size);
+ log->Printf ("error: failed to send packet entire packet %" PRIu64 " of %" PRIu64 " bytes sent", (uint64_t)bytes_written, (uint64_t)packet_size);
}
return false;
}
@@ -210,7 +215,7 @@
size_t bytes_read = Read (buffer, sizeof(buffer), timeout_usec, status, &error);
if (log)
- log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %llu",
+ log->Printf ("%s: Read (buffer, (sizeof(buffer), timeout_usec = 0x%x, status = %s, error = %s) => bytes_read = %" PRIu64,
__PRETTY_FUNCTION__,
timeout_usec,
Communication::ConnectionStatusAsCString (status),
@@ -273,7 +278,7 @@
if (bytes_available >= 8)
{
packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint8_t reply_command = packet.GetU8(&offset);
switch (reply_command)
{
@@ -315,6 +320,13 @@
case ePacketTypeReply | KDP_BREAKPOINT_SET64:
case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
case ePacketTypeReply | KDP_KERNELVERSION:
+ case ePacketTypeReply | KDP_READPHYSMEM64:
+ case ePacketTypeReply | KDP_WRITEPHYSMEM64:
+ case ePacketTypeReply | KDP_READIOPORT:
+ case ePacketTypeReply | KDP_WRITEIOPORT:
+ case ePacketTypeReply | KDP_READMSR64:
+ case ePacketTypeReply | KDP_WRITEMSR64:
+ case ePacketTypeReply | KDP_DUMPINFO:
{
offset = 2;
const uint16_t length = packet.GetU16 (&offset);
@@ -365,7 +377,6 @@
const CommandType command = KDP_CONNECT;
// Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
// Always send connect ports as little endian
request_packet.SetByteOrder (eByteOrderLittle);
@@ -374,7 +385,7 @@
request_packet.SetByteOrder (m_byte_order);
request_packet.PutCString (greeting);
DataExtractor reply_packet;
- return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet);
+ return SendRequestAndGetReply (command, request_packet, reply_packet);
}
void
@@ -395,18 +406,17 @@
const CommandType command = KDP_REATTACH;
// Length is 8 bytes for the header plus 2 bytes for the reply UDP port
const uint32_t command_length = 8 + 2;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
// Always send connect ports as little endian
request_packet.SetByteOrder (eByteOrderLittle);
request_packet.PutHex16(reply_port);
request_packet.SetByteOrder (m_byte_order);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
// Reset the sequence ID to zero for reattach
ClearKDPSettings ();
- uint32_t offset = 4;
+ lldb::offset_t offset = 4;
m_session_key = reply_packet.GetU32 (&offset);
return true;
}
@@ -435,12 +445,11 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_VERSION;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
m_kdp_version_version = reply_packet.GetU32 (&offset);
m_kdp_version_feature = reply_packet.GetU32 (&offset);
return true;
@@ -463,10 +472,9 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_IMAGEPATH;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
const char *path = reply_packet.PeekCStr(8);
if (path && path[0])
@@ -563,12 +571,11 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_HOSTINFO;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset);
m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset);
m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset);
@@ -599,10 +606,9 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_KERNELVERSION;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
const char *kernel_version_cstr = reply_packet.PeekCStr(8);
if (kernel_version_cstr && kernel_version_cstr[0])
@@ -618,10 +624,9 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_DISCONNECT;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
// Are we supposed to get a reply for disconnect?
}
@@ -641,14 +646,13 @@
const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
// Size is header + address size + uint32_t length
const uint32_t command_length = 8 + command_addr_byte_size + 4;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutMaxHex64 (addr, command_addr_byte_size);
request_packet.PutHex32 (dst_len);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
uint32_t src_len = reply_packet.GetByteSize() - 12;
@@ -687,16 +691,15 @@
const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
// Size is header + address size + uint32_t length
const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutMaxHex64 (addr, command_addr_byte_size);
request_packet.PutHex32 (src_len);
request_packet.PutRawBytes(src, src_len);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
if (kdp_error)
error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
@@ -724,15 +727,14 @@
// Size is header + address size + uint32_t length
const uint32_t command_length = 8 + src_len;
const CommandType command = (CommandType)command_byte;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutRawBytes(src, src_len);
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error)
+ if (kdp_error && (command_byte != KDP_DUMPINFO))
error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error);
else
{
@@ -778,6 +780,13 @@
case KDP_BREAKPOINT_SET64: return "KDP_BREAKPOINT64_SET";
case KDP_BREAKPOINT_REMOVE64: return "KDP_BREAKPOINT64_REMOVE";
case KDP_KERNELVERSION: return "KDP_KERNELVERSION";
+ case KDP_READPHYSMEM64: return "KDP_READPHYSMEM64";
+ case KDP_WRITEPHYSMEM64: return "KDP_WRITEPHYSMEM64";
+ case KDP_READIOPORT: return "KDP_READIOPORT";
+ case KDP_WRITEIOPORT: return "KDP_WRITEIOPORT";
+ case KDP_READMSR64: return "KDP_READMSR64";
+ case KDP_WRITEMSR64: return "KDP_WRITEMSR64";
+ case KDP_DUMPINFO: return "KDP_DUMPINFO";
}
return NULL;
}
@@ -799,7 +808,7 @@
}
else
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
const uint8_t first_packet_byte = packet.GetU8 (&offset);
const uint8_t sequence_id = packet.GetU8 (&offset);
const uint16_t length = packet.GetU16 (&offset);
@@ -833,6 +842,8 @@
case KDP_BREAKPOINT_REMOVE64:
case KDP_WRITEREGS:
case KDP_LOAD:
+ case KDP_WRITEIOPORT:
+ case KDP_WRITEMSR64:
{
const uint32_t error = packet.GetU32 (&offset);
s.Printf(" (error=0x%8.8x)", error);
@@ -876,13 +887,14 @@
const addr_t region_addr = packet.GetPointer (&offset);
const uint32_t region_size = packet.GetU32 (&offset);
const uint32_t region_prot = packet.GetU32 (&offset);
- s.Printf("\n\tregion[%llu] = { range = [0x%16.16llx - 0x%16.16llx), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
+ s.Printf("\n\tregion[%" PRIu64 "] = { range = [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), size = 0x%8.8x, prot = %s }", region_addr, region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
}
}
break;
case KDP_READMEM:
case KDP_READMEM64:
+ case KDP_READPHYSMEM64:
{
const uint32_t error = packet.GetU32 (&offset);
const uint32_t count = packet.GetByteSize() - offset;
@@ -935,6 +947,41 @@
s.Printf(" (path = \"%s\")", path);
}
break;
+
+ case KDP_READIOPORT:
+ case KDP_READMSR64:
+ {
+ const uint32_t error = packet.GetU32 (&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x io:\n", error);
+ if (count > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ }
+ break;
+ case KDP_DUMPINFO:
+ {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ }
+ break;
+
default:
s.Printf(" (add support for dumping this packet reply!!!");
break;
@@ -997,7 +1044,17 @@
{
const uint64_t addr = packet.GetU64 (&offset);
const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u)", addr, size);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u)", addr, size);
+ m_last_read_memory_addr = addr;
+ }
+ break;
+
+ case KDP_READPHYSMEM64:
+ {
+ const uint64_t addr = packet.GetU64 (&offset);
+ const uint32_t size = packet.GetU32 (&offset);
+ const uint32_t lcpu = packet.GetU16 (&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu);
m_last_read_memory_addr = addr;
}
break;
@@ -1006,7 +1063,18 @@
{
const uint64_t addr = packet.GetU64 (&offset);
const uint32_t size = packet.GetU32 (&offset);
- s.Printf(" (addr = 0x%16.16llx, size = %u, bytes = \n", addr, size);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ", size = %u, bytes = \n", addr, size);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
+ }
+ break;
+
+ case KDP_WRITEPHYSMEM64:
+ {
+ const uint64_t addr = packet.GetU64 (&offset);
+ const uint32_t size = packet.GetU32 (&offset);
+ const uint32_t lcpu = packet.GetU16 (&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu);
if (size > 0)
DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
}
@@ -1051,7 +1119,7 @@
case KDP_BREAKPOINT_REMOVE64:
{
const uint64_t addr = packet.GetU64 (&offset);
- s.Printf(" (addr = 0x%16.16llx)", addr);
+ s.Printf(" (addr = 0x%16.16" PRIx64 ")", addr);
}
break;
@@ -1110,7 +1178,78 @@
s.Printf(" (reply_port = %u)", reply_port);
}
break;
- }
+
+ case KDP_READMSR64:
+ {
+ const uint32_t address = packet.GetU32 (&offset);
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
+ }
+ break;
+
+ case KDP_WRITEMSR64:
+ {
+ const uint32_t address = packet.GetU32 (&offset);
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ const uint32_t nbytes = packet.GetByteSize() - offset;
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes);
+ if (nbytes > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ }
+ break;
+
+ case KDP_READIOPORT:
+ {
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ const uint16_t address = packet.GetU16 (&offset);
+ const uint16_t nbytes = packet.GetU16 (&offset);
+ s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes);
+ }
+ break;
+
+ case KDP_WRITEIOPORT:
+ {
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ const uint16_t address = packet.GetU16 (&offset);
+ const uint16_t nbytes = packet.GetU16 (&offset);
+ s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes);
+ if (nbytes > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ }
+ break;
+
+ case KDP_DUMPINFO:
+ {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ }
+ break;
+
+ }
}
}
else
@@ -1145,14 +1284,13 @@
const CommandType command = KDP_READREGS;
// Size is header + 4 byte cpu and 4 byte flavor
const uint32_t command_length = 8 + 4 + 4;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex32 (cpu);
request_packet.PutHex32 (flavor);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
uint32_t src_len = reply_packet.GetByteSize() - 12;
@@ -1192,15 +1330,14 @@
const CommandType command = KDP_WRITEREGS;
// Size is header + 4 byte cpu and 4 byte flavor
const uint32_t command_length = 8 + 4 + 4 + src_len;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex32 (cpu);
request_packet.PutHex32 (flavor);
request_packet.Write(src, src_len);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
if (kdp_error == 0)
return src_len;
@@ -1220,12 +1357,11 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_RESUMECPUS;
const uint32_t command_length = 12;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex32(GetCPUMask());
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
return true;
return false;
}
@@ -1240,14 +1376,13 @@
(use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
const uint32_t command_length = 8 + command_addr_byte_size;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutMaxHex64 (addr, command_addr_byte_size);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
if (kdp_error == 0)
return true;
@@ -1261,10 +1396,9 @@
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_SUSPEND;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
return true;
return false;
}
Index: aze/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h 2013-03-03 09:35:50.239457350 +0100
@@ -62,7 +62,14 @@
KDP_WRITEMEM64,
KDP_BREAKPOINT_SET64,
KDP_BREAKPOINT_REMOVE64,
- KDP_KERNELVERSION
+ KDP_KERNELVERSION,
+ KDP_READPHYSMEM64,
+ KDP_WRITEPHYSMEM64,
+ KDP_READIOPORT,
+ KDP_WRITEIOPORT,
+ KDP_READMSR64,
+ KDP_WRITEMSR64,
+ KDP_DUMPINFO
} CommandType;
enum
@@ -315,7 +322,6 @@
bool
SendRequestAndGetReply (const CommandType command,
- const uint8_t request_sequence_id,
const PacketStreamType &request_packet,
lldb_private::DataExtractor &reply_packet);
//------------------------------------------------------------------
Index: aze/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -114,7 +114,6 @@
m_comm("lldb.process.kdp-remote.communication"),
m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
m_async_thread (LLDB_INVALID_HOST_THREAD),
- m_destroy_in_process (false),
m_dyld_plugin_name (),
m_kernel_load_addr (LLDB_INVALID_ADDRESS),
m_command_sp()
@@ -448,7 +447,7 @@
// locker will keep a mutex locked until it goes out of scope
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
- log->Printf ("ProcessKDP::%s (pid = %llu)", __FUNCTION__, GetID());
+ log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
// Even though there is a CPU mask, it doesn't mean to can see each CPU
// indivudually, there is really only one. Lets call this thread 1.
@@ -532,14 +531,6 @@
}
Error
-ProcessKDP::WillDestroy ()
-{
- Error error;
- m_destroy_in_process = true;
- return error;
-}
-
-Error
ProcessKDP::DoDestroy ()
{
// For KDP there really is no difference between destroy and detach
@@ -593,7 +584,7 @@
}
Error
-ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
+ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site)
{
if (m_comm.LocalBreakpointsAreSupported ())
{
@@ -616,7 +607,7 @@
}
Error
-ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
+ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site)
{
if (m_comm.LocalBreakpointsAreSupported ())
{
@@ -650,7 +641,7 @@
}
Error
-ProcessKDP::EnableWatchpoint (Watchpoint *wp)
+ProcessKDP::EnableWatchpoint (Watchpoint *wp, bool notify)
{
Error error;
error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
@@ -658,7 +649,7 @@
}
Error
-ProcessKDP::DisableWatchpoint (Watchpoint *wp)
+ProcessKDP::DisableWatchpoint (Watchpoint *wp, bool notify)
{
Error error;
error.SetErrorString ("watchpoints are not suppported in kdp remote debugging");
@@ -744,7 +735,7 @@
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
if (log)
- log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %llu) thread starting...", arg, pid);
+ log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
Listener listener ("ProcessKDP::AsyncThread");
EventSP event_sp;
@@ -758,13 +749,13 @@
while (!done)
{
if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %llu) listener.WaitForEvent (NULL, event_sp)...",
+ log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp)...",
pid);
if (listener.WaitForEvent (NULL, event_sp))
{
uint32_t event_type = event_sp->GetType();
if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %llu) Got an event of type: %d...",
+ log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") Got an event of type: %d...",
pid,
event_type);
@@ -806,7 +797,7 @@
case eBroadcastBitAsyncThreadShouldExit:
if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %llu) got eBroadcastBitAsyncThreadShouldExit...",
+ log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got eBroadcastBitAsyncThreadShouldExit...",
pid);
done = true;
is_running = false;
@@ -814,7 +805,7 @@
default:
if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %llu) got unknown event 0x%8.8x",
+ log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") got unknown event 0x%8.8x",
pid,
event_type);
done = true;
@@ -826,7 +817,7 @@
else
{
if (log)
- log->Printf ("ProcessKDP::AsyncThread (pid = %llu) listener.WaitForEvent (NULL, event_sp) => false",
+ log->Printf ("ProcessKDP::AsyncThread (pid = %" PRIu64 ") listener.WaitForEvent (NULL, event_sp) => false",
pid);
done = true;
}
@@ -834,7 +825,7 @@
}
if (log)
- log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %llu) thread exiting...",
+ log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread exiting...",
arg,
pid);
@@ -965,7 +956,7 @@
}
else
{
- result.AppendErrorWithFormat ("invalid command byte 0x%llx, valid values are 1 - 255", command_byte);
+ result.AppendErrorWithFormat ("invalid command byte 0x%" PRIx64 ", valid values are 1 - 255", command_byte);
result.SetStatus (eReturnStatusFailed);
}
}
Index: aze/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h 2013-03-03 09:35:50.243457351 +0100
@@ -141,9 +141,6 @@
DoSignal (int signal);
virtual lldb_private::Error
- WillDestroy ();
-
- virtual lldb_private::Error
DoDestroy ();
virtual void
@@ -174,19 +171,19 @@
// Process Breakpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
//----------------------------------------------------------------------
// Process Watchpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableWatchpoint (lldb_private::Watchpoint *wp);
+ EnableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
virtual lldb_private::Error
- DisableWatchpoint (lldb_private::Watchpoint *wp);
+ DisableWatchpoint (lldb_private::Watchpoint *wp, bool notify = true);
CommunicationKDP &
GetCommunication()
@@ -257,7 +254,6 @@
CommunicationKDP m_comm;
lldb_private::Broadcaster m_async_broadcaster;
lldb::thread_t m_async_thread;
- bool m_destroy_in_process;
std::string m_dyld_plugin_name;
lldb::addr_t m_kernel_load_addr;
lldb::CommandObjectSP m_command_sp;
Index: aze/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -78,7 +78,7 @@
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
- log->Printf ("Resuming thread: %4.4llx with state: %s.", GetID(), StateAsCString(resume_state));
+ log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", GetID(), StateAsCString(resume_state));
return true;
}
@@ -194,7 +194,7 @@
void
ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint8_t reply_command = exc_reply_packet.GetU8(&offset);
if (reply_command == CommunicationKDP::KDP_EXCEPTION)
{
Index: aze/lldb/source/Plugins/Process/POSIX/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/POSIX/CMakeLists.txt 2013-03-03 09:35:50.243457351 +0100
@@ -0,0 +1,15 @@
+set(LLVM_NO_RTTI 1)
+
+include_directories(.)
+include_directories(../Linux)
+include_directories(../Utility)
+
+add_lldb_library(lldbPluginProcessPOSIX
+ POSIXStopInfo.cpp
+ POSIXThread.cpp
+ ProcessMessage.cpp
+ ProcessPOSIX.cpp
+ ProcessPOSIXLog.cpp
+ RegisterContext_i386.cpp
+ RegisterContext_x86_64.cpp
+ )
Index: aze/lldb/source/Plugins/Process/POSIX/Makefile
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/Makefile 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/Makefile 2013-03-03 09:35:50.243457351 +0100
@@ -18,6 +18,10 @@
ifeq ($(HOST_OS),Linux)
CPPFLAGS += -I$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/source/Plugins/Process/Linux
+
+# Disable warning for now as offsetof is used with an index into a structure member array
+# in defining register info tables.
+CPPFLAGS += -Wno-extended-offsetof
endif
ifeq ($(HOST_OS),FreeBSD)
Index: aze/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -21,7 +21,7 @@
lldb::StopReason
POSIXLimboStopInfo::GetStopReason() const
{
- return lldb::eStopReasonTrace;
+ return lldb::eStopReasonThreadExiting;
}
const char *
@@ -33,13 +33,13 @@
bool
POSIXLimboStopInfo::ShouldStop(Event *event_ptr)
{
- return true;
+ return false;
}
bool
POSIXLimboStopInfo::ShouldNotify(Event *event_ptr)
{
- return true;
+ return false;
}
//===----------------------------------------------------------------------===//
@@ -58,3 +58,32 @@
{
return ProcessMessage::GetCrashReasonString(m_crash_reason);
}
+
+//===----------------------------------------------------------------------===//
+// POSIXNewThreadStopInfo
+
+POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() { }
+
+lldb::StopReason
+POSIXNewThreadStopInfo::GetStopReason() const
+{
+ return lldb::eStopReasonNone;
+}
+
+const char *
+POSIXNewThreadStopInfo::GetDescription()
+{
+ return "thread spawned";
+}
+
+bool
+POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr)
+{
+ return false;
+}
+
+bool
+POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr)
+{
+ return false;
+}
Index: aze/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/POSIXStopInfo.h 2013-03-03 09:35:50.243457351 +0100
@@ -89,4 +89,32 @@
ProcessMessage::CrashReason m_crash_reason;
};
+//===----------------------------------------------------------------------===//
+/// @class POSIXNewThreadStopInfo
+/// @brief Represents the stop state of process when a new thread is spawned.
+///
+
+class POSIXNewThreadStopInfo
+ : public POSIXStopInfo
+{
+public:
+ POSIXNewThreadStopInfo (POSIXThread &thread)
+ : POSIXStopInfo (thread, 0)
+ { }
+
+ ~POSIXNewThreadStopInfo();
+
+ lldb::StopReason
+ GetStopReason() const;
+
+ const char *
+ GetDescription();
+
+ bool
+ ShouldStop(lldb_private::Event *event_ptr);
+
+ bool
+ ShouldNotify(lldb_private::Event *event_ptr);
+};
+
#endif
Index: aze/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <errno.h>
@@ -39,7 +41,7 @@
{
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("POSIXThread::%s (tid = %i)", __FUNCTION__, tid);
+ log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
}
POSIXThread::~POSIXThread()
@@ -183,6 +185,10 @@
SetState(resume_state);
status = monitor.SingleStep(GetID(), GetResumeSignal());
break;
+ case lldb::eStateStopped:
+ case lldb::eStateSuspended:
+ status = true;
+ break;
}
return status;
@@ -224,6 +230,10 @@
case ProcessMessage::eCrashMessage:
CrashNotify(message);
break;
+
+ case ProcessMessage::eNewThreadMessage:
+ ThreadNotify(message);
+ break;
}
}
@@ -242,7 +252,7 @@
assert(GetRegisterContext());
lldb::addr_t pc = GetRegisterContext()->GetPC();
if (log)
- log->Printf ("POSIXThread::%s () PC=0x%8.8llx", __FUNCTION__, pc);
+ log->Printf ("POSIXThread::%s () PC=0x%8.8" PRIx64, __FUNCTION__, pc);
lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
assert(bp_site);
lldb::break_id_t bp_id = bp_site->GetID();
@@ -279,8 +289,7 @@
{
int signo = message.GetSignal();
- // Just treat debugger generated signal events like breakpoints for now.
- m_stop_info = StopInfo::CreateStopReasonToTrace(*this);
+ m_stop_info = StopInfo::CreateStopReasonWithSignal(*this, signo);
SetResumeSignal(signo);
}
@@ -300,6 +309,12 @@
SetResumeSignal(signo);
}
+void
+POSIXThread::ThreadNotify(const ProcessMessage &message)
+{
+ m_stop_info = lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this));
+}
+
unsigned
POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
{
Index: aze/lldb/source/Plugins/Process/POSIX/POSIXThread.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/POSIXThread.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/POSIXThread.h 2013-03-03 09:35:50.243457351 +0100
@@ -98,6 +98,7 @@
void SignalNotify(const ProcessMessage &message);
void SignalDeliveredNotify(const ProcessMessage &message);
void CrashNotify(const ProcessMessage &message);
+ void ThreadNotify(const ProcessMessage &message);
lldb_private::Unwind *
GetUnwinder();
Index: aze/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -102,10 +102,6 @@
switch (reason)
{
- default:
- assert(false && "invalid CrashReason");
- break;
-
case eInvalidCrashReason:
str = "eInvalidCrashReason";
break;
@@ -204,10 +200,6 @@
switch (kind)
{
- default:
- assert(false && "invalid Kind");
- break;
-
case eInvalidMessage:
str = "eInvalidMessage";
break;
@@ -232,6 +224,9 @@
case eCrashMessage:
str = "eCrashMessage";
break;
+ case eNewThreadMessage:
+ str = "eNewThreadMessage";
+ break;
}
#endif
Index: aze/lldb/source/Plugins/Process/POSIX/ProcessMessage.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/ProcessMessage.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/ProcessMessage.h 2013-03-03 09:35:50.243457351 +0100
@@ -29,7 +29,8 @@
eSignalDeliveredMessage,
eTraceMessage,
eBreakpointMessage,
- eCrashMessage
+ eCrashMessage,
+ eNewThreadMessage
};
enum CrashReason
@@ -111,6 +112,11 @@
return message;
}
+ /// Indicates that the thread @p tid was spawned.
+ static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
+ return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
+ }
+
int GetExitStatus() const {
assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
return m_status;
@@ -137,6 +143,11 @@
return m_addr;
}
+ lldb::tid_t GetChildTID() const {
+ assert(GetKind() == eNewThreadMessage);
+ return m_child_tid;
+ }
+
static const char *
GetCrashReasonString(CrashReason reason);
@@ -159,13 +170,23 @@
m_kind(kind),
m_crash_reason(eInvalidCrashReason),
m_status(status),
- m_addr(addr) { }
+ m_addr(addr),
+ m_child_tid(0) { }
+
+ ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
+ : m_tid(tid),
+ m_kind(kind),
+ m_crash_reason(eInvalidCrashReason),
+ m_status(0),
+ m_addr(0),
+ m_child_tid(child_tid) { }
lldb::tid_t m_tid;
Kind m_kind : 8;
CrashReason m_crash_reason : 8;
int m_status;
lldb::addr_t m_addr;
+ lldb::tid_t m_child_tid;
};
#endif // #ifndef liblldb_ProcessMessage_H_
Index: aze/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <errno.h>
@@ -15,6 +17,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
@@ -106,7 +109,7 @@
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessPOSIX::%s(pid = %i)", __FUNCTION__, GetID());
+ log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
m_monitor = new ProcessMonitor(this, pid, error);
@@ -160,6 +163,16 @@
Error error;
assert(m_monitor == NULL);
+ const char* working_dir = launch_info.GetWorkingDirectory();
+ if (working_dir) {
+ FileSpec WorkingDir(working_dir, true);
+ if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
+ {
+ error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
+ return error;
+ }
+ }
+
SetPrivateState(eStateLaunching);
const lldb_private::ProcessLaunchInfo::FileAction *file_action;
@@ -168,7 +181,7 @@
const char *stdin_path = NULL;
const char *stdout_path = NULL;
const char *stderr_path = NULL;
-
+
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
stdin_path = GetFilePath(file_action, stdin_path);
@@ -185,6 +198,7 @@
stdin_path,
stdout_path,
stderr_path,
+ working_dir,
error);
m_module = module;
@@ -320,10 +334,6 @@
switch (message.GetKind())
{
- default:
- assert(false && "Unexpected process message!");
- break;
-
case ProcessMessage::eInvalidMessage:
return;
@@ -351,11 +361,25 @@
case ProcessMessage::eSignalMessage:
case ProcessMessage::eSignalDeliveredMessage:
+ {
+ lldb::tid_t tid = message.GetTID();
+ lldb::tid_t pid = GetID();
+ if (tid == pid) {
+ SetPrivateState(eStateStopped);
+ break;
+ } else {
+ // FIXME: Ignore any signals generated by children.
+ return;
+ }
+ }
+
+ case ProcessMessage::eCrashMessage:
+ // FIXME: Update stop reason as per bugzilla 14598
SetPrivateState(eStateStopped);
break;
- case ProcessMessage::eCrashMessage:
- SetPrivateState(eStateCrashed);
+ case ProcessMessage::eNewThreadMessage:
+ SetPrivateState(eStateStopped);
break;
}
@@ -380,10 +404,16 @@
// fixed when this code is fixed to handle multiple threads.
lldb::tid_t tid = message.GetTID();
if (log)
- log->Printf ("ProcessPOSIX::%s() pid = %i", __FUNCTION__, tid);
+ log->Printf ("ProcessPOSIX::%s() pid = %" PRIi64, __FUNCTION__, tid);
POSIXThread *thread = static_cast<POSIXThread*>(
GetThreadList().FindThreadByID(tid, false).get());
+ if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
+ ThreadSP thread_sp;
+ thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
+ m_thread_list.AddThread(thread_sp);
+ }
+
assert(thread);
thread->Notify(message);
@@ -448,11 +478,25 @@
InferiorCallMunmap(this, addr, pos->second))
m_addr_to_mmap_size.erase (pos);
else
- error.SetErrorStringWithFormat("unable to deallocate memory at 0x%llx", addr);
+ error.SetErrorStringWithFormat("unable to deallocate memory at 0x%" PRIx64, addr);
return error;
}
+addr_t
+ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
+{
+ addr_t function_addr = LLDB_INVALID_ADDRESS;
+ if (address == NULL) {
+ error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
+ } else if (!InferiorCall(this, address, function_addr)) {
+ function_addr = LLDB_INVALID_ADDRESS;
+ error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
+ address->CalculateSymbolContextSymbol()->GetName().AsCString());
+ }
+ return function_addr;
+}
+
size_t
ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
{
@@ -480,13 +524,13 @@
}
Error
-ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site)
+ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
{
return EnableSoftwareBreakpoint(bp_site);
}
Error
-ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site)
+ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
{
return DisableSoftwareBreakpoint(bp_site);
}
@@ -503,7 +547,7 @@
{
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessPOSIX::%s() (pid = %i)", __FUNCTION__, GetID());
+ log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
// Update the process thread list with this new thread.
// FIXME: We should be using tid, not pid.
@@ -514,7 +558,7 @@
}
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessPOSIX::%s() updated pid = %i", __FUNCTION__, GetID());
+ log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
new_thread_list.AddThread(thread_sp);
return new_thread_list.GetSize(false) > 0;
Index: aze/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/ProcessPOSIX.h 2013-03-03 09:35:50.243457351 +0100
@@ -96,14 +96,17 @@
virtual lldb_private::Error
DoDeallocateMemory(lldb::addr_t ptr);
+ virtual lldb::addr_t
+ ResolveIndirectFunction(const lldb_private::Address *address, lldb_private::Error &error);
+
virtual size_t
GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
virtual lldb_private::Error
- EnableBreakpoint(lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint(lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site);
virtual uint32_t
UpdateThreadListIfNeeded();
Index: aze/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -15,6 +15,7 @@
#include "ProcessPOSIXLog.h"
#include "ProcessMonitor.h"
#include "RegisterContext_i386.h"
+#include "RegisterContext_x86.h"
using namespace lldb_private;
using namespace lldb;
@@ -82,103 +83,6 @@
k_num_register_sets = 2
};
-enum
-{
- gcc_eax = 0,
- gcc_ecx,
- gcc_edx,
- gcc_ebx,
- gcc_ebp,
- gcc_esp,
- gcc_esi,
- gcc_edi,
- gcc_eip,
- gcc_eflags
-};
-
-enum
-{
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7
-};
-
-enum
-{
- gdb_eax = 0,
- gdb_ecx = 1,
- gdb_edx = 2,
- gdb_ebx = 3,
- gdb_esp = 4,
- gdb_ebp = 5,
- gdb_esi = 6,
- gdb_edi = 7,
- gdb_eip = 8,
- gdb_eflags = 9,
- gdb_cs = 10,
- gdb_ss = 11,
- gdb_ds = 12,
- gdb_es = 13,
- gdb_fs = 14,
- gdb_gs = 15,
- gdb_stmm0 = 16,
- gdb_stmm1 = 17,
- gdb_stmm2 = 18,
- gdb_stmm3 = 19,
- gdb_stmm4 = 20,
- gdb_stmm5 = 21,
- gdb_stmm6 = 22,
- gdb_stmm7 = 23,
- gdb_fcw = 24,
- gdb_fsw = 25,
- gdb_ftw = 26,
- gdb_fpu_cs = 27,
- gdb_ip = 28,
- gdb_fpu_ds = 29,
- gdb_dp = 30,
- gdb_fop = 31,
- gdb_xmm0 = 32,
- gdb_xmm1 = 33,
- gdb_xmm2 = 34,
- gdb_xmm3 = 35,
- gdb_xmm4 = 36,
- gdb_xmm5 = 37,
- gdb_xmm6 = 38,
- gdb_xmm7 = 39,
- gdb_mxcsr = 40,
- gdb_mm0 = 41,
- gdb_mm1 = 42,
- gdb_mm2 = 43,
- gdb_mm3 = 44,
- gdb_mm4 = 45,
- gdb_mm5 = 46,
- gdb_mm6 = 47,
- gdb_mm7 = 48
-};
-
static const
uint32_t g_gpr_regnums[k_num_gpr_registers] =
{
@@ -387,7 +291,7 @@
}
const RegisterInfo *
-RegisterContext_i386::GetRegisterInfoAtIndex(uint32_t reg)
+RegisterContext_i386::GetRegisterInfoAtIndex(size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -403,7 +307,7 @@
}
const RegisterSet *
-RegisterContext_i386::GetRegisterSet(uint32_t set)
+RegisterContext_i386::GetRegisterSet(size_t set)
{
if (set < k_num_register_sets)
return &g_reg_sets[set];
@@ -437,7 +341,7 @@
{
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(GetRegOffset(reg), GetRegSize(reg), value);
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg), GetRegSize(reg), value);
}
bool
@@ -451,7 +355,7 @@
{
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(GetRegOffset(reg), value);
+ return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value);
}
bool
@@ -620,7 +524,7 @@
for (uint32_t i=0; i<k_num_gpr_registers; i++)
{
uint32_t reg = gpr_eax + i;
- log->Printf("%12s = 0x%8.8x", g_register_infos[reg].name, (&user.regs)[reg]);
+ log->Printf("%12s = 0x%8.8" PRIx64, g_register_infos[reg].name, ((uint64_t*)&user.regs)[reg]);
}
}
}
@@ -631,7 +535,7 @@
bool result;
ProcessMonitor &monitor = GetMonitor();
- result = monitor.ReadGPR(&user.regs);
+ result = monitor.ReadGPR(m_thread.GetID(), &user.regs);
LogGPR("RegisterContext_i386::ReadGPR()");
return result;
}
@@ -640,5 +544,5 @@
RegisterContext_i386::ReadFPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(&user.i387);
+ return monitor.ReadFPR(m_thread.GetID(), &user.i387);
}
Index: aze/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/RegisterContext_i386.h 2013-03-03 09:35:50.243457351 +0100
@@ -35,13 +35,13 @@
GetRegisterCount();
const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(uint32_t reg);
+ GetRegisterInfoAtIndex(size_t reg);
size_t
GetRegisterSetCount();
const lldb_private::RegisterSet *
- GetRegisterSet(uint32_t set);
+ GetRegisterSet(size_t set);
static unsigned
GetRegisterIndexFromOffset(unsigned offset);
Index: aze/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp 2013-03-03 09:35:50.243457351 +0100
@@ -15,11 +15,14 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Host/Endian.h"
#include "ProcessPOSIX.h"
#include "ProcessMonitor.h"
+#include "RegisterContext_i386.h"
+#include "RegisterContext_x86.h"
#include "RegisterContext_x86_64.h"
using namespace lldb_private;
@@ -53,7 +56,17 @@
gpr_ss,
gpr_ds,
gpr_es,
- k_last_gpr = gpr_es,
+ gpr_eax,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_eip,
+ gpr_eflags,
+ k_last_gpr = gpr_eflags,
k_first_fpr,
fpu_fcw = k_first_fpr,
@@ -103,7 +116,7 @@
k_num_register_sets = 2
};
-enum gcc_dwarf_regnums
+enum
{
gcc_dwarf_gpr_rax = 0,
gcc_dwarf_gpr_rdx,
@@ -148,7 +161,7 @@
gcc_dwarf_fpu_stmm7
};
-enum gdb_regnums
+enum
{
gdb_gpr_rax = 0,
gdb_gpr_rbx = 1,
@@ -185,9 +198,9 @@
gdb_fpu_fcw = 32,
gdb_fpu_fsw = 33,
gdb_fpu_ftw = 34,
- gdb_fpu_cs = 35,
+ gdb_fpu_cs_64 = 35,
gdb_fpu_ip = 36,
- gdb_fpu_ds = 37,
+ gdb_fpu_ds_64 = 37,
gdb_fpu_dp = 38,
gdb_fpu_fop = 39,
gdb_fpu_xmm0 = 40,
@@ -235,7 +248,17 @@
gpr_gs,
gpr_ss,
gpr_ds,
- gpr_es
+ gpr_es,
+ gpr_eax,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_eip,
+ gpr_eflags
};
static const uint32_t
@@ -297,6 +320,9 @@
// Number of bytes needed to represent a GPR.
#define GPR_SIZE(reg) sizeof(((GPR*)NULL)->reg)
+// Number of bytes needed to represent a i386 GPR
+#define GPR_i386_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg)
+
// Number of bytes needed to represent a FPR.
#define FPR_SIZE(reg) sizeof(((RegisterContext_x86_64::FPU*)NULL)->reg)
@@ -310,6 +336,10 @@
{ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg }, NULL, NULL }
+#define DEFINE_GPR_i386(reg_i386, reg_x86_64, alt, kind1, kind2, kind3, kind4) \
+ { #reg_i386, alt, GPR_i386_SIZE(reg_i386), GPR_OFFSET(reg_x86_64), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg_i386 }, NULL, NULL }
+
#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
{ #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg }, NULL, NULL }
@@ -356,7 +386,17 @@
DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss),
DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds),
DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es),
-
+ // i386 registers
+ DEFINE_GPR_i386(eax, rax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax),
+ DEFINE_GPR_i386(ebx, rbx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx),
+ DEFINE_GPR_i386(ecx, rcx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx),
+ DEFINE_GPR_i386(edx, rdx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx),
+ DEFINE_GPR_i386(edi, rdi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi),
+ DEFINE_GPR_i386(esi, rsi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi),
+ DEFINE_GPR_i386(ebp, rbp, "fp", gcc_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, gdb_ebp),
+ DEFINE_GPR_i386(esp, rsp, "sp", gcc_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, gdb_esp),
+ DEFINE_GPR_i386(eip, rip, "pc", gcc_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, gdb_eip),
+ DEFINE_GPR_i386(eflags, rflags, "flags", gcc_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, gdb_eflags),
// i387 Floating point registers.
DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw),
DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw),
@@ -364,10 +404,10 @@
DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop),
DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip),
// FIXME: Extract segment from ip.
- DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
+ DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs_64),
DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp),
// FIXME: Extract segment from dp.
- DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
+ DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds_64),
DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr),
DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
@@ -457,7 +497,7 @@
}
const RegisterInfo *
-RegisterContext_x86_64::GetRegisterInfoAtIndex(uint32_t reg)
+RegisterContext_x86_64::GetRegisterInfoAtIndex(size_t reg)
{
if (reg < k_num_registers)
return &g_register_infos[reg];
@@ -472,7 +512,7 @@
}
const RegisterSet *
-RegisterContext_x86_64::GetRegisterSet(uint32_t set)
+RegisterContext_x86_64::GetRegisterSet(size_t set)
{
if (set < k_num_register_sets)
return &g_reg_sets[set];
@@ -511,7 +551,7 @@
}
else {
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(GetRegOffset(reg),GetRegSize(reg), value);
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg),GetRegSize(reg), value);
}
if (reg_info->encoding == eEncodingVector) {
@@ -585,7 +625,7 @@
{
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(GetRegOffset(reg), value);
+ return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value);
}
bool
@@ -620,138 +660,262 @@
RegisterContext_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
uint32_t num)
{
- if (kind == eRegisterKindGeneric)
+ const Process *process = CalculateProcess().get();
+ if (process)
{
- switch (num)
+ const ArchSpec arch = process->GetTarget().GetArchitecture();;
+ switch (arch.GetCore())
{
- case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
- case LLDB_REGNUM_GENERIC_RA:
default:
- return LLDB_INVALID_REGNUM;
- }
- }
+ assert(false && "CPU type not supported!");
+ break;
- if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
- {
- switch (num)
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
{
- case gcc_dwarf_gpr_rax: return gpr_rax;
- case gcc_dwarf_gpr_rdx: return gpr_rdx;
- case gcc_dwarf_gpr_rcx: return gpr_rcx;
- case gcc_dwarf_gpr_rbx: return gpr_rbx;
- case gcc_dwarf_gpr_rsi: return gpr_rsi;
- case gcc_dwarf_gpr_rdi: return gpr_rdi;
- case gcc_dwarf_gpr_rbp: return gpr_rbp;
- case gcc_dwarf_gpr_rsp: return gpr_rsp;
- case gcc_dwarf_gpr_r8: return gpr_r8;
- case gcc_dwarf_gpr_r9: return gpr_r9;
- case gcc_dwarf_gpr_r10: return gpr_r10;
- case gcc_dwarf_gpr_r11: return gpr_r11;
- case gcc_dwarf_gpr_r12: return gpr_r12;
- case gcc_dwarf_gpr_r13: return gpr_r13;
- case gcc_dwarf_gpr_r14: return gpr_r14;
- case gcc_dwarf_gpr_r15: return gpr_r15;
- case gcc_dwarf_gpr_rip: return gpr_rip;
- case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
- case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
- case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
- case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
- case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
- case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
- case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
- case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
- case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
- case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
- case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
- case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
- case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
- case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
- case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
- case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
- case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
- case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
- case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
- case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
- case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
- case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
- case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
- case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
- default:
- return LLDB_INVALID_REGNUM;
+ if (kind == eRegisterKindGeneric)
+ {
+ switch (num)
+ {
+ case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
+ case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
+ case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
+ case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
+ {
+ switch (num)
+ {
+ case dwarf_eax: return gpr_eax;
+ case dwarf_edx: return gpr_edx;
+ case dwarf_ecx: return gpr_ecx;
+ case dwarf_ebx: return gpr_ebx;
+ case dwarf_esi: return gpr_esi;
+ case dwarf_edi: return gpr_edi;
+ case dwarf_ebp: return gpr_ebp;
+ case dwarf_esp: return gpr_esp;
+ case dwarf_eip: return gpr_eip;
+ case dwarf_xmm0: return fpu_xmm0;
+ case dwarf_xmm1: return fpu_xmm1;
+ case dwarf_xmm2: return fpu_xmm2;
+ case dwarf_xmm3: return fpu_xmm3;
+ case dwarf_xmm4: return fpu_xmm4;
+ case dwarf_xmm5: return fpu_xmm5;
+ case dwarf_xmm6: return fpu_xmm6;
+ case dwarf_xmm7: return fpu_xmm7;
+ case dwarf_stmm0: return fpu_stmm0;
+ case dwarf_stmm1: return fpu_stmm1;
+ case dwarf_stmm2: return fpu_stmm2;
+ case dwarf_stmm3: return fpu_stmm3;
+ case dwarf_stmm4: return fpu_stmm4;
+ case dwarf_stmm5: return fpu_stmm5;
+ case dwarf_stmm6: return fpu_stmm6;
+ case dwarf_stmm7: return fpu_stmm7;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGDB)
+ {
+ switch (num)
+ {
+ case gdb_eax : return gpr_eax;
+ case gdb_ebx : return gpr_ebx;
+ case gdb_ecx : return gpr_ecx;
+ case gdb_edx : return gpr_edx;
+ case gdb_esi : return gpr_esi;
+ case gdb_edi : return gpr_edi;
+ case gdb_ebp : return gpr_ebp;
+ case gdb_esp : return gpr_esp;
+ case gdb_eip : return gpr_eip;
+ case gdb_eflags : return gpr_eflags;
+ case gdb_cs : return gpr_cs;
+ case gdb_ss : return gpr_ss;
+ case gdb_ds : return gpr_ds;
+ case gdb_es : return gpr_es;
+ case gdb_fs : return gpr_fs;
+ case gdb_gs : return gpr_gs;
+ case gdb_stmm0 : return fpu_stmm0;
+ case gdb_stmm1 : return fpu_stmm1;
+ case gdb_stmm2 : return fpu_stmm2;
+ case gdb_stmm3 : return fpu_stmm3;
+ case gdb_stmm4 : return fpu_stmm4;
+ case gdb_stmm5 : return fpu_stmm5;
+ case gdb_stmm6 : return fpu_stmm6;
+ case gdb_stmm7 : return fpu_stmm7;
+ case gdb_fcw : return fpu_fcw;
+ case gdb_fsw : return fpu_fsw;
+ case gdb_ftw : return fpu_ftw;
+ case gdb_fpu_cs : return fpu_cs;
+ case gdb_ip : return fpu_ip;
+ case gdb_fpu_ds : return fpu_ds; //fpu_fos
+ case gdb_dp : return fpu_dp; //fpu_foo
+ case gdb_fop : return fpu_fop;
+ case gdb_xmm0 : return fpu_xmm0;
+ case gdb_xmm1 : return fpu_xmm1;
+ case gdb_xmm2 : return fpu_xmm2;
+ case gdb_xmm3 : return fpu_xmm3;
+ case gdb_xmm4 : return fpu_xmm4;
+ case gdb_xmm5 : return fpu_xmm5;
+ case gdb_xmm6 : return fpu_xmm6;
+ case gdb_xmm7 : return fpu_xmm7;
+ case gdb_mxcsr : return fpu_mxcsr;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+ else if (kind == eRegisterKindLLDB)
+ {
+ return num;
+ }
+
+ break;
}
- }
- if (kind == eRegisterKindGDB)
- {
- switch (num)
+ case ArchSpec::eCore_x86_64_x86_64:
{
- case gdb_gpr_rax : return gpr_rax;
- case gdb_gpr_rbx : return gpr_rbx;
- case gdb_gpr_rcx : return gpr_rcx;
- case gdb_gpr_rdx : return gpr_rdx;
- case gdb_gpr_rsi : return gpr_rsi;
- case gdb_gpr_rdi : return gpr_rdi;
- case gdb_gpr_rbp : return gpr_rbp;
- case gdb_gpr_rsp : return gpr_rsp;
- case gdb_gpr_r8 : return gpr_r8;
- case gdb_gpr_r9 : return gpr_r9;
- case gdb_gpr_r10 : return gpr_r10;
- case gdb_gpr_r11 : return gpr_r11;
- case gdb_gpr_r12 : return gpr_r12;
- case gdb_gpr_r13 : return gpr_r13;
- case gdb_gpr_r14 : return gpr_r14;
- case gdb_gpr_r15 : return gpr_r15;
- case gdb_gpr_rip : return gpr_rip;
- case gdb_gpr_rflags : return gpr_rflags;
- case gdb_gpr_cs : return gpr_cs;
- case gdb_gpr_ss : return gpr_ss;
- case gdb_gpr_ds : return gpr_ds;
- case gdb_gpr_es : return gpr_es;
- case gdb_gpr_fs : return gpr_fs;
- case gdb_gpr_gs : return gpr_gs;
- case gdb_fpu_stmm0 : return fpu_stmm0;
- case gdb_fpu_stmm1 : return fpu_stmm1;
- case gdb_fpu_stmm2 : return fpu_stmm2;
- case gdb_fpu_stmm3 : return fpu_stmm3;
- case gdb_fpu_stmm4 : return fpu_stmm4;
- case gdb_fpu_stmm5 : return fpu_stmm5;
- case gdb_fpu_stmm6 : return fpu_stmm6;
- case gdb_fpu_stmm7 : return fpu_stmm7;
- case gdb_fpu_fcw : return fpu_fcw;
- case gdb_fpu_fsw : return fpu_fsw;
- case gdb_fpu_ftw : return fpu_ftw;
- case gdb_fpu_cs : return fpu_cs;
- case gdb_fpu_ip : return fpu_ip;
- case gdb_fpu_ds : return fpu_ds;
- case gdb_fpu_dp : return fpu_dp;
- case gdb_fpu_fop : return fpu_fop;
- case gdb_fpu_xmm0 : return fpu_xmm0;
- case gdb_fpu_xmm1 : return fpu_xmm1;
- case gdb_fpu_xmm2 : return fpu_xmm2;
- case gdb_fpu_xmm3 : return fpu_xmm3;
- case gdb_fpu_xmm4 : return fpu_xmm4;
- case gdb_fpu_xmm5 : return fpu_xmm5;
- case gdb_fpu_xmm6 : return fpu_xmm6;
- case gdb_fpu_xmm7 : return fpu_xmm7;
- case gdb_fpu_xmm8 : return fpu_xmm8;
- case gdb_fpu_xmm9 : return fpu_xmm9;
- case gdb_fpu_xmm10 : return fpu_xmm10;
- case gdb_fpu_xmm11 : return fpu_xmm11;
- case gdb_fpu_xmm12 : return fpu_xmm12;
- case gdb_fpu_xmm13 : return fpu_xmm13;
- case gdb_fpu_xmm14 : return fpu_xmm14;
- case gdb_fpu_xmm15 : return fpu_xmm15;
- case gdb_fpu_mxcsr : return fpu_mxcsr;
- default:
- return LLDB_INVALID_REGNUM;
+ if (kind == eRegisterKindGeneric)
+ {
+ switch (num)
+ {
+ case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
+ case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
+ case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
+ case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
+ {
+ switch (num)
+ {
+ case gcc_dwarf_gpr_rax: return gpr_rax;
+ case gcc_dwarf_gpr_rdx: return gpr_rdx;
+ case gcc_dwarf_gpr_rcx: return gpr_rcx;
+ case gcc_dwarf_gpr_rbx: return gpr_rbx;
+ case gcc_dwarf_gpr_rsi: return gpr_rsi;
+ case gcc_dwarf_gpr_rdi: return gpr_rdi;
+ case gcc_dwarf_gpr_rbp: return gpr_rbp;
+ case gcc_dwarf_gpr_rsp: return gpr_rsp;
+ case gcc_dwarf_gpr_r8: return gpr_r8;
+ case gcc_dwarf_gpr_r9: return gpr_r9;
+ case gcc_dwarf_gpr_r10: return gpr_r10;
+ case gcc_dwarf_gpr_r11: return gpr_r11;
+ case gcc_dwarf_gpr_r12: return gpr_r12;
+ case gcc_dwarf_gpr_r13: return gpr_r13;
+ case gcc_dwarf_gpr_r14: return gpr_r14;
+ case gcc_dwarf_gpr_r15: return gpr_r15;
+ case gcc_dwarf_gpr_rip: return gpr_rip;
+ case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
+ case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
+ case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
+ case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
+ case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
+ case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
+ case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
+ case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
+ case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
+ case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
+ case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
+ case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
+ case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
+ case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
+ case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
+ case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
+ case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
+ case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
+ case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
+ case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
+ case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
+ case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
+ case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
+ case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGDB)
+ {
+ switch (num)
+ {
+ case gdb_gpr_rax : return gpr_rax;
+ case gdb_gpr_rbx : return gpr_rbx;
+ case gdb_gpr_rcx : return gpr_rcx;
+ case gdb_gpr_rdx : return gpr_rdx;
+ case gdb_gpr_rsi : return gpr_rsi;
+ case gdb_gpr_rdi : return gpr_rdi;
+ case gdb_gpr_rbp : return gpr_rbp;
+ case gdb_gpr_rsp : return gpr_rsp;
+ case gdb_gpr_r8 : return gpr_r8;
+ case gdb_gpr_r9 : return gpr_r9;
+ case gdb_gpr_r10 : return gpr_r10;
+ case gdb_gpr_r11 : return gpr_r11;
+ case gdb_gpr_r12 : return gpr_r12;
+ case gdb_gpr_r13 : return gpr_r13;
+ case gdb_gpr_r14 : return gpr_r14;
+ case gdb_gpr_r15 : return gpr_r15;
+ case gdb_gpr_rip : return gpr_rip;
+ case gdb_gpr_rflags : return gpr_rflags;
+ case gdb_gpr_cs : return gpr_cs;
+ case gdb_gpr_ss : return gpr_ss;
+ case gdb_gpr_ds : return gpr_ds;
+ case gdb_gpr_es : return gpr_es;
+ case gdb_gpr_fs : return gpr_fs;
+ case gdb_gpr_gs : return gpr_gs;
+ case gdb_fpu_stmm0 : return fpu_stmm0;
+ case gdb_fpu_stmm1 : return fpu_stmm1;
+ case gdb_fpu_stmm2 : return fpu_stmm2;
+ case gdb_fpu_stmm3 : return fpu_stmm3;
+ case gdb_fpu_stmm4 : return fpu_stmm4;
+ case gdb_fpu_stmm5 : return fpu_stmm5;
+ case gdb_fpu_stmm6 : return fpu_stmm6;
+ case gdb_fpu_stmm7 : return fpu_stmm7;
+ case gdb_fpu_fcw : return fpu_fcw;
+ case gdb_fpu_fsw : return fpu_fsw;
+ case gdb_fpu_ftw : return fpu_ftw;
+ case gdb_fpu_cs_64 : return fpu_cs;
+ case gdb_fpu_ip : return fpu_ip;
+ case gdb_fpu_ds_64 : return fpu_ds;
+ case gdb_fpu_dp : return fpu_dp;
+ case gdb_fpu_fop : return fpu_fop;
+ case gdb_fpu_xmm0 : return fpu_xmm0;
+ case gdb_fpu_xmm1 : return fpu_xmm1;
+ case gdb_fpu_xmm2 : return fpu_xmm2;
+ case gdb_fpu_xmm3 : return fpu_xmm3;
+ case gdb_fpu_xmm4 : return fpu_xmm4;
+ case gdb_fpu_xmm5 : return fpu_xmm5;
+ case gdb_fpu_xmm6 : return fpu_xmm6;
+ case gdb_fpu_xmm7 : return fpu_xmm7;
+ case gdb_fpu_xmm8 : return fpu_xmm8;
+ case gdb_fpu_xmm9 : return fpu_xmm9;
+ case gdb_fpu_xmm10 : return fpu_xmm10;
+ case gdb_fpu_xmm11 : return fpu_xmm11;
+ case gdb_fpu_xmm12 : return fpu_xmm12;
+ case gdb_fpu_xmm13 : return fpu_xmm13;
+ case gdb_fpu_xmm14 : return fpu_xmm14;
+ case gdb_fpu_xmm15 : return fpu_xmm15;
+ case gdb_fpu_mxcsr : return fpu_mxcsr;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+ else if (kind == eRegisterKindLLDB)
+ {
+ return num;
+ }
+ }
}
- }
- else if (kind == eRegisterKindLLDB)
- {
- return num;
}
return LLDB_INVALID_REGNUM;
@@ -788,26 +952,26 @@
RegisterContext_x86_64::ReadGPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(&user.regs);
+ return monitor.ReadGPR(m_thread.GetID(), &user.regs);
}
bool
RegisterContext_x86_64::ReadFPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(&user.i387);
+ return monitor.ReadFPR(m_thread.GetID(), &user.i387);
}
bool
RegisterContext_x86_64::WriteGPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(&user.regs);
+ return monitor.WriteGPR(m_thread.GetID(), &user.regs);
}
bool
RegisterContext_x86_64::WriteFPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(&user.i387);
+ return monitor.WriteFPR(m_thread.GetID(), &user.i387);
}
Index: aze/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h 2013-03-03 09:35:50.243457351 +0100
@@ -42,13 +42,13 @@
GetRegisterCount();
const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(uint32_t reg);
+ GetRegisterInfoAtIndex(size_t reg);
size_t
GetRegisterSetCount();
const lldb_private::RegisterSet *
- GetRegisterSet(uint32_t set);
+ GetRegisterSet(size_t set);
static unsigned
GetRegisterIndexFromOffset(unsigned offset);
Index: aze/lldb/source/Plugins/Process/POSIX/RegisterContext_x86.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/POSIX/RegisterContext_x86.h 2013-03-03 09:35:50.247457352 +0100
@@ -0,0 +1,110 @@
+//===-- RegisterContext_x86.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_RegisterContext_x86_H_
+#define liblldb_RegisterContext_x86_H_
+
+enum
+{
+ gcc_eax = 0,
+ gcc_ecx,
+ gcc_edx,
+ gcc_ebx,
+ gcc_ebp,
+ gcc_esp,
+ gcc_esi,
+ gcc_edi,
+ gcc_eip,
+ gcc_eflags
+};
+
+enum
+{
+ dwarf_eax = 0,
+ dwarf_ecx,
+ dwarf_edx,
+ dwarf_ebx,
+ dwarf_esp,
+ dwarf_ebp,
+ dwarf_esi,
+ dwarf_edi,
+ dwarf_eip,
+ dwarf_eflags,
+ dwarf_stmm0 = 11,
+ dwarf_stmm1,
+ dwarf_stmm2,
+ dwarf_stmm3,
+ dwarf_stmm4,
+ dwarf_stmm5,
+ dwarf_stmm6,
+ dwarf_stmm7,
+ dwarf_xmm0 = 21,
+ dwarf_xmm1,
+ dwarf_xmm2,
+ dwarf_xmm3,
+ dwarf_xmm4,
+ dwarf_xmm5,
+ dwarf_xmm6,
+ dwarf_xmm7
+};
+
+enum
+{
+ gdb_eax = 0,
+ gdb_ecx = 1,
+ gdb_edx = 2,
+ gdb_ebx = 3,
+ gdb_esp = 4,
+ gdb_ebp = 5,
+ gdb_esi = 6,
+ gdb_edi = 7,
+ gdb_eip = 8,
+ gdb_eflags = 9,
+ gdb_cs = 10,
+ gdb_ss = 11,
+ gdb_ds = 12,
+ gdb_es = 13,
+ gdb_fs = 14,
+ gdb_gs = 15,
+ gdb_stmm0 = 16,
+ gdb_stmm1 = 17,
+ gdb_stmm2 = 18,
+ gdb_stmm3 = 19,
+ gdb_stmm4 = 20,
+ gdb_stmm5 = 21,
+ gdb_stmm6 = 22,
+ gdb_stmm7 = 23,
+ gdb_fcw = 24,
+ gdb_fsw = 25,
+ gdb_ftw = 26,
+ gdb_fpu_cs = 27,
+ gdb_ip = 28,
+ gdb_fpu_ds = 29,
+ gdb_dp = 30,
+ gdb_fop = 31,
+ gdb_xmm0 = 32,
+ gdb_xmm1 = 33,
+ gdb_xmm2 = 34,
+ gdb_xmm3 = 35,
+ gdb_xmm4 = 36,
+ gdb_xmm5 = 37,
+ gdb_xmm6 = 38,
+ gdb_xmm7 = 39,
+ gdb_mxcsr = 40,
+ gdb_mm0 = 41,
+ gdb_mm1 = 42,
+ gdb_mm2 = 43,
+ gdb_mm3 = 44,
+ gdb_mm4 = 45,
+ gdb_mm5 = 46,
+ gdb_mm6 = 47,
+ gdb_mm7 = 48
+};
+
+#endif
Index: aze/lldb/source/Plugins/Process/Utility/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/Process/Utility/CMakeLists.txt 2013-03-03 09:35:50.247457352 +0100
@@ -0,0 +1,19 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginProcessUtility
+ DynamicRegisterInfo.cpp
+ InferiorCallPOSIX.cpp
+ RegisterContextDarwin_arm.cpp
+ RegisterContextDarwin_i386.cpp
+ RegisterContextDarwin_x86_64.cpp
+ RegisterContextLLDB.cpp
+ RegisterContextMach_arm.cpp
+ RegisterContextMach_i386.cpp
+ RegisterContextMach_x86_64.cpp
+ RegisterContextMacOSXFrameBackchain.cpp
+ RegisterContextMemory.cpp
+ StopInfoMachException.cpp
+ ThreadMemory.cpp
+ UnwindLLDB.cpp
+ UnwindMacOSXFrameBackchain.cpp
+ )
\ No newline at end of file
Index: aze/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp 2013-03-03 09:35:50.247457352 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "DynamicRegisterInfo.h"
// C Includes
@@ -31,7 +33,7 @@
{
}
-DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDataDictionary &dict) :
+DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict) :
m_regs (),
m_sets (),
m_set_reg_nums (),
@@ -47,16 +49,19 @@
size_t
-DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDataDictionary &dict)
+DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict)
{
#ifndef LLDB_DISABLE_PYTHON
- PythonDataArray sets (dict.GetItemForKey("sets").GetArrayObject());
+ PythonList sets (dict.GetItemForKey("sets"));
if (sets)
{
const uint32_t num_sets = sets.GetSize();
for (uint32_t i=0; i<num_sets; ++i)
{
- ConstString set_name (sets.GetItemAtIndex(i).GetStringObject().GetString());
+ PythonString py_set_name(sets.GetItemAtIndex(i));
+ ConstString set_name;
+ if (py_set_name)
+ set_name.SetCString(py_set_name.GetString());
if (set_name)
{
RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
@@ -70,23 +75,23 @@
}
m_set_reg_nums.resize(m_sets.size());
}
- PythonDataArray regs (dict.GetItemForKey("registers").GetArrayObject());
+ PythonList regs (dict.GetItemForKey("registers"));
if (regs)
{
const uint32_t num_regs = regs.GetSize();
- PythonDataString name_pystr("name");
- PythonDataString altname_pystr("alt-name");
- PythonDataString bitsize_pystr("bitsize");
- PythonDataString offset_pystr("offset");
- PythonDataString encoding_pystr("encoding");
- PythonDataString format_pystr("format");
- PythonDataString set_pystr("set");
- PythonDataString gcc_pystr("gcc");
- PythonDataString dwarf_pystr("dwarf");
- PythonDataString generic_pystr("generic");
+ PythonString name_pystr("name");
+ PythonString altname_pystr("alt-name");
+ PythonString bitsize_pystr("bitsize");
+ PythonString offset_pystr("offset");
+ PythonString encoding_pystr("encoding");
+ PythonString format_pystr("format");
+ PythonString set_pystr("set");
+ PythonString gcc_pystr("gcc");
+ PythonString dwarf_pystr("dwarf");
+ PythonString generic_pystr("generic");
for (uint32_t i=0; i<num_regs; ++i)
{
- PythonDataDictionary reg_info_dict(regs.GetItemAtIndex(i).GetDictionaryObject());
+ PythonDictionary reg_info_dict(regs.GetItemAtIndex(i));
if (reg_info_dict)
{
// { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
Index: aze/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h 2013-03-03 09:35:50.247457352 +0100
@@ -24,13 +24,13 @@
public:
DynamicRegisterInfo ();
- DynamicRegisterInfo (const lldb_private::PythonDataDictionary &dict);
+ DynamicRegisterInfo (const lldb_private::PythonDictionary &dict);
virtual
~DynamicRegisterInfo ();
size_t
- SetRegisterInfo (const lldb_private::PythonDataDictionary &dict);
+ SetRegisterInfo (const lldb_private::PythonDictionary &dict);
void
AddRegister (lldb_private::RegisterInfo &reg_info,
Index: aze/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp 2013-03-03 09:35:50.247457352 +0100
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "InferiorCallPOSIX.h"
+#include "lldb/Core/Address.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -48,7 +49,8 @@
const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
const bool stop_other_threads = true;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
const bool try_all_threads = true;
const uint32_t timeout_usec = 500000;
@@ -80,7 +82,8 @@
mmap_range.GetBaseAddress(),
ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
stop_other_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
&addr,
&length,
&prot_arg,
@@ -104,7 +107,8 @@
call_plan_sp,
stop_other_threads,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
error_strm);
if (result == eExecutionCompleted)
@@ -116,6 +120,11 @@
if (allocated_addr == UINT32_MAX)
return false;
}
+ else if (process->GetAddressByteSize() == 8)
+ {
+ if (allocated_addr == UINT64_MAX)
+ return false;
+ }
return true;
}
}
@@ -152,7 +161,8 @@
const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
const bool stop_other_threads = true;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
const bool try_all_threads = true;
const uint32_t timeout_usec = 500000;
@@ -163,7 +173,8 @@
munmap_range.GetBaseAddress(),
ClangASTType(),
stop_other_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
&addr,
&length));
if (call_plan_sp)
@@ -182,7 +193,8 @@
call_plan_sp,
stop_other_threads,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
error_strm);
if (result == eExecutionCompleted)
@@ -197,3 +209,66 @@
return false;
}
+
+bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) {
+ Thread *thread = process->GetThreadList().GetSelectedThread().get();
+ if (thread == NULL || address == NULL)
+ return false;
+
+ const bool stop_other_threads = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
+ const bool try_all_threads = true;
+ const uint32_t timeout_usec = 500000;
+
+ ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
+ lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ThreadPlanCallFunction *call_function_thread_plan
+ = new ThreadPlanCallFunction (*thread,
+ *address,
+ ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+ stop_other_threads,
+ unwind_on_error,
+ ignore_breakpoints);
+ lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
+ if (call_plan_sp)
+ {
+ StreamFile error_strm;
+ // This plan is a utility plan, so set it to discard itself when done.
+ call_plan_sp->SetIsMasterPlan (true);
+ call_plan_sp->SetOkayToDiscard(true);
+
+ StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ if (frame)
+ {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext (exe_ctx);
+ ExecutionResults result = process->RunThreadPlan (exe_ctx,
+ call_plan_sp,
+ stop_other_threads,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ timeout_usec,
+ error_strm);
+ if (result == eExecutionCompleted)
+ {
+ returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+ if (process->GetAddressByteSize() == 4)
+ {
+ if (returned_func == UINT32_MAX)
+ return false;
+ }
+ else if (process->GetAddressByteSize() == 8)
+ {
+ if (returned_func == UINT64_MAX)
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
Index: aze/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.h 2013-03-03 09:35:50.247457352 +0100
@@ -36,6 +36,8 @@
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
+bool InferiorCall(Process *proc, const Address *address, lldb::addr_t &returned_func);
+
} // namespace lldb_private
#endif // lldb_InferiorCallPOSIX_h_
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp 2013-03-03 09:35:50.247457352 +0100
@@ -416,7 +416,7 @@
}
const RegisterInfo *
-RegisterContextDarwin_arm::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -464,7 +464,7 @@
}
const RegisterSet *
-RegisterContextDarwin_arm::GetRegisterSet (uint32_t reg_set)
+RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
{
if (reg_set < k_num_regsets)
return &g_reg_sets[reg_set];
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h 2013-03-03 09:35:50.247457352 +0100
@@ -64,13 +64,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t set);
+ GetRegisterSet (size_t set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info,
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp 2013-03-03 09:35:50.247457352 +0100
@@ -298,7 +298,7 @@
}
const RegisterInfo *
-RegisterContextDarwin_i386::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextDarwin_i386::GetRegisterInfoAtIndex (size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -410,7 +410,7 @@
}
const RegisterSet *
-RegisterContextDarwin_i386::GetRegisterSet (uint32_t reg_set)
+RegisterContextDarwin_i386::GetRegisterSet (size_t reg_set)
{
if (reg_set < k_num_regsets)
return &g_reg_sets[reg_set];
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h 2013-03-03 09:35:50.247457352 +0100
@@ -34,13 +34,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t set);
+ GetRegisterSet (size_t set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp 2013-03-03 09:35:50.247457352 +0100
@@ -336,7 +336,7 @@
const RegisterInfo *
-RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -457,7 +457,7 @@
}
const RegisterSet *
-RegisterContextDarwin_x86_64::GetRegisterSet (uint32_t reg_set)
+RegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set)
{
if (reg_set < k_num_regsets)
return &g_reg_sets[reg_set];
@@ -491,7 +491,7 @@
for (uint32_t i=0; i<k_num_gpr_registers; i++)
{
uint32_t reg = gpr_rax + i;
- log->Printf("%12s = 0x%16.16llx", g_register_infos[reg].name, (&gpr.rax)[reg]);
+ log->Printf("%12s = 0x%16.16" PRIx64, g_register_infos[reg].name, (&gpr.rax)[reg]);
}
}
}
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h 2013-03-03 09:35:50.247457352 +0100
@@ -33,13 +33,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t set);
+ GetRegisterSet (size_t set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp 2013-03-03 09:35:50.247457352 +0100
@@ -60,7 +60,7 @@
m_registers(),
m_parent_unwind (unwind_lldb)
{
- m_sym_ctx.Clear();
+ m_sym_ctx.Clear(false);
m_sym_ctx_valid = false;
if (IsFrameZero ())
@@ -87,6 +87,7 @@
void
RegisterContextLLDB::InitializeZerothFrame()
{
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
ExecutionContext exe_ctx(m_thread.shared_from_this());
RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
@@ -213,8 +214,8 @@
m_cfa = cfa_regval + cfa_offset;
- UnwindLogMsg ("cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
- UnwindLogMsg ("initialized frame current pc is 0x%llx cfa is 0x%llx using %s UnwindPlan",
+ UnwindLogMsg ("cfa_regval = 0x%16.16" PRIx64 " (cfa_regval = 0x%16.16" PRIx64 ", cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
+ UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 " using %s UnwindPlan",
(uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()),
(uint64_t) m_cfa,
m_full_unwind_plan_sp->GetSourceName().GetCString());
@@ -254,12 +255,12 @@
if (log)
{
- UnwindLogMsg ("pc = 0x%16.16llx", pc);
+ UnwindLogMsg ("pc = 0x%16.16" PRIx64, pc);
addr_t reg_val;
if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val))
- UnwindLogMsg ("fp = 0x%16.16llx", reg_val);
+ UnwindLogMsg ("fp = 0x%16.16" PRIx64, reg_val);
if (ReadGPRValue (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val))
- UnwindLogMsg ("sp = 0x%16.16llx", reg_val);
+ UnwindLogMsg ("sp = 0x%16.16" PRIx64, reg_val);
}
// A pc of 0x0 means it's the end of the stack crawl
@@ -297,7 +298,7 @@
// pc and see if we can get any further.
if (GetNextFrame().get() && GetNextFrame()->IsValid() && GetNextFrame()->IsFrameZero())
{
- UnwindLogMsg ("had a pc of 0x%llx which is not in executable memory but on frame 1 -- allowing it once.",
+ UnwindLogMsg ("had a pc of 0x%" PRIx64 " which is not in executable memory but on frame 1 -- allowing it once.",
(uint64_t) pc);
m_frame_type = eSkipFrame;
}
@@ -363,7 +364,7 @@
return;
}
- UnwindLogMsg ("initialized frame cfa is 0x%llx", (uint64_t) m_cfa);
+ UnwindLogMsg ("initialized frame cfa is 0x%" PRIx64, (uint64_t) m_cfa);
return;
}
m_frame_type = eNotAValidFrame;
@@ -408,7 +409,7 @@
{
Address temporary_pc(m_current_pc);
temporary_pc.SetOffset(m_current_pc.GetOffset() - 1);
- m_sym_ctx.Clear();
+ m_sym_ctx.Clear(false);
m_sym_ctx_valid = false;
if ((pc_module_sp->ResolveSymbolContextForAddress (temporary_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
{
@@ -506,7 +507,7 @@
m_cfa = cfa_regval + cfa_offset;
- UnwindLogMsg ("cfa_regval = 0x%16.16llx (cfa_regval = 0x%16.16llx, cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
+ UnwindLogMsg ("cfa_regval = 0x%16.16" PRIx64 " (cfa_regval = 0x%16.16" PRIx64 ", cfa_offset = %i)", m_cfa, cfa_regval, cfa_offset);
// A couple of sanity checks..
if (cfa_regval == LLDB_INVALID_ADDRESS || cfa_regval == 0 || cfa_regval == 1)
@@ -544,7 +545,7 @@
}
}
- UnwindLogMsg ("initialized frame current pc is 0x%llx cfa is 0x%llx",
+ UnwindLogMsg ("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64,
(uint64_t) m_current_pc.GetLoadAddress (exe_ctx.GetTargetPtr()), (uint64_t) m_cfa);
}
@@ -759,7 +760,7 @@
}
const RegisterInfo *
-RegisterContextLLDB::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextLLDB::GetRegisterInfoAtIndex (size_t reg)
{
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg);
}
@@ -771,7 +772,7 @@
}
const RegisterSet *
-RegisterContextLLDB::GetRegisterSet (uint32_t reg_set)
+RegisterContextLLDB::GetRegisterSet (size_t reg_set)
{
return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}
@@ -903,7 +904,7 @@
// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
-bool
+enum UnwindLLDB::RegisterSearchResult
RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc)
{
// Have we already found this register location?
@@ -914,7 +915,8 @@
if (iterator != m_registers.end())
{
regloc = iterator->second;
- return true;
+ UnwindLogMsg ("supplying caller's saved reg %d's location, cached", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
}
@@ -937,7 +939,8 @@
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = m_cfa;
m_registers[lldb_regnum] = regloc;
- return true;
+ UnwindLogMsg ("supplying caller's stack pointer (%d) value, computed from CFA", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
// Look through the available UnwindPlans for the register location.
@@ -955,7 +958,7 @@
{
UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
lldb_regnum, (int) unwindplan_registerkind);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
{
@@ -993,7 +996,7 @@
else
UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
lldb_regnum, (int) unwindplan_registerkind);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
}
@@ -1064,7 +1067,7 @@
if (reg_info && abi->RegisterIsVolatile (reg_info))
{
UnwindLogMsg ("did not supply reg location for %d because it is volatile", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
}
}
@@ -1076,11 +1079,12 @@
new_regloc.location.register_number = lldb_regnum;
m_registers[lldb_regnum] = new_regloc;
regloc = new_regloc;
- return true;
+ UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
else
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
// unwindplan_regloc has valid contents about where to retrieve the register
@@ -1090,7 +1094,7 @@
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
m_registers[lldb_regnum] = new_regloc;
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
if (unwindplan_regloc.IsSame())
@@ -1098,11 +1102,11 @@
if (IsFrameZero ())
{
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
else
{
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
}
@@ -1112,7 +1116,8 @@
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = m_cfa + offset;
m_registers[lldb_regnum] = regloc;
- return true;
+ UnwindLogMsg ("supplying caller's register %d, value is CFA plus offset", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
if (unwindplan_regloc.IsAtCFAPlusOffset())
@@ -1121,7 +1126,8 @@
regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
regloc.location.target_memory_location = m_cfa + offset;
m_registers[lldb_regnum] = regloc;
- return true;
+ UnwindLogMsg ("supplying caller's register %d from the stack, saved at CFA plus offset", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
if (unwindplan_regloc.IsInOtherRegister())
@@ -1131,12 +1137,13 @@
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
{
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
regloc.location.register_number = row_regnum_in_lldb;
m_registers[lldb_regnum] = regloc;
- return true;
+ UnwindLogMsg ("supplying caller's register %d, saved in register %d", lldb_regnum, row_regnum_in_lldb);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
@@ -1157,25 +1164,27 @@
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = val;
m_registers[lldb_regnum] = regloc;
- return true;
+ UnwindLogMsg ("supplying caller's register %d via DWARF expression (IsDWARFExpression)", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
else
{
- regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
- regloc.location.target_memory_location = val;
- m_registers[lldb_regnum] = regloc;
- return true;
+ regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = val;
+ m_registers[lldb_regnum] = regloc;
+ UnwindLogMsg ("supplying caller's register %d via DWARF expression (IsAtDWARFExpression)", lldb_regnum);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
}
UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
// FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
// If the Full unwindplan has been determined to be incorrect, this method will
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h 2013-03-03 09:35:50.251457352 +0100
@@ -46,13 +46,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
@@ -131,7 +131,7 @@
// If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
// stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
// as the requesting frame's.
- bool
+ lldb_private::UnwindLLDB::RegisterSearchResult
SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc);
bool
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -59,7 +59,7 @@
}
const RegisterInfo *
-RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (size_t reg)
{
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
@@ -73,7 +73,7 @@
const RegisterSet *
-RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set)
+RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_t reg_set)
{
return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h 2013-03-03 09:35:50.251457352 +0100
@@ -42,13 +42,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -80,7 +80,7 @@
}
const RegisterInfo *
-RegisterContextMemory::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
{
return m_reg_infos.GetRegisterInfoAtIndex (reg);
}
@@ -92,7 +92,7 @@
}
const RegisterSet *
-RegisterContextMemory::GetRegisterSet (uint32_t reg_set)
+RegisterContextMemory::GetRegisterSet (size_t reg_set)
{
return m_reg_infos.GetRegisterSet (reg_set);
}
Index: aze/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h 2013-03-03 09:35:50.251457352 +0100
@@ -46,13 +46,13 @@
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual uint32_t
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
@@ -60,7 +60,7 @@
//------------------------------------------------------------------
// If all of the thread register are in a contiguous buffer in
- // memory, then the default ReadRegister/WriteRegiter and
+ // memory, then the default ReadRegister/WriteRegister and
// ReadAllRegisterValues/WriteAllRegisterValues will work. If thread
// registers are not contiguous, clients will want to subclass this
// class and modify the read/write functions as needed.
Index: aze/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -16,6 +16,8 @@
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
@@ -208,6 +210,12 @@
case 10:
exc_desc = "EXC_CRASH";
break;
+ case 11:
+ exc_desc = "EXC_RESOURCE";
+ break;
+ case 12:
+ exc_desc = "EXC_GUARD";
+ break;
}
StreamString strm;
@@ -215,14 +223,14 @@
if (exc_desc)
strm.PutCString(exc_desc);
else
- strm.Printf("EXC_??? (%llu)", m_value);
+ strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
if (m_exc_data_count >= 1)
{
if (code_desc)
strm.Printf(" (%s=%s", code_label, code_desc);
else
- strm.Printf(" (%s=%llu", code_label, m_exc_code);
+ strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
}
if (m_exc_data_count >= 2)
@@ -230,7 +238,7 @@
if (subcode_desc)
strm.Printf(", %s=%s", subcode_label, subcode_desc);
else
- strm.Printf(", %s=0x%llx", subcode_label, m_exc_subcode);
+ strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
}
if (m_exc_data_count > 0)
@@ -300,13 +308,45 @@
case 5: // EXC_SOFTWARE
if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
+ {
+ if (exc_sub_code == 5)
+ {
+ // On MacOSX, a SIGTRAP can signify that a process has called
+ // exec, so we should check with our dynamic loader to verify.
+ ProcessSP process_sp (thread.GetProcess());
+ if (process_sp)
+ {
+ DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
+ if (dynamic_loader && dynamic_loader->ProcessDidExec())
+ {
+ // The program was re-exec'ed
+ return StopInfo::CreateStopReasonWithExec (thread);
+ }
+// if (!process_did_exec)
+// {
+// // We have a SIGTRAP, make sure we didn't exec by checking
+// // for the PC being at "_dyld_start"...
+// lldb::StackFrameSP frame_sp (thread.GetStackFrameAtIndex(0));
+// if (frame_sp)
+// {
+// const Symbol *symbol = frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
+// if (symbol)
+// {
+// if (symbol->GetName() == ConstString("_dyld_start"))
+// process_did_exec = true;
+// }
+// }
+// }
+ }
+ }
return StopInfo::CreateStopReasonWithSignal (thread, exc_sub_code);
+ }
break;
case 6: // EXC_BREAKPOINT
{
- bool is_software_breakpoint = false;
- bool is_trace_if_software_breakpoint_missing = false;
+ bool is_actual_breakpoint = false;
+ bool is_trace_if_actual_breakpoint_missing = false;
switch (cpu)
{
case llvm::Triple::x86:
@@ -335,9 +375,9 @@
{
// KDP returns EXC_I386_BPTFLT for trace breakpoints
if (exc_code == 3)
- is_trace_if_software_breakpoint_missing = true;
+ is_trace_if_actual_breakpoint_missing = true;
- is_software_breakpoint = true;
+ is_actual_breakpoint = true;
if (!pc_already_adjusted)
pc_decrement = 1;
}
@@ -345,11 +385,11 @@
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
- is_software_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
+ is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
break;
case llvm::Triple::arm:
- if (exc_code == 0x102)
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
// It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
// data break address from our watchpoint list.
@@ -368,10 +408,10 @@
if (thread.GetTemporaryResumeState() == eStateStepping)
return StopInfo::CreateStopReasonToTrace(thread);
}
- else if (exc_code == 1)
+ else if (exc_code == 1) // EXC_ARM_BREAKPOINT
{
- is_software_breakpoint = true;
- is_trace_if_software_breakpoint_missing = true;
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
}
break;
@@ -379,7 +419,7 @@
break;
}
- if (is_software_breakpoint)
+ if (is_actual_breakpoint)
{
RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
@@ -407,7 +447,7 @@
}
// Don't call this a trace if we weren't single stepping this thread.
- if (is_trace_if_software_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
+ if (is_trace_if_actual_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
{
return StopInfo::CreateStopReasonToTrace (thread);
}
Index: aze/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -135,7 +135,10 @@
void
ThreadMemory::RefreshStateAfterStop()
{
- RegisterContextSP reg_ctx_sp(GetRegisterContext());
+ // Don't fetch the registers by calling Thread::GetRegisterContext() below.
+ // We might not have fetched any registers yet and we don't want to fetch
+ // the registers just to call invalidate on them...
+ RegisterContextSP reg_ctx_sp(m_reg_context_sp);
if (reg_ctx_sp)
{
const bool force = true;
Index: aze/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -53,7 +53,7 @@
{
TimeValue now(TimeValue::Now());
uint64_t delta_t = now - time_value;
- printf ("%u frames in %llu.%09llu ms (%g frames/sec)\n",
+ printf ("%u frames in %" PRIu64 ".%09llu ms (%g frames/sec)\n",
FRAME_COUNT,
delta_t / TimeValue::NanoSecPerSec,
delta_t % TimeValue::NanoSecPerSec,
@@ -272,15 +272,34 @@
// isn't saved by frame_num, none of the frames lower on the stack will have a useful value.
if (pc_or_return_address_reg)
{
- if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc))
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
return true;
else
return false;
}
while (frame_num >= 0)
{
- if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc))
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+
+ // If we have unwind instructions saying that register N is saved in register M in the middle of
+ // the stack (and N can equal M here, meaning the register was not used in this function), then
+ // change the register number we're looking for to M and keep looking for a concrete location
+ // down the stack, or an actual value from a live RegisterContext at frame 0.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
+ && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister
+ && frame_num > 0)
+ {
+ result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ lldb_regnum = regloc.location.register_number;
+ }
+
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
return true;
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
+ return false;
frame_num--;
}
return false;
Index: aze/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/UnwindLLDB.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/UnwindLLDB.h 2013-03-03 09:35:50.251457352 +0100
@@ -30,6 +30,13 @@
virtual
~UnwindLLDB() { }
+ enum RegisterSearchResult
+ {
+ eRegisterFound = 0,
+ eRegisterNotFound,
+ eRegisterIsVolatile
+ };
+
protected:
friend class lldb_private::RegisterContextLLDB;
Index: aze/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -176,7 +176,7 @@
// printf(" ------------------ ------------------ \n");
// for (i=0; i<m_cursors.size(); ++i)
// {
-// printf("[%3u] 0x%16.16llx 0x%16.16llx\n", i, m_cursors[i].pc, m_cursors[i].fp);
+// printf("[%3u] 0x%16.16" PRIx64 " 0x%16.16" PRIx64 "\n", i, m_cursors[i].pc, m_cursors[i].fp);
// }
return m_cursors.size();
}
Index: aze/lldb/source/Plugins/SymbolFile/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/SymbolFile/CMakeLists.txt 2013-03-03 09:35:50.251457352 +0100
@@ -0,0 +1,2 @@
+add_subdirectory(DWARF)
+add_subdirectory(Symtab)
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt 2013-03-03 09:35:50.251457352 +0100
@@ -0,0 +1,28 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginSymbolFileDWARF
+ DWARFAbbreviationDeclaration.cpp
+ DWARFCompileUnit.cpp
+ DWARFDebugAbbrev.cpp
+ DWARFDebugAranges.cpp
+ DWARFDebugArangeSet.cpp
+ DWARFDebugInfo.cpp
+ DWARFDebugInfoEntry.cpp
+ DWARFDebugLine.cpp
+ DWARFDebugMacinfo.cpp
+ DWARFDebugMacinfoEntry.cpp
+ DWARFDebugPubnames.cpp
+ DWARFDebugPubnamesSet.cpp
+ DWARFDebugRanges.cpp
+ DWARFDeclContext.cpp
+ DWARFDefines.cpp
+ DWARFDIECollection.cpp
+ DWARFFormValue.cpp
+ DWARFLocationDescription.cpp
+ DWARFLocationList.cpp
+ LogChannelDWARF.cpp
+ NameToDIE.cpp
+ SymbolFileDWARF.cpp
+ SymbolFileDWARFDebugMap.cpp
+ UniqueDWARFASTType.cpp
+ )
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -32,13 +32,13 @@
}
bool
-DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr)
{
return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
}
bool
-DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code)
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
{
m_code = code;
m_attributes.clear();
@@ -155,7 +155,7 @@
dw_attr_t attr;
dw_form_t form;
uint32_t i;
- dw_offset_t offset = debug_info_offset;
+ lldb::offset_t offset = debug_info_offset;
for (i = 0; i < num_abbr_decl_attributes; ++i)
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h 2013-03-03 09:35:50.251457352 +0100
@@ -32,7 +32,7 @@
void SetCode(dw_uleb128_t code) { m_code = code; }
dw_tag_t Tag() const { return m_tag; }
bool HasChildren() const { return m_has_children; }
- uint32_t NumAttributes() const { return m_attributes.size(); }
+ size_t NumAttributes() const { return m_attributes.size(); }
dw_attr_t GetAttrByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; }
dw_form_t GetFormByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; }
bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t& attr, dw_form_t& form) const
@@ -63,8 +63,8 @@
const DWARFCompileUnit* cu,
const uint32_t strp_min_len);
uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code);
// void Append(BinaryStreamBuf& out_buff) const;
bool IsValid();
void Dump(lldb_private::Stream *s) const;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h 2013-03-03 09:35:50.251457352 +0100
@@ -25,12 +25,12 @@
void set_attr(dw_attr_t attr) { m_attr_form = (m_attr_form & 0x0000ffffu) | (attr << 16); }
void set_form(dw_form_t form) { m_attr_form = (m_attr_form & 0xffff0000u) | form; }
dw_attr_t get_attr() const { return m_attr_form >> 16; }
- dw_form_t get_form() const { return m_attr_form; }
+ dw_form_t get_form() const { return (dw_form_t)m_attr_form; }
void get(dw_attr_t& attr, dw_form_t& form) const
{
register uint32_t attr_form = m_attr_form;
attr = attr_form >> 16;
- form = attr_form;
+ form = (dw_form_t)attr_form;
}
bool operator == (const DWARFAttribute& rhs) const { return m_attr_form == rhs.m_attr_form; }
typedef std::vector<DWARFAttribute> collection;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -13,6 +13,8 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -43,7 +45,10 @@
m_length (0),
m_version (0),
m_addr_size (DWARFCompileUnit::GetDefaultAddressSize()),
- m_producer (eProducerInvalid)
+ m_producer (eProducerInvalid),
+ m_producer_version_major (0),
+ m_producer_version_minor (0),
+ m_producer_version_update (0)
{
}
@@ -63,7 +68,7 @@
}
bool
-DWARFCompileUnit::Extract(const DataExtractor &debug_info, uint32_t* offset_ptr)
+DWARFCompileUnit::Extract(const DataExtractor &debug_info, lldb::offset_t *offset_ptr)
{
Clear();
@@ -98,7 +103,7 @@
dw_offset_t
-DWARFCompileUnit::Extract(dw_offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs)
+DWARFCompileUnit::Extract(lldb::offset_t offset, const DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs)
{
Clear();
@@ -162,8 +167,8 @@
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
- uint32_t offset = GetFirstDIEOffset();
- uint32_t next_cu_offset = GetNextCompileUnitOffset();
+ lldb::offset_t offset = GetFirstDIEOffset();
+ lldb::offset_t next_cu_offset = GetNextCompileUnitOffset();
DWARFDebugInfoEntry die;
// Keep a flat array of the DIE for binary lookup by DIE offset
@@ -268,7 +273,7 @@
// unit header).
if (offset > next_cu_offset)
{
- m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8x\n",
+ m_dwarf2Data->GetObjectFile()->GetModule()->ReportWarning ("DWARF compile unit extends beyond its bounds cu 0x%8.8x at 0x%8.8" PRIx64 "\n",
GetOffset(),
offset);
}
@@ -390,6 +395,31 @@
if (die)
die->BuildAddressRangeTable(dwarf2Data, this, debug_aranges);
+ if (debug_aranges->IsEmpty())
+ {
+ // We got nothing from the functions, maybe we have a line tables only
+ // situation. Check the line tables and build the arange table from this.
+ SymbolContext sc;
+ sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this);
+ if (sc.comp_unit)
+ {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+
+ if (line_table)
+ {
+ LineTable::FileAddressRanges file_ranges;
+ const bool append = true;
+ const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append);
+ for (uint32_t idx=0; idx<num_ranges; ++idx)
+ {
+ const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx);
+ debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+ printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd());
+ }
+ }
+ }
+ }
+
// Keep memory down by clearing DIEs if this generate function
// caused them to be parsed
if (clear_dies)
@@ -654,6 +684,7 @@
// break;
case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
if (attributes.ExtractFormValueAtIndex(m_dwarf2Data, i, form_value))
mangled_cstr = form_value.AsCString(debug_str);
break;
@@ -733,28 +764,22 @@
{
// Note, this check is also done in ParseMethodName, but since this is a hot loop, we do the
// simple inlined check outside the call.
- if (ObjCLanguageRuntime::IsPossibleObjCMethodName(name))
+ ObjCLanguageRuntime::MethodName objc_method(name, true);
+ if (objc_method.IsValid(true))
{
- ConstString objc_class_name;
- ConstString objc_selector_name;
- ConstString objc_fullname_no_category_name;
- ConstString objc_class_name_no_category;
- if (ObjCLanguageRuntime::ParseMethodName (name,
- &objc_class_name,
- &objc_selector_name,
- &objc_fullname_no_category_name,
- &objc_class_name_no_category))
- {
- func_fullnames.Insert (ConstString(name), die.GetOffset());
- if (objc_class_name)
- objc_class_selectors.Insert(objc_class_name, die.GetOffset());
- if (objc_class_name_no_category)
- objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset());
- if (objc_selector_name)
- func_selectors.Insert (objc_selector_name, die.GetOffset());
- if (objc_fullname_no_category_name)
- func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset());
- }
+ ConstString objc_class_name_with_category (objc_method.GetClassNameWithCategory());
+ ConstString objc_selector_name (objc_method.GetSelector());
+ ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true));
+ ConstString objc_class_name_no_category (objc_method.GetClassName());
+ func_fullnames.Insert (ConstString(name), die.GetOffset());
+ if (objc_class_name_with_category)
+ objc_class_selectors.Insert(objc_class_name_with_category, die.GetOffset());
+ if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category)
+ objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset());
+ if (objc_selector_name)
+ func_selectors.Insert (objc_selector_name, die.GetOffset());
+ if (objc_fullname_no_category_name)
+ func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset());
}
// If we have a mangled name, then the DW_AT_name attribute
// is usually the method name without the class or any parameters
@@ -883,9 +908,23 @@
}
bool
+DWARFCompileUnit::Supports_unnamed_objc_bitfields ()
+{
+ if (GetProducer() == eProducerClang)
+ {
+ const uint32_t major_version = GetProducerVersionMajor();
+ if (major_version > 425 || (major_version == 425 && GetProducerVersionUpdate() >= 13))
+ return true;
+ else
+ return false;
+ }
+ return true; // Assume all other compilers didn't have incorrect ObjC bitfield info
+}
+
+bool
DWARFCompileUnit::Supports_DW_AT_APPLE_objc_complete_type ()
{
- if (GetProducer() == eProcucerLLVMGCC)
+ if (GetProducer() == eProducerLLVMGCC)
return false;
return true;
}
@@ -895,34 +934,81 @@
{
// llvm-gcc makes completely invalid decl file attributes and won't ever
// be fixed, so we need to know to ignore these.
- return GetProducer() == eProcucerLLVMGCC;
+ return GetProducer() == eProducerLLVMGCC;
}
-DWARFCompileUnit::Producer
-DWARFCompileUnit::GetProducer ()
+void
+DWARFCompileUnit::ParseProducerInfo ()
{
- if (m_producer == eProducerInvalid)
+ m_producer_version_major = UINT32_MAX;
+ m_producer_version_minor = UINT32_MAX;
+ m_producer_version_update = UINT32_MAX;
+
+ const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly();
+ if (die)
{
- const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly();
- if (die)
+
+ const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL);
+ if (producer_cstr)
{
- const char *producer_cstr = die->GetAttributeValueAsString(m_dwarf2Data, this, DW_AT_producer, NULL);
- if (producer_cstr)
+ RegularExpression llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$");
+ if (llvm_gcc_regex.Execute (producer_cstr))
{
- RegularExpression g_llvm_gcc_regex("^4\\.[012]\\.[01] \\(Based on Apple Inc\\. build [0-9]+\\) \\(LLVM build [\\.0-9]+\\)$");
- if (g_llvm_gcc_regex.Execute (producer_cstr))
- m_producer = eProcucerLLVMGCC;
- else if (strstr(producer_cstr, "clang"))
- m_producer = eProducerClang;
- else if (strstr(producer_cstr, "GNU"))
- m_producer = eProducerGCC;
+ m_producer = eProducerLLVMGCC;
}
+ else if (strstr(producer_cstr, "clang"))
+ {
+ RegularExpression clang_regex("clang-([0-9]+)\\.([0-9]+)\\.([0-9]+)");
+ if (clang_regex.Execute (producer_cstr, 3))
+ {
+ std::string str;
+ if (clang_regex.GetMatchAtIndex (producer_cstr, 1, str))
+ m_producer_version_major = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (clang_regex.GetMatchAtIndex (producer_cstr, 2, str))
+ m_producer_version_minor = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ if (clang_regex.GetMatchAtIndex (producer_cstr, 3, str))
+ m_producer_version_update = Args::StringToUInt32(str.c_str(), UINT32_MAX, 10);
+ }
+ m_producer = eProducerClang;
+ }
+ else if (strstr(producer_cstr, "GNU"))
+ m_producer = eProducerGCC;
}
- if (m_producer == eProducerInvalid)
- m_producer = eProcucerOther;
}
+ if (m_producer == eProducerInvalid)
+ m_producer = eProcucerOther;
+}
+
+DWARFCompileUnit::Producer
+DWARFCompileUnit::GetProducer ()
+{
+ if (m_producer == eProducerInvalid)
+ ParseProducerInfo ();
return m_producer;
}
+uint32_t
+DWARFCompileUnit::GetProducerVersionMajor()
+{
+ if (m_producer_version_major == 0)
+ ParseProducerInfo ();
+ return m_producer_version_major;
+}
+
+uint32_t
+DWARFCompileUnit::GetProducerVersionMinor()
+{
+ if (m_producer_version_minor == 0)
+ ParseProducerInfo ();
+ return m_producer_version_minor;
+}
+
+uint32_t
+DWARFCompileUnit::GetProducerVersionUpdate()
+{
+ if (m_producer_version_update == 0)
+ ParseProducerInfo ();
+ return m_producer_version_update;
+}
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h 2013-03-03 09:35:50.251457352 +0100
@@ -23,14 +23,14 @@
eProducerInvalid = 0,
eProducerClang,
eProducerGCC,
- eProcucerLLVMGCC,
+ eProducerLLVMGCC,
eProcucerOther
};
DWARFCompileUnit(SymbolFileDWARF* dwarf2Data);
- bool Extract(const lldb_private::DataExtractor &debug_info, uint32_t* offset_ptr);
- dw_offset_t Extract(dw_offset_t offset, const lldb_private::DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs);
+ bool Extract(const lldb_private::DataExtractor &debug_info, lldb::offset_t *offset_ptr);
+ dw_offset_t Extract(lldb::offset_t offset, const lldb_private::DataExtractor& debug_info_data, const DWARFAbbreviationDeclarationSet* abbrevs);
size_t ExtractDIEsIfNeeded (bool cu_die_only);
bool LookupAddress(
const dw_addr_t address,
@@ -144,6 +144,9 @@
bool
DW_AT_decl_file_attributes_are_invalid();
+ bool
+ Supports_unnamed_objc_bitfields ();
+
// void
// AddGlobalDIEByIndex (uint32_t die_idx);
//
@@ -173,6 +176,14 @@
Producer
GetProducer ();
+ uint32_t
+ GetProducerVersionMajor();
+
+ uint32_t
+ GetProducerVersionMinor();
+
+ uint32_t
+ GetProducerVersionUpdate();
protected:
SymbolFileDWARF* m_dwarf2Data;
@@ -186,6 +197,12 @@
uint16_t m_version;
uint8_t m_addr_size;
Producer m_producer;
+ uint32_t m_producer_version_major;
+ uint32_t m_producer_version_minor;
+ uint32_t m_producer_version_update;
+
+ void
+ ParseProducerInfo ();
private:
DISALLOW_COPY_AND_ASSIGN (DWARFCompileUnit);
};
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp 2013-03-03 09:35:50.251457352 +0100
@@ -30,9 +30,9 @@
// DWARFAbbreviationDeclarationSet::Extract()
//----------------------------------------------------------------------
bool
-DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
{
- const uint32_t begin_offset = *offset_ptr;
+ const lldb::offset_t begin_offset = *offset_ptr;
m_offset = begin_offset;
Clear();
DWARFAbbreviationDeclaration abbrevDeclaration;
@@ -144,7 +144,7 @@
void
DWARFDebugAbbrev::Parse(const DataExtractor& data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (data.ValidOffset(offset))
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h 2013-03-03 09:35:50.251457352 +0100
@@ -43,7 +43,7 @@
void Clear();
dw_offset_t GetOffset() const { return m_offset; }
void Dump(lldb_private::Stream *s) const;
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr);
//void Encode(BinaryStreamBuf& debug_abbrev_buf) const;
dw_uleb128_t AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl);
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -60,7 +60,7 @@
{
if (debug_aranges_data.ValidOffset(0))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
DWARFDebugArangeSet set;
Range range;
@@ -118,7 +118,7 @@
{
const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
if (entry)
- log->Printf ("0x%8.8x: [0x%llx - 0x%llx)",
+ log->Printf ("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")",
entry->data,
entry->GetRangeBase(),
entry->GetRangeEnd());
@@ -143,7 +143,7 @@
if (log)
{
orig_arange_size = m_aranges.GetSize();
- log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %llu entries", minimize, (uint64_t)orig_arange_size);
+ log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 " entries", minimize, (uint64_t)orig_arange_size);
}
m_aranges.Sort();
@@ -155,7 +155,7 @@
{
const size_t new_arange_size = m_aranges.GetSize();
const size_t delta = orig_arange_size - new_arange_size;
- log->Printf ("DWARFDebugAranges::Sort() %llu entries after minimizing (%llu entries combined for %llu bytes saved)",
+ log->Printf ("DWARFDebugAranges::Sort() %" PRIu64 " entries after minimizing (%" PRIu64 " entries combined for %" PRIu64 " bytes saved)",
(uint64_t)new_arange_size,
(uint64_t)delta,
(uint64_t)delta * sizeof(Range));
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -162,7 +162,7 @@
}
bool
-DWARFDebugArangeSet::Extract(const DataExtractor &data, uint32_t* offset_ptr)
+DWARFDebugArangeSet::Extract(const DataExtractor &data, lldb::offset_t *offset_ptr)
{
if (data.ValidOffset(*offset_ptr))
{
@@ -243,7 +243,7 @@
DescriptorConstIter pos;
DescriptorConstIter end = m_arange_descriptors.end();
for (pos = m_arange_descriptors.begin(); pos != end; ++pos)
- s->Printf("[0x%*.*llx - 0x%*.*llx)\n",
+ s->Printf("[0x%*.*" PRIx64 " - 0x%*.*" PRIx64 ")\n",
hex_width, hex_width, pos->address,
hex_width, hex_width, pos->end_address());
}
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h 2013-03-03 09:35:50.255457352 +0100
@@ -41,12 +41,12 @@
void SetHeader(uint16_t version, uint32_t cu_offset, uint8_t addr_size, uint8_t seg_size);
void AddDescriptor(const DWARFDebugArangeSet::Descriptor& range);
void Compact();
- bool Extract(const lldb_private::DataExtractor &data, uint32_t* offset_ptr);
+ bool Extract(const lldb_private::DataExtractor &data, lldb::offset_t *offset_ptr);
void Dump(lldb_private::Stream *s) const;
dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
dw_offset_t GetOffsetOfNextEntry() const;
dw_offset_t FindAddress(dw_addr_t address) const;
- uint32_t NumDescriptors() const { return m_arange_descriptors.size(); }
+ size_t NumDescriptors() const { return m_arange_descriptors.size(); }
const Header& GetHeader() const { return m_header; }
const Descriptor* GetDescriptor(uint32_t i) const
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h 2013-03-03 09:35:50.255457352 +0100
@@ -66,7 +66,7 @@
{
return m_aranges.IsEmpty();
}
- uint32_t
+ size_t
GetNumRanges() const
{
return m_aranges.GetSize();
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -73,10 +73,9 @@
log->Printf ("DWARFDebugInfo::GetCompileUnitAranges() for \"%s/%s\" by parsing",
m_dwarf2Data->GetObjectFile()->GetFileSpec().GetDirectory().GetCString(),
m_dwarf2Data->GetObjectFile()->GetFileSpec().GetFilename().GetCString());
- const uint32_t num_compile_units = GetNumCompileUnits();
- uint32_t idx;
+ const size_t num_compile_units = GetNumCompileUnits();
const bool clear_dies_if_already_not_parsed = true;
- for (idx = 0; idx < num_compile_units; ++idx)
+ for (size_t idx = 0; idx < num_compile_units; ++idx)
{
DWARFCompileUnit* cu = GetCompileUnitAtIndex(idx);
if (cu)
@@ -148,7 +147,7 @@
{
if (m_dwarf2Data != NULL)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
const DataExtractor &debug_info_data = m_dwarf2Data->get_debug_info_data();
while (debug_info_data.ValidOffset(offset))
{
@@ -168,7 +167,7 @@
}
}
-uint32_t
+size_t
DWARFDebugInfo::GetNumCompileUnits()
{
ParseCompileUnitHeadersIfNeeded();
@@ -395,7 +394,7 @@
{
if (dwarf2Data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t depth = 0;
DWARFCompileUnitSP cu(new DWARFCompileUnit(dwarf2Data));
if (cu.get() == NULL)
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -89,7 +89,7 @@
DWARFDebugInfoEntry::Attributes::ExtractFormValueAtIndex (SymbolFileDWARF* dwarf2Data, uint32_t i, DWARFFormValue &form_value) const
{
form_value.SetForm(FormAtIndex(i));
- dw_offset_t offset = DIEOffsetAtIndex(i);
+ lldb::offset_t offset = DIEOffsetAtIndex(i);
return form_value.ExtractValue(dwarf2Data->get_debug_info_data(), &offset, CompileUnitAtIndex(i));
}
@@ -119,7 +119,7 @@
const DataExtractor& debug_info_data,
const DWARFCompileUnit* cu,
const uint8_t *fixed_form_sizes,
- uint32_t* offset_ptr
+ lldb::offset_t *offset_ptr
)
{
m_offset = *offset_ptr;
@@ -134,7 +134,7 @@
if (m_abbr_idx)
{
- uint32_t offset = *offset_ptr;
+ lldb::offset_t offset = *offset_ptr;
const DWARFAbbreviationDeclaration *abbrevDecl = cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);
@@ -273,14 +273,14 @@
(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- uint32_t* offset_ptr
+ lldb::offset_t *offset_ptr
)
{
const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
// const DataExtractor& debug_str_data = dwarf2Data->get_debug_str_data();
const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
const uint8_t cu_addr_size = cu->GetAddressByteSize();
- uint32_t offset = *offset_ptr;
+ lldb::offset_t offset = *offset_ptr;
// if (offset >= cu_end_offset)
// Log::Error("DIE at offset 0x%8.8x is beyond the end of the current compile unit (0x%8.8x)", m_offset, cu_end_offset);
if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset))
@@ -745,12 +745,12 @@
if (dwarf2Data == NULL)
return false;
- dw_addr_t lo_pc = DW_INVALID_ADDRESS;
- dw_addr_t hi_pc = DW_INVALID_ADDRESS;
+ dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
std::vector<dw_offset_t> die_offsets;
bool set_frame_base_loclist_addr = false;
- dw_offset_t offset;
+ lldb::offset_t offset;
const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
if (abbrevDecl)
@@ -798,6 +798,7 @@
break;
case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
if (mangled == NULL)
mangled = form_value.AsCString(&dwarf2Data->get_debug_str_data());
break;
@@ -858,7 +859,7 @@
if (loc_list_length > 0)
{
frame_base->SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
- if (lo_pc != DW_INVALID_ADDRESS)
+ if (lo_pc != LLDB_INVALID_ADDRESS)
{
assert (lo_pc >= cu->GetBaseAddress());
frame_base->SetLocationListSlide(lo_pc - cu->GetBaseAddress());
@@ -881,9 +882,9 @@
if (ranges.IsEmpty())
{
- if (lo_pc != DW_INVALID_ADDRESS)
+ if (lo_pc != LLDB_INVALID_ADDRESS)
{
- if (hi_pc != DW_INVALID_ADDRESS && hi_pc > lo_pc)
+ if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
ranges.Append(DWARFDebugRanges::Range (lo_pc, hi_pc - lo_pc));
else
ranges.Append(DWARFDebugRanges::Range (lo_pc, 0));
@@ -933,7 +934,7 @@
) const
{
const DataExtractor& debug_info_data = dwarf2Data->get_debug_info_data();
- uint32_t offset = m_offset;
+ lldb::offset_t offset = m_offset;
if (debug_info_data.ValidOffset(offset))
{
@@ -1027,7 +1028,7 @@
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
const DataExtractor& debug_info_data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
Stream &s,
dw_attr_t attr,
dw_form_t form
@@ -1077,7 +1078,7 @@
{
case DW_AT_stmt_list:
if ( verbose ) s.PutCString(" ( ");
- s.Printf( "0x%8.8llx", form_value.Unsigned());
+ s.Printf( "0x%8.8" PRIx64, form_value.Unsigned());
if ( verbose ) s.PutCString(" )");
break;
@@ -1157,7 +1158,7 @@
{
if ( !verbose )
form_value.Dump(s, debug_str_data, cu);
- uint32_t ranges_offset = form_value.Unsigned();
+ lldb::offset_t ranges_offset = form_value.Unsigned();
dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
if (dwarf2Data)
DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), &ranges_offset, base_addr);
@@ -1189,7 +1190,7 @@
uint32_t curr_depth
) const
{
- uint32_t offset;
+ lldb::offset_t offset;
const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
if (abbrevDecl)
@@ -1286,7 +1287,7 @@
dw_offset_t* end_attr_offset_ptr
) const
{
- uint32_t offset;
+ lldb::offset_t offset;
const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
if (abbrevDecl)
@@ -1437,7 +1438,7 @@
// We have a location list offset as the value that is
// the offset into the .debug_loc section that describes
// the value over it's lifetime
- dw_offset_t debug_loc_offset = form_value.Unsigned();
+ lldb::offset_t debug_loc_offset = form_value.Unsigned();
if (dwarf2Data)
{
assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
@@ -1488,6 +1489,9 @@
if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+ if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
+ name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+
if (substitute_name_allowed && name == NULL)
{
if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
@@ -1518,6 +1522,8 @@
if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
+ else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
+ name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
@@ -1547,7 +1553,7 @@
(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- const uint32_t die_offset,
+ const dw_offset_t die_offset,
Stream &s
)
{
@@ -1558,7 +1564,7 @@
}
DWARFDebugInfoEntry die;
- uint32_t offset = die_offset;
+ lldb::offset_t offset = die_offset;
if (die.Extract(dwarf2Data, cu, &offset))
{
if (die.IsNULL())
@@ -1596,7 +1602,7 @@
(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- const uint32_t die_offset,
+ const dw_offset_t die_offset,
Stream &s
)
{
@@ -1607,7 +1613,7 @@
}
DWARFDebugInfoEntry die;
- uint32_t offset = die_offset;
+ lldb::offset_t offset = die_offset;
if (die.Extract(dwarf2Data, cu, &offset))
{
if (die.IsNULL())
@@ -1714,11 +1720,11 @@
{
if (m_tag == DW_TAG_subprogram)
{
- dw_addr_t hi_pc = DW_INVALID_ADDRESS;
- dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (lo_pc != DW_INVALID_ADDRESS)
- hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
- if (hi_pc != DW_INVALID_ADDRESS)
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS)
+ hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS)
{
/// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
debug_aranges->AppendRange (cu->GetOffset(), lo_pc, hi_pc);
@@ -1755,13 +1761,13 @@
{
if (m_tag == DW_TAG_subprogram)
{
- dw_addr_t hi_pc = DW_INVALID_ADDRESS;
- dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (lo_pc != DW_INVALID_ADDRESS)
- hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
- if (hi_pc != DW_INVALID_ADDRESS)
+ dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
+ dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS)
+ hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS)
{
- // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16llx - 0x%16.16llx)\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
+ // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
debug_aranges->AppendRange (GetOffset(), lo_pc, hi_pc);
}
}
@@ -2046,11 +2052,11 @@
if (match_addr_range)
{
- dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (lo_pc != DW_INVALID_ADDRESS)
+ dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (lo_pc != LLDB_INVALID_ADDRESS)
{
- dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, DW_INVALID_ADDRESS);
- if (hi_pc != DW_INVALID_ADDRESS)
+ dw_addr_t hi_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_high_pc, LLDB_INVALID_ADDRESS);
+ if (hi_pc != LLDB_INVALID_ADDRESS)
{
// printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
if ((lo_pc <= address) && (address < hi_pc))
@@ -2160,7 +2166,7 @@
const DWARFAbbreviationDeclaration*
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit *cu,
- dw_offset_t &offset) const
+ lldb::offset_t &offset) const
{
if (dwarf2Data)
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h 2013-03-03 09:35:50.255457352 +0100
@@ -75,7 +75,7 @@
bool ContainsAttribute(dw_attr_t attr) const;
bool RemoveAttribute(dw_attr_t attr);
void Clear() { m_infos.clear(); }
- uint32_t Size() const { return m_infos.size(); }
+ size_t Size() const { return m_infos.size(); }
protected:
struct Info
@@ -145,12 +145,12 @@
const lldb_private::DataExtractor& debug_info_data,
const DWARFCompileUnit* cu,
const uint8_t *fixed_form_sizes,
- dw_offset_t* offset_ptr);
+ lldb::offset_t* offset_ptr);
bool Extract(
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
- dw_offset_t* offset_ptr);
+ lldb::offset_t* offset_ptr);
bool LookupAddress(
const dw_addr_t address,
@@ -277,7 +277,7 @@
SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit* cu,
const lldb_private::DataExtractor& debug_info_data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
lldb_private::Stream &s,
dw_attr_t attr,
dw_form_t form);
@@ -304,7 +304,7 @@
const DWARFAbbreviationDeclaration*
GetAbbreviationDeclarationPtr (SymbolFileDWARF* dwarf2Data,
const DWARFCompileUnit *cu,
- dw_offset_t &offset) const;
+ lldb::offset_t &offset) const;
dw_tag_t
Tag () const
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h 2013-03-03 09:35:50.255457352 +0100
@@ -45,7 +45,7 @@
DWARFDebugInfoEntry** block_die);
void AddCompileUnit(DWARFCompileUnitSP& cu);
- uint32_t GetNumCompileUnits();
+ size_t GetNumCompileUnits();
bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
DWARFCompileUnit* GetCompileUnitAtIndex(uint32_t idx);
DWARFCompileUnitSP GetCompileUnit(dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -35,11 +35,11 @@
DWARFDebugLine::Parse(const DataExtractor& debug_line_data)
{
m_lineTableMap.clear();
- dw_offset_t offset = 0;
+ lldb::offset_t offset = 0;
LineTable::shared_ptr line_table_sp(new LineTable);
while (debug_line_data.ValidOffset(offset))
{
- const uint32_t debug_line_offset = offset;
+ const lldb::offset_t debug_line_offset = offset;
if (line_table_sp.get() == NULL)
break;
@@ -100,7 +100,7 @@
}
else
{
- log->Printf( "0x%16.16llx %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
+ log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u%s\n", state.address, state.line, state.column, state.file, state.end_sequence ? " END" : "");
}
}
@@ -135,7 +135,7 @@
{
if (debug_line_data.ValidOffset(debug_line_offset))
{
- uint32_t offset = debug_line_offset;
+ lldb::offset_t offset = debug_line_offset;
log->Printf( "----------------------------------------------------------------------\n"
"debug_line[0x%8.8x]\n"
"----------------------------------------------------------------------\n", debug_line_offset);
@@ -185,7 +185,7 @@
dw_offset_t
DWARFDebugLine::DumpStatementOpcodes(Log *log, const DataExtractor& debug_line_data, const dw_offset_t debug_line_offset, uint32_t flags)
{
- uint32_t offset = debug_line_offset;
+ lldb::offset_t offset = debug_line_offset;
if (debug_line_data.ValidOffset(offset))
{
Prologue prologue;
@@ -200,7 +200,7 @@
else
{
offset = debug_line_offset;
- log->Printf( "0x%8.8x: skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
+ log->Printf( "0x%8.8" PRIx64 ": skipping pad byte %2.2x", offset, debug_line_data.GetU8(&offset));
return offset;
}
@@ -236,7 +236,7 @@
case DW_LNE_set_address :
{
row.address = debug_line_data.GetMaxU64(&offset, arg_size);
- log->Printf( "0x%8.8x: DW_LNE_set_address (0x%llx)", op_offset, row.address);
+ log->Printf( "0x%8.8x: DW_LNE_set_address (0x%" PRIx64 ")", op_offset, row.address);
}
break;
@@ -314,7 +314,7 @@
{
uint8_t adjust_opcode = 255 - prologue.opcode_base;
dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
- log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8llx)", op_offset, addr_offset);
+ log->Printf( "0x%8.8x: DW_LNS_const_add_pc (0x%8.8" PRIx64 ")", op_offset, addr_offset);
row.address += addr_offset;
}
break;
@@ -362,7 +362,7 @@
uint8_t adjust_opcode = opcode - prologue.opcode_base;
dw_addr_t addr_offset = (adjust_opcode / prologue.line_range) * prologue.min_inst_length;
int32_t line_offset = prologue.line_base + (adjust_opcode % prologue.line_range);
- log->Printf("0x%8.8x: address += 0x%llx, line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
+ log->Printf("0x%8.8x: address += 0x%" PRIx64 ", line += %i\n", op_offset, (uint64_t)addr_offset, line_offset);
row.address += addr_offset;
row.line += line_offset;
row.Dump (log);
@@ -388,7 +388,7 @@
void
DWARFDebugLine::Parse(const DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (debug_line_data.ValidOffset(offset))
{
if (!ParseStatementTable(debug_line_data, &offset, callback, userData))
@@ -401,9 +401,9 @@
// DWARFDebugLine::ParsePrologue
//----------------------------------------------------------------------
bool
-DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue)
+DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue)
{
- const uint32_t prologue_offset = *offset_ptr;
+ const lldb::offset_t prologue_offset = *offset_ptr;
//DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr);
@@ -416,7 +416,7 @@
return false;
prologue->prologue_length = debug_line_data.GetU32(offset_ptr);
- const dw_offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
+ const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
prologue->min_inst_length = debug_line_data.GetU8(offset_ptr);
prologue->default_is_stmt = debug_line_data.GetU8(offset_ptr);
prologue->line_base = debug_line_data.GetU8(offset_ptr);
@@ -459,8 +459,8 @@
if (*offset_ptr != end_prologue_offset)
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended ad 0x%8.8x\n",
- prologue_offset,
+ "warning: parsing line table prologue at 0x%8.8" PRIx64 " should have ended at 0x%8.8" PRIx64 " but it ended ad 0x%8.8" PRIx64 "\n",
+ prologue_offset,
end_prologue_offset,
*offset_ptr);
}
@@ -474,7 +474,7 @@
dw_offset_t stmt_list,
FileSpecList &support_files)
{
- uint32_t offset = stmt_list + 4; // Skip the total length
+ lldb::offset_t offset = stmt_list + 4; // Skip the total length
const char * s;
uint32_t version = debug_line_data.GetU16(&offset);
if (version != 2)
@@ -554,7 +554,7 @@
if (offset != end_prologue_offset)
{
Host::SystemLog (Host::eSystemLogError,
- "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended ad 0x%8.8x\n",
+ "warning: parsing line table prologue at 0x%8.8x should have ended at 0x%8.8x but it ended ad 0x%8.8" PRIx64 "\n",
stmt_list,
end_prologue_offset,
offset);
@@ -573,7 +573,7 @@
DWARFDebugLine::ParseStatementTable
(
const DataExtractor& debug_line_data,
- dw_offset_t* offset_ptr,
+ lldb::offset_t* offset_ptr,
DWARFDebugLine::State::Callback callback,
void* userData
)
@@ -613,7 +613,7 @@
{
// Extended Opcodes always start with a zero opcode followed by
// a uleb128 length so you can skip ones you don't know about
- dw_offset_t ext_offset = *offset_ptr;
+ lldb::offset_t ext_offset = *offset_ptr;
dw_uleb128_t len = debug_line_data.GetULEB128(offset_ptr);
dw_offset_t arg_size = len - (*offset_ptr - ext_offset);
@@ -873,7 +873,7 @@
// the prologue and all rows.
//----------------------------------------------------------------------
bool
-DWARFDebugLine::ParseStatementTable(const DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table)
+DWARFDebugLine::ParseStatementTable(const DataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table)
{
return ParseStatementTable(debug_line_data, offset_ptr, ParseStatementTableCallback, line_table);
}
@@ -1122,7 +1122,7 @@
void
DWARFDebugLine::Row::Dump(Log *log) const
{
- log->Printf( "0x%16.16llx %6u %6u %6u %3u %s%s%s%s%s",
+ log->Printf( "0x%16.16" PRIx64 " %6u %6u %6u %3u %s%s%s%s%s",
address,
line,
column,
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h 2013-03-03 09:35:50.255457352 +0100
@@ -197,11 +197,11 @@
static bool DumpOpcodes(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET, uint32_t dump_flags = 0); // If line_offset is invalid, dump everything
static bool DumpLineTableRows(lldb_private::Log *log, SymbolFileDWARF* dwarf2Data, dw_offset_t line_offset = DW_INVALID_OFFSET); // If line_offset is invalid, dump everything
static bool ParseSupportFiles(const lldb::ModuleSP &module_sp, const lldb_private::DataExtractor& debug_line_data, const char *cu_comp_dir, dw_offset_t stmt_list, lldb_private::FileSpecList &support_files);
- static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, Prologue* prologue);
- static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, dw_offset_t* offset_ptr, State::Callback callback, void* userData);
+ static bool ParsePrologue(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, Prologue* prologue);
+ static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t* offset_ptr, State::Callback callback, void* userData);
static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset);
static dw_offset_t DumpStatementOpcodes(lldb_private::Log *log, const lldb_private::DataExtractor& debug_line_data, const dw_offset_t line_offset, uint32_t flags);
- static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, uint32_t* offset_ptr, LineTable* line_table);
+ static bool ParseStatementTable(const lldb_private::DataExtractor& debug_line_data, lldb::offset_t *offset_ptr, LineTable* line_table);
static void Parse(const lldb_private::DataExtractor& debug_line_data, DWARFDebugLine::State::Callback callback, void* userData);
// static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, const DWARFDebugLine::Row::collection& state_coll, const uint32_t addr_size, BinaryStreamBuf &debug_line_data);
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -26,7 +26,7 @@
}
void
-DWARFDebugMacinfo::Dump(Stream *s, const DataExtractor& macinfo_data, dw_offset_t offset)
+DWARFDebugMacinfo::Dump(Stream *s, const DataExtractor& macinfo_data, lldb::offset_t offset)
{
DWARFDebugMacinfoEntry maninfo_entry;
if (macinfo_data.GetByteSize() == 0)
@@ -34,7 +34,7 @@
s->PutCString("< EMPTY >\n");
return;
}
- if (offset == DW_INVALID_OFFSET)
+ if (offset == LLDB_INVALID_OFFSET)
{
offset = 0;
while (maninfo_entry.Extract(macinfo_data, &offset))
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -80,7 +80,7 @@
bool
-DWARFDebugMacinfoEntry::Extract(const DataExtractor& mac_info_data, dw_offset_t* offset_ptr)
+DWARFDebugMacinfoEntry::Extract(const DataExtractor& mac_info_data, lldb::offset_t* offset_ptr)
{
if (mac_info_data.ValidOffset(*offset_ptr))
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfoEntry.h 2013-03-03 09:35:50.255457352 +0100
@@ -39,7 +39,7 @@
bool
Extract(const lldb_private::DataExtractor& mac_info_data,
- dw_offset_t* offset_ptr);
+ lldb::offset_t* offset_ptr);
protected:
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h 2013-03-03 09:35:50.255457352 +0100
@@ -22,7 +22,7 @@
static void
Dump (lldb_private::Stream *s,
const lldb_private::DataExtractor& macinfo_data,
- dw_offset_t offset = DW_INVALID_OFFSET);
+ lldb::offset_t offset = LLDB_INVALID_OFFSET);
};
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -32,15 +32,15 @@
DWARFDebugPubnames::Extract(const DataExtractor& data)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
- "DWARFDebugPubnames::Extract (byte_size = %llu)",
+ "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")",
(uint64_t)data.GetByteSize());
LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES));
if (log)
- log->Printf("DWARFDebugPubnames::Extract (byte_size = %llu)", (uint64_t)data.GetByteSize());
+ log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", (uint64_t)data.GetByteSize());
if (data.ValidOffset(0))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
DWARFDebugPubnamesSet set;
while (data.ValidOffset(offset))
@@ -124,6 +124,7 @@
break;
case DW_AT_MIPS_linkage_name:
+ case DW_AT_linkage_name:
if (attributes.ExtractFormValueAtIndex(dwarf2Data, i, form_value))
mangled = form_value.AsCString(debug_str);
break;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp 2013-03-03 09:35:50.255457352 +0100
@@ -78,7 +78,7 @@
bool
-DWARFDebugPubnamesSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFDebugPubnamesSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
{
if (data.ValidOffset(*offset_ptr))
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.h 2013-03-03 09:35:50.259457351 +0100
@@ -70,7 +70,7 @@
uint32_t NumDescriptors() const { return m_descriptors.size(); }
void AddDescriptor(dw_offset_t cu_rel_offset, const char* name);
void Clear();
- bool Extract(const lldb_private::DataExtractor& debug_pubnames_data, uint32_t* offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& debug_pubnames_data, lldb::offset_t *offset_ptr);
void Dump(lldb_private::Log *s) const;
void InitNameIndexes() const;
void Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp 2013-03-03 09:35:50.259457351 +0100
@@ -28,7 +28,7 @@
DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
{
RangeList range_list;
- dw_offset_t offset = 0;
+ lldb::offset_t offset = 0;
dw_offset_t debug_ranges_offset = offset;
while (Extract(dwarf2Data, &offset, range_list))
{
@@ -82,11 +82,11 @@
//}
bool
-DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, uint32_t* offset_ptr, RangeList &range_list)
+DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, RangeList &range_list)
{
range_list.Clear();
- uint32_t range_offset = *offset_ptr;
+ lldb::offset_t range_offset = *offset_ptr;
const DataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
@@ -105,12 +105,12 @@
{
case 2:
if (begin == 0xFFFFull)
- begin = DW_INVALID_ADDRESS;
+ begin = LLDB_INVALID_ADDRESS;
break;
case 4:
if (begin == 0xFFFFFFFFull)
- begin = DW_INVALID_ADDRESS;
+ begin = LLDB_INVALID_ADDRESS;
break;
case 8:
@@ -130,60 +130,9 @@
return range_offset != *offset_ptr;
}
-//
-//dw_addr_t
-//DWARFDebugRanges::RangeList::LowestAddress(const dw_addr_t cu_base_addr) const
-//{
-// dw_addr_t addr = DW_INVALID_ADDRESS;
-// dw_addr_t curr_base_addr = cu_base_addr;
-// if (!ranges.empty())
-// {
-// Range::const_iterator pos = ranges.begin();
-// Range::const_iterator end_pos = ranges.end();
-// for (pos = ranges.begin(); pos != end_pos; ++pos)
-// {
-// if (pos->begin_offset == DW_INVALID_ADDRESS)
-// curr_base_addr = pos->end_offset;
-// else if (curr_base_addr != DW_INVALID_ADDRESS)
-// {
-// dw_addr_t curr_addr = curr_base_addr + pos->begin_offset;
-// if (addr > curr_addr)
-// addr = curr_addr;
-// }
-// }
-// }
-// return addr;
-//}
-//
-//dw_addr_t
-//DWARFDebugRanges::RangeList::HighestAddress(const dw_addr_t cu_base_addr) const
-//{
-// dw_addr_t addr = 0;
-// dw_addr_t curr_base_addr = cu_base_addr;
-// if (!ranges.empty())
-// {
-// Range::const_iterator pos = ranges.begin();
-// Range::const_iterator end_pos = ranges.end();
-// for (pos = ranges.begin(); pos != end_pos; ++pos)
-// {
-// if (pos->begin_offset == DW_INVALID_ADDRESS)
-// curr_base_addr = pos->end_offset;
-// else if (curr_base_addr != DW_INVALID_ADDRESS)
-// {
-// dw_addr_t curr_addr = curr_base_addr + pos->end_offset;
-// if (addr < curr_addr)
-// addr = curr_addr;
-// }
-// }
-// }
-// if (addr != 0)
-// return addr;
-// return DW_INVALID_ADDRESS;
-//}
-//
void
-DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr)
+DWARFDebugRanges::Dump(Stream &s, const DataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
{
uint32_t addr_size = s.GetAddressByteSize();
bool verbose = s.GetVerbose();
@@ -196,7 +145,7 @@
// Extend 4 byte addresses that consits of 32 bits of 1's to be 64 bits
// of ones
if (begin == 0xFFFFFFFFull && addr_size == 4)
- begin = DW_INVALID_ADDRESS;
+ begin = LLDB_INVALID_ADDRESS;
s.Indent();
if (verbose)
@@ -210,7 +159,7 @@
s.PutCString(" End");
break;
}
- else if (begin == DW_INVALID_ADDRESS)
+ else if (begin == LLDB_INVALID_ADDRESS)
{
// A base address selection entry
base_addr = end;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h 2013-03-03 09:35:50.259457351 +0100
@@ -26,14 +26,14 @@
DWARFDebugRanges();
~DWARFDebugRanges();
void Extract(SymbolFileDWARF* dwarf2Data);
- static void Dump(lldb_private::Stream &s, const lldb_private::DataExtractor& debug_ranges_data, uint32_t* offset_ptr, dw_addr_t cu_base_addr);
+ static void Dump(lldb_private::Stream &s, const lldb_private::DataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
bool FindRanges(dw_offset_t debug_ranges_offset, DWARFDebugRanges::RangeList& range_list) const;
protected:
bool
Extract (SymbolFileDWARF* dwarf2Data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
RangeList &range_list);
typedef std::map<dw_offset_t, RangeList> range_map;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp 2013-03-03 09:35:50.259457351 +0100
@@ -114,7 +114,7 @@
}
bool
-DWARFFormValue::ExtractValue(const DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu)
+DWARFFormValue::ExtractValue(const DataExtractor& data, lldb::offset_t* offset_ptr, const DWARFCompileUnit* cu)
{
bool indirect = false;
bool is_block = false;
@@ -178,13 +178,13 @@
}
bool
-DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu) const
+DWARFFormValue::SkipValue(const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const
{
return DWARFFormValue::SkipValue(m_form, debug_info_data, offset_ptr, cu);
}
bool
-DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu)
+DWARFFormValue::SkipValue(dw_form_t form, const DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu)
{
switch (form)
{
@@ -295,7 +295,7 @@
switch (m_form)
{
case DW_FORM_exprloc:
- case DW_FORM_block: s.Printf("<0x%llx> ", uvalue); break;
+ case DW_FORM_block: s.Printf("<0x%" PRIx64 "> ", uvalue); break;
case DW_FORM_block1: s.Printf("<0x%2.2x> ", (uint8_t)uvalue); break;
case DW_FORM_block2: s.Printf("<0x%4.4x> ", (uint16_t)uvalue); break;
case DW_FORM_block4: s.Printf("<0x%8.8x> ", (uint32_t)uvalue); break;
@@ -343,8 +343,8 @@
case DW_FORM_ref1: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%2.2x", (uint8_t)uvalue); break;
case DW_FORM_ref2: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint16_t)uvalue); break;
case DW_FORM_ref4: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%4.4x", (uint32_t)uvalue); break;
- case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8llx", uvalue); break;
- case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%llx", uvalue); break;
+ case DW_FORM_ref8: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%8.8" PRIx64, uvalue); break;
+ case DW_FORM_ref_udata: cu_relative_offset = true; if (verbose) s.Printf("cu + 0x%" PRIx64, uvalue); break;
// All DW_FORM_indirect attributes should be resolved prior to calling this function
case DW_FORM_indirect: s.PutCString("DW_FORM_indirect"); break;
@@ -359,7 +359,7 @@
if (verbose)
s.PutCString(" => ");
- s.Printf("{0x%8.8llx}", (uvalue + (cu ? cu->GetOffset() : 0)));
+ s.Printf("{0x%8.8" PRIx64 "}", (uvalue + (cu ? cu->GetOffset() : 0)));
}
}
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h 2013-03-03 09:35:50.259457351 +0100
@@ -49,7 +49,9 @@
void SetForm(dw_form_t form) { m_form = form; }
const ValueType& Value() const { return m_value; }
void Dump(lldb_private::Stream &s, const lldb_private::DataExtractor* debug_str_data, const DWARFCompileUnit* cu) const;
- bool ExtractValue(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, const DWARFCompileUnit* cu);
+ bool ExtractValue(const lldb_private::DataExtractor& data,
+ lldb::offset_t* offset_ptr,
+ const DWARFCompileUnit* cu);
bool IsInlinedCStr() const { return (m_value.data != NULL) && m_value.data == (uint8_t*)m_value.value.cstr; }
const uint8_t* BlockData() const;
uint64_t Reference(const DWARFCompileUnit* cu) const;
@@ -60,9 +62,9 @@
int64_t Signed() const { return m_value.value.sval; }
void SetSigned(int64_t sval) { m_value.value.sval = sval; }
const char* AsCString(const lldb_private::DataExtractor* debug_str_data_ptr) const;
- bool SkipValue(const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu) const;
- static bool SkipValue(const dw_form_t form, const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu);
-// static bool TransferValue(dw_form_t form, const lldb_private::DataExtractor& debug_info_data, uint32_t* offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
+ bool SkipValue(const lldb_private::DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu) const;
+ static bool SkipValue(const dw_form_t form, const lldb_private::DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu);
+// static bool TransferValue(dw_form_t form, const lldb_private::DataExtractor& debug_info_data, lldb::offset_t *offset_ptr, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
// static bool TransferValue(const DWARFFormValue& formValue, const DWARFCompileUnit* cu, BinaryStreamBuf& out_buff);
// static bool PutUnsigned(dw_form_t form, dw_offset_t offset, uint64_t value, BinaryStreamBuf& out_buff, const DWARFCompileUnit* cu, bool fixup_cu_relative_refs);
static bool IsBlockForm(const dw_form_t form);
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationDescription.cpp 2013-03-03 09:35:50.259457351 +0100
@@ -15,7 +15,7 @@
using namespace lldb_private;
-static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, uint32_t* offset_ptr, int address_size, int dwarf_ref_size);
+static int print_dwarf_exp_op (Stream &s, const DataExtractor& data, lldb::offset_t *offset_ptr, int address_size, int dwarf_ref_size);
int
print_dwarf_expression (Stream &s,
@@ -25,7 +25,7 @@
bool location_expression)
{
int op_count = 0;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (data.ValidOffset(offset))
{
if (location_expression && op_count > 0)
@@ -48,7 +48,7 @@
static int
print_dwarf_exp_op (Stream &s,
const DataExtractor& data,
- uint32_t* offset_ptr,
+ lldb::offset_t *offset_ptr,
int address_size,
int dwarf_ref_size)
{
@@ -71,7 +71,7 @@
{
uint = data.GetULEB128(offset_ptr);
sint = data.GetSLEB128(offset_ptr);
- s.Printf("%llu %lli", uint, sint);
+ s.Printf("%" PRIu64 " %" PRIi64, uint, sint);
return 0;
}
if (opcode_class != DRC_ONEOPERAND)
@@ -156,16 +156,16 @@
switch (size)
{
- case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+lli", sint); break;
- case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+lli", sint); break;
- case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+lli", sint); break;
- case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+lli", sint); break;
- case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+lli", sint); break;
- case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2llx", uint); break;
- case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4llx", uint); break;
- case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8llx", uint); break;
- case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16llx", uint); break;
- case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%llx", uint); break;
+ case -1: sint = (int8_t) data.GetU8(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -2: sint = (int16_t) data.GetU16(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -4: sint = (int32_t) data.GetU32(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -8: sint = (int64_t) data.GetU64(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case -128: sint = data.GetSLEB128(offset_ptr); s.Printf("%+" PRIi64, sint); break;
+ case 1: uint = data.GetU8(offset_ptr); s.Printf("0x%2.2" PRIx64, uint); break;
+ case 2: uint = data.GetU16(offset_ptr); s.Printf("0x%4.4" PRIx64, uint); break;
+ case 4: uint = data.GetU32(offset_ptr); s.Printf("0x%8.8" PRIx64, uint); break;
+ case 8: uint = data.GetU64(offset_ptr); s.Printf("0x%16.16" PRIx64, uint); break;
+ case 128: uint = data.GetULEB128(offset_ptr); s.Printf("0x%" PRIx64, uint); break;
}
return 0;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationList.cpp 2013-03-03 09:35:50.259457351 +0100
@@ -18,7 +18,7 @@
using namespace lldb_private;
dw_offset_t
-DWARFLocationList::Dump(Stream &s, const DWARFCompileUnit* cu, const DataExtractor& debug_loc_data, dw_offset_t offset)
+DWARFLocationList::Dump(Stream &s, const DWARFCompileUnit* cu, const DataExtractor& debug_loc_data, lldb::offset_t offset)
{
uint64_t start_addr, end_addr;
uint32_t addr_size = DWARFCompileUnit::GetAddressByteSize(cu);
@@ -52,7 +52,7 @@
}
bool
-DWARFLocationList::Extract(const DataExtractor& debug_loc_data, dw_offset_t* offset_ptr, DataExtractor& location_list_data)
+DWARFLocationList::Extract(const DataExtractor& debug_loc_data, lldb::offset_t* offset_ptr, DataExtractor& location_list_data)
{
// Initialize with no data just in case we don't find anything
location_list_data.Clear();
@@ -69,7 +69,7 @@
}
size_t
-DWARFLocationList::Size(const DataExtractor& debug_loc_data, dw_offset_t offset)
+DWARFLocationList::Size(const DataExtractor& debug_loc_data, lldb::offset_t offset)
{
const dw_offset_t debug_loc_offset = offset;
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/DWARFLocationList.h 2013-03-03 09:35:50.259457351 +0100
@@ -19,16 +19,16 @@
Dump (lldb_private::Stream &s,
const DWARFCompileUnit* cu,
const lldb_private::DataExtractor& debug_loc_data,
- dw_offset_t offset);
+ lldb::offset_t offset);
static bool
Extract (const lldb_private::DataExtractor& debug_loc_data,
- dw_offset_t* offset_ptr,
+ lldb::offset_t* offset_ptr,
lldb_private::DataExtractor& location_list_data);
static size_t
Size (const lldb_private::DataExtractor& debug_loc_data,
- dw_offset_t offset);
+ lldb::offset_t offset);
};
#endif // SymbolFileDWARF_DWARFLocationList_h_
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h 2013-03-03 09:35:50.259457351 +0100
@@ -32,18 +32,21 @@
dw_offset_t offset; // The DIE offset
dw_tag_t tag;
uint32_t type_flags; // Any flags for this DIEInfo
+ uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
DIEInfo () :
offset (DW_INVALID_OFFSET),
tag (0),
- type_flags (0)
+ type_flags (0),
+ qualified_name_hash (0)
{
}
- DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f) :
+ DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) :
offset(o),
tag (t),
- type_flags (f)
+ type_flags (f),
+ qualified_name_hash (h)
{
}
@@ -53,6 +56,7 @@
offset = DW_INVALID_OFFSET;
tag = 0;
type_flags = 0;
+ qualified_name_hash = 0;
}
};
@@ -96,6 +100,37 @@
}
}
}
+
+ static void
+ ExtractDIEArray (const DIEInfoArray &die_info_array,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets)
+ {
+ if (tag == 0)
+ {
+ ExtractDIEArray (die_info_array, die_offsets);
+ }
+ else
+ {
+ const size_t count = die_info_array.size();
+ for (size_t i=0; i<count; ++i)
+ {
+ if (qualified_name_hash != die_info_array[i].qualified_name_hash)
+ continue;
+ const dw_tag_t die_tag = die_info_array[i].tag;
+ bool tag_matches = die_tag == 0 || tag == die_tag;
+ if (!tag_matches)
+ {
+ if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type)
+ tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
+ }
+ if (tag_matches)
+ die_offsets.push_back (die_info_array[i].offset);
+ }
+ }
+ }
+
enum AtomType
{
eAtomTypeNULL = 0u,
@@ -103,7 +138,11 @@
eAtomTypeCUOffset = 2u, // DIE offset of the compiler unit header that contains the item in question
eAtomTypeTag = 3u, // DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed 255) or DW_FORM_data2
eAtomTypeNameFlags = 4u, // Flags from enum NameFlags
- eAtomTypeTypeFlags = 5u // Flags from enum TypeFlags
+ eAtomTypeTypeFlags = 5u, // Flags from enum TypeFlags,
+ eAtomTypeQualNameHash = 6u // A 32 bit hash of the full qualified name (since all hash entries are basename only)
+ // For example a type like "std::vector<int>::iterator" would have a name of "iterator"
+ // and a 32 bit hash for "std::vector<int>::iterator" to allow us to not have to pull
+ // in debug info for a type when we know the fully qualified name.
};
// Bit definitions for the eAtomTypeTypeFlags flags
@@ -196,6 +235,7 @@
case eAtomTypeTag: return "die-tag";
case eAtomTypeNameFlags: return "name-flags";
case eAtomTypeTypeFlags: return "type-flags";
+ case eAtomTypeQualNameHash: return "qualified-name-hash";
}
return "<invalid>";
}
@@ -306,8 +346,9 @@
// void
// Dump (std::ostream* ostrm_ptr);
- uint32_t
- Read (const lldb_private::DataExtractor &data, uint32_t offset)
+ lldb::offset_t
+ Read (const lldb_private::DataExtractor &data,
+ lldb::offset_t offset)
{
ClearAtoms ();
@@ -379,8 +420,8 @@
// virtual void
// Dump (std::ostream* ostrm_ptr);
//
- virtual uint32_t
- Read (lldb_private::DataExtractor &data, uint32_t offset)
+ virtual lldb::offset_t
+ Read (lldb_private::DataExtractor &data, lldb::offset_t offset)
{
offset = MappedHash::Header<Prologue>::Read (data, offset);
if (offset != UINT32_MAX)
@@ -392,7 +433,7 @@
bool
Read (const lldb_private::DataExtractor &data,
- uint32_t *offset_ptr,
+ lldb::offset_t *offset_ptr,
DIEInfo &hash_data) const
{
const size_t num_atoms = header_data.atoms.size();
@@ -409,17 +450,22 @@
switch (header_data.atoms[i].type)
{
case eAtomTypeDIEOffset: // DIE offset, check form for encoding
- hash_data.offset = form_value.Reference (header_data.die_base_offset);
+ hash_data.offset = (dw_offset_t)form_value.Reference (header_data.die_base_offset);
break;
case eAtomTypeTag: // DW_TAG value for the DIE
- hash_data.tag = form_value.Unsigned ();
+ hash_data.tag = (dw_tag_t)form_value.Unsigned ();
case eAtomTypeTypeFlags: // Flags from enum TypeFlags
- hash_data.type_flags = form_value.Unsigned ();
+ hash_data.type_flags = (uint32_t)form_value.Unsigned ();
+ break;
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ hash_data.qualified_name_hash = form_value.Unsigned ();
break;
+
default:
- return false;
+ // We can always skip atomes we don't know about
break;
}
}
@@ -462,7 +508,11 @@
strm.PutCString (" )");
}
break;
-
+
+ case eAtomTypeQualNameHash: // Flags from enum TypeFlags
+ strm.Printf ("0x%8.8x", hash_data.qualified_name_hash);
+ break;
+
default:
strm.Printf ("AtomType(0x%x)", header_data.atoms[i].type);
break;
@@ -559,7 +609,7 @@
virtual Result
GetHashDataForName (const char *name,
- uint32_t* hash_data_offset_ptr,
+ lldb::offset_t* hash_data_offset_ptr,
Pair &pair) const
{
pair.key = m_data.GetU32 (hash_data_offset_ptr);
@@ -580,7 +630,7 @@
}
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const uint32_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
+ const size_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
{
// We have at least one HashData entry, and we have enough
@@ -637,7 +687,7 @@
virtual Result
AppendHashDataForRegularExpression (const lldb_private::RegularExpression& regex,
- uint32_t* hash_data_offset_ptr,
+ lldb::offset_t* hash_data_offset_ptr,
Pair &pair) const
{
pair.key = m_data.GetU32 (hash_data_offset_ptr);
@@ -653,7 +703,7 @@
return eResultError;
const uint32_t count = m_data.GetU32 (hash_data_offset_ptr);
- const uint32_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
+ const size_t min_total_hash_data_size = count * m_header.header_data.GetMinumumHashDataByteSize();
if (count > 0 && m_data.ValidOffsetForDataOfSize (*hash_data_offset_ptr, min_total_hash_data_size))
{
const bool match = regex.Execute(strp_cstr);
@@ -712,10 +762,10 @@
Pair pair;
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
{
- uint32_t hash_data_offset = GetHashDataOffset (offset_idx);
+ lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
while (hash_data_offset != UINT32_MAX)
{
- const uint32_t prev_hash_data_offset = hash_data_offset;
+ const lldb::offset_t prev_hash_data_offset = hash_data_offset;
Result hash_result = AppendHashDataForRegularExpression (regex, &hash_data_offset, pair);
if (prev_hash_data_offset == hash_data_offset)
break;
@@ -749,7 +799,7 @@
for (uint32_t offset_idx=0; offset_idx<hash_count; ++offset_idx)
{
bool done = false;
- uint32_t hash_data_offset = GetHashDataOffset (offset_idx);
+ lldb::offset_t hash_data_offset = GetHashDataOffset (offset_idx);
while (!done && hash_data_offset != UINT32_MAX)
{
KeyType key = m_data.GetU32 (&hash_data_offset);
@@ -795,6 +845,18 @@
return die_info_array.size();
}
+ size_t
+ FindByNameAndTagAndQualifiedNameHash (const char *name,
+ const dw_tag_t tag,
+ const uint32_t qualified_name_hash,
+ DIEArray &die_offsets)
+ {
+ DIEInfoArray die_info_array;
+ if (FindByName(name, die_info_array))
+ DWARFMappedHash::ExtractDIEArray (die_info_array, tag, qualified_name_hash, die_offsets);
+ return die_info_array.size();
+ }
+
size_t
FindCompleteObjCClassByName (const char *name, DIEArray &die_offsets, bool must_be_implementation)
{
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp 2013-03-03 09:35:50.263457350 +0100
@@ -126,14 +126,14 @@
{
StreamString log_strm;
const size_t n = m_dies.size();
- log_strm.Printf("DIEStack[%llu]:\n", (uint64_t)n);
+ log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
for (size_t i=0; i<n; i++)
{
DWARFCompileUnit *cu = m_dies[i].cu;
const DWARFDebugInfoEntry *die = m_dies[i].die;
std::string qualified_name;
die->GetQualifiedName(dwarf, cu, qualified_name);
- log_strm.Printf ("[%llu] 0x%8.8x: %s name='%s'\n",
+ log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
(uint64_t)i,
die->GetOffset(),
DW_TAG_value_to_name(die->Tag()),
@@ -991,6 +991,7 @@
DWARFDebugLine::Row prev_row;
SectionSP prev_section_sp;
SectionSP curr_section_sp;
+ llvm::OwningPtr<LineSequence> curr_sequence_ap;
};
//----------------------------------------------------------------------
@@ -1137,20 +1138,36 @@
// We are not in an object file that contains DWARF for an
// N_OSO, this is just a normal DWARF file. The DWARF spec
// guarantees that the addresses will be in increasing order
- // so, since we store line tables in file address order, we
- // can always just append the line entry without needing to
- // search for the correct insertion point (we don't need to
- // use LineEntry::InsertLineEntry()).
- line_table->AppendLineEntry (info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
+ // for a sequence, but the line table for a single compile unit
+ // may contain multiple sequences so we append entries to the
+ // current sequence until we find its end, then we merge the
+ // sequence into the main line table collection.
+
+ // If this is our first time here, we need to create a
+ // sequence container.
+ if (!info->curr_sequence_ap)
+ {
+ info->curr_sequence_ap.reset(line_table->CreateLineSequenceContainer());
+ assert(info->curr_sequence_ap);
+ }
+ line_table->AppendLineEntryToSequence(info->curr_sequence_ap.get(),
+ info->curr_section_sp,
+ curr_line_section_offset,
+ state.line,
+ state.column,
+ state.file,
+ state.is_stmt,
+ state.basic_block,
+ state.prologue_end,
+ state.epilogue_begin,
+ state.end_sequence);
+ if (state.end_sequence)
+ {
+ // First, put the current sequence into the line table.
+ line_table->InsertSequence(info->curr_sequence_ap.get());
+ // Then, empty it to prepare for the next sequence.
+ info->curr_sequence_ap->Clear();
+ }
}
}
@@ -1186,9 +1203,10 @@
false,
DWARFDebugLine::Row(),
SectionSP(),
- SectionSP()
+ SectionSP(),
+ llvm::OwningPtr<LineSequence>()
};
- uint32_t offset = cu_line_offset;
+ lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
sc.comp_unit->SetLineTable(line_table_ap.release());
return true;
@@ -1504,6 +1522,11 @@
DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
{
+ *this = rhs;
+ }
+
+ DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
+ {
m_ast = rhs.m_ast;
m_class_opaque_type = rhs.m_class_opaque_type;
m_property_name = rhs.m_property_name;
@@ -1518,7 +1541,7 @@
m_metadata_ap.reset (new ClangASTMetadata());
*(m_metadata_ap.get()) = *(rhs.m_metadata_ap.get());
}
-
+ return *this;
}
bool Finalize() const
@@ -1545,6 +1568,24 @@
std::auto_ptr<ClangASTMetadata> m_metadata_ap;
};
+struct BitfieldInfo
+{
+ uint64_t bit_size;
+ uint64_t bit_offset;
+
+ BitfieldInfo () :
+ bit_size (LLDB_INVALID_ADDRESS),
+ bit_offset (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ bool IsValid ()
+ {
+ return (bit_size != LLDB_INVALID_ADDRESS) &&
+ (bit_offset != LLDB_INVALID_ADDRESS);
+ }
+};
+
size_t
SymbolFileDWARF::ParseChildMembers
(
@@ -1556,7 +1597,6 @@
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
DWARFDIECollection& member_function_dies,
- BitfieldMap &bitfield_map,
DelayedPropertyList& delayed_properties,
AccessType& default_accessibility,
bool &is_a_class,
@@ -1570,6 +1610,7 @@
const DWARFDebugInfoEntry *die;
const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
uint32_t member_idx = 0;
+ BitfieldInfo last_field_info;
for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
{
@@ -1593,7 +1634,7 @@
const char *prop_name = NULL;
const char *prop_getter_name = NULL;
const char *prop_setter_name = NULL;
- uint32_t prop_attributes = 0;
+ uint32_t prop_attributes = 0;
bool is_artificial = false;
@@ -1603,6 +1644,7 @@
size_t byte_size = 0;
size_t bit_offset = 0;
size_t bit_size = 0;
+ bool is_external = false; // On DW_TAG_members, this means the member is static
uint32_t i;
for (i=0; i<num_attributes && !is_artificial; ++i)
{
@@ -1647,11 +1689,12 @@
break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
- case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
+ case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
case DW_AT_APPLE_property_name: prop_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_getter: prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_setter: prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
+ case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
default:
case DW_AT_declaration:
@@ -1674,22 +1717,14 @@
if (prop_getter_name && prop_getter_name[0] == '-')
{
- ObjCLanguageRuntime::ParseMethodName (prop_getter_name,
- NULL,
- &fixed_getter,
- NULL,
- NULL);
- prop_getter_name = fixed_getter.GetCString();
+ ObjCLanguageRuntime::MethodName prop_getter_method(prop_getter_name, true);
+ prop_getter_name = prop_getter_method.GetSelector().GetCString();
}
if (prop_setter_name && prop_setter_name[0] == '-')
{
- ObjCLanguageRuntime::ParseMethodName (prop_setter_name,
- NULL,
- &fixed_setter,
- NULL,
- NULL);
- prop_setter_name = fixed_setter.GetCString();
+ ObjCLanguageRuntime::MethodName prop_setter_method(prop_setter_name, true);
+ prop_setter_name = prop_setter_method.GetSelector().GetCString();
}
// If the names haven't been provided, they need to be
@@ -1748,9 +1783,14 @@
is_artificial = true;
}
+ // Skip static members
+ if (is_external && member_byte_offset == UINT32_MAX)
+ break;
+
if (is_artificial == false)
{
Type *member_type = ResolveTypeUID(encoding_uid);
+
clang::FieldDecl *field_decl = NULL;
if (tag == DW_TAG_member)
{
@@ -1759,138 +1799,175 @@
if (accessibility == eAccessNone)
accessibility = default_accessibility;
member_accessibilities.push_back(accessibility);
+
+ BitfieldInfo this_field_info;
+
+ this_field_info.bit_size = bit_size;
+
+ if (member_byte_offset != UINT32_MAX || bit_size != 0)
+ {
+ /////////////////////////////////////////////////////////////
+ // How to locate a field given the DWARF debug information
+ //
+ // AT_byte_size indicates the size of the word in which the
+ // bit offset must be interpreted.
+ //
+ // AT_data_member_location indicates the byte offset of the
+ // word from the base address of the structure.
+ //
+ // AT_bit_offset indicates how many bits into the word
+ // (according to the host endianness) the low-order bit of
+ // the field starts. AT_bit_offset can be negative.
+ //
+ // AT_bit_size indicates the size of the field in bits.
+ /////////////////////////////////////////////////////////////
+
+ this_field_info.bit_offset = 0;
+
+ this_field_info.bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+
+ if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
+ {
+ this_field_info.bit_offset += byte_size * 8;
+ this_field_info.bit_offset -= (bit_offset + bit_size);
+ }
+ else
+ {
+ this_field_info.bit_offset += bit_offset;
+ }
+ }
- // Code to detect unnamed bitifields
- if (bit_size > 0 && member_byte_offset != UINT32_MAX)
+ // If the member to be emitted did not start on a character boundary and there is
+ // empty space between the last field and this one, then we need to emit an
+ // anonymous member filling up the space up to its start. There are three cases
+ // here:
+ //
+ // 1 If the previous member ended on a character boundary, then we can emit an
+ // anonymous member starting at the most recent character boundary.
+ //
+ // 2 If the previous member did not end on a character boundary and the distance
+ // from the end of the previous member to the current member is less than a
+ // word width, then we can emit an anonymous member starting right after the
+ // previous member and right before this member.
+ //
+ // 3 If the previous member did not end on a character boundary and the distance
+ // from the end of the previous member to the current member is greater than
+ // or equal a word width, then we act as in Case 1.
+
+ const uint64_t character_width = 8;
+ const uint64_t word_width = 32;
+
+ if (this_field_info.IsValid())
{
- // Objective C has invalid DW_AT_bit_offset values so we can't use them to detect
- // unnamed bitfields. Once clang is fixed we will enable unnamed bitfields
- // in ObjC classes (<rdar://problem/12636970>)
+ // Objective-C has invalid DW_AT_bit_offset values in older versions
+ // of clang, so we have to be careful and only insert unnammed bitfields
+ // if we have a new enough clang.
+ bool detect_unnamed_bitfields = true;
- if (!(class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus))
+ if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
+ detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields ();
+
+ if (detect_unnamed_bitfields)
{
- // We have a bitfield, we need to watch out for
- // unnamed bitfields that we need to insert if
- // there is a gap in the bytes as many compilers
- // doesn't emit DWARF DW_TAG_member tags for
- // unnammed bitfields.
- BitfieldMap::iterator bit_pos = bitfield_map.find(member_byte_offset);
- uint32_t unnamed_bit_size = 0;
- uint32_t unnamed_bit_offset = 0;
- if (bit_pos == bitfield_map.end())
+ BitfieldInfo anon_field_info;
+
+ if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
{
- // First bitfield in an integral type.
+ uint64_t last_field_end = 0;
- // We might need to insert a leading unnamed bitfield
- if (bit_offset < byte_size * 8)
- {
- unnamed_bit_size = byte_size * 8 - (bit_size + bit_offset);
- unnamed_bit_offset = byte_size * 8 - unnamed_bit_size;
- }
+ if (last_field_info.IsValid())
+ last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
- // Now put the current bitfield info into the map
- bitfield_map[member_byte_offset].bit_size = bit_size;
- bitfield_map[member_byte_offset].bit_offset = bit_offset;
- }
- else
- {
- // Subsequent bitfield in an integral type.
-
- // We have a bitfield that isn't the first for this
- // integral type, check to make sure there aren't any
- // gaps.
- assert (bit_pos->second.bit_size > 0);
- if (bit_offset < bit_pos->second.bit_offset)
- {
- unnamed_bit_size = bit_pos->second.bit_offset - (bit_size + bit_offset);
- unnamed_bit_offset = bit_pos->second.bit_offset - unnamed_bit_size;
+ if (this_field_info.bit_offset != last_field_end)
+ {
+ if (((last_field_end % character_width) == 0) || // case 1
+ (this_field_info.bit_offset - last_field_end >= word_width)) // case 3
+ {
+ anon_field_info.bit_size = this_field_info.bit_offset % character_width;
+ anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
+ }
+ else // case 2
+ {
+ anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
+ anon_field_info.bit_offset = last_field_end;
+ }
}
-
- // Now put the current bitfield info into the map
- bit_pos->second.bit_size = bit_size;
- bit_pos->second.bit_offset = bit_offset;
}
- if (unnamed_bit_size > 0)
+ if (anon_field_info.IsValid())
{
clang::FieldDecl *unnamed_bitfield_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
NULL,
- member_type->GetClangLayoutType(),
+ GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
accessibility,
- unnamed_bit_size);
- uint64_t total_bit_offset = 0;
-
- total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
+ anon_field_info.bit_size);
- if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
- {
- total_bit_offset += byte_size * 8;
- total_bit_offset -= (unnamed_bit_offset + unnamed_bit_size);
- }
- else
+ layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
+ }
+ }
+ }
+
+ clang_type_t member_clang_type = member_type->GetClangLayoutType();
+
+ {
+ // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
+ // If the current field is at the end of the structure, then there is definitely no room for extra
+ // elements and we override the type to array[0].
+
+ clang_type_t member_array_element_type;
+ uint64_t member_array_size;
+ bool member_array_is_incomplete;
+
+ if (GetClangASTContext().IsArrayType(member_clang_type,
+ &member_array_element_type,
+ &member_array_size,
+ &member_array_is_incomplete) &&
+ !member_array_is_incomplete)
+ {
+ uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
+
+ if (member_byte_offset >= parent_byte_size)
+ {
+ if (member_array_size != 1)
{
- total_bit_offset += unnamed_bit_size;
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
+ MakeUserID(die->GetOffset()),
+ name,
+ encoding_uid,
+ MakeUserID(parent_die->GetOffset()));
}
- layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, total_bit_offset));
+ member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0);
}
}
}
+
field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
name,
- member_type->GetClangLayoutType(),
+ member_clang_type,
accessibility,
bit_size);
GetClangASTContext().SetMetadataAsUserID ((uintptr_t)field_decl, MakeUserID(die->GetOffset()));
+
+ if (this_field_info.IsValid())
+ {
+ layout_info.field_offsets.insert(std::make_pair(field_decl, this_field_info.bit_offset));
+ last_field_info = this_field_info;
+ }
}
else
{
if (name)
- GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
MakeUserID(die->GetOffset()),
name,
encoding_uid);
else
- GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
+ GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
MakeUserID(die->GetOffset()),
encoding_uid);
}
-
- if (member_byte_offset != UINT32_MAX || bit_size != 0)
- {
- /////////////////////////////////////////////////////////////
- // How to locate a field given the DWARF debug information
- //
- // AT_byte_size indicates the size of the word in which the
- // bit offset must be interpreted.
- //
- // AT_data_member_location indicates the byte offset of the
- // word from the base address of the structure.
- //
- // AT_bit_offset indicates how many bits into the word
- // (according to the host endianness) the low-order bit of
- // the field starts. AT_bit_offset can be negative.
- //
- // AT_bit_size indicates the size of the field in bits.
- /////////////////////////////////////////////////////////////
-
- uint64_t total_bit_offset = 0;
-
- total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
-
- if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
- {
- total_bit_offset += byte_size * 8;
- total_bit_offset -= (bit_offset + bit_size);
- }
- else
- {
- total_bit_offset += bit_offset;
- }
-
- layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
- }
}
if (prop_name != NULL)
@@ -2183,7 +2260,7 @@
if (log)
{
GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log.get(),
- "0x%8.8llx: %s '%s' resolving forward declaration...",
+ "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
MakeUserID(die->GetOffset()),
DW_TAG_value_to_name(tag),
type->GetName().AsCString());
@@ -2242,7 +2319,6 @@
DWARFDIECollection member_function_dies;
DelayedPropertyList delayed_properties;
- BitfieldMap bitfield_map;
ParseChildMembers (sc,
dwarf_cu,
die,
@@ -2251,7 +2327,6 @@
base_classes,
member_accessibilities,
member_function_dies,
- bitfield_map,
delayed_properties,
default_accessibility,
is_a_class,
@@ -2380,7 +2455,7 @@
if (log)
{
GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
+ "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
clang_type,
record_decl,
layout_info.bit_size,
@@ -2495,7 +2570,7 @@
bool
SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
{
- sc.Clear();
+ sc.Clear(false);
// Check if the symbol vendor already knows about this compile unit?
sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
@@ -2516,7 +2591,7 @@
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
Timer scoped_timer(__PRETTY_FUNCTION__,
- "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
+ "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
so_addr.GetSection().get(),
so_addr.GetOffset(),
resolve_scope);
@@ -2543,27 +2618,7 @@
{
resolved |= eSymbolContextCompUnit;
- if (resolve_scope & eSymbolContextLineEntry)
- {
- LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line_table != NULL)
- {
- if (so_addr.IsLinkedAddress())
- {
- Address linked_addr (so_addr);
- linked_addr.ResolveLinkedAddress();
- if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
- }
- else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
- }
- }
-
+ bool force_check_line_table = false;
if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
{
DWARFDebugInfoEntry *function_die = NULL;
@@ -2591,8 +2646,7 @@
// should only happen when there aren't other functions from
// other compile units in these gaps. This helps keep the size
// of the aranges down.
- sc.comp_unit = NULL;
- resolved &= ~eSymbolContextCompUnit;
+ force_check_line_table = true;
}
if (sc.function != NULL)
@@ -2612,6 +2666,39 @@
}
}
}
+
+ if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
+ {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
+ if (line_table != NULL)
+ {
+ if (so_addr.IsLinkedAddress())
+ {
+ Address linked_addr (so_addr);
+ linked_addr.ResolveLinkedAddress();
+ if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
+ {
+ resolved |= eSymbolContextLineEntry;
+ }
+ }
+ else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
+ {
+ resolved |= eSymbolContextLineEntry;
+ }
+ }
+ }
+
+ if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
+ {
+ // We might have had a compile unit that had discontiguous
+ // address ranges where the gaps are symbols that don't have
+ // any debug info. Discontiguous compile unit address ranges
+ // should only happen when there aren't other functions from
+ // other compile units in these gaps. This helps keep the size
+ // of the aranges down.
+ sc.comp_unit = NULL;
+ resolved &= ~eSymbolContextCompUnit;
+ }
}
else
{
@@ -3217,9 +3304,8 @@
const char *base_name_start,
const char *base_name_end)
{
- // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
- if (name_type_mask == eFunctionNameTypeMethod
- || name_type_mask == eFunctionNameTypeBase)
+ // If we are looking only for methods, throw away all the ones that are or aren't in C++ classes:
+ if (name_type_mask == eFunctionNameTypeMethod || name_type_mask == eFunctionNameTypeBase)
{
clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
if (!containing_decl_ctx)
@@ -3227,10 +3313,17 @@
bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
- if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
- return false;
- if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
- return false;
+ if (name_type_mask == eFunctionNameTypeMethod)
+ {
+ if (is_cxx_method == false)
+ return false;
+ }
+
+ if (name_type_mask == eFunctionNameTypeBase)
+ {
+ if (is_cxx_method == true)
+ return false;
+ }
}
// Now we need to check whether the name we got back for this type matches the extra specifications
@@ -3241,20 +3334,33 @@
// we can pull out the mips linkage name attribute:
Mangled best_name;
-
DWARFDebugInfoEntry::Attributes attributes;
+ DWARFFormValue form_value;
die->GetAttributes(this, dwarf_cu, NULL, attributes);
uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
+ if (idx == UINT32_MAX)
+ idx = attributes.FindAttributeIndex(DW_AT_linkage_name);
if (idx != UINT32_MAX)
{
- DWARFFormValue form_value;
if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
{
+ const char *mangled_name = form_value.AsCString(&get_debug_str_data());
+ if (mangled_name)
+ best_name.SetValue (ConstString(mangled_name), true);
+ }
+ }
+
+ if (!best_name)
+ {
+ idx = attributes.FindAttributeIndex(DW_AT_name);
+ if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value))
+ {
const char *name = form_value.AsCString(&get_debug_str_data());
- best_name.SetValue (ConstString(name), true);
- }
+ best_name.SetValue (ConstString(name), false);
+ }
}
- if (best_name)
+
+ if (best_name.GetDemangledName())
{
const char *demangled = best_name.GetDemangledName().GetCString();
if (demangled)
@@ -3484,20 +3590,20 @@
const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
if (die)
{
+ if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+ continue;
+
if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
continue;
- if (!FunctionDieMatchesPartialName(die,
+ if (!FunctionDieMatchesPartialName(die,
dwarf_cu,
- effective_name_type_mask,
+ effective_name_type_mask,
name_cstr,
base_name_start,
base_name_end))
continue;
- if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
- continue;
-
// If we get to here, the die is good, and we should add it:
ResolveFunction (dwarf_cu, die, sc_list);
}
@@ -3535,20 +3641,20 @@
const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
if (die)
{
+ if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+ continue;
+
if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
continue;
if (!FunctionDieMatchesPartialName(die,
dwarf_cu,
- effective_name_type_mask,
+ eFunctionNameTypeBase,
name_cstr,
base_name_start,
base_name_end))
continue;
- if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
- continue;
-
// If we get to here, the die is good, and we should add it:
ResolveFunction (dwarf_cu, die, sc_list);
}
@@ -3568,17 +3674,17 @@
const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
if (die)
{
- if (!FunctionDieMatchesPartialName(die,
+ if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
+ continue;
+
+ if (!FunctionDieMatchesPartialName(die,
dwarf_cu,
- effective_name_type_mask,
+ eFunctionNameTypeMethod,
name_cstr,
base_name_start,
base_name_end))
continue;
- if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine)
- continue;
-
// If we get to here, the die is good, and we should add it:
ResolveFunction (dwarf_cu, die, sc_list);
}
@@ -4178,6 +4284,7 @@
uint64_t num_elements = 0;
uint64_t lower_bound = 0;
uint64_t upper_bound = 0;
+ bool upper_bound_valid = false;
uint32_t i;
for (i=0; i<num_child_attributes; ++i)
{
@@ -4207,6 +4314,7 @@
break;
case DW_AT_upper_bound:
+ upper_bound_valid = true;
upper_bound = form_value.Unsigned();
break;
@@ -4227,8 +4335,11 @@
}
}
- if (upper_bound > lower_bound)
- num_elements = upper_bound - lower_bound + 1;
+ if (num_elements == 0)
+ {
+ if (upper_bound_valid && upper_bound >= lower_bound)
+ num_elements = upper_bound - lower_bound + 1;
+ }
element_orders.push_back (num_elements);
}
@@ -4313,7 +4424,7 @@
if (namespace_name)
{
GetObjectFile()->GetModule()->LogMessage (log.get(),
- "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
+ "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
GetClangASTContext().getASTContext(),
MakeUserID(die->GetOffset()),
namespace_name,
@@ -4323,7 +4434,7 @@
else
{
GetObjectFile()->GetModule()->LogMessage (log.get(),
- "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
+ "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
GetClangASTContext().getASTContext(),
MakeUserID(die->GetOffset()),
namespace_decl,
@@ -4597,7 +4708,7 @@
Type *resolved_type = ResolveType (type_cu, type_die, false);
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
{
- DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
+ DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
MakeUserID(die->GetOffset()),
MakeUserID(dwarf_cu->GetOffset()),
m_obj_file->GetFileSpec().GetFilename().AsCString(),
@@ -4750,10 +4861,11 @@
if (cu == NULL || die == NULL || !type_name)
return type_sp;
+ std::string qualified_name;
+
LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
if (log)
{
- std::string qualified_name;
die->GetQualifiedName(this, cu, qualified_name);
GetObjectFile()->GetModule()->LogMessage (log.get(),
"SymbolFileDWARF::FindDefinitionTypeForDIE(die=0x%8.8x (%s), name='%s')",
@@ -4768,8 +4880,22 @@
{
if (m_apple_types_ap.get())
{
- if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash)
{
+ if (qualified_name.empty())
+ die->GetQualifiedName(this, cu, qualified_name);
+
+ const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name.c_str());
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), die->Tag(), qualified_name_hash, die_offsets);
+ }
+ else if (has_tag > 1)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTag()");
m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets);
}
else
@@ -4858,7 +4984,7 @@
Type *resolved_type = ResolveType (type_cu, type_die, false);
if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
{
- DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
+ DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ") from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
MakeUserID(die->GetOffset()),
MakeUserID(dwarf_cu->GetOffset()),
m_obj_file->GetFileSpec().GetFilename().AsCString(),
@@ -4928,8 +5054,20 @@
{
if (m_apple_types_ap.get())
{
- if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
+ const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
+ const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
+ if (has_tag && has_qualified_name_hash)
+ {
+ const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
+ const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTagAndQualifiedNameHash()");
+ m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
+ }
+ else if (has_tag)
{
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(),"FindByNameAndTag()");
m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
}
else
@@ -5052,11 +5190,13 @@
}
bool
-SymbolFileDWARF::CopyUniqueClassMethodTypes (Type *class_type,
+SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *src_symfile,
+ Type *class_type,
DWARFCompileUnit* src_cu,
const DWARFDebugInfoEntry *src_class_die,
DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die)
+ const DWARFDebugInfoEntry *dst_class_die,
+ llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures)
{
if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
return false;
@@ -5072,6 +5212,8 @@
const DWARFDebugInfoEntry *dst_die;
UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
+ UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die_artificial;
+ UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die_artificial;
for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
{
if (src_die->Tag() == DW_TAG_subprogram)
@@ -5080,11 +5222,17 @@
// for DW_AT_declaration set to 1. Sometimes concrete function instances
// are placed inside the class definitions and shouldn't be included in
// the list of things are are tracking here.
- if (src_die->GetAttributeValueAsUnsigned(this, src_cu, DW_AT_declaration, 0) == 1)
+ if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_declaration, 0) == 1)
{
- const char *src_name = src_die->GetMangledName (this, src_cu);
+ const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
if (src_name)
- src_name_to_die.Append(ConstString(src_name).GetCString(), src_die);
+ {
+ ConstString src_const_name(src_name);
+ if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_artificial, 0))
+ src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
+ else
+ src_name_to_die.Append(src_const_name.GetCString(), src_die);
+ }
}
}
}
@@ -5100,29 +5248,42 @@
{
const char *dst_name = dst_die->GetMangledName (this, dst_cu);
if (dst_name)
- dst_name_to_die.Append(ConstString(dst_name).GetCString(), dst_die);
+ {
+ ConstString dst_const_name(dst_name);
+ if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_artificial, 0))
+ dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
+ else
+ dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
+ }
}
}
}
const uint32_t src_size = src_name_to_die.GetSize ();
const uint32_t dst_size = dst_name_to_die.GetSize ();
LogSP log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));
-
- if (src_size && dst_size)
+
+ // Is everything kosher so we can go through the members at top speed?
+ bool fast_path = true;
+
+ if (src_size != dst_size)
{
- if (src_size != dst_size)
+ if (src_size != 0 && dst_size != 0)
{
if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
+ log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
src_class_die->GetOffset(),
dst_class_die->GetOffset(),
src_size,
dst_size);
-
- return false;
}
-
- uint32_t idx;
+
+ fast_path = false;
+ }
+
+ uint32_t idx;
+
+ if (fast_path)
+ {
for (idx = 0; idx < src_size; ++idx)
{
src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
@@ -5138,10 +5299,10 @@
DW_TAG_value_to_name(src_die->Tag()),
dst_die->GetOffset(),
DW_TAG_value_to_name(src_die->Tag()));
- return false;
+ fast_path = false;
}
- const char *src_name = src_die->GetMangledName (this, src_cu);
+ const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
const char *dst_name = dst_die->GetMangledName (this, dst_cu);
// Make sure the names match
@@ -5157,54 +5318,163 @@
dst_die->GetOffset(),
dst_name);
- return false;
+ fast_path = false;
}
+ }
+ // Now do the work of linking the DeclContexts and Types.
+ if (fast_path)
+ {
+ // We can do this quickly. Just run across the tables index-for-index since
+ // we know each node has matching names and tags.
for (idx = 0; idx < src_size; ++idx)
{
src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);
- clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
+ clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
if (src_decl_ctx)
{
if (log)
- log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x\n", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+ log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
LinkDeclContextToDIE (src_decl_ctx, dst_die);
}
else
{
if (log)
- log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+ log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
}
Type *src_child_type = m_die_to_type[src_die];
if (src_child_type)
{
if (log)
- log->Printf ("uniquing type %p (uid=0x%llx) from 0x%8.8x for 0x%8.8x\n", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+ log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
m_die_to_type[dst_die] = src_child_type;
}
else
{
if (log)
- log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found\n", src_die->GetOffset(), dst_die->GetOffset());
+ log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
}
}
- return true;
}
else
{
- if (log)
- log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x has %u methods and 0x%8.8x has %u",
- src_class_die->GetOffset(),
- dst_class_die->GetOffset(),
- src_die->GetOffset(),
- src_size,
- dst_die->GetOffset(),
- dst_size);
+ // We must do this slowly. For each member of the destination, look
+ // up a member in the source with the same name, check its tag, and
+ // unique them if everything matches up. Report failures.
+
+ if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
+ {
+ src_name_to_die.Sort();
+
+ for (idx = 0; idx < dst_size; ++idx)
+ {
+ const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
+ src_die = src_name_to_die.Find(dst_name, NULL);
+
+ if (src_die && (src_die->Tag() == dst_die->Tag()))
+ {
+ clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
+ if (src_decl_ctx)
+ {
+ if (log)
+ log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+ LinkDeclContextToDIE (src_decl_ctx, dst_die);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+
+ Type *src_child_type = m_die_to_type[src_die];
+ if (src_child_type)
+ {
+ if (log)
+ log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+ m_die_to_type[dst_die] = src_child_type;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());
+
+ failures.push_back(dst_die);
+ }
+ }
+ }
}
- return false;
+
+ const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
+ const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
+
+ UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;
+
+ if (src_size_artificial && dst_size_artificial)
+ {
+ dst_name_to_die_artificial.Sort();
+
+ for (idx = 0; idx < src_size_artificial; ++idx)
+ {
+ const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
+ src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
+ dst_die = dst_name_to_die_artificial.Find(src_name_artificial, NULL);
+
+ if (dst_die)
+ {
+ // Both classes have the artificial types, link them
+ clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
+ if (src_decl_ctx)
+ {
+ if (log)
+ log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x", src_decl_ctx, src_die->GetOffset(), dst_die->GetOffset());
+ LinkDeclContextToDIE (src_decl_ctx, dst_die);
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+
+ Type *src_child_type = m_die_to_type[src_die];
+ if (src_child_type)
+ {
+ if (log)
+ log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x", src_child_type, src_child_type->GetID(), src_die->GetOffset(), dst_die->GetOffset());
+ m_die_to_type[dst_die] = src_child_type;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
+ }
+ }
+ }
+ }
+
+ if (dst_size_artificial)
+ {
+ for (idx = 0; idx < dst_size_artificial; ++idx)
+ {
+ const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
+ dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
+ if (log)
+ log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
+
+ failures.push_back(dst_die);
+ }
+ }
+
+ return (failures.size() != 0);
}
TypeSP
@@ -5331,7 +5601,7 @@
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
switch (tag)
{
@@ -5363,51 +5633,80 @@
case DW_TAG_volatile_type: encoding_data_type = Type::eEncodingIsVolatileUID; break;
}
- if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID))
+ if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
{
- if (type_name_cstr != NULL && sc.comp_unit != NULL &&
- (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
+ bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
+
+ if (translation_unit_is_objc)
{
- static ConstString g_objc_type_name_id("id");
- static ConstString g_objc_type_name_Class("Class");
- static ConstString g_objc_type_name_selector("SEL");
-
- if (type_name_const_str == g_objc_type_name_id)
+ if (type_name_cstr != NULL)
{
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_id();
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
+ static ConstString g_objc_type_name_id("id");
+ static ConstString g_objc_type_name_Class("Class");
+ static ConstString g_objc_type_name_selector("SEL");
+
+ if (type_name_const_str == g_objc_type_name_id)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_id();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
+ else if (type_name_const_str == g_objc_type_name_Class)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_Class();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
+ else if (type_name_const_str == g_objc_type_name_selector)
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_selector();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
}
- else if (type_name_const_str == g_objc_type_name_Class)
- {
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_Class();
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
- }
- else if (type_name_const_str == g_objc_type_name_selector)
+ else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
{
- if (log)
- GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
- die->GetOffset(),
- DW_TAG_value_to_name(die->Tag()),
- die->GetName(this, dwarf_cu));
- clang_type = ast.GetBuiltInType_objc_selector();
- encoding_data_type = Type::eEncodingIsUID;
- encoding_uid = LLDB_INVALID_UID;
- resolve_state = Type::eResolveStateFull;
+ // Clang sometimes erroneously emits id as objc_object*. In that case we fix up the type to "id".
+
+ DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid);
+
+ if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type)
+ {
+ if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL))
+ {
+ if (!strcmp(struct_name, "objc_object"))
+ {
+ if (log)
+ GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
+ die->GetOffset(),
+ DW_TAG_value_to_name(die->Tag()),
+ die->GetName(this, dwarf_cu));
+ clang_type = ast.GetBuiltInType_objc_id();
+ encoding_data_type = Type::eEncodingIsUID;
+ encoding_uid = LLDB_INVALID_UID;
+ resolve_state = Type::eResolveStateFull;
+ }
+ }
+ }
}
}
}
@@ -5544,7 +5843,7 @@
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
int tag_decl_kind = -1;
AccessType default_accessibility = eAccessNone;
@@ -5607,7 +5906,7 @@
if (log)
{
GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8llx",
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64,
this,
die->GetOffset(),
DW_TAG_value_to_name(tag),
@@ -5661,7 +5960,7 @@
if (log)
{
GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8llx",
+ "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
this,
die->GetOffset(),
DW_TAG_value_to_name(tag),
@@ -5868,7 +6167,7 @@
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
clang_type_t enumerator_clang_type = NULL;
clang_type = m_forward_decl_die_to_clang_type.lookup (die);
@@ -5955,6 +6254,7 @@
type_name_const_str.SetCString(type_name_cstr);
break;
+ case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name: break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_die_offset = form_value.Reference(dwarf_cu); break;
case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
@@ -6027,7 +6327,7 @@
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
clang_type_t return_clang_type = NULL;
Type *func_type = NULL;
@@ -6085,16 +6385,12 @@
bool type_handled = false;
if (tag == DW_TAG_subprogram)
{
- ConstString class_name;
- ConstString class_name_no_category;
- if (ObjCLanguageRuntime::ParseMethodName (type_name_cstr, &class_name, NULL, NULL, &class_name_no_category))
- {
- // Use the class name with no category if there is one
- if (class_name_no_category)
- class_name = class_name_no_category;
-
+ ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
+ if (objc_method.IsValid(true))
+ {
SymbolContext empty_sc;
clang_type_t class_opaque_type = NULL;
+ ConstString class_name(objc_method.GetClassName());
if (class_name)
{
TypeList types;
@@ -6125,6 +6421,13 @@
LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
GetClangASTContext().SetMetadataAsUserID ((uintptr_t)objc_method_decl, MakeUserID(die->GetOffset()));
}
+ else
+ {
+ GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invaliad Objective-C method 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
+ die->GetOffset(),
+ tag,
+ DW_TAG_value_to_name(tag));
+ }
}
}
else if (is_cxx_method)
@@ -6140,22 +6443,43 @@
// We uniqued the parent class of this function to another class
// so we now need to associate all dies under "decl_ctx_die" to
// DIEs in the DIE for "class_type"...
+ SymbolFileDWARF *class_symfile = NULL;
DWARFCompileUnitSP class_type_cu_sp;
- const DWARFDebugInfoEntry *class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ const DWARFDebugInfoEntry *class_type_die = NULL;
+
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile)
+ {
+ class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
+ class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ }
+ else
+ {
+ class_symfile = this;
+ class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
+ }
if (class_type_die)
{
- if (CopyUniqueClassMethodTypes (class_type,
- class_type_cu_sp.get(),
- class_type_die,
- dwarf_cu,
- decl_ctx_die))
+ llvm::SmallVector<const DWARFDebugInfoEntry *, 0> failures;
+
+ CopyUniqueClassMethodTypes (class_symfile,
+ class_type,
+ class_type_cu_sp.get(),
+ class_type_die,
+ dwarf_cu,
+ decl_ctx_die,
+ failures);
+
+ // FIXME do something with these failures that's smarter than
+ // just dropping them on the ground. Unfortunately classes don't
+ // like having stuff added to them after their definitions are
+ // complete...
+
+ type_ptr = m_die_to_type[die];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
{
- type_ptr = m_die_to_type[die];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
- {
- type_sp = type_ptr->shared_from_this();
- break;
- }
+ type_sp = type_ptr->shared_from_this();
+ break;
}
}
}
@@ -6178,7 +6502,7 @@
}
else
{
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n",
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x) has no decl\n",
MakeUserID(die->GetOffset()),
specification_die_offset);
}
@@ -6201,7 +6525,7 @@
}
else
{
- GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
+ GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x) has no decl\n",
MakeUserID(die->GetOffset()),
abstract_origin_die_offset);
}
@@ -6230,7 +6554,7 @@
{
clang::CXXMethodDecl *cxx_method_decl;
// REMOVE THE CRASH DESCRIPTION BELOW
- Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s",
+ Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s/%s",
type_name_cstr,
class_type->GetName().GetCString(),
MakeUserID(die->GetOffset()),
@@ -6416,7 +6740,7 @@
}
}
- DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
+ DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
Type *element_type = ResolveTypeUID(type_die_offset);
@@ -6435,10 +6759,9 @@
{
num_elements = *pos;
clang_type = ast.CreateArrayType (array_element_type,
- num_elements,
- num_elements * array_element_bit_stride);
+ num_elements);
array_element_type = clang_type;
- array_element_bit_stride = array_element_bit_stride * num_elements;
+ array_element_bit_stride = num_elements ? array_element_bit_stride * num_elements : array_element_bit_stride;
}
ConstString empty_name;
type_sp.reset( new Type (MakeUserID(die->GetOffset()),
@@ -6663,8 +6986,8 @@
{
const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
- dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
- if (func_lo_pc != DW_INVALID_ADDRESS)
+ dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+ if (func_lo_pc != LLDB_INVALID_ADDRESS)
{
const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
@@ -6779,6 +7102,7 @@
bool is_external = false;
bool is_artificial = false;
bool location_is_const_value_data = false;
+ bool has_explicit_location = false;
//AccessType accessibility = eAccessNone;
for (i=0; i<num_attributes; ++i)
@@ -6793,14 +7117,56 @@
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
+ case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: type_uid = form_value.Reference(dwarf_cu); break;
case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
case DW_AT_const_value:
- location_is_const_value_data = true;
- // Fall through...
+ // If we have already found a DW_AT_location attribute, ignore this attribute.
+ if (!has_explicit_location)
+ {
+ location_is_const_value_data = true;
+ // The constant value will be either a block, a data value or a string.
+ const DataExtractor& debug_info_data = get_debug_info_data();
+ if (DWARFFormValue::IsBlockForm(form_value.Form()))
+ {
+ // Retrieve the value as a block expression.
+ uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
+ uint32_t block_length = form_value.Unsigned();
+ location.CopyOpcodeData(debug_info_data, block_offset, block_length);
+ }
+ else if (DWARFFormValue::IsDataForm(form_value.Form()))
+ {
+ // Retrieve the value as a data expression.
+ const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length = fixed_form_sizes[form_value.Form()];
+ location.CopyOpcodeData(debug_info_data, data_offset, data_length);
+ }
+ else
+ {
+ // Retrieve the value as a string expression.
+ if (form_value.Form() == DW_FORM_strp)
+ {
+ const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
+ uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+ uint32_t data_length = fixed_form_sizes[form_value.Form()];
+ location.CopyOpcodeData(debug_info_data, data_offset, data_length);
+ }
+ else
+ {
+ const char *str = form_value.AsCString(&debug_info_data);
+ uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
+ uint32_t string_length = strlen(str) + 1;
+ location.CopyOpcodeData(debug_info_data, string_offset, string_length);
+ }
+ }
+ }
+ break;
case DW_AT_location:
{
+ location_is_const_value_data = false;
+ has_explicit_location = true;
if (form_value.BlockData())
{
const DataExtractor& debug_info_data = get_debug_info_data();
@@ -6891,7 +7257,7 @@
// the .o file might not have allocated a virtual
// address for the global variable. In this case it will
// have created a symbol for the global variable
- // that is undefined and external and the value will
+ // that is undefined/data and external and the value will
// be the byte size of the variable. When we do the
// address map in SymbolFileDWARFDebugMap we rely on
// having an address, we need to do some magic here
@@ -6911,13 +7277,13 @@
Symtab *symtab = m_obj_file->GetSymtab();
if (symtab)
{
- ConstString const_name(name);
- Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeUndefined,
- Symtab::eDebugNo,
- Symtab::eVisibilityExtern);
+ ConstString const_name(mangled ? mangled : name);
+ Symbol *o_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
+ eSymbolTypeAny,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityExtern);
- if (undefined_symbol)
+ if (o_symbol)
{
ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
if (debug_map_objfile)
@@ -7134,7 +7500,7 @@
}
else
{
- GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n",
+ GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
MakeUserID(sc_parent_die->GetOffset()),
DW_TAG_value_to_name (parent_tag),
MakeUserID(orig_die->GetOffset()),
@@ -7178,7 +7544,7 @@
break;
default:
- GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n",
+ GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
MakeUserID(orig_die->GetOffset()),
DW_TAG_value_to_name (orig_die->Tag()));
break;
@@ -7408,7 +7774,7 @@
if (log)
GetObjectFile()->GetModule()->LogMessage (log.get(),
- "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
+ "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
record_decl,
bit_size,
alignment,
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp 2013-03-03 09:35:50.263457350 +0100
@@ -48,11 +48,23 @@
m_exe_module_wp (exe_module_sp),
m_cu_idx (cu_idx)
{
+ LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log)
+ log->Printf("%p: DebugMapModule::DebugMapModule (exe_module=%p, cu_idx=%u, oso_path='%s/%s', object_name='%s')",
+ this,
+ exe_module_sp.get(),
+ cu_idx,
+ file_spec.GetDirectory().GetCString(),
+ file_spec.GetFilename().GetCString(),
+ object_name ? object_name->GetCString() : "");
}
virtual
~DebugMapModule ()
{
+ LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log)
+ log->Printf("%p: DebugMapModule::~DebugMapModule ()", this);
}
virtual ObjectFile *
@@ -73,147 +85,150 @@
SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile();
if (exe_symfile)
{
- SymbolFileDWARFDebugMap::CompileUnitInfo *comp_unit_info = exe_symfile->GetCompUnitInfo (this);
- if (comp_unit_info)
+ std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+ if (exe_symfile->GetCompUnitInfosForModule(this, cu_infos))
{
- // Set the ID of the symbol file DWARF to the index of the OSO
- // shifted left by 32 bits to provide a unique prefix for any
- // UserID's that get created in the symbol file.
- //comp_unit_info->exe_sections_sp.reset(new SectionList);
-
- Symtab *exe_symtab = exe_objfile->GetSymtab();
- ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab();
- //#define DEBUG_OSO_DMAP // Do not check in with this defined...
+ for (auto comp_unit_info : cu_infos)
+ {
+ // Set the ID of the symbol file DWARF to the index of the OSO
+ // shifted left by 32 bits to provide a unique prefix for any
+ // UserID's that get created in the symbol file.
+ //comp_unit_info->exe_sections_sp.reset(new SectionList);
+
+ Symtab *exe_symtab = exe_objfile->GetSymtab();
+ ModuleSP oso_module_sp (oso_objfile->GetModule());
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
+ //#define DEBUG_OSO_DMAP // Do not check in with this defined...
#if defined(DEBUG_OSO_DMAP)
- StreamFile s(stdout);
- s << "OSO symtab:\n";
- oso_symtab->Dump(&s, NULL);
- s << "OSO sections before:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
+ StreamFile s(stdout);
+ s << "OSO symtab:\n";
+ oso_symtab->Dump(&s, NULL);
+ s << "OSO sections before:\n";
+ oso_objfile->GetSectionList()->Dump(&s, NULL, true);
#endif
- ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
- //SectionList *oso_sections = oso_objfile->Sections();
- // Now we need to make sections that map from zero based object
- // file addresses to where things eneded up in the main executable.
-
- assert (comp_unit_info->first_symbol_index != UINT32_MAX);
- // End index is one past the last valid symbol index
- const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
- uint32_t sect_id = 0x10000;
- for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
- idx < oso_end_idx;
- ++idx)
- {
- Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
- if (exe_symbol)
+ ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
+ //SectionList *oso_sections = oso_objfile->Sections();
+ // Now we need to make sections that map from zero based object
+ // file addresses to where things eneded up in the main executable.
+
+ assert (comp_unit_info->first_symbol_index != UINT32_MAX);
+ // End index is one past the last valid symbol index
+ const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
+ uint32_t sect_id = 0x10000;
+ for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
+ idx < oso_end_idx;
+ ++idx)
{
- if (exe_symbol->IsDebug() == false)
- continue;
-
- switch (exe_symbol->GetType())
+ Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+ if (exe_symbol)
{
- default:
- break;
-
- case eSymbolTypeCode:
+ if (exe_symbol->IsDebug() == false)
+ continue;
+
+ switch (exe_symbol->GetType())
{
- // For each N_FUN, or function that we run into in the debug map
- // we make a new section that we add to the sections found in the
- // .o file. This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable.
-
- // First we find the original symbol in the .o file's symbol table
- Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
- if (oso_fun_symbol)
+ default:
+ break;
+
+ case eSymbolTypeCode:
{
- // If we found the symbol, then we
- SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
- if (oso_fun_section)
+ // For each N_FUN, or function that we run into in the debug map
+ // we make a new section that we add to the sections found in the
+ // .o file. This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable.
+
+ // First we find the original symbol in the .o file's symbol table
+ Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
+ if (oso_fun_symbol)
{
- // Now we create a section that we will add as a child of the
- // section in which the .o symbol (the N_FUN) exists.
-
- // We use the exe_symbol size because the one in the .o file
- // will just be a symbol with no size, and the exe_symbol
- // size will reflect any size changes (ppc has been known to
- // shrink function sizes when it gets rid of jump islands that
- // aren't needed anymore).
- SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- exe_symbol->GetByteSize(), // File size (we need the size from the executable)
- 0, 0, 0));
-
- oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
- oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
+ // If we found the symbol, then we
+ SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
+ SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
+ if (oso_fun_section)
+ {
+ // Now we create a section that we will add as a child of the
+ // section in which the .o symbol (the N_FUN) exists.
+
+ // We use the exe_symbol size because the one in the .o file
+ // will just be a symbol with no size, and the exe_symbol
+ // size will reflect any size changes (ppc has been known to
+ // shrink function sizes when it gets rid of jump islands that
+ // aren't needed anymore).
+ SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
+ oso_module_sp, // Module (the .o file)
+ sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
+ exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
+ eSectionTypeDebug,
+ oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
+ exe_symbol->GetByteSize(), // File size (we need the size from the executable)
+ 0, 0, 0));
+
+ oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
+ exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
+ oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
+ }
}
}
- }
- break;
-
- case eSymbolTypeData:
- {
- // For each N_GSYM we remap the address for the global by making
- // a new section that we add to the sections found in the .o file.
- // This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable. We
- // initially set the section size to be 1 byte, but will need to
- // fix up these addresses further after all globals have been
- // parsed to span the gaps, or we can find the global variable
- // sizes from the DWARF info as we are parsing.
-
- // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
- Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
- eSymbolTypeData,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
-
- if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
+ break;
+
+ case eSymbolTypeData:
{
- // If we found the symbol, then we
- SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
- if (oso_gsym_section)
+ // For each N_GSYM we remap the address for the global by making
+ // a new section that we add to the sections found in the .o file.
+ // This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable. We
+ // initially set the section size to be 1 byte, but will need to
+ // fix up these addresses further after all globals have been
+ // parsed to span the gaps, or we can find the global variable
+ // sizes from the DWARF info as we are parsing.
+
+ // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
+ Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
+ eSymbolTypeData,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+
+ if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
{
- SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- 1, // We don't know the size of the global, just do the main address for now.
- 0, 0, 0));
-
- oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
- oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
+ // If we found the symbol, then we
+ SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
+ SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
+ if (oso_gsym_section)
+ {
+ SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
+ oso_module_sp, // Module (the .o file)
+ sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
+ exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
+ eSectionTypeDebug,
+ oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
+ 1, // We don't know the size of the global, just do the main address for now.
+ 0, 0, 0));
+
+ oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
+ exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
+ oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
+ }
}
}
+ break;
}
- break;
}
}
+ oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
+ #if defined(DEBUG_OSO_DMAP)
+ s << "OSO sections after:\n";
+ oso_objfile->GetSectionList()->Dump(&s, NULL, true);
+ #endif
}
- oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
-#if defined(DEBUG_OSO_DMAP)
- s << "OSO sections after:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
}
}
}
@@ -223,7 +238,7 @@
}
virtual SymbolVendor*
- GetSymbolVendor(bool can_create = true)
+ GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
{
// Scope for locker
if (m_symfile_ap.get() || can_create == false)
@@ -237,7 +252,7 @@
if (oso_objfile)
{
Mutex::Locker locker (m_mutex);
- SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create);
+ SymbolVendor* symbol_vendor = Module::GetSymbolVendor(can_create, feedback_strm);
if (symbol_vendor)
{
// Set a a pointer to this class to set our OSO DWARF file know
@@ -390,30 +405,45 @@
for (uint32_t i=0; i<oso_index_count; ++i)
{
- const Symbol *so_symbol = symtab->SymbolAtIndex(oso_indexes[i] - 1);
- const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_indexes[i]);
- assert (so_symbol);
- assert (oso_symbol);
- assert (so_symbol->GetType() == eSymbolTypeSourceFile);
- assert (oso_symbol->GetType() == eSymbolTypeObjectFile);
- m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), true);
- m_compile_unit_infos[i].oso_file.SetFile(oso_symbol->GetName().AsCString(), true);
- uint32_t sibling_idx = so_symbol->GetSiblingIndex();
- // The sibling index can't be less that or equal to the current index "i"
- if (sibling_idx <= i)
+ const uint32_t so_idx = oso_indexes[i] - 1;
+ const uint32_t oso_idx = oso_indexes[i];
+ const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
+ const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
+ if (so_symbol &&
+ oso_symbol &&
+ so_symbol->GetType() == eSymbolTypeSourceFile &&
+ oso_symbol->GetType() == eSymbolTypeObjectFile)
{
- m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
+ m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), true);
+ m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
+ uint32_t sibling_idx = so_symbol->GetSiblingIndex();
+ // The sibling index can't be less that or equal to the current index "i"
+ if (sibling_idx <= i)
+ {
+ m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID());
+ }
+ else
+ {
+ const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
+ m_compile_unit_infos[i].first_symbol_index = so_idx;
+ m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
+ m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
+ m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
+
+ if (log)
+ log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
+ }
}
else
{
- const Symbol* last_symbol = symtab->SymbolAtIndex (sibling_idx - 1);
- m_compile_unit_infos[i].first_symbol_index = symtab->GetIndexForSymbol(so_symbol);
- m_compile_unit_infos[i].last_symbol_index = symtab->GetIndexForSymbol(last_symbol);
- m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
- m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
-
- if (log)
- log->Printf("Initialized OSO 0x%8.8x: file=%s", i, oso_symbol->GetName().GetCString());
+ if (oso_symbol == NULL)
+ m_obj_file->GetModule()->ReportError ("N_OSO symbol[%u] can't be found, please file a bug and attach the binary listed in this error", oso_idx);
+ else if (so_symbol == NULL)
+ m_obj_file->GetModule()->ReportError ("N_SO not found for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_idx);
+ else if (so_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError ("N_SO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", so_symbol->GetType(), oso_idx);
+ else if (oso_symbol->GetType() != eSymbolTypeSourceFile)
+ m_obj_file->GetModule()->ReportError ("N_OSO has incorrect symbol type (%u) for N_OSO symbol[%u], please file a bug and attach the binary listed in this error", oso_symbol->GetType(), oso_idx);
}
}
}
@@ -432,37 +462,48 @@
Module *
SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info)
{
- if (comp_unit_info->oso_module_sp.get() == NULL && comp_unit_info->symbol_file_supported)
+ if (!comp_unit_info->oso_sp)
{
- if (!comp_unit_info->oso_file.Exists())
+ auto pos = m_oso_map.find (comp_unit_info->oso_path);
+ if (pos != m_oso_map.end())
{
- char path[PATH_MAX*2];
- comp_unit_info->oso_file.GetPath(path, sizeof(path));
- if (ObjectFile::SplitArchivePathWithObject (path,
- comp_unit_info->oso_file,
- comp_unit_info->oso_object))
- {
- comp_unit_info->oso_file.GetPath(path, sizeof(path));
- //printf ("resolved archive '%s' and object '%s'\n", path, comp_unit_info->oso_object.GetCString());
- }
- else
+ comp_unit_info->oso_sp = pos->second;
+ }
+ else
+ {
+ comp_unit_info->oso_sp.reset (new OSOInfo());
+ m_oso_map[comp_unit_info->oso_path] = comp_unit_info->oso_sp;
+ const char *oso_path = comp_unit_info->oso_path.GetCString();
+ FileSpec oso_file (oso_path, true);
+ ConstString oso_object;
+ if (!oso_file.Exists())
{
- comp_unit_info->symbol_file_supported = false;
- return false;
+ const bool must_exist = true;
+
+ if (!ObjectFile::SplitArchivePathWithObject (oso_path,
+ oso_file,
+ oso_object,
+ must_exist))
+ {
+ comp_unit_info->oso_sp->symbol_file_supported = false;
+ return NULL;
+ }
}
+ // Always create a new module for .o files. Why? Because we
+ // use the debug map, to add new sections to each .o file and
+ // even though a .o file might not have changed, the sections
+ // that get added to the .o file can change.
+ comp_unit_info->oso_sp->module_sp.reset (new DebugMapModule (GetObjectFile()->GetModule(),
+ GetCompUnitInfoIndex(comp_unit_info),
+ oso_file,
+ m_obj_file->GetModule()->GetArchitecture(),
+ oso_object ? &oso_object : NULL,
+ 0));
}
- // Always create a new module for .o files. Why? Because we
- // use the debug map, to add new sections to each .o file and
- // even though a .o file might not have changed, the sections
- // that get added to the .o file can change.
- comp_unit_info->oso_module_sp.reset (new DebugMapModule (GetObjectFile()->GetModule(),
- GetCompUnitInfoIndex(comp_unit_info),
- comp_unit_info->oso_file,
- m_obj_file->GetModule()->GetArchitecture(),
- comp_unit_info->oso_object ? &comp_unit_info->oso_object : NULL,
- 0));
}
- return comp_unit_info->oso_module_sp.get();
+ if (comp_unit_info->oso_sp)
+ return comp_unit_info->oso_sp->module_sp.get();
+ return NULL;
}
@@ -596,8 +637,8 @@
if (cu_idx < cu_count)
{
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == NULL &&
- m_compile_unit_infos[cu_idx].symbol_file_supported)
+ Module *oso_module = GetModuleByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_module)
{
FileSpec so_file_spec;
if (GetFileSpecForSO (cu_idx, so_file_spec))
@@ -609,31 +650,31 @@
// zero in each .o file since each .o file can only have
// one compile unit for now.
lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(),
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(),
NULL,
so_file_spec,
cu_id,
eLanguageTypeUnknown));
}
- if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
{
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
NULL,
so_file_spec,
cu_idx,
eLanguageTypeUnknown));
}
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp)
{
// Let our symbol vendor know about this compile unit
m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp);
+ m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
- comp_unit_sp = m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
+ comp_unit_sp = m_compile_unit_infos[cu_idx].compile_unit_sp;
}
return comp_unit_sp;
@@ -645,23 +686,23 @@
const uint32_t cu_count = GetNumCompileUnits();
for (uint32_t i=0; i<cu_count; ++i)
{
- if (sc.comp_unit == m_compile_unit_infos[i].oso_compile_unit_sp.get())
+ if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get())
return &m_compile_unit_infos[i];
}
return NULL;
}
-SymbolFileDWARFDebugMap::CompileUnitInfo *
-SymbolFileDWARFDebugMap::GetCompUnitInfo (const lldb_private::Module *module)
+size_t
+SymbolFileDWARFDebugMap::GetCompUnitInfosForModule (const lldb_private::Module *module, std::vector<CompileUnitInfo *>& cu_infos)
{
const uint32_t cu_count = GetNumCompileUnits();
for (uint32_t i=0; i<cu_count; ++i)
{
- if (module == m_compile_unit_infos[i].oso_module_sp.get())
- return &m_compile_unit_infos[i];
+ if (module == GetModuleByCompUnitInfo (&m_compile_unit_infos[i]))
+ cu_infos.push_back (&m_compile_unit_infos[i]);
}
- return NULL;
+ return cu_infos.size();
}
lldb::LanguageType
@@ -1255,10 +1296,10 @@
SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
if (oso_symfile == oso_dwarf)
{
- if (!m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
+ if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
+ m_compile_unit_infos[cu_idx].compile_unit_sp = ParseCompileUnitAtIndex (cu_idx);
- return m_compile_unit_infos[cu_idx].oso_compile_unit_sp;
+ return m_compile_unit_infos[cu_idx].compile_unit_sp;
}
}
}
@@ -1278,13 +1319,13 @@
SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
if (oso_symfile == oso_dwarf)
{
- if (m_compile_unit_infos[cu_idx].oso_compile_unit_sp)
+ if (m_compile_unit_infos[cu_idx].compile_unit_sp)
{
- assert (m_compile_unit_infos[cu_idx].oso_compile_unit_sp.get() == cu_sp.get());
+ assert (m_compile_unit_infos[cu_idx].compile_unit_sp.get() == cu_sp.get());
}
else
{
- m_compile_unit_infos[cu_idx].oso_compile_unit_sp = cu_sp;
+ m_compile_unit_infos[cu_idx].compile_unit_sp = cu_sp;
m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
}
}
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h 2013-03-03 09:35:50.263457350 +0100
@@ -129,41 +129,43 @@
friend class SymbolFileDWARF;
friend class DebugMapModule;
+ struct OSOInfo
+ {
+ lldb::ModuleSP module_sp;
+ bool symbol_file_supported;
+
+ OSOInfo() :
+ module_sp (),
+ symbol_file_supported (true)
+ {
+ }
+ };
+
+ typedef STD_SHARED_PTR(OSOInfo) OSOInfoSP;
+
//------------------------------------------------------------------
// Class specific types
//------------------------------------------------------------------
struct CompileUnitInfo
{
lldb_private::FileSpec so_file;
- lldb_private::FileSpec oso_file;
- lldb_private::ConstString oso_object; // for archives this will be the .o file in the "oso_file"
-// lldb_private::Symbol *so_symbol;
-// lldb_private::Symbol *oso_symbol;
-// lldb_private::Symbol *last_symbol;
+ lldb_private::ConstString oso_path;
+ OSOInfoSP oso_sp;
+ lldb::CompUnitSP compile_unit_sp;
uint32_t first_symbol_index;
uint32_t last_symbol_index;
uint32_t first_symbol_id;
uint32_t last_symbol_id;
- lldb::ModuleSP oso_module_sp;
- lldb::CompUnitSP oso_compile_unit_sp;
-// SymbolFileDWARF *oso_symfile;
- bool symbol_file_supported;
CompileUnitInfo() :
so_file (),
- oso_file (),
- oso_object (),
-// so_symbol (NULL),
-// oso_symbol (NULL),
-// last_symbol (NULL),
+ oso_path (),
+ oso_sp (),
+ compile_unit_sp (),
first_symbol_index (UINT32_MAX),
last_symbol_index (UINT32_MAX),
first_symbol_id (UINT32_MAX),
- last_symbol_id (UINT32_MAX),
- oso_module_sp (),
- oso_compile_unit_sp (),
-// oso_symfile (NULL),
- symbol_file_supported (true)
+ last_symbol_id (UINT32_MAX)
{
}
};
@@ -185,8 +187,9 @@
CompileUnitInfo *
GetCompUnitInfo (const lldb_private::SymbolContext& sc);
- CompileUnitInfo *
- GetCompUnitInfo (const lldb_private::Module *oso_module);
+ size_t
+ GetCompUnitInfosForModule (const lldb_private::Module *oso_module,
+ std::vector<CompileUnitInfo *>& cu_infos);
lldb_private::Module *
GetModuleByCompUnitInfo (CompileUnitInfo *comp_unit_info);
@@ -262,6 +265,7 @@
std::vector<CompileUnitInfo> m_compile_unit_infos;
std::vector<uint32_t> m_func_indexes; // Sorted by address
std::vector<uint32_t> m_glob_indexes;
+ std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
};
Index: aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h 2013-03-03 09:35:50.263457350 +0100
@@ -22,6 +22,7 @@
#include "clang/AST/ExternalASTSource.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "lldb/lldb-private.h"
#include "lldb/Core/ClangForward.h"
@@ -59,19 +60,12 @@
class DWARFFormValue;
class SymbolFileDWARFDebugMap;
-struct BitfieldInfo
-{
- uint32_t bit_size;
- uint32_t bit_offset;
-};
-
-typedef std::map<int64_t, BitfieldInfo> BitfieldMap;
-
class SymbolFileDWARF : public lldb_private::SymbolFile, public lldb_private::UserID
{
public:
- friend class SymbolFileDWARFDebugMap;
+ friend class SymbolFileDWARFDebugMap;
friend class DebugMapModule;
+ friend class DWARFCompileUnit;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
@@ -353,7 +347,6 @@
std::vector<clang::CXXBaseSpecifier *>& base_classes,
std::vector<int>& member_accessibilities,
DWARFDIECollection& member_function_dies,
- BitfieldMap &bitfield_map,
DelayedPropertyList& delayed_properties,
lldb::AccessType &default_accessibility,
bool &is_a_class,
@@ -540,11 +533,13 @@
const lldb_private::ConstString &selector);
bool
- CopyUniqueClassMethodTypes (lldb_private::Type *class_type,
+ CopyUniqueClassMethodTypes (SymbolFileDWARF *class_symfile,
+ lldb_private::Type *class_type,
DWARFCompileUnit* src_cu,
const DWARFDebugInfoEntry *src_class_die,
DWARFCompileUnit* dst_cu,
- const DWARFDebugInfoEntry *dst_class_die);
+ const DWARFDebugInfoEntry *dst_class_die,
+ llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
Index: aze/lldb/source/Plugins/SymbolFile/Symtab/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/SymbolFile/Symtab/CMakeLists.txt 2013-03-03 09:35:50.263457350 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginSymbolFileSymtab
+ SymbolFileSymtab.cpp
+ )
Index: aze/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp 2013-03-03 09:35:50.263457350 +0100
@@ -381,66 +381,8 @@
uint32_t max_matches,
lldb_private::TypeList& types)
{
- if (!append)
- types.Clear();
-
- if (!m_objc_class_name_to_index.IsEmpty())
- {
- TypeMap::iterator iter = m_objc_class_types.find(name);
-
- if (iter != m_objc_class_types.end())
- {
- types.Insert(iter->second);
- return 1;
- }
-
- const Symtab::NameToIndexMap::Entry *match = m_objc_class_name_to_index.FindFirstValueForName(name.GetCString());
-
- if (match == NULL)
- return 0;
-
- const bool isForwardDecl = false;
- const bool isInternal = true;
-
- ClangASTContext &ast = GetClangASTContext();
-
- ClangASTMetadata metadata;
- metadata.SetUserID(0xffaaffaaffaaffaall);
- lldb::clang_type_t objc_object_type = ast.CreateObjCClass (name.AsCString(),
- ast.GetTranslationUnitDecl(),
- isForwardDecl,
- isInternal,
- &metadata);
-
- Declaration decl;
-
- lldb::TypeSP type(new Type (match->value,
- this,
- name,
- 0, // byte_size - don't change this from 0, we currently use that to identify these "synthetic" ObjC class types.
- NULL, // SymbolContextScope*
- 0, // encoding_uid
- Type::eEncodingInvalid,
- decl,
- objc_object_type,
- Type::eResolveStateFull));
-
- m_objc_class_types[name] = type;
-
- types.Insert(type);
-
- return 1;
- }
-
return 0;
}
-//
-//uint32_t
-//SymbolFileSymtab::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types)
-//{
-// return 0;
-//}
-
//------------------------------------------------------------------
// PluginInterface protocol
Index: aze/lldb/source/Plugins/SymbolVendor/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/SymbolVendor/CMakeLists.txt 2013-03-03 09:35:50.263457350 +0100
@@ -0,0 +1 @@
+#add_subdirectory(MacOSX)
Index: aze/lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt 2013-03-03 09:35:50.263457350 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginSymbolVendorMacOSX
+ SymbolVendorMacOSX.cpp
+ )
Index: aze/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp 2013-03-03 09:35:50.263457350 +0100
@@ -45,7 +45,7 @@
static bool
-UUIDsMatch(Module *module, ObjectFile *ofile)
+UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm)
{
if (module && ofile)
{
@@ -54,9 +54,12 @@
if (!ofile->GetUUID(&dsym_uuid))
{
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: failed to get the uuid for object file: '%s'\n",
- ofile->GetFileSpec().GetFilename().GetCString());
+ if (feedback_strm)
+ {
+ feedback_strm->PutCString("warning: failed to get the uuid for object file: '");
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n");
+ }
return false;
}
@@ -64,18 +67,18 @@
return true;
// Emit some warning messages since the UUIDs do not match!
- const FileSpec &m_file_spec = module->GetFileSpec();
- const FileSpec &o_file_spec = ofile->GetFileSpec();
- StreamString ss_m_path, ss_o_path;
- m_file_spec.Dump(&ss_m_path);
- o_file_spec.Dump(&ss_o_path);
-
- StreamString ss_m_uuid, ss_o_uuid;
- module->GetUUID().Dump(&ss_m_uuid);
- dsym_uuid.Dump(&ss_o_uuid);
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: UUID mismatch detected between module '%s' (%s) and:\n\t'%s' (%s)\n",
- ss_m_path.GetData(), ss_m_uuid.GetData(), ss_o_path.GetData(), ss_o_uuid.GetData());
+ if (feedback_strm)
+ {
+ feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n ");
+ module->GetUUID().Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ module->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->PutCString("\n ");
+ dsym_uuid.Dump(feedback_strm);
+ feedback_strm->PutChar(' ');
+ ofile->GetFileSpec().Dump(feedback_strm);
+ feedback_strm->EOL();
+ }
}
return false;
}
@@ -150,7 +153,7 @@
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor*
-SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp)
+SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
{
if (!module_sp)
return NULL;
@@ -183,24 +186,23 @@
{
// No symbol file was specified in the module, lets try and find
// one ourselves.
- const FileSpec &file_spec = obj_file->GetFileSpec();
- if (file_spec)
- {
- ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
- module_spec.GetUUID() = module_sp->GetUUID();
- dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
- if (module_spec.GetSourceMappingList().GetSize())
- {
- module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
- }
- }
+ FileSpec file_spec = obj_file->GetFileSpec();
+ if (!file_spec)
+ file_spec = module_sp->GetFileSpec();
+
+ ModuleSpec module_spec(file_spec, module_sp->GetArchitecture());
+ module_spec.GetUUID() = module_sp->GetUUID();
+ dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
+ if (module_spec.GetSourceMappingList().GetSize())
+ module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true);
}
if (dsym_fspec)
{
DataBufferSP dsym_file_data_sp;
- dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp);
- if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get()))
+ lldb::offset_t dsym_file_data_offset = 0;
+ dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
+ if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm))
{
char dsym_path[PATH_MAX];
if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
Index: aze/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h
===================================================================
--- aze.orig/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h 2013-03-03 09:35:50.267457350 +0100
@@ -32,7 +32,7 @@
GetPluginDescriptionStatic();
static lldb_private::SymbolVendor*
- CreateInstance (const lldb::ModuleSP &module_sp);
+ CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);
//------------------------------------------------------------------
// Constructors and Destructors
Index: aze/lldb/source/Plugins/UnwindAssembly/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/UnwindAssembly/CMakeLists.txt 2013-03-03 09:35:50.267457350 +0100
@@ -0,0 +1,2 @@
+add_subdirectory(InstEmulation)
+add_subdirectory(x86)
Index: aze/lldb/source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt 2013-03-03 09:35:50.267457350 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginUnwindAssemblyInstEmulation
+ UnwindAssemblyInstEmulation.cpp
+ )
Index: aze/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp
===================================================================
--- aze.orig/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp 2013-03-03 09:35:50.267457350 +0100
@@ -9,8 +9,6 @@
#include "UnwindAssemblyInstEmulation.h"
-#include "llvm-c/EnhancedDisassembly.h"
-
#include "lldb/Core/Address.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBufferHeap.h"
@@ -57,6 +55,7 @@
thread.CalculateExecutionContext(exe_ctx);
DisassemblerSP disasm_sp (Disassembler::DisassembleRange (m_arch,
NULL,
+ NULL,
exe_ctx,
range));
@@ -271,7 +270,7 @@
{
StreamString strm;
lldb::addr_t base_addr = range.GetBaseAddress().GetLoadAddress(thread.CalculateTarget().get());
- strm.Printf ("Resulting unwind rows for [0x%llx - 0x%llx):", base_addr, base_addr + range.GetByteSize());
+ strm.Printf ("Resulting unwind rows for [0x%" PRIx64 " - 0x%" PRIx64 "):", base_addr, base_addr + range.GetByteSize());
unwind_plan.Dump(strm, &thread, base_addr);
log->PutCString (strm.GetData());
}
@@ -403,7 +402,7 @@
if (log && log->GetVerbose ())
{
StreamString strm;
- strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16llx, dst = %p, dst_len = %llu, context = ",
+ strm.Printf ("UnwindAssemblyInstEmulation::ReadMemory (addr = 0x%16.16" PRIx64 ", dst = %p, dst_len = %" PRIu64 ", context = ",
addr,
dst,
(uint64_t)dst_len);
@@ -594,7 +593,6 @@
switch (context.type)
{
- default:
case EmulateInstruction::eContextInvalid:
case EmulateInstruction::eContextReadOpcode:
case EmulateInstruction::eContextImmediate:
Index: aze/lldb/source/Plugins/UnwindAssembly/x86/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Plugins/UnwindAssembly/x86/CMakeLists.txt 2013-03-03 09:35:50.267457350 +0100
@@ -0,0 +1,5 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbPluginUnwindAssemblyX86
+ UnwindAssembly-x86.cpp
+ )
Index: aze/lldb/source/Symbol/Block.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/Block.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/Block.cpp 2013-03-03 09:35:50.267457350 +0100
@@ -89,7 +89,7 @@
const Block* parent_block = GetParent();
if (parent_block)
{
- s->Printf(", parent = {0x%8.8llx}", parent_block->GetID());
+ s->Printf(", parent = {0x%8.8" PRIx64 "}", parent_block->GetID());
}
if (m_inlineInfoSP.get() != NULL)
{
@@ -194,7 +194,7 @@
Function *function = CalculateSymbolContextFunction();
if (function)
function->DumpSymbolContext(s);
- s->Printf(", Block{0x%8.8llx}", GetID());
+ s->Printf(", Block{0x%8.8" PRIx64 "}", GetID());
}
void
@@ -408,7 +408,7 @@
const Declaration &func_decl = func_type->GetDeclaration();
if (func_decl.GetLine())
{
- log->Printf ("warning: %s/%s:%u block {0x%8.8llx} has range[%u] [0x%llx - 0x%llx) which is not contained in parent block {0x%8.8llx} in function {0x%8.8llx} from %s/%s",
+ log->Printf ("warning: %s/%s:%u block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s/%s",
func_decl.GetFile().GetDirectory().GetCString(),
func_decl.GetFile().GetFilename().GetCString(),
func_decl.GetLine(),
@@ -423,7 +423,7 @@
}
else
{
- log->Printf ("warning: block {0x%8.8llx} has range[%u] [0x%llx - 0x%llx) which is not contained in parent block {0x%8.8llx} in function {0x%8.8llx} from %s/%s",
+ log->Printf ("warning: block {0x%8.8" PRIx64 "} has range[%u] [0x%" PRIx64 " - 0x%" PRIx64 ") which is not contained in parent block {0x%8.8" PRIx64 "} in function {0x%8.8" PRIx64 "} from %s/%s",
GetID(),
(uint32_t)m_ranges.GetSize(),
block_start_addr,
Index: aze/lldb/source/Symbol/ClangASTContext.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/ClangASTContext.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/ClangASTContext.cpp 2013-03-03 09:35:50.267457350 +0100
@@ -34,6 +34,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTImporter.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
@@ -193,7 +194,6 @@
{
switch (access)
{
- default: break;
case eAccessNone: return ObjCIvarDecl::None;
case eAccessPublic: return ObjCIvarDecl::Public;
case eAccessPrivate: return ObjCIvarDecl::Private;
@@ -257,15 +257,17 @@
}
const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
- Opts.BCPLComment = Std.hasBCPLComments();
+ Opts.LineComment = Std.hasLineComments();
Opts.C99 = Std.isC99();
Opts.CPlusPlus = Std.isCPlusPlus();
- Opts.CPlusPlus0x = Std.isCPlusPlus0x();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
Opts.Digraphs = Std.hasDigraphs();
Opts.GNUMode = Std.isGNUMode();
Opts.GNUInline = !Std.isC99();
Opts.HexFloats = Std.hasHexFloats();
Opts.ImplicitInt = Std.hasImplicitInt();
+
+ Opts.WChar = true;
// OpenCL has some additional defaults.
if (LangStd == LangStandard::lang_opencl) {
@@ -298,7 +300,7 @@
// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility,
// "default");
// if (Vis == "default")
- Opts.setVisibilityMode(DefaultVisibility);
+ Opts.setValueVisibilityMode(DefaultVisibility);
// else if (Vis == "hidden")
// Opts.setVisibilityMode(LangOptions::Hidden);
// else if (Vis == "protected")
@@ -625,7 +627,7 @@
{
// target_triple should be something like "x86_64-apple-macosx"
if (m_target_info_ap.get() == NULL && !m_target_triple.empty())
- m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), *getTargetOptions()));
+ m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnosticsEngine(), getTargetOptions()));
return m_target_info_ap.get();
}
@@ -707,8 +709,6 @@
if (bit_size && !(bit_size & 0x7u))
return ast->getExtVectorType (ast->UnsignedCharTy, bit_size/8).getAsOpaquePtr();
break;
- default:
- break;
}
return NULL;
@@ -1279,9 +1279,10 @@
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
- for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
+
+ for (NamedDecl *decl : result)
{
- class_template_decl = dyn_cast<clang::ClassTemplateDecl>(*pos);
+ class_template_decl = dyn_cast<clang::ClassTemplateDecl>(decl);
if (class_template_decl)
return class_template_decl;
}
@@ -1308,8 +1309,8 @@
// With templated classes, we say that a class is templated with
// specializations, but that the bare class has no functions.
- template_cxx_decl->startDefinition();
- template_cxx_decl->completeDefinition();
+ //template_cxx_decl->startDefinition();
+ //template_cxx_decl->completeDefinition();
class_template_decl = ClassTemplateDecl::Create (*ast,
decl_ctx, // What decl context do we use here? TU? The actual decl context?
@@ -1355,6 +1356,8 @@
template_param_infos.args.size(),
NULL);
+ class_template_specialization_decl->setSpecializationKind(TSK_ExplicitSpecialization);
+
return class_template_specialization_decl;
}
@@ -2045,14 +2048,14 @@
typedef llvm::SmallVector <IndirectFieldDecl *, 1> IndirectFieldVector;
IndirectFieldVector indirect_fields;
-
- for (RecordDecl::field_iterator fi = record_decl->field_begin(), fe = record_decl->field_end();
- fi != fe;
- ++fi)
+ RecordDecl::field_iterator field_pos;
+ RecordDecl::field_iterator field_end_pos = record_decl->field_end();
+ RecordDecl::field_iterator last_field_pos = field_end_pos;
+ for (field_pos = record_decl->field_begin(); field_pos != field_end_pos; last_field_pos = field_pos++)
{
- if (fi->isAnonymousStructOrUnion())
+ if (field_pos->isAnonymousStructOrUnion())
{
- QualType field_qual_type = fi->getType();
+ QualType field_qual_type = field_pos->getType();
const RecordType *field_record_type = field_qual_type->getAs<RecordType>();
@@ -2071,7 +2074,7 @@
if (FieldDecl *nested_field_decl = dyn_cast<FieldDecl>(*di))
{
NamedDecl **chain = new (*ast) NamedDecl*[2];
- chain[0] = *fi;
+ chain[0] = *field_pos;
chain[1] = nested_field_decl;
IndirectFieldDecl *indirect_field = IndirectFieldDecl::Create(*ast,
record_decl,
@@ -2081,7 +2084,7 @@
chain,
2);
- indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+ indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
nested_field_decl->getAccess()));
indirect_fields.push_back(indirect_field);
@@ -2090,7 +2093,7 @@
{
int nested_chain_size = nested_indirect_field_decl->getChainingSize();
NamedDecl **chain = new (*ast) NamedDecl*[nested_chain_size + 1];
- chain[0] = *fi;
+ chain[0] = *field_pos;
int chain_index = 1;
for (IndirectFieldDecl::chain_iterator nci = nested_indirect_field_decl->chain_begin(),
@@ -2110,7 +2113,7 @@
chain,
nested_chain_size + 1);
- indirect_field->setAccess(UnifyAccessSpecifiers(fi->getAccess(),
+ indirect_field->setAccess(UnifyAccessSpecifiers(field_pos->getAccess(),
nested_indirect_field_decl->getAccess()));
indirect_fields.push_back(indirect_field);
@@ -2119,6 +2122,14 @@
}
}
+ // Check the last field to see if it has an incomplete array type as its
+ // last member and if it does, the tell the record decl about it
+ if (last_field_pos != field_end_pos)
+ {
+ if (last_field_pos->getType()->isIncompleteArrayType())
+ record_decl->hasFlexibleArrayMember();
+ }
+
for (IndirectFieldVector::iterator ifi = indirect_fields.begin(), ife = indirect_fields.end();
ifi < ife;
++ifi)
@@ -2711,6 +2722,9 @@
ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None;
const unsigned num_args = method_function_prototype->getNumArgs();
+
+ if (num_args != num_selectors_with_args)
+ return NULL; // some debug information is corrupt. We are not going to deal with it.
ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast,
SourceLocation(), // beginLoc,
@@ -2786,6 +2800,10 @@
case clang::Type::Typedef:
return ClangASTContext::GetNumTemplateArguments (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
+
+ case clang::Type::Elaborated:
+ return ClangASTContext::GetNumTemplateArguments (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
default:
break;
}
@@ -2859,6 +2877,10 @@
case clang::Type::Typedef:
return ClangASTContext::GetTemplateArgument (ast, cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), arg_idx, kind);
+
+ case clang::Type::Elaborated:
+ return ClangASTContext::GetTemplateArgument (ast, cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), arg_idx, kind);
+
default:
break;
}
@@ -3355,7 +3377,7 @@
clang_type_t
ClangASTContext::GetDirectBaseClassAtIndex (clang::ASTContext *ast,
clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
uint32_t *bit_offset_ptr)
{
if (clang_type == NULL)
@@ -3440,7 +3462,7 @@
clang_type_t
ClangASTContext::GetVirtualBaseClassAtIndex (clang::ASTContext *ast,
clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
uint32_t *bit_offset_ptr)
{
if (clang_type == NULL)
@@ -3499,7 +3521,7 @@
clang_type_t
ClangASTContext::GetFieldAtIndex (clang::ASTContext *ast,
clang_type_t clang_type,
- uint32_t idx,
+ size_t idx,
std::string& name,
uint64_t *bit_offset_ptr,
uint32_t *bitfield_bit_size_ptr,
@@ -3694,6 +3716,14 @@
case clang::BuiltinType::UnknownAny:
case clang::BuiltinType::BuiltinFn:
case clang::BuiltinType::ARCUnbridgedCast:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
return eBasicTypeOther;
}
}
@@ -3725,6 +3755,14 @@
case clang::BuiltinType::UnknownAny:
case clang::BuiltinType::Void:
case clang::BuiltinType::NullPtr:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
return 0;
case clang::BuiltinType::Bool:
case clang::BuiltinType::Char_U:
@@ -3807,7 +3845,7 @@
ExecutionContext *exe_ctx,
const char *parent_name,
clang_type_t parent_clang_type,
- uint32_t idx,
+ size_t idx,
bool transparent_pointers,
bool omit_empty_base_classes,
bool ignore_array_bounds,
@@ -3847,7 +3885,7 @@
ASTContext *ast,
const char *parent_name,
clang_type_t parent_clang_type,
- uint32_t idx,
+ size_t idx,
bool transparent_pointers,
bool omit_empty_base_classes,
bool ignore_array_bounds,
@@ -3863,17 +3901,19 @@
if (parent_clang_type == NULL)
return NULL;
- if (idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes))
+ QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
+ const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
+ child_bitfield_bit_size = 0;
+ child_bitfield_bit_offset = 0;
+ child_is_base_class = false;
+
+ const bool idx_is_valid = idx < ClangASTContext::GetNumChildren (ast, parent_clang_type, omit_empty_base_classes);
+ uint32_t bit_offset;
+ switch (parent_type_class)
{
- uint32_t bit_offset;
- child_bitfield_bit_size = 0;
- child_bitfield_bit_offset = 0;
- child_is_base_class = false;
- QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type));
- const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass();
- switch (parent_type_class)
+ case clang::Type::Builtin:
+ if (idx_is_valid)
{
- case clang::Type::Builtin:
switch (cast<clang::BuiltinType>(parent_qual_type)->getKind())
{
case clang::BuiltinType::ObjCId:
@@ -3885,270 +3925,272 @@
default:
break;
}
- break;
+ }
+ break;
- case clang::Type::Record:
- if (GetCompleteQualType (ast, parent_qual_type))
- {
- const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
- const RecordDecl *record_decl = record_type->getDecl();
- assert(record_decl);
- const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
- uint32_t child_idx = 0;
+ case clang::Type::Record:
+ if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
+ {
+ const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr());
+ const RecordDecl *record_decl = record_type->getDecl();
+ assert(record_decl);
+ const ASTRecordLayout &record_layout = ast->getASTRecordLayout(record_decl);
+ uint32_t child_idx = 0;
- const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
- if (cxx_record_decl)
+ const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl);
+ if (cxx_record_decl)
+ {
+ // We might have base classes to print out first
+ CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
+ for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
+ base_class != base_class_end;
+ ++base_class)
{
- // We might have base classes to print out first
- CXXRecordDecl::base_class_const_iterator base_class, base_class_end;
- for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end();
- base_class != base_class_end;
- ++base_class)
+ const CXXRecordDecl *base_class_decl = NULL;
+
+ // Skip empty base classes
+ if (omit_empty_base_classes)
{
- const CXXRecordDecl *base_class_decl = NULL;
+ base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
+ if (RecordHasFields(base_class_decl) == false)
+ continue;
+ }
- // Skip empty base classes
- if (omit_empty_base_classes)
- {
+ if (idx == child_idx)
+ {
+ if (base_class_decl == NULL)
base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (RecordHasFields(base_class_decl) == false)
- continue;
- }
-
- if (idx == child_idx)
- {
- if (base_class_decl == NULL)
- base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl());
- if (base_class->isVirtual())
- bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
- else
- bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
+ if (base_class->isVirtual())
+ bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity() * 8;
+ else
+ bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity() * 8;
- // Base classes should be a multiple of 8 bits in size
- child_byte_offset = bit_offset/8;
-
- child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
+ // Base classes should be a multiple of 8 bits in size
+ child_byte_offset = bit_offset/8;
+
+ child_name = ClangASTType::GetTypeNameForQualType(ast, base_class->getType());
- uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
+ uint64_t clang_type_info_bit_size = ast->getTypeSize(base_class->getType());
- // Base classes bit sizes should be a multiple of 8 bits in size
- assert (clang_type_info_bit_size % 8 == 0);
- child_byte_size = clang_type_info_bit_size / 8;
- child_is_base_class = true;
- return base_class->getType().getAsOpaquePtr();
- }
- // We don't increment the child index in the for loop since we might
- // be skipping empty base classes
- ++child_idx;
+ // Base classes bit sizes should be a multiple of 8 bits in size
+ assert (clang_type_info_bit_size % 8 == 0);
+ child_byte_size = clang_type_info_bit_size / 8;
+ child_is_base_class = true;
+ return base_class->getType().getAsOpaquePtr();
}
+ // We don't increment the child index in the for loop since we might
+ // be skipping empty base classes
+ ++child_idx;
}
- // Make sure index is in range...
- uint32_t field_idx = 0;
- RecordDecl::field_iterator field, field_end;
- for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+ }
+ // Make sure index is in range...
+ uint32_t field_idx = 0;
+ RecordDecl::field_iterator field, field_end;
+ for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx)
+ {
+ if (idx == child_idx)
{
- if (idx == child_idx)
- {
- // Print the member type if requested
- // Print the member name and equal sign
- child_name.assign(field->getNameAsString().c_str());
+ // Print the member type if requested
+ // Print the member name and equal sign
+ child_name.assign(field->getNameAsString().c_str());
- // Figure out the type byte size (field_type_info.first) and
- // alignment (field_type_info.second) from the AST context.
- std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
- assert(field_idx < record_layout.getFieldCount());
+ // Figure out the type byte size (field_type_info.first) and
+ // alignment (field_type_info.second) from the AST context.
+ std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(field->getType());
+ assert(field_idx < record_layout.getFieldCount());
- child_byte_size = field_type_info.first / 8;
+ child_byte_size = field_type_info.first / 8;
- // Figure out the field offset within the current struct/union/class type
- bit_offset = record_layout.getFieldOffset (field_idx);
- child_byte_offset = bit_offset / 8;
- if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
- child_bitfield_bit_offset = bit_offset % 8;
+ // Figure out the field offset within the current struct/union/class type
+ bit_offset = record_layout.getFieldOffset (field_idx);
+ child_byte_offset = bit_offset / 8;
+ if (ClangASTContext::FieldIsBitfield (ast, *field, child_bitfield_bit_size))
+ child_bitfield_bit_offset = bit_offset % 8;
- return field->getType().getAsOpaquePtr();
- }
+ return field->getType().getAsOpaquePtr();
}
}
- break;
+ }
+ break;
- case clang::Type::ObjCObject:
- case clang::Type::ObjCInterface:
- if (GetCompleteQualType (ast, parent_qual_type))
+ case clang::Type::ObjCObject:
+ case clang::Type::ObjCInterface:
+ if (idx_is_valid && GetCompleteQualType (ast, parent_qual_type))
+ {
+ const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
+ assert (objc_class_type);
+ if (objc_class_type)
{
- const ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr());
- assert (objc_class_type);
- if (objc_class_type)
+ uint32_t child_idx = 0;
+ ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
+
+ if (class_interface_decl)
{
- uint32_t child_idx = 0;
- ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
-
- if (class_interface_decl)
+
+ const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
+ ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
+ if (superclass_interface_decl)
{
-
- const ASTRecordLayout &interface_layout = ast->getASTObjCInterfaceLayout(class_interface_decl);
- ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
- if (superclass_interface_decl)
+ if (omit_empty_base_classes)
{
- if (omit_empty_base_classes)
+ if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
{
- if (ClangASTContext::GetNumChildren(ast, ast->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0)
+ if (idx == 0)
{
- if (idx == 0)
- {
- QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
-
-
- child_name.assign(superclass_interface_decl->getNameAsString().c_str());
+ QualType ivar_qual_type(ast->getObjCInterfaceType(superclass_interface_decl));
+
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+ child_name.assign(superclass_interface_decl->getNameAsString().c_str());
- child_byte_size = ivar_type_info.first / 8;
- child_byte_offset = 0;
- child_is_base_class = true;
+ std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
- return ivar_qual_type.getAsOpaquePtr();
- }
+ child_byte_size = ivar_type_info.first / 8;
+ child_byte_offset = 0;
+ child_is_base_class = true;
- ++child_idx;
+ return ivar_qual_type.getAsOpaquePtr();
}
- }
- else
+
++child_idx;
+ }
}
-
- const uint32_t superclass_idx = child_idx;
+ else
+ ++child_idx;
+ }
- if (idx < (child_idx + class_interface_decl->ivar_size()))
+ const uint32_t superclass_idx = child_idx;
+
+ if (idx < (child_idx + class_interface_decl->ivar_size()))
+ {
+ ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
+
+ for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
{
- ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end();
-
- for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos)
+ if (child_idx == idx)
{
- if (child_idx == idx)
+ ObjCIvarDecl* ivar_decl = *ivar_pos;
+
+ QualType ivar_qual_type(ivar_decl->getType());
+
+ child_name.assign(ivar_decl->getNameAsString().c_str());
+
+ std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
+
+ child_byte_size = ivar_type_info.first / 8;
+
+ // Figure out the field offset within the current struct/union/class type
+ // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
+ // that doesn't account for the space taken up by unbacked properties, or from
+ // the changing size of base classes that are newer than this class.
+ // So if we have a process around that we can ask about this object, do so.
+ child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
+ Process *process = NULL;
+ if (exe_ctx)
+ process = exe_ctx->GetProcessPtr();
+ if (process)
{
- ObjCIvarDecl* ivar_decl = *ivar_pos;
-
- QualType ivar_qual_type(ivar_decl->getType());
-
- child_name.assign(ivar_decl->getNameAsString().c_str());
-
- std::pair<uint64_t, unsigned> ivar_type_info = ast->getTypeInfo(ivar_qual_type.getTypePtr());
-
- child_byte_size = ivar_type_info.first / 8;
-
- // Figure out the field offset within the current struct/union/class type
- // For ObjC objects, we can't trust the bit offset we get from the Clang AST, since
- // that doesn't account for the space taken up by unbacked properties, or from
- // the changing size of base classes that are newer than this class.
- // So if we have a process around that we can ask about this object, do so.
- child_byte_offset = LLDB_INVALID_IVAR_OFFSET;
- Process *process = NULL;
- if (exe_ctx)
- process = exe_ctx->GetProcessPtr();
- if (process)
+ ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
+ if (objc_runtime != NULL)
{
- ObjCLanguageRuntime *objc_runtime = process->GetObjCLanguageRuntime();
- if (objc_runtime != NULL)
- {
- ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
- child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
- }
+ ClangASTType parent_ast_type (ast, parent_qual_type.getAsOpaquePtr());
+ child_byte_offset = objc_runtime->GetByteOffsetForIvar (parent_ast_type, ivar_decl->getNameAsString().c_str());
}
-
- // Setting this to UINT32_MAX to make sure we don't compute it twice...
- bit_offset = UINT32_MAX;
-
- if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
- {
+ }
+
+ // Setting this to UINT32_MAX to make sure we don't compute it twice...
+ bit_offset = UINT32_MAX;
+
+ if (child_byte_offset == LLDB_INVALID_IVAR_OFFSET)
+ {
+ bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
+ child_byte_offset = bit_offset / 8;
+ }
+
+ // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
+ // of a bitfield within its containing object. So regardless of where we get the byte
+ // offset from, we still need to get the bit offset for bitfields from the layout.
+
+ if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
+ {
+ if (bit_offset == UINT32_MAX)
bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
- child_byte_offset = bit_offset / 8;
- }
-
- // Note, the ObjC Ivar Byte offset is just that, it doesn't account for the bit offset
- // of a bitfield within its containing object. So regardless of where we get the byte
- // offset from, we still need to get the bit offset for bitfields from the layout.
-
- if (ClangASTContext::FieldIsBitfield (ast, ivar_decl, child_bitfield_bit_size))
- {
- if (bit_offset == UINT32_MAX)
- bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx);
-
- child_bitfield_bit_offset = bit_offset % 8;
- }
- return ivar_qual_type.getAsOpaquePtr();
+
+ child_bitfield_bit_offset = bit_offset % 8;
}
- ++child_idx;
+ return ivar_qual_type.getAsOpaquePtr();
}
+ ++child_idx;
}
}
}
}
- break;
-
- case clang::Type::ObjCObjectPointer:
- {
- const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
+ }
+ break;
+
+ case clang::Type::ObjCObjectPointer:
+ if (idx_is_valid)
+ {
+ const ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointer_type->getPointeeType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
+ {
+ child_is_deref_of_parent = true;
+ if (parent_name)
{
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- else
- {
- child_is_deref_of_parent = true;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
- // We have a pointer to an simple type
- if (idx == 0 && GetCompleteQualType(ast, pointee_type))
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ // We have a pointer to an simple type
+ if (idx == 0 && GetCompleteQualType(ast, pointee_type))
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
+ }
+ break;
case clang::Type::ConstantArray:
+ case clang::Type::IncompleteArray:
+ if (ignore_array_bounds || idx_is_valid)
{
- const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr());
- const uint64_t element_count = array->getSize().getLimitedValue();
-
- if (ignore_array_bounds || idx < element_count)
+ const ArrayType *array = cast<ArrayType>(parent_qual_type.getTypePtr());
+ if (array)
{
if (GetCompleteQualType (ast, array->getElementType()))
{
std::pair<uint64_t, unsigned> field_type_info = ast->getTypeInfo(array->getElementType());
-
+
char element_name[64];
- ::snprintf (element_name, sizeof (element_name), "[%u]", idx);
-
+ ::snprintf (element_name, sizeof (element_name), "[%zu]", idx);
+
child_name.assign(element_name);
assert(field_type_info.first % 8 == 0);
child_byte_size = field_type_info.first / 8;
@@ -4158,144 +4200,146 @@
}
}
break;
+
- case clang::Type::Pointer:
+ case clang::Type::Pointer:
+ if (idx_is_valid)
+ {
+ const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
+ QualType pointee_type = pointer_type->getPointeeType();
+
+ // Don't dereference "void *" pointers
+ if (pointee_type->isVoidType())
+ return NULL;
+
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointer_type->getPointeeType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
{
- const PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr());
- QualType pointee_type = pointer_type->getPointeeType();
-
- // Don't dereference "void *" pointers
- if (pointee_type->isVoidType())
- return NULL;
+ child_is_deref_of_parent = true;
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr()))
+ if (parent_name)
{
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointer_type->getPointeeType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
+ child_name.assign(1, '*');
+ child_name += parent_name;
}
- else
- {
- child_is_deref_of_parent = true;
- if (parent_name)
- {
- child_name.assign(1, '*');
- child_name += parent_name;
- }
-
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
+ }
+ break;
- case clang::Type::LValueReference:
- case clang::Type::RValueReference:
+ case clang::Type::LValueReference:
+ case clang::Type::RValueReference:
+ if (idx_is_valid)
+ {
+ const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
+ QualType pointee_type(reference_type->getPointeeType());
+ clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
+ if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
+ {
+ child_is_deref_of_parent = false;
+ bool tmp_child_is_deref_of_parent = false;
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ pointee_clang_type,
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ tmp_child_is_deref_of_parent);
+ }
+ else
{
- const ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr());
- QualType pointee_type(reference_type->getPointeeType());
- clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr();
- if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type))
- {
- child_is_deref_of_parent = false;
- bool tmp_child_is_deref_of_parent = false;
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- pointee_clang_type,
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- tmp_child_is_deref_of_parent);
- }
- else
+ if (parent_name)
{
- if (parent_name)
- {
- child_name.assign(1, '&');
- child_name += parent_name;
- }
+ child_name.assign(1, '&');
+ child_name += parent_name;
+ }
- // We have a pointer to an simple type
- if (idx == 0)
- {
- std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
- assert(clang_type_info.first % 8 == 0);
- child_byte_size = clang_type_info.first / 8;
- child_byte_offset = 0;
- return pointee_type.getAsOpaquePtr();
- }
+ // We have a pointer to an simple type
+ if (idx == 0)
+ {
+ std::pair<uint64_t, unsigned> clang_type_info = ast->getTypeInfo(pointee_type);
+ assert(clang_type_info.first % 8 == 0);
+ child_byte_size = clang_type_info.first / 8;
+ child_byte_offset = 0;
+ return pointee_type.getAsOpaquePtr();
}
}
- break;
+ }
+ break;
- case clang::Type::Typedef:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
- break;
-
- case clang::Type::Elaborated:
- return GetChildClangTypeAtIndex (exe_ctx,
- ast,
- parent_name,
- cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
- idx,
- transparent_pointers,
- omit_empty_base_classes,
- ignore_array_bounds,
- child_name,
- child_byte_size,
- child_byte_offset,
- child_bitfield_bit_size,
- child_bitfield_bit_offset,
- child_is_base_class,
- child_is_deref_of_parent);
+ case clang::Type::Typedef:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ cast<TypedefType>(parent_qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+ break;
- default:
- break;
- }
+ case clang::Type::Elaborated:
+ return GetChildClangTypeAtIndex (exe_ctx,
+ ast,
+ parent_name,
+ cast<ElaboratedType>(parent_qual_type)->getNamedType().getAsOpaquePtr(),
+ idx,
+ transparent_pointers,
+ omit_empty_base_classes,
+ ignore_array_bounds,
+ child_name,
+ child_byte_size,
+ child_byte_offset,
+ child_bitfield_bit_size,
+ child_bitfield_bit_offset,
+ child_is_base_class,
+ child_is_deref_of_parent);
+
+ default:
+ break;
}
return NULL;
}
@@ -4552,12 +4596,9 @@
parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl());
}
}
- DeclContext::lookup_iterator named_decl_pos;
- for (named_decl_pos = path->Decls.first;
- named_decl_pos != path->Decls.second && parent_record_decl;
- ++named_decl_pos)
+ for (NamedDecl *path_decl : path->Decls)
{
- child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes);
+ child_idx = GetIndexForRecordChild (parent_record_decl, path_decl, omit_empty_base_classes);
if (child_idx == UINT32_MAX)
{
child_indexes.clear();
@@ -4740,6 +4781,13 @@
omit_empty_base_classes,
child_indexes);
+ case clang::Type::Elaborated:
+ return GetIndexOfChildMemberWithName (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes,
+ child_indexes);
+
default:
break;
}
@@ -4947,6 +4995,12 @@
}
break;
+ case clang::Type::Elaborated:
+ return GetIndexOfChildWithName (ast,
+ cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ name,
+ omit_empty_base_classes);
+
case clang::Type::Typedef:
return GetIndexOfChildWithName (ast,
cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
@@ -5061,9 +5115,9 @@
IdentifierInfo &identifier_info = ast->Idents.get(name);
DeclarationName decl_name (&identifier_info);
clang::DeclContext::lookup_result result = decl_ctx->lookup(decl_name);
- for (clang::DeclContext::lookup_iterator pos = result.first, end = result.second; pos != end; ++pos)
+ for (NamedDecl *decl : result)
{
- namespace_decl = dyn_cast<clang::NamespaceDecl>(*pos);
+ namespace_decl = dyn_cast<clang::NamespaceDecl>(decl);
if (namespace_decl)
return namespace_decl;
}
@@ -5249,17 +5303,27 @@
#pragma mark Array Types
clang_type_t
-ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride)
+ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count)
{
if (element_type)
{
ASTContext *ast = getASTContext();
assert (ast != NULL);
llvm::APInt ap_element_count (64, element_count);
- return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
- ap_element_count,
- ArrayType::Normal,
- 0).getAsOpaquePtr(); // ElemQuals
+ if (element_count == 0)
+ {
+ return ast->getIncompleteArrayType(QualType::getFromOpaquePtr(element_type),
+ ArrayType::Normal,
+ 0).getAsOpaquePtr();
+
+ }
+ else
+ {
+ return ast->getConstantArrayType(QualType::getFromOpaquePtr(element_type),
+ ap_element_count,
+ ArrayType::Normal,
+ 0).getAsOpaquePtr(); // ElemQuals
+ }
}
return NULL;
}
@@ -5647,6 +5711,14 @@
case clang::BuiltinType::ARCUnbridgedCast:
case clang::BuiltinType::PseudoObject:
case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
break;
}
break;
@@ -5930,7 +6002,7 @@
bool
ClangASTContext::IsArrayOfScalarType (lldb::clang_type_t clang_type)
{
- clang_type = GetAsArrayType(clang_type);
+ clang_type = GetAsArrayType(clang_type, NULL, NULL, NULL);
if (clang_type == 0)
return false;
@@ -6150,8 +6222,10 @@
}
clang_type_t
-ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size)
+ClangASTContext::GetAsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size, bool *is_incomplete)
{
+ if (is_incomplete)
+ *is_incomplete = false;
if (!clang_type)
return 0;
@@ -6175,6 +6249,8 @@
*member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr();
if (size)
*size = 0;
+ if (is_incomplete)
+ *is_incomplete = true;
return clang_type;
case clang::Type::VariableArray:
@@ -6194,12 +6270,14 @@
case clang::Type::Typedef:
return ClangASTContext::GetAsArrayType (cast<TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(),
member_type,
- size);
+ size,
+ is_incomplete);
case clang::Type::Elaborated:
return ClangASTContext::GetAsArrayType (cast<ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
member_type,
- size);
+ size,
+ is_incomplete);
}
return 0;
}
Index: aze/lldb/source/Symbol/ClangASTImporter.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/ClangASTImporter.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/ClangASTImporter.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -10,6 +10,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "llvm/Support/raw_ostream.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -66,12 +67,12 @@
user_id = metadata->GetUserID();
if (NamedDecl *named_decl = dyn_cast<NamedDecl>(decl))
- log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s '%s', metadata 0x%" PRIx64,
decl->getDeclKindName(),
named_decl->getNameAsString().c_str(),
user_id);
else
- log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] WARNING: Failed to import a %s, metadata 0x%" PRIx64,
decl->getDeclKindName(),
user_id);
}
@@ -125,11 +126,20 @@
clang::ASTContext *src_ctx,
clang::Decl *decl)
{
+ lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+
+ if (log)
+ log->Printf(" [ClangASTImporter] DeportDecl called on (%sDecl*)%p from (ASTContext*)%p to (ASTContex*)%p",
+ decl->getDeclKindName(),
+ decl,
+ src_ctx,
+ dst_ctx);
+
clang::Decl *result = CopyDecl(dst_ctx, src_ctx, decl);
if (!result)
return NULL;
-
+
ClangASTContext::GetCompleteDecl (src_ctx, decl);
MinionSP minion_sp (GetMinion (dst_ctx, src_ctx));
@@ -139,12 +149,25 @@
ASTContextMetadataSP to_context_md = GetContextMetadata(dst_ctx);
- OriginMap::iterator oi = to_context_md->m_origins.find(decl);
+ OriginMap::iterator oi = to_context_md->m_origins.find(result);
if (oi != to_context_md->m_origins.end() &&
oi->second.ctx == src_ctx)
to_context_md->m_origins.erase(oi);
+ if (TagDecl *result_tag_decl = dyn_cast<TagDecl>(result))
+ {
+ result_tag_decl->setHasExternalLexicalStorage(false);
+ result_tag_decl->setHasExternalVisibleStorage(false);
+ }
+
+ if (log)
+ log->Printf(" [ClangASTImporter] DeportDecl deported (%sDecl*)%p to (%sDecl*)%p",
+ decl->getDeclKindName(),
+ decl,
+ result->getDeclKindName(),
+ result);
+
return result;
}
@@ -467,7 +490,7 @@
from_named_decl->printName(name_stream);
name_stream.flush();
- log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p, named %s (from (Decl*)%p), metadata 0x%" PRIx64,
from->getDeclKindName(),
to,
name_string.c_str(),
@@ -476,7 +499,7 @@
}
else
{
- log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%llx",
+ log->Printf(" [ClangASTImporter] Imported (%sDecl*)%p (from (Decl*)%p), metadata 0x%" PRIx64,
from->getDeclKindName(),
to,
from,
Index: aze/lldb/source/Symbol/ClangASTType.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/ClangASTType.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/ClangASTType.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -1,4 +1,4 @@
-//===-- ClangASTType.cpp ---------------------------------------------*- C++ -*-===//
+//===-- ClangASTType.cpp ----------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Symbol/ClangASTType.h"
#include "clang/AST/ASTConsumer.h"
@@ -34,10 +36,13 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include <mutex>
+
using namespace lldb;
using namespace lldb_private;
@@ -53,6 +58,7 @@
clang::PrintingPolicy printing_policy (ast->getPrintingPolicy());
printing_policy.SuppressTagKeyword = true;
+ printing_policy.LangOpts.WChar = true;
const clang::TypedefType *typedef_type = qual_type->getAs<clang::TypedefType>();
if (typedef_type)
{
@@ -245,7 +251,9 @@
case clang::Type::Typedef: return lldb::eTypeClassTypedef;
case clang::Type::UnresolvedUsing: break;
case clang::Type::Paren: break;
- case clang::Type::Elaborated: break;
+ case clang::Type::Elaborated:
+ return ClangASTType::GetTypeClass (ast_context, llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
+
case clang::Type::Attributed: break;
case clang::Type::TemplateTypeParm: break;
case clang::Type::SubstTemplateTypeParm: break;
@@ -450,14 +458,15 @@
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eEncodingSint;
case clang::Type::Typedef:
- return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
- break;
+ return GetEncoding(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr(), count);
+
+ case clang::Type::Elaborated:
+ return ClangASTType::GetEncoding (llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(), count);
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
case clang::Type::Paren:
- case clang::Type::Elaborated:
case clang::Type::Attributed:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -556,6 +565,14 @@
case clang::BuiltinType::ARCUnbridgedCast:
case clang::BuiltinType::PseudoObject:
case clang::BuiltinType::BuiltinFn:
+ case clang::BuiltinType::OCLEvent:
+ case clang::BuiltinType::OCLImage1d:
+ case clang::BuiltinType::OCLImage1dArray:
+ case clang::BuiltinType::OCLImage1dBuffer:
+ case clang::BuiltinType::OCLImage2d:
+ case clang::BuiltinType::OCLImage2dArray:
+ case clang::BuiltinType::OCLImage3d:
+ case clang::BuiltinType::OCLSampler:
return lldb::eFormatHex;
}
break;
@@ -576,15 +593,15 @@
case clang::Type::Record: break;
case clang::Type::Enum: return lldb::eFormatEnum;
case clang::Type::Typedef:
- return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
-
+ return ClangASTType::GetFormat(llvm::cast<clang::TypedefType>(qual_type)->getDecl()->getUnderlyingType().getAsOpaquePtr());
case clang::Type::Auto:
- return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+ return ClangASTType::GetFormat(llvm::cast<clang::AutoType>(qual_type)->desugar().getAsOpaquePtr());
+ case clang::Type::Elaborated:
+ return ClangASTType::GetFormat(llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr());
case clang::Type::DependentSizedArray:
case clang::Type::DependentSizedExtVector:
case clang::Type::UnresolvedUsing:
case clang::Type::Paren:
- case clang::Type::Elaborated:
case clang::Type::Attributed:
case clang::Type::TemplateTypeParm:
case clang::Type::SubstTemplateTypeParm:
@@ -799,7 +816,7 @@
const clang::EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
- uint32_t offset = data_byte_offset;
+ lldb::offset_t offset = data_byte_offset;
const int64_t enum_value = data.GetMaxU64Bitfield(&offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
{
@@ -811,7 +828,7 @@
}
// If we have gotten here we didn't get find the enumerator in the
// enum decl, so just print the integer.
- s->Printf("%lli", enum_value);
+ s->Printf("%" PRIi64, enum_value);
}
return;
@@ -909,6 +926,29 @@
}
break;
+ case clang::Type::Elaborated:
+ {
+ clang::QualType elaborated_qual_type = llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType();
+ lldb::Format elaborated_format = ClangASTType::GetFormat(elaborated_qual_type.getAsOpaquePtr());
+ std::pair<uint64_t, unsigned> elaborated_type_info = ast_context->getTypeInfo(elaborated_qual_type);
+ uint64_t elaborated_byte_size = elaborated_type_info.first / 8;
+
+ return DumpValue (ast_context, // The clang AST context for this type
+ elaborated_qual_type.getAsOpaquePtr(), // The clang type we want to dump
+ exe_ctx,
+ s, // Stream to dump to
+ elaborated_format, // The format with which to display the element
+ data, // Data buffer containing all bytes for this type
+ data_byte_offset, // Offset into "data" where to grab value from
+ elaborated_byte_size, // Size of this type in bytes
+ bitfield_bit_size, // Bitfield bit size
+ bitfield_bit_offset,// Bitfield bit offset
+ show_types, // Boolean indicating if we should show the variable types
+ show_summary, // Boolean indicating if we should show a summary for the current type
+ verbose, // Verbose output?
+ depth); // Scope depth for any types that have children
+ }
+ break;
default:
// We are down the a scalar type that we just need to display.
data.Dump(s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset);
@@ -997,7 +1037,7 @@
const clang::EnumDecl *enum_decl = enum_type->getDecl();
assert(enum_decl);
clang::EnumDecl::enumerator_iterator enum_pos, enum_end_pos;
- uint32_t offset = byte_offset;
+ lldb::offset_t offset = byte_offset;
const int64_t enum_value = data.GetMaxU64Bitfield (&offset, byte_size, bitfield_bit_size, bitfield_bit_offset);
for (enum_pos = enum_decl->enumerator_begin(), enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos)
{
@@ -1010,7 +1050,7 @@
// If we have gotten here we didn't get find the enumerator in the
// enum decl, so just print the integer.
- s->Printf("%lli", enum_value);
+ s->Printf("%" PRIi64, enum_value);
return true;
}
// format was not enum, just fall through and dump the value as requested....
@@ -1128,7 +1168,7 @@
Process *process = exe_ctx->GetProcessPtr();
if (process)
{
- uint32_t offset = data_byte_offset;
+ lldb::offset_t offset = data_byte_offset;
lldb::addr_t pointer_addresss = data.GetMaxU64(&offset, data_byte_size);
std::vector<uint8_t> buf;
if (length > 0)
@@ -1162,6 +1202,12 @@
}
uint32_t
+ClangASTType::GetClangTypeByteSize ()
+{
+ return (GetClangTypeBitWidth (m_ast, m_type) + 7) / 8;
+}
+
+uint32_t
ClangASTType::GetClangTypeBitWidth ()
{
return GetClangTypeBitWidth (m_ast, m_type);
@@ -1173,7 +1219,13 @@
if (ClangASTContext::GetCompleteType (ast_context, clang_type))
{
clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
- return ast_context->getTypeSize (qual_type);
+ const uint32_t bit_size = ast_context->getTypeSize (qual_type);
+ if (bit_size == 0)
+ {
+ if (qual_type->isIncompleteArrayType())
+ return ast_context->getTypeSize (qual_type->getArrayElementTypeNoTypeQual()->getCanonicalTypeUnqualified());
+ }
+ return bit_size;
}
return 0;
}
@@ -1272,7 +1324,6 @@
if (class_interface_decl)
{
clang::PrintingPolicy policy = ast_context->getPrintingPolicy();
- policy.DumpSourceManager = &ast_context->getSourceManager();
class_interface_decl->print(llvm_ostrm, policy, s->GetIndentLevel());
}
}
@@ -1295,6 +1346,12 @@
}
break;
+ case clang::Type::Elaborated:
+ DumpTypeDescription (ast_context,
+ llvm::cast<clang::ElaboratedType>(qual_type)->getNamedType().getAsOpaquePtr(),
+ s);
+ return;
+
case clang::Type::Record:
if (ClangASTContext::GetCompleteType (ast_context, clang_type))
{
@@ -1393,7 +1450,7 @@
uint64_t bit_width = ast_context->getTypeSize(qual_type);
uint32_t byte_size = (bit_width + 7 ) / 8;
- uint32_t offset = data_byte_offset;
+ lldb::offset_t offset = data_byte_offset;
switch (encoding)
{
case lldb::eEncodingInvalid:
@@ -1785,3 +1842,191 @@
{
return lhs.GetASTContext() != rhs.GetASTContext() || lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType();
}
+
+lldb::BasicType
+ClangASTType::GetBasicTypeEnumeration (const ConstString &name)
+{
+ if (name)
+ {
+ typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap;
+ static TypeNameToBasicTypeMap g_type_map;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, [](){
+ // "void"
+ g_type_map.Append(ConstString("void").GetCString(), eBasicTypeVoid);
+
+ // "char"
+ g_type_map.Append(ConstString("char").GetCString(), eBasicTypeChar);
+ g_type_map.Append(ConstString("signed char").GetCString(), eBasicTypeSignedChar);
+ g_type_map.Append(ConstString("unsigned char").GetCString(), eBasicTypeUnsignedChar);
+ g_type_map.Append(ConstString("wchar_t").GetCString(), eBasicTypeWChar);
+ g_type_map.Append(ConstString("signed wchar_t").GetCString(), eBasicTypeSignedWChar);
+ g_type_map.Append(ConstString("unsigned wchar_t").GetCString(), eBasicTypeUnsignedWChar);
+ // "short"
+ g_type_map.Append(ConstString("short").GetCString(), eBasicTypeShort);
+ g_type_map.Append(ConstString("short int").GetCString(), eBasicTypeShort);
+ g_type_map.Append(ConstString("unsigned short").GetCString(), eBasicTypeUnsignedShort);
+ g_type_map.Append(ConstString("unsigned short int").GetCString(), eBasicTypeUnsignedShort);
+
+ // "int"
+ g_type_map.Append(ConstString("int").GetCString(), eBasicTypeInt);
+ g_type_map.Append(ConstString("signed int").GetCString(), eBasicTypeInt);
+ g_type_map.Append(ConstString("unsigned int").GetCString(), eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("unsigned").GetCString(), eBasicTypeUnsignedInt);
+
+ // "long"
+ g_type_map.Append(ConstString("long").GetCString(), eBasicTypeLong);
+ g_type_map.Append(ConstString("long int").GetCString(), eBasicTypeLong);
+ g_type_map.Append(ConstString("unsigned long").GetCString(), eBasicTypeUnsignedLong);
+ g_type_map.Append(ConstString("unsigned long int").GetCString(), eBasicTypeUnsignedLong);
+
+ // "long long"
+ g_type_map.Append(ConstString("long long").GetCString(), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("long long int").GetCString(), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("unsigned long long").GetCString(), eBasicTypeUnsignedLongLong);
+ g_type_map.Append(ConstString("unsigned long long int").GetCString(), eBasicTypeUnsignedLongLong);
+
+ // "int128"
+ g_type_map.Append(ConstString("__int128_t").GetCString(), eBasicTypeInt128);
+ g_type_map.Append(ConstString("__uint128_t").GetCString(), eBasicTypeUnsignedInt128);
+
+ // Miscelaneous
+ g_type_map.Append(ConstString("bool").GetCString(), eBasicTypeBool);
+ g_type_map.Append(ConstString("float").GetCString(), eBasicTypeFloat);
+ g_type_map.Append(ConstString("double").GetCString(), eBasicTypeDouble);
+ g_type_map.Append(ConstString("long double").GetCString(), eBasicTypeLongDouble);
+ g_type_map.Append(ConstString("id").GetCString(), eBasicTypeObjCID);
+ g_type_map.Append(ConstString("SEL").GetCString(), eBasicTypeObjCSel);
+ g_type_map.Append(ConstString("nullptr").GetCString(), eBasicTypeNullPtr);
+ g_type_map.Sort();
+ });
+
+ return g_type_map.Find(name.GetCString(), eBasicTypeInvalid);
+ }
+ return eBasicTypeInvalid;
+}
+
+ClangASTType
+ClangASTType::GetBasicType (clang::ASTContext *ast, const ConstString &name)
+{
+ if (ast)
+ {
+ lldb::BasicType basic_type = ClangASTType::GetBasicTypeEnumeration (name);
+ return ClangASTType::GetBasicType (ast, basic_type);
+ }
+ return ClangASTType();
+}
+
+ClangASTType
+ClangASTType::GetBasicType (clang::ASTContext *ast, lldb::BasicType type)
+{
+ if (ast)
+ {
+ clang_type_t clang_type = NULL;
+
+ switch (type)
+ {
+ case eBasicTypeInvalid:
+ case eBasicTypeOther:
+ break;
+ case eBasicTypeVoid:
+ clang_type = ast->VoidTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeChar:
+ clang_type = ast->CharTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeSignedChar:
+ clang_type = ast->SignedCharTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedChar:
+ clang_type = ast->UnsignedCharTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeWChar:
+ clang_type = ast->getWCharType().getAsOpaquePtr();
+ break;
+ case eBasicTypeSignedWChar:
+ clang_type = ast->getSignedWCharType().getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedWChar:
+ clang_type = ast->getUnsignedWCharType().getAsOpaquePtr();
+ break;
+ case eBasicTypeChar16:
+ clang_type = ast->Char16Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeChar32:
+ clang_type = ast->Char32Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeShort:
+ clang_type = ast->ShortTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedShort:
+ clang_type = ast->UnsignedShortTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeInt:
+ clang_type = ast->IntTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedInt:
+ clang_type = ast->UnsignedIntTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLong:
+ clang_type = ast->LongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedLong:
+ clang_type = ast->UnsignedLongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLongLong:
+ clang_type = ast->LongLongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedLongLong:
+ clang_type = ast->UnsignedLongLongTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeInt128:
+ clang_type = ast->Int128Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeUnsignedInt128:
+ clang_type = ast->UnsignedInt128Ty.getAsOpaquePtr();
+ break;
+ case eBasicTypeBool:
+ clang_type = ast->BoolTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeHalf:
+ clang_type = ast->HalfTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeFloat:
+ clang_type = ast->FloatTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeDouble:
+ clang_type = ast->DoubleTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLongDouble:
+ clang_type = ast->LongDoubleTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeFloatComplex:
+ clang_type = ast->FloatComplexTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeDoubleComplex:
+ clang_type = ast->DoubleComplexTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeLongDoubleComplex:
+ clang_type = ast->LongDoubleComplexTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeObjCID:
+ clang_type = ast->ObjCBuiltinIdTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeObjCClass:
+ clang_type = ast->ObjCBuiltinClassTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeObjCSel:
+ clang_type = ast->ObjCBuiltinSelTy.getAsOpaquePtr();
+ break;
+ case eBasicTypeNullPtr:
+ clang_type = ast->NullPtrTy.getAsOpaquePtr();
+ break;
+ }
+
+ if (clang_type)
+ return ClangASTType (ast, clang_type);
+ }
+ return ClangASTType();
+}
+
Index: aze/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -45,7 +45,7 @@
using namespace clang;
using namespace lldb_private;
-clang::DeclContextLookupResult
+bool
ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName
(
const clang::DeclContext *decl_ctx,
@@ -58,9 +58,9 @@
m_callback_find_by_name (m_callback_baton, decl_ctx, clang_decl_name, &results);
- DeclContextLookupResult lookup_result (SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results));
+ SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, results);
- return lookup_result;
+ return (results.size() != 0);
}
std::string decl_name (clang_decl_name.getAsString());
@@ -70,55 +70,61 @@
case clang::DeclarationName::Identifier:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"Identifier\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
if (clang_decl_name.getAsIdentifierInfo()->getBuiltinID() != 0)
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ {
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+ }
break;
case clang::DeclarationName::ObjCZeroArgSelector:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCZeroArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::ObjCOneArgSelector:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCOneArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::ObjCMultiArgSelector:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"ObjCMultiArgSelector\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXConstructorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConstructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
+
case clang::DeclarationName::CXXDestructorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXDestructorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXConversionFunctionName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXConversionFunctionName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXOperatorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXLiteralOperatorName:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXLiteralOperatorName\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return DeclContext::lookup_result();
- break;
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
case clang::DeclarationName::CXXUsingDirective:
//printf ("ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName(decl_ctx = %p, decl_name = { kind = \"CXXUsingDirective\", name = \"%s\")\n", decl_ctx, decl_name.c_str());
- return SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
- return DeclContext::lookup_result();
+ SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
+ return false;
}
void
Index: aze/lldb/source/Symbol/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Symbol/CMakeLists.txt 2013-03-03 09:35:50.271457351 +0100
@@ -0,0 +1,32 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbSymbol
+ Block.cpp
+ ClangASTContext.cpp
+ ClangASTImporter.cpp
+ ClangASTType.cpp
+ ClangExternalASTSourceCallbacks.cpp
+ ClangExternalASTSourceCommon.cpp
+ ClangNamespaceDecl.cpp
+ CompileUnit.cpp
+ Declaration.cpp
+ DWARFCallFrameInfo.cpp
+ Function.cpp
+ FuncUnwinders.cpp
+ LineEntry.cpp
+ LineTable.cpp
+ ObjectFile.cpp
+ Symbol.cpp
+ SymbolContext.cpp
+ SymbolFile.cpp
+ SymbolVendor.cpp
+ Symtab.cpp
+ Type.cpp
+ TypeHierarchyNavigator.cpp
+ TypeList.cpp
+ UnwindPlan.cpp
+ UnwindTable.cpp
+ Variable.cpp
+ VariableList.cpp
+ VerifyDecl.cpp
+ )
Index: aze/lldb/source/Symbol/CompileUnit.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/CompileUnit.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/CompileUnit.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -78,7 +78,7 @@
CompileUnit::DumpSymbolContext(Stream *s)
{
GetModule()->DumpSymbolContext(s);
- s->Printf(", CompileUnit{0x%8.8llx}", GetID());
+ s->Printf(", CompileUnit{0x%8.8" PRIx64 "}", GetID());
}
Index: aze/lldb/source/Symbol/DWARFCallFrameInfo.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/DWARFCallFrameInfo.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/DWARFCallFrameInfo.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -117,13 +117,13 @@
DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset)
{
CIESP cie_sp(new CIE(cie_offset));
- dw_offset_t offset = cie_offset;
+ lldb::offset_t offset = cie_offset;
if (m_cfi_data_initialized == false)
GetCFIData();
const uint32_t length = m_cfi_data.GetU32(&offset);
const dw_offset_t cie_id = m_cfi_data.GetU32(&offset);
const dw_offset_t end_offset = cie_offset + length + 4;
- if (length > 0 && ((!m_is_eh_frame && cie_id == 0xfffffffful) || (m_is_eh_frame && cie_id == 0ul)))
+ if (length > 0 && ((!m_is_eh_frame && cie_id == UINT32_MAX) || (m_is_eh_frame && cie_id == 0ul)))
{
size_t i;
// cie.offset = cie_offset;
@@ -302,7 +302,7 @@
if (m_fde_index_initialized) // if two threads hit the locker
return;
- dw_offset_t offset = 0;
+ lldb::offset_t offset = 0;
if (m_cfi_data_initialized == false)
GetCFIData();
while (m_cfi_data.ValidOffsetForDataOfSize (offset, 8))
@@ -349,9 +349,10 @@
}
bool
-DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t offset, Address startaddr, UnwindPlan& unwind_plan)
+DWARFCallFrameInfo::FDEToUnwindPlan (dw_offset_t dwarf_offset, Address startaddr, UnwindPlan& unwind_plan)
{
- dw_offset_t current_entry = offset;
+ lldb::offset_t offset = dwarf_offset;
+ lldb::offset_t current_entry = offset;
if (m_section_sp.get() == NULL || m_section_sp->IsEncrypted())
return false;
Index: aze/lldb/source/Symbol/Function.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/Function.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/Function.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -370,7 +370,7 @@
}
else if (m_type_uid != LLDB_INVALID_UID)
{
- s->Printf(", type_uid = 0x%8.8llx", m_type_uid);
+ s->Printf(", type_uid = 0x%8.8" PRIx64, m_type_uid);
}
s->EOL();
@@ -426,7 +426,7 @@
Function::DumpSymbolContext(Stream *s)
{
m_comp_unit->DumpSymbolContext(s);
- s->Printf(", Function{0x%8.8llx}", GetID());
+ s->Printf(", Function{0x%8.8" PRIx64 "}", GetID());
}
size_t
Index: aze/lldb/source/Symbol/LineTable.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/LineTable.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/LineTable.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -34,34 +34,6 @@
{
}
-//void
-//LineTable::AddLineEntry(const LineEntry& entry)
-//{
-// // Do a binary search for the correct entry and insert it
-// m_line_entries.insert(std::upper_bound(m_line_entries.begin(), m_line_entries.end(), entry), entry);
-//}
-
-void
-LineTable::AppendLineEntry
-(
- const lldb::SectionSP& section_sp,
- lldb::addr_t section_offset,
- uint32_t line,
- uint16_t column,
- uint16_t file_idx,
- bool is_start_of_statement,
- bool is_start_of_basic_block,
- bool is_prologue_end,
- bool is_epilogue_begin,
- bool is_terminal_entry
-)
-{
- uint32_t sect_idx = m_section_list.AddUniqueSection (section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
- m_entries.push_back (entry);
-}
-
-
void
LineTable::InsertLineEntry
(
@@ -106,6 +78,80 @@
// Dump (&s, Address::DumpStyleFileAddress);
}
+LineSequence::LineSequence()
+{
+}
+
+void
+LineTable::LineSequenceImpl::Clear()
+{
+ m_seq_entries.clear();
+}
+
+LineSequence* LineTable::CreateLineSequenceContainer ()
+{
+ return new LineTable::LineSequenceImpl();
+}
+
+void
+LineTable::AppendLineEntryToSequence
+(
+ LineSequence* sequence,
+ const SectionSP& section_sp,
+ lldb::addr_t section_offset,
+ uint32_t line,
+ uint16_t column,
+ uint16_t file_idx,
+ bool is_start_of_statement,
+ bool is_start_of_basic_block,
+ bool is_prologue_end,
+ bool is_epilogue_begin,
+ bool is_terminal_entry
+)
+{
+ assert(sequence != NULL);
+ LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
+ uint32_t sect_idx = m_section_list.AddUniqueSection (section_sp);
+ Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ seq->m_seq_entries.push_back (entry);
+}
+
+void
+LineTable::InsertSequence (LineSequence* sequence)
+{
+ assert(sequence != NULL);
+ LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
+ if (seq->m_seq_entries.empty())
+ return;
+ Entry& entry = seq->m_seq_entries.front();
+
+ // If the first entry address in this sequence is greater than or equal to
+ // the address of the last item in our entry collection, just append.
+ if (m_entries.empty() || !Entry::EntryAddressLessThan(entry, m_entries.back()))
+ {
+ m_entries.insert(m_entries.end(),
+ seq->m_seq_entries.begin(),
+ seq->m_seq_entries.end());
+ return;
+ }
+
+ // Otherwise, find where this belongs in the collection
+ entry_collection::iterator begin_pos = m_entries.begin();
+ entry_collection::iterator end_pos = m_entries.end();
+ LineTable::Entry::LessThanBinaryPredicate less_than_bp(this);
+ entry_collection::iterator pos = upper_bound(begin_pos, end_pos, entry, less_than_bp);
+#ifdef LLDB_CONFIGURATION_DEBUG
+ // If we aren't inserting at the beginning, the previous entry should
+ // terminate a sequence.
+ if (pos != begin_pos)
+ {
+ entry_collection::iterator prev_pos = pos - 1;
+ assert(prev_pos->is_terminal_entry);
+ }
+#endif
+ m_entries.insert(pos, seq->m_seq_entries.begin(), seq->m_seq_entries.end());
+}
+
//----------------------------------------------------------------------
LineTable::Entry::LessThanBinaryPredicate::LessThanBinaryPredicate(LineTable *line_table) :
m_line_table (line_table)
@@ -448,5 +494,42 @@
}
}
+size_t
+LineTable::GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append)
+{
+ if (!append)
+ file_ranges.Clear();
+ const size_t initial_count = file_ranges.GetSize();
+
+ const size_t count = m_entries.size();
+ LineEntry line_entry;
+ std::vector<addr_t> section_base_file_addrs (m_section_list.GetSize(), LLDB_INVALID_ADDRESS);
+ FileAddressRanges::Entry range (LLDB_INVALID_ADDRESS, 0);
+ for (size_t idx = 0; idx < count; ++idx)
+ {
+ const Entry& entry = m_entries[idx];
+
+ if (entry.is_terminal_entry)
+ {
+ if (range.GetRangeBase() != LLDB_INVALID_ADDRESS)
+ {
+ if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
+ section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
+ range.SetRangeEnd(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+ file_ranges.Append(range);
+ range.Clear(LLDB_INVALID_ADDRESS);
+ }
+ }
+ else if (range.GetRangeBase() == LLDB_INVALID_ADDRESS)
+ {
+ if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
+ section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
+ range.SetRangeBase(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+ }
+ }
+ return file_ranges.GetSize() - initial_count;
+}
+
+
Index: aze/lldb/source/Symbol/ObjectFile.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/ObjectFile.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/ObjectFile.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -27,55 +27,103 @@
using namespace lldb_private;
ObjectFileSP
-ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp, const FileSpec* file, addr_t file_offset, addr_t file_size, DataBufferSP &file_data_sp)
+ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp,
+ const FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
+ DataBufferSP &data_sp,
+ lldb::offset_t &data_offset)
{
ObjectFileSP object_file_sp;
if (module_sp)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%8.8llx, file_size = 0x%8.8llx)",
+ "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
module_sp->GetFileSpec().GetDirectory().AsCString(),
module_sp->GetFileSpec().GetFilename().AsCString(),
file, (uint64_t) file_offset, (uint64_t) file_size);
if (file)
{
- // Memory map the entire file contents
- if (!file_data_sp && file_size > 0)
+ FileSpec archive_file;
+ ObjectContainerCreateInstance create_object_container_callback;
+
+ const bool file_exists = file->Exists();
+ if (!data_sp)
{
- assert (file_offset == 0);
- file_data_sp = file->MemoryMapFileContents(file_offset, file_size);
+ // We have an object name which most likely means we have
+ // a .o file in a static archive (.a file). Try and see if
+ // we have a cached archive first without reading any data
+ // first
+ if (file_exists && module_sp->GetObjectName())
+ {
+ for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
+
+ if (object_container_ap.get())
+ object_file_sp = object_container_ap->GetObjectFile(file);
+
+ if (object_file_sp.get())
+ return object_file_sp;
+ }
+ }
+ // Ok, we didn't find any containers that have a named object, now
+ // lets read the first 512 bytes from the file so the object file
+ // and object container plug-ins can use these bytes to see if they
+ // can parse this file.
+ if (file_size > 0)
+ {
+ data_sp = file->ReadFileContents(file_offset, std::min<size_t>(512, file_size));
+ data_offset = 0;
+ }
}
- if (!file_data_sp || file_data_sp->GetByteSize() == 0)
+ if (!data_sp || data_sp->GetByteSize() == 0)
{
// Check for archive file with format "/path/to/archive.a(object.o)"
char path_with_object[PATH_MAX*2];
module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
- FileSpec archive_file;
ConstString archive_object;
- if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object))
+ const bool must_exist = true;
+ if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object, must_exist))
{
file_size = archive_file.GetByteSize();
if (file_size > 0)
{
+ file = &archive_file;
module_sp->SetFileSpecAndObjectName (archive_file, archive_object);
- file_data_sp = archive_file.MemoryMapFileContents(file_offset, file_size);
+ // Check if this is a object container by iterating through all object
+ // container plugin instances and then trying to get an object file
+ // from the container plugins since we had a name. Also, don't read
+ // ANY data in case there is data cached in the container plug-ins
+ // (like BSD archives caching the contained objects within an file).
+ for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ {
+ std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
+
+ if (object_container_ap.get())
+ object_file_sp = object_container_ap->GetObjectFile(file);
+
+ if (object_file_sp.get())
+ return object_file_sp;
+ }
+ // We failed to find any cached object files in the container
+ // plug-ins, so lets read the first 512 bytes and try again below...
+ data_sp = archive_file.ReadFileContents(file_offset, 512);
}
}
}
- if (file_data_sp && file_data_sp->GetByteSize() > 0)
+ if (data_sp && data_sp->GetByteSize() > 0)
{
- uint32_t idx;
-
// Check if this is a normal object file by iterating through
// all object file plugin instances.
ObjectFileCreateInstance create_object_file_callback;
- for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- object_file_sp.reset (create_object_file_callback(module_sp, file_data_sp, file, file_offset, file_size));
+ object_file_sp.reset (create_object_file_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
if (object_file_sp.get())
return object_file_sp;
}
@@ -83,10 +131,9 @@
// Check if this is a object container by iterating through
// all object container plugin instances and then trying to get
// an object file from the container.
- ObjectContainerCreateInstance create_object_container_callback;
- for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, file_data_sp, file, file_offset, file_size));
+ std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
if (object_container_ap.get())
object_file_sp = object_container_ap->GetObjectFile(file);
@@ -107,14 +154,14 @@
ObjectFile::FindPlugin (const lldb::ModuleSP &module_sp,
const ProcessSP &process_sp,
lldb::addr_t header_addr,
- DataBufferSP &file_data_sp)
+ DataBufferSP &data_sp)
{
ObjectFileSP object_file_sp;
if (module_sp)
{
Timer scoped_timer (__PRETTY_FUNCTION__,
- "ObjectFile::FindPlugin (module = %s/%s, process = %p, header_addr = 0x%llx)",
+ "ObjectFile::FindPlugin (module = %s/%s, process = %p, header_addr = 0x%" PRIx64 ")",
module_sp->GetFileSpec().GetDirectory().AsCString(),
module_sp->GetFileSpec().GetFilename().AsCString(),
process_sp.get(), header_addr);
@@ -125,7 +172,7 @@
ObjectFileCreateMemoryInstance create_callback;
for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx)
{
- object_file_sp.reset (create_callback(module_sp, file_data_sp, process_sp, header_addr));
+ object_file_sp.reset (create_callback(module_sp, data_sp, process_sp, header_addr));
if (object_file_sp.get())
return object_file_sp;
}
@@ -139,15 +186,17 @@
ObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
const FileSpec *file_spec_ptr,
- addr_t file_offset,
- addr_t file_size,
- DataBufferSP& file_data_sp) :
+ lldb::offset_t file_offset,
+ lldb::offset_t length,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset
+) :
ModuleChild (module_sp),
m_file (), // This file could be different from the original module's file
m_type (eTypeInvalid),
m_strata (eStrataInvalid),
- m_offset (file_offset),
- m_length (file_size),
+ m_file_offset (file_offset),
+ m_length (length),
m_data (),
m_unwind_table (*this),
m_process_wp(),
@@ -155,29 +204,29 @@
{
if (file_spec_ptr)
m_file = *file_spec_ptr;
- if (file_data_sp)
- m_data.SetData (file_data_sp, file_offset, file_size);
+ if (data_sp)
+ m_data.SetData (data_sp, data_offset, length);
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
if (m_file)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
+ log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
this,
module_sp->GetFileSpec().GetDirectory().AsCString(),
module_sp->GetFileSpec().GetFilename().AsCString(),
m_file.GetDirectory().AsCString(),
m_file.GetFilename().AsCString(),
- m_offset,
+ m_file_offset,
m_length);
}
else
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
+ log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
this,
module_sp->GetFileSpec().GetDirectory().AsCString(),
module_sp->GetFileSpec().GetFilename().AsCString(),
- m_offset,
+ m_file_offset,
m_length);
}
}
@@ -192,7 +241,7 @@
m_file (),
m_type (eTypeInvalid),
m_strata (eStrataInvalid),
- m_offset (header_addr),
+ m_file_offset (0),
m_length (0),
m_data (),
m_unwind_table (*this),
@@ -204,12 +253,12 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%llx\n",
+ log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%" PRIx64 "\n",
this,
module_sp->GetFileSpec().GetDirectory().AsCString(),
module_sp->GetFileSpec().GetFilename().AsCString(),
process_sp.get(),
- m_offset);
+ m_memory_addr);
}
}
@@ -218,29 +267,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- {
- ModuleSP module_sp (GetModule());
- if (m_file)
- {
- log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = %s/%s, offset = 0x%8.8llx, size = %llu\n",
- this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- m_file.GetDirectory().AsCString(),
- m_file.GetFilename().AsCString(),
- m_offset,
- m_length);
- }
- else
- {
- log->Printf ("%p ObjectFile::~ObjectFile () module = %s/%s, file = <NULL>, offset = 0x%8.8llx, size = %llu\n",
- this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString(),
- m_offset,
- m_length);
- }
- }
+ log->Printf ("%p ObjectFile::~ObjectFile ()\n", this);
}
bool
@@ -314,6 +341,7 @@
case eSymbolTypeAbsolute: return eAddressClassUnknown;
case eSymbolTypeCode: return eAddressClassCode;
case eSymbolTypeTrampoline: return eAddressClassCode;
+ case eSymbolTypeResolver: return eAddressClassCode;
case eSymbolTypeData: return eAddressClassData;
case eSymbolTypeRuntime: return eAddressClassRuntime;
case eSymbolTypeException: return eAddressClassRuntime;
@@ -386,7 +414,9 @@
if (process_sp)
{
Error error;
- return process_sp->ReadMemory (section->GetLoadBaseAddress (&process_sp->GetTarget()) + section_offset, dst, dst_len, error);
+ const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
+ if (base_load_addr != LLDB_INVALID_ADDRESS)
+ return process_sp->ReadMemory (base_load_addr + section_offset, dst, dst_len, error);
}
}
else
@@ -400,6 +430,19 @@
section_dst_len = section_bytes_left;
return CopyData (section->GetFileOffset() + section_offset, section_dst_len, dst);
}
+ else
+ {
+ if (section->GetType() == eSectionTypeZeroFill)
+ {
+ const uint64_t section_size = section->GetByteSize();
+ const uint64_t section_bytes_left = section_size - section_offset;
+ uint64_t section_dst_len = dst_len;
+ if (section_dst_len > section_bytes_left)
+ section_dst_len = section_bytes_left;
+ bzero(dst, section_dst_len);
+ return section_dst_len;
+ }
+ }
}
return 0;
}
@@ -415,13 +458,17 @@
ProcessSP process_sp (m_process_wp.lock());
if (process_sp)
{
- DataBufferSP data_sp (ReadMemory (process_sp, section->GetLoadBaseAddress (&process_sp->GetTarget()), section->GetByteSize()));
- if (data_sp)
+ const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
+ if (base_load_addr != LLDB_INVALID_ADDRESS)
{
- section_data.SetData (data_sp, 0, data_sp->GetByteSize());
- section_data.SetByteOrder (process_sp->GetByteOrder());
- section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
- return section_data.GetByteSize();
+ DataBufferSP data_sp (ReadMemory (process_sp, base_load_addr, section->GetByteSize()));
+ if (data_sp)
+ {
+ section_data.SetData (data_sp, 0, data_sp->GetByteSize());
+ section_data.SetByteOrder (process_sp->GetByteOrder());
+ section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
+ return section_data.GetByteSize();
+ }
}
}
}
@@ -452,7 +499,7 @@
bool
-ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object)
+ObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object, bool must_exist)
{
RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
if (g_object_regex.Execute (path_with_object, 2))
@@ -464,6 +511,8 @@
{
archive_file.SetFile (path.c_str(), false);
archive_object.SetCString(obj.c_str());
+ if (must_exist && !archive_file.Exists())
+ return false;
return true;
}
}
Index: aze/lldb/source/Symbol/SymbolContext.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/SymbolContext.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/SymbolContext.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -108,9 +108,10 @@
}
void
-SymbolContext::Clear()
+SymbolContext::Clear(bool clear_target)
{
- target_sp.reset();
+ if (clear_target)
+ target_sp.reset();
module_sp.reset();
comp_unit = NULL;
function = NULL;
@@ -157,7 +158,7 @@
if (function_offset)
{
dumped_something = true;
- s->Printf(" + %llu", function_offset);
+ s->Printf(" + %" PRIu64, function_offset);
}
}
@@ -174,7 +175,7 @@
const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
if (inlined_function_offset)
{
- s->Printf(" + %llu", inlined_function_offset);
+ s->Printf(" + %" PRIu64, inlined_function_offset);
}
}
const Declaration &call_site = inlined_block_info->GetCallSite();
@@ -217,7 +218,7 @@
if (symbol_offset)
{
dumped_something = true;
- s->Printf(" + %llu", symbol_offset);
+ s->Printf(" + %" PRIu64, symbol_offset);
}
}
}
@@ -453,7 +454,7 @@
SymbolContext &next_frame_sc,
Address &next_frame_pc) const
{
- next_frame_sc.Clear();
+ next_frame_sc.Clear(false);
next_frame_pc.Clear();
if (block)
@@ -496,7 +497,7 @@
if (log)
{
- log->Printf ("warning: inlined block 0x%8.8llx doesn't have a range that contains file address 0x%llx",
+ log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
}
#ifdef LLDB_CONFIGURATION_DEBUG
@@ -516,7 +517,7 @@
if (objfile)
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: inlined block 0x%8.8llx doesn't have a range that contains file address 0x%llx in %s/%s\n",
+ "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s/%s\n",
curr_inlined_block->GetID(),
curr_frame_pc.GetFileAddress(),
objfile->GetFileSpec().GetDirectory().GetCString(),
@@ -525,7 +526,7 @@
else
{
Host::SystemLog (Host::eSystemLogWarning,
- "warning: inlined block 0x%8.8llx doesn't have a range that contains file address 0x%llx\n",
+ "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
curr_inlined_block->GetID(),
curr_frame_pc.GetFileAddress());
}
@@ -1044,7 +1045,7 @@
}
bool
-SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
+SymbolContextList::GetContextAtIndex(size_t idx, SymbolContext& sc) const
{
if (idx < m_symbol_contexts.size())
{
@@ -1055,7 +1056,7 @@
}
bool
-SymbolContextList::RemoveContextAtIndex (uint32_t idx)
+SymbolContextList::RemoveContextAtIndex (size_t idx)
{
if (idx < m_symbol_contexts.size())
{
@@ -1075,8 +1076,8 @@
SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
{
uint32_t match_count = 0;
- const uint32_t size = m_symbol_contexts.size();
- for (uint32_t idx = 0; idx<size; ++idx)
+ const size_t size = m_symbol_contexts.size();
+ for (size_t idx = 0; idx<size; ++idx)
{
if (m_symbol_contexts[idx].line_entry.line == line)
++match_count;
@@ -1089,8 +1090,8 @@
lldb::DescriptionLevel level,
Target *target) const
{
- const uint32_t size = m_symbol_contexts.size();
- for (uint32_t idx = 0; idx<size; ++idx)
+ const size_t size = m_symbol_contexts.size();
+ for (size_t idx = 0; idx<size; ++idx)
m_symbol_contexts[idx].GetDescription (s, level, target);
}
Index: aze/lldb/source/Symbol/Symbol.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/Symbol.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/Symbol.cpp 2013-03-03 09:35:50.271457351 +0100
@@ -33,6 +33,7 @@
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (false),
+ m_demangled_is_synthesized (false),
m_type (eSymbolTypeInvalid),
m_flags (),
m_addr_range ()
@@ -51,7 +52,7 @@
bool is_artificial,
const lldb::SectionSP &section_sp,
addr_t offset,
- uint32_t size,
+ addr_t size,
uint32_t flags
) :
SymbolContextScope (),
@@ -65,6 +66,7 @@
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (size > 0),
+ m_demangled_is_synthesized (false),
m_type (type),
m_flags (flags),
m_addr_range (section_sp, offset, size)
@@ -95,6 +97,7 @@
m_size_is_sibling (false),
m_size_is_synthesized (false),
m_calculated_size (range.GetByteSize() > 0),
+ m_demangled_is_synthesized (false),
m_type (type),
m_flags (flags),
m_addr_range (range)
@@ -113,6 +116,7 @@
m_size_is_sibling (rhs.m_size_is_sibling),
m_size_is_synthesized (false),
m_calculated_size (rhs.m_calculated_size),
+ m_demangled_is_synthesized (rhs.m_demangled_is_synthesized),
m_type (rhs.m_type),
m_flags (rhs.m_flags),
m_addr_range (rhs.m_addr_range)
@@ -135,6 +139,7 @@
m_size_is_sibling = rhs.m_size_is_sibling;
m_size_is_synthesized = rhs.m_size_is_sibling;
m_calculated_size = rhs.m_calculated_size;
+ m_demangled_is_synthesized = rhs.m_demangled_is_synthesized;
m_type = rhs.m_type;
m_flags = rhs.m_flags;
m_addr_range = rhs.m_addr_range;
@@ -155,6 +160,7 @@
m_size_is_sibling = false;
m_size_is_synthesized = false;
m_calculated_size = false;
+ m_demangled_is_synthesized = false;
m_type = eSymbolTypeInvalid;
m_flags = 0;
m_addr_range.Clear();
@@ -178,6 +184,12 @@
return m_type == eSymbolTypeTrampoline;
}
+bool
+Symbol::IsIndirect () const
+{
+ return m_type == eSymbolTypeResolver;
+}
+
void
Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const
{
@@ -200,14 +212,14 @@
}
}
else
- s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
+ s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
}
else
{
if (m_size_is_sibling)
- s->Printf (", sibling = %5llu", m_addr_range.GetBaseAddress().GetOffset());
+ s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset());
else
- s->Printf (", value = 0x%16.16llx", m_addr_range.GetBaseAddress().GetOffset());
+ s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset());
}
if (m_mangled.GetDemangledName())
s->Printf(", name=\"%s\"", m_mangled.GetDemangledName().AsCString());
@@ -245,7 +257,7 @@
const char *format = m_size_is_sibling ?
" Sibling -> [%5llu] 0x%8.8x %s\n":
- " 0x%16.16llx 0x%8.8x %s\n";
+ " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
s->Printf( format,
GetByteSize(),
m_flags,
@@ -254,8 +266,8 @@
else
{
const char *format = m_size_is_sibling ?
- "0x%16.16llx Sibling -> [%5llu] 0x%8.8x %s\n":
- "0x%16.16llx 0x%16.16llx 0x%8.8x %s\n";
+ "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n":
+ "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n";
s->Printf( format,
m_addr_range.GetBaseAddress().GetOffset(),
GetByteSize(),
@@ -267,7 +279,7 @@
uint32_t
Symbol::GetPrologueByteSize ()
{
- if (m_type == eSymbolTypeCode)
+ if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver)
{
if (!m_type_data_resolved)
{
Index: aze/lldb/source/Symbol/SymbolVendor.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/SymbolVendor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/SymbolVendor.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -32,16 +32,16 @@
// also allow for finding separate debug information files.
//----------------------------------------------------------------------
SymbolVendor*
-SymbolVendor::FindPlugin (const lldb::ModuleSP &module_sp)
+SymbolVendor::FindPlugin (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
{
std::auto_ptr<SymbolVendor> instance_ap;
//----------------------------------------------------------------------
// We currently only have one debug symbol parser...
//----------------------------------------------------------------------
SymbolVendorCreateInstance create_callback;
- for (uint32_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
+ for (size_t idx = 0; (create_callback = PluginManager::GetSymbolVendorCreateCallbackAtIndex(idx)) != NULL; ++idx)
{
- instance_ap.reset(create_callback(module_sp));
+ instance_ap.reset(create_callback(module_sp, feedback_strm));
if (instance_ap.get())
{
@@ -102,13 +102,13 @@
}
bool
-SymbolVendor::SetCompileUnitAtIndex (uint32_t idx, const CompUnitSP &cu_sp)
+SymbolVendor::SetCompileUnitAtIndex (size_t idx, const CompUnitSP &cu_sp)
{
ModuleSP module_sp(GetModule());
if (module_sp)
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
- const uint32_t num_compile_units = GetNumCompileUnits();
+ const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
// Fire off an assertion if this compile unit already exists for now.
@@ -130,7 +130,7 @@
return false;
}
-uint32_t
+size_t
SymbolVendor::GetNumCompileUnits()
{
ModuleSP module_sp(GetModule());
@@ -284,8 +284,8 @@
return 0;
}
-uint32_t
-SymbolVendor::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
+size_t
+SymbolVendor::FindGlobalVariables (const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, size_t max_matches, VariableList& variables)
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -297,8 +297,8 @@
return 0;
}
-uint32_t
-SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
+size_t
+SymbolVendor::FindGlobalVariables (const RegularExpression& regex, bool append, size_t max_matches, VariableList& variables)
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -310,7 +310,7 @@
return 0;
}
-uint32_t
+size_t
SymbolVendor::FindFunctions(const ConstString &name, const ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list)
{
ModuleSP module_sp(GetModule());
@@ -323,7 +323,7 @@
return 0;
}
-uint32_t
+size_t
SymbolVendor::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
{
ModuleSP module_sp(GetModule());
@@ -337,8 +337,8 @@
}
-uint32_t
-SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, TypeList& types)
+size_t
+SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const ClangNamespaceDecl *namespace_decl, bool append, size_t max_matches, TypeList& types)
{
ModuleSP module_sp(GetModule());
if (module_sp)
@@ -409,13 +409,13 @@
}
CompUnitSP
-SymbolVendor::GetCompileUnitAtIndex(uint32_t idx)
+SymbolVendor::GetCompileUnitAtIndex(size_t idx)
{
CompUnitSP cu_sp;
ModuleSP module_sp(GetModule());
if (module_sp)
{
- const uint32_t num_compile_units = GetNumCompileUnits();
+ const size_t num_compile_units = GetNumCompileUnits();
if (idx < num_compile_units)
{
cu_sp = m_compile_units[idx];
Index: aze/lldb/source/Symbol/Symtab.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/Symtab.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/Symtab.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -13,6 +13,7 @@
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@@ -37,7 +38,7 @@
}
void
-Symtab::Reserve(uint32_t count)
+Symtab::Reserve(size_t count)
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -45,7 +46,7 @@
}
Symbol *
-Symtab::Resize(uint32_t count)
+Symtab::Resize(size_t count)
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -149,7 +150,7 @@
std::vector<uint32_t>::const_iterator end = m_addr_indexes.end();
for (pos = m_addr_indexes.begin(); pos != end; ++pos)
{
- uint32_t idx = *pos;
+ size_t idx = *pos;
if (idx < num_symbols)
{
s->Indent();
@@ -179,7 +180,7 @@
DumpSymbolHeader (s);
for (pos = indexes.begin(); pos != end; ++pos)
{
- uint32_t idx = *pos;
+ size_t idx = *pos;
if (idx < num_symbols)
{
s->Indent();
@@ -229,7 +230,7 @@
Symbol *
-Symtab::SymbolAtIndex(uint32_t idx)
+Symtab::SymbolAtIndex(size_t idx)
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -240,7 +241,7 @@
const Symbol *
-Symtab::SymbolAtIndex(uint32_t idx) const
+Symtab::SymbolAtIndex(size_t idx) const
{
// Clients should grab the mutex from this symbol table and lock it manually
// when calling this function to avoid performance issues.
@@ -309,20 +310,25 @@
// If the demangled name turns out to be an ObjC name, and
// is a category name, add the version without categories to the index too.
- ConstString objc_base_name;
- if (ObjCLanguageRuntime::ParseMethodName (entry.cstring,
- NULL,
- NULL,
- &objc_base_name,
- NULL))
+ ObjCLanguageRuntime::MethodName objc_method (entry.cstring, true);
+ if (objc_method.IsValid(true))
{
- entry.cstring = objc_base_name.GetCString();
- m_name_to_index.Append (entry);
+ entry.cstring = objc_method.GetSelector().GetCString();
+ m_selector_to_index.Append (entry);
+
+ ConstString objc_method_no_category (objc_method.GetFullNameWithoutCategory(true));
+ if (objc_method_no_category)
+ {
+ entry.cstring = objc_method_no_category.GetCString();
+ m_name_to_index.Append (entry);
+ }
}
}
m_name_to_index.Sort();
m_name_to_index.SizeToFit();
+ m_selector_to_index.Sort();
+ m_selector_to_index.SizeToFit();
}
}
@@ -651,7 +657,7 @@
Mutex::Locker locker (m_mutex);
const size_t count = m_symbols.size();
- for (uint32_t idx = start_idx; idx < count; ++idx)
+ for (size_t idx = start_idx; idx < count; ++idx)
{
if (symbol_type == eSymbolTypeAny || m_symbols[idx].GetType() == symbol_type)
{
@@ -979,3 +985,64 @@
return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
}
+void
+Symtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
+{
+ // No need to protect this call using m_mutex all other method calls are
+ // already thread safe.
+
+ size_t num_indices = symbol_indexes.size();
+ if (num_indices > 0)
+ {
+ SymbolContext sc;
+ sc.module_sp = m_objfile->GetModule();
+ for (size_t i = 0; i < num_indices; i++)
+ {
+ sc.symbol = SymbolAtIndex (symbol_indexes[i]);
+ if (sc.symbol)
+ sc_list.Append (sc);
+ }
+ }
+}
+
+
+size_t
+Symtab::FindFunctionSymbols (const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList& sc_list)
+{
+ size_t count = 0;
+ std::vector<uint32_t> symbol_indexes;
+ if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
+ {
+ FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, symbol_indexes);
+ }
+
+ if (name_type_mask & eFunctionNameTypeSelector)
+ {
+ if (!m_name_indexes_computed)
+ InitNameIndexes();
+
+ if (!m_selector_to_index.IsEmpty())
+ {
+ const UniqueCStringMap<uint32_t>::Entry *match;
+ for (match = m_selector_to_index.FindFirstValueForName(name.AsCString());
+ match != NULL;
+ match = m_selector_to_index.FindNextValueForName(match))
+ {
+ symbol_indexes.push_back(match->value);
+ }
+ }
+ }
+
+ if (!symbol_indexes.empty())
+ {
+ std::sort(symbol_indexes.begin(), symbol_indexes.end());
+ symbol_indexes.erase(std::unique(symbol_indexes.begin(), symbol_indexes.end()), symbol_indexes.end());
+ count = symbol_indexes.size();
+ SymbolIndicesToSymbolContextList (symbol_indexes, sc_list);
+ }
+
+ return count;
+}
+
Index: aze/lldb/source/Symbol/Type.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/Type.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/Type.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -80,7 +80,7 @@
m_symbol_file (NULL),
m_context (NULL),
m_encoding_type (NULL),
- m_encoding_uid (0),
+ m_encoding_uid (LLDB_INVALID_UID),
m_encoding_uid_type (eEncodingInvalid),
m_byte_size (0),
m_decl (),
@@ -150,7 +150,7 @@
}
else if (m_encoding_uid != LLDB_INVALID_UID)
{
- s->Printf(", type_uid = 0x%8.8x", m_encoding_uid);
+ s->Printf(", type_uid = 0x%8.8" PRIx64, m_encoding_uid);
switch (m_encoding_uid_type)
{
case eEncodingInvalid: break;
@@ -257,7 +257,7 @@
{
s->PutChar('(');
if (verbose)
- s->Printf("Type{0x%8.8llx} ", GetID());
+ s->Printf("Type{0x%8.8" PRIx64 "} ", GetID());
DumpTypeName (s);
s->PutCString(") ");
}
@@ -828,6 +828,26 @@
return *this;
}
+bool
+TypeAndOrName::operator==(const TypeAndOrName &other) const
+{
+ if (m_type_sp != other.m_type_sp)
+ return false;
+ if (m_type_name != other.m_type_name)
+ return false;
+ return true;
+}
+
+bool
+TypeAndOrName::operator!=(const TypeAndOrName &other) const
+{
+ if (m_type_sp != other.m_type_sp)
+ return true;
+ if (m_type_name != other.m_type_name)
+ return true;
+ return false;
+}
+
ConstString
TypeAndOrName::GetName () const
{
@@ -866,6 +886,25 @@
return true;
}
+void
+TypeAndOrName::Clear ()
+{
+ m_type_name.Clear();
+ m_type_sp.reset();
+}
+
+bool
+TypeAndOrName::HasName ()
+{
+ return (bool)m_type_name;
+}
+
+bool
+TypeAndOrName::HasTypeSP ()
+{
+ return m_type_sp.get() != NULL;
+}
+
TypeImpl::TypeImpl(const lldb_private::ClangASTType& clang_ast_type) :
m_clang_ast_type(clang_ast_type.GetASTContext(), clang_ast_type.GetOpaqueQualType()),
m_type_sp()
Index: aze/lldb/source/Symbol/UnwindPlan.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/UnwindPlan.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/UnwindPlan.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -164,9 +164,9 @@
const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, GetCFARegister());
if (base_addr != LLDB_INVALID_ADDRESS)
- s.Printf ("0x%16.16llx: CFA=", base_addr + GetOffset());
+ s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
else
- s.Printf ("0x%8.8llx: CFA=", GetOffset());
+ s.Printf ("0x%8.8" PRIx64 ": CFA=", GetOffset());
if (reg_info)
s.Printf ("%s", reg_info->name);
Index: aze/lldb/source/Symbol/UnwindTable.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/UnwindTable.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/UnwindTable.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -140,7 +140,7 @@
const_iterator end = m_unwinds.end();
for (const_iterator pos = begin; pos != end; ++pos)
{
- s.Printf ("[%u] 0x%16.16llx\n", (unsigned)std::distance (begin, pos), pos->first);
+ s.Printf ("[%u] 0x%16.16" PRIx64 "\n", (unsigned)std::distance (begin, pos), pos->first);
}
s.EOL();
}
Index: aze/lldb/source/Symbol/Variable.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/Variable.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/Variable.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -203,7 +203,7 @@
if (m_owner_scope)
m_owner_scope->CalculateSymbolContext(sc);
else
- sc->Clear();
+ sc->Clear(false);
}
bool
Index: aze/lldb/source/Symbol/VariableList.cpp
===================================================================
--- aze.orig/lldb/source/Symbol/VariableList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Symbol/VariableList.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -67,7 +67,7 @@
}
VariableSP
-VariableList::GetVariableAtIndex(uint32_t idx)
+VariableList::GetVariableAtIndex(size_t idx) const
{
VariableSP var_sp;
if (idx < m_variables.size())
@@ -76,7 +76,7 @@
}
VariableSP
-VariableList::RemoveVariableAtIndex(uint32_t idx)
+VariableList::RemoveVariableAtIndex(size_t idx)
{
VariableSP var_sp;
if (idx < m_variables.size())
Index: aze/lldb/source/Target/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Target/CMakeLists.txt 2013-03-03 09:35:50.275457351 +0100
@@ -0,0 +1,44 @@
+set(LLVM_NO_RTTI 1)
+
+include_directories(../Plugins/Process/Utility)
+
+add_lldb_library(lldbTarget
+ ABI.cpp
+ CPPLanguageRuntime.cpp
+ ExecutionContext.cpp
+ LanguageRuntime.cpp
+ Memory.cpp
+ ObjCLanguageRuntime.cpp
+ OperatingSystem.cpp
+ PathMappingList.cpp
+ Platform.cpp
+ Process.cpp
+ RegisterContext.cpp
+ SectionLoadList.cpp
+ StackFrame.cpp
+ StackFrameList.cpp
+ StackID.cpp
+ StopInfo.cpp
+ Target.cpp
+ TargetList.cpp
+ Thread.cpp
+ ThreadList.cpp
+ ThreadPlan.cpp
+ ThreadPlanBase.cpp
+ ThreadPlanCallFunction.cpp
+ ThreadPlanCallUserExpression.cpp
+ ThreadPlanRunToAddress.cpp
+ ThreadPlanShouldStopHere.cpp
+ ThreadPlanStepInRange.cpp
+ ThreadPlanStepInstruction.cpp
+ ThreadPlanStepOut.cpp
+ ThreadPlanStepOverBreakpoint.cpp
+ ThreadPlanStepOverRange.cpp
+ ThreadPlanStepRange.cpp
+ ThreadPlanStepThrough.cpp
+ ThreadPlanStepUntil.cpp
+ ThreadPlanTracer.cpp
+ ThreadSpec.cpp
+ UnixSignals.cpp
+ UnwindAssembly.cpp
+ )
Index: aze/lldb/source/Target/LanguageRuntime.cpp
===================================================================
--- aze.orig/lldb/source/Target/LanguageRuntime.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/LanguageRuntime.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -61,6 +61,8 @@
SearchFilterSP filter_sp(target.GetSearchFilterForModule(NULL));
exc_breakpt_sp = target.CreateBreakpoint (filter_sp, resolver_sp, is_internal);
+ if (is_internal)
+ exc_breakpt_sp->SetBreakpointKind("exception");
return exc_breakpt_sp;
}
Index: aze/lldb/source/Target/Memory.cpp
===================================================================
--- aze.orig/lldb/source/Target/Memory.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/Memory.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -326,7 +326,7 @@
}
LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log)
- log->Printf ("AllocatedBlock::ReserveBlock (size = %u (0x%x)) => 0x%16.16llx", size, size, (uint64_t)addr);
+ log->Printf ("AllocatedBlock::ReserveBlock (size = %u (0x%x)) => 0x%16.16" PRIx64, size, size, (uint64_t)addr);
return addr;
}
@@ -343,7 +343,7 @@
}
LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_VERBOSE));
if (log)
- log->Printf ("AllocatedBlock::FreeBlock (addr = 0x%16.16llx) => %i", (uint64_t)addr, success);
+ log->Printf ("AllocatedBlock::FreeBlock (addr = 0x%16.16" PRIx64 ") => %i", (uint64_t)addr, success);
return success;
}
@@ -390,7 +390,7 @@
LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
{
- log->Printf ("Process::DoAllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16llx",
+ log->Printf ("Process::DoAllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16" PRIx64,
page_byte_size,
GetPermissionsAsCString(permissions),
(uint64_t)addr);
@@ -428,7 +428,7 @@
}
LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16llx", byte_size, GetPermissionsAsCString(permissions), (uint64_t)addr);
+ log->Printf ("AllocatedMemoryCache::AllocateMemory (byte_size = 0x%8.8zx, permissions = %s) => 0x%16.16" PRIx64, byte_size, GetPermissionsAsCString(permissions), (uint64_t)addr);
return addr;
}
@@ -449,7 +449,7 @@
}
LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16llx) => %i", (uint64_t)addr, success);
+ log->Printf("AllocatedMemoryCache::DeallocateMemory (addr = 0x%16.16" PRIx64 ") => %i", (uint64_t)addr, success);
return success;
}
Index: aze/lldb/source/Target/ObjCLanguageRuntime.cpp
===================================================================
--- aze.orig/lldb/source/Target/ObjCLanguageRuntime.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ObjCLanguageRuntime.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -9,8 +9,10 @@
#include "clang/AST/Type.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/MappedHash.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Timer.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/Type.h"
@@ -18,6 +20,8 @@
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
+#include "llvm/ADT/StringRef.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -31,19 +35,32 @@
ObjCLanguageRuntime::ObjCLanguageRuntime (Process *process) :
LanguageRuntime (process),
m_has_new_literals_and_indexing (eLazyBoolCalculate),
- m_isa_to_descriptor_cache(),
- m_isa_to_descriptor_cache_stop_id (UINT32_MAX)
+ m_isa_to_descriptor(),
+ m_isa_to_descriptor_stop_id (UINT32_MAX)
{
}
+bool
+ObjCLanguageRuntime::AddClass (ObjCISA isa, const ClassDescriptorSP &descriptor_sp, const char *class_name)
+{
+ if (isa != 0)
+ {
+ m_isa_to_descriptor[isa] = descriptor_sp;
+ // class_name is assumed to be valid
+ m_hash_to_isa_map.insert(std::make_pair(MappedHash::HashStringUsingDJB(class_name), isa));
+ return true;
+ }
+ return false;
+}
+
void
ObjCLanguageRuntime::AddToMethodCache (lldb::addr_t class_addr, lldb::addr_t selector, lldb::addr_t impl_addr)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
{
- log->Printf ("Caching: class 0x%llx selector 0x%llx implementation 0x%llx.", class_addr, selector, impl_addr);
+ log->Printf ("Caching: class 0x%" PRIx64 " selector 0x%" PRIx64 " implementation 0x%" PRIx64 ".", class_addr, selector, impl_addr);
}
m_impl_cache.insert (std::pair<ClassAndSel,lldb::addr_t> (ClassAndSel(class_addr, selector), impl_addr));
}
@@ -105,9 +122,7 @@
types);
if (num_types)
- {
- TypeSP incomplete_type_sp;
-
+ {
uint32_t i;
for (i = 0; i < num_types; ++i)
{
@@ -120,8 +135,6 @@
m_complete_class_cache[name] = type_sp;
return type_sp;
}
- else if (!incomplete_type_sp)
- incomplete_type_sp = type_sp;
}
}
}
@@ -135,89 +148,283 @@
return LLDB_INVALID_IVAR_OFFSET;
}
+void
+ObjCLanguageRuntime::MethodName::Clear()
+{
+ m_full.Clear();
+ m_class.Clear();
+ m_category.Clear();
+ m_selector.Clear();
+ m_type = eTypeUnspecified;
+ m_category_is_valid = false;
+}
+
+//bool
+//ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
+//{
+// Clear();
+// if (name && name[0])
+// {
+// // If "strict" is true. then the method must be specified with a
+// // '+' or '-' at the beginning. If "strict" is false, then the '+'
+// // or '-' can be omitted
+// bool valid_prefix = false;
+//
+// if (name[0] == '+' || name[0] == '-')
+// {
+// valid_prefix = name[1] == '[';
+// }
+// else if (!strict)
+// {
+// // "strict" is false, the name just needs to start with '['
+// valid_prefix = name[0] == '[';
+// }
+//
+// if (valid_prefix)
+// {
+// static RegularExpression g_regex("^([-+]?)\\[([A-Za-z_][A-Za-z_0-9]*)(\\([A-Za-z_][A-Za-z_0-9]*\\))? ([A-Za-z_][A-Za-z_0-9:]*)\\]$");
+// llvm::StringRef matches[4];
+// // Since we are using a global regular expression, we must use the threadsafe version of execute
+// if (g_regex.ExecuteThreadSafe(name, matches, 4))
+// {
+// m_full.SetCString(name);
+// if (matches[0].empty())
+// m_type = eTypeUnspecified;
+// else if (matches[0][0] == '+')
+// m_type = eTypeClassMethod;
+// else
+// m_type = eTypeInstanceMethod;
+// m_class.SetString(matches[1]);
+// m_selector.SetString(matches[3]);
+// if (!matches[2].empty())
+// m_category.SetString(matches[2]);
+// }
+// }
+// }
+// return IsValid(strict);
+//}
-uint32_t
-ObjCLanguageRuntime::ParseMethodName (const char *name,
- ConstString *class_name, // Class name (with category if any)
- ConstString *selector_name, // selector on its own
- ConstString *name_sans_category, // Full function prototype with no category
- ConstString *class_name_sans_category)// Class name with no category (or empty if no category as answer will be in "class_name"
-{
- if (class_name)
- class_name->Clear();
- if (selector_name)
- selector_name->Clear();
- if (name_sans_category)
- name_sans_category->Clear();
- if (class_name_sans_category)
- class_name_sans_category->Clear();
-
- uint32_t result = 0;
+bool
+ObjCLanguageRuntime::MethodName::SetName (const char *name, bool strict)
+{
+ Clear();
+ if (name && name[0])
+ {
+ // If "strict" is true. then the method must be specified with a
+ // '+' or '-' at the beginning. If "strict" is false, then the '+'
+ // or '-' can be omitted
+ bool valid_prefix = false;
+
+ if (name[0] == '+' || name[0] == '-')
+ {
+ valid_prefix = name[1] == '[';
+ if (name[0] == '+')
+ m_type = eTypeClassMethod;
+ else
+ m_type = eTypeInstanceMethod;
+ }
+ else if (!strict)
+ {
+ // "strict" is false, the name just needs to start with '['
+ valid_prefix = name[0] == '[';
+ }
+
+ if (valid_prefix)
+ {
+ int name_len = strlen (name);
+ // Objective C methods must have at least:
+ // "-[" or "+[" prefix
+ // One character for a class name
+ // One character for the space between the class name
+ // One character for the method name
+ // "]" suffix
+ if (name_len >= (5 + (strict ? 1 : 0)) && name[name_len - 1] == ']')
+ {
+ m_full.SetCStringWithLength(name, name_len);
+ }
+ }
+ }
+ return IsValid(strict);
+}
- if (IsPossibleObjCMethodName (name))
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetClassName ()
+{
+ if (!m_class)
{
- int name_len = strlen (name);
- // Objective C methods must have at least:
- // "-[" or "+[" prefix
- // One character for a class name
- // One character for the space between the class name
- // One character for the method name
- // "]" suffix
- if (name_len >= 6 && name[name_len - 1] == ']')
+ if (IsValid(false))
{
- const char *selector_name_ptr = strchr (name, ' ');
- if (selector_name_ptr)
+ const char *full = m_full.GetCString();
+ const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+ const char *paren_pos = strchr (class_start, '(');
+ if (paren_pos)
{
- if (class_name)
- {
- class_name->SetCStringWithLength (name + 2, selector_name_ptr - name - 2);
- ++result;
- }
-
- // Skip the space
- ++selector_name_ptr;
- // Extract the objective C basename and add it to the
- // accelerator tables
- size_t selector_name_len = name_len - (selector_name_ptr - name) - 1;
- if (selector_name)
- {
- selector_name->SetCStringWithLength (selector_name_ptr, selector_name_len);
- ++result;
- }
-
- // Also see if this is a "category" on our class. If so strip off the category name,
- // and add the class name without it to the basename table.
-
- if (name_sans_category || class_name_sans_category)
+ m_class.SetCStringWithLength (class_start, paren_pos - class_start);
+ }
+ else
+ {
+ // No '(' was found in the full name, we can definitively say
+ // that our category was valid (and empty).
+ m_category_is_valid = true;
+ const char *space_pos = strchr (full, ' ');
+ if (space_pos)
{
- const char *open_paren = strchr (name, '(');
- if (open_paren)
+ m_class.SetCStringWithLength (class_start, space_pos - class_start);
+ if (!m_class_category)
{
- if (class_name_sans_category)
- {
- class_name_sans_category->SetCStringWithLength (name + 2, open_paren - name - 2);
- ++result;
- }
-
- if (name_sans_category)
- {
- const char *close_paren = strchr (open_paren, ')');
- if (open_paren < close_paren)
- {
- std::string buffer (name, open_paren - name);
- buffer.append (close_paren + 1);
- name_sans_category->SetCString (buffer.c_str());
- ++result;
- }
- }
+ // No category in name, so we can also fill in the m_class_category
+ m_class_category = m_class;
}
}
}
}
}
- return result;
+ return m_class;
+}
+
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetClassNameWithCategory ()
+{
+ if (!m_class_category)
+ {
+ if (IsValid(false))
+ {
+ const char *full = m_full.GetCString();
+ const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+ const char *space_pos = strchr (full, ' ');
+ if (space_pos)
+ {
+ m_class_category.SetCStringWithLength (class_start, space_pos - class_start);
+ // If m_class hasn't been filled in and the class with category doesn't
+ // contain a '(', then we can also fill in the m_class
+ if (!m_class && strchr (m_class_category.GetCString(), '(') == NULL)
+ {
+ m_class = m_class_category;
+ // No '(' was found in the full name, we can definitively say
+ // that our category was valid (and empty).
+ m_category_is_valid = true;
+
+ }
+ }
+ }
+ }
+ return m_class_category;
+}
+
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetSelector ()
+{
+ if (!m_selector)
+ {
+ if (IsValid(false))
+ {
+ const char *full = m_full.GetCString();
+ const char *space_pos = strchr (full, ' ');
+ if (space_pos)
+ {
+ ++space_pos; // skip the space
+ m_selector.SetCStringWithLength (space_pos, m_full.GetLength() - (space_pos - full) - 1);
+ }
+ }
+ }
+ return m_selector;
}
+const ConstString &
+ObjCLanguageRuntime::MethodName::GetCategory ()
+{
+ if (!m_category_is_valid && !m_category)
+ {
+ if (IsValid(false))
+ {
+ m_category_is_valid = true;
+ const char *full = m_full.GetCString();
+ const char *class_start = (full[0] == '[' ? full + 1 : full + 2);
+ const char *open_paren_pos = strchr (class_start, '(');
+ if (open_paren_pos)
+ {
+ ++open_paren_pos; // Skip the open paren
+ const char *close_paren_pos = strchr (open_paren_pos, ')');
+ if (close_paren_pos)
+ m_category.SetCStringWithLength (open_paren_pos, close_paren_pos - open_paren_pos);
+ }
+ }
+ }
+ return m_category;
+}
+
+ConstString
+ObjCLanguageRuntime::MethodName::GetFullNameWithoutCategory (bool empty_if_no_category)
+{
+ if (IsValid(false))
+ {
+ if (HasCategory())
+ {
+ StreamString strm;
+ if (m_type == eTypeClassMethod)
+ strm.PutChar('+');
+ else if (m_type == eTypeInstanceMethod)
+ strm.PutChar('-');
+ strm.Printf("[%s %s]", GetClassName().GetCString(), GetSelector().GetCString());
+ return ConstString(strm.GetString().c_str());
+ }
+
+ if (!empty_if_no_category)
+ {
+ // Just return the full name since it doesn't have a category
+ return GetFullName();
+ }
+ }
+ return ConstString();
+}
+
+size_t
+ObjCLanguageRuntime::MethodName::GetFullNames (std::vector<ConstString> &names, bool append)
+{
+ if (!append)
+ names.clear();
+ if (IsValid(false))
+ {
+ StreamString strm;
+ const bool is_class_method = m_type == eTypeClassMethod;
+ const bool is_instance_method = m_type == eTypeInstanceMethod;
+ const ConstString &category = GetCategory();
+ if (is_class_method || is_instance_method)
+ {
+ names.push_back (m_full);
+ if (category)
+ {
+ strm.Printf("%c[%s %s]",
+ is_class_method ? '+' : '-',
+ GetClassName().GetCString(),
+ GetSelector().GetCString());
+ names.push_back(ConstString(strm.GetString().c_str()));
+ }
+ }
+ else
+ {
+ const ConstString &class_name = GetClassName();
+ const ConstString &selector = GetSelector();
+ strm.Printf("+[%s %s]", class_name.GetCString(), selector.GetCString());
+ names.push_back(ConstString(strm.GetString().c_str()));
+ strm.Clear();
+ strm.Printf("-[%s %s]", class_name.GetCString(), selector.GetCString());
+ names.push_back(ConstString(strm.GetString().c_str()));
+ strm.Clear();
+ if (category)
+ {
+ strm.Printf("+[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
+ names.push_back(ConstString(strm.GetString().c_str()));
+ strm.Clear();
+ strm.Printf("-[%s(%s) %s]", class_name.GetCString(), category.GetCString(), selector.GetCString());
+ names.push_back(ConstString(strm.GetString().c_str()));
+ }
+ }
+ }
+ return names.size();
+}
+
+
bool
ObjCLanguageRuntime::ClassDescriptor::IsPointerValid (lldb::addr_t value,
uint32_t ptr_size,
@@ -238,13 +445,50 @@
ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetISA(const ConstString &name)
{
- UpdateISAToDescriptorMap();
- for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
- if (val.second && val.second->GetClassName() == name)
- return val.first;
+ ISAToDescriptorIterator pos = GetDescriptorIterator (name);
+ if (pos != m_isa_to_descriptor.end())
+ return pos->first;
return 0;
}
+ObjCLanguageRuntime::ISAToDescriptorIterator
+ObjCLanguageRuntime::GetDescriptorIterator (const ConstString &name)
+{
+ ISAToDescriptorIterator end = m_isa_to_descriptor.end();
+
+ if (name)
+ {
+ UpdateISAToDescriptorMap();
+ if (m_hash_to_isa_map.empty())
+ {
+ // No name hashes were provided, we need to just linearly power through the
+ // names and find a match
+ for (ISAToDescriptorIterator pos = m_isa_to_descriptor.begin(); pos != end; ++pos)
+ {
+ if (pos->second->GetClassName() == name)
+ return pos;
+ }
+ }
+ else
+ {
+ // Name hashes were provided, so use them to efficiently lookup name to isa/descriptor
+ const uint32_t name_hash = MappedHash::HashStringUsingDJB (name.GetCString());
+ std::pair <HashToISAIterator, HashToISAIterator> range = m_hash_to_isa_map.equal_range(name_hash);
+ for (HashToISAIterator range_pos = range.first; range_pos != range.second; ++range_pos)
+ {
+ ISAToDescriptorIterator pos = m_isa_to_descriptor.find (range_pos->second);
+ if (pos != m_isa_to_descriptor.end())
+ {
+ if (pos->second->GetClassName() == name)
+ return pos;
+ }
+ }
+ }
+ }
+ return end;
+}
+
+
ObjCLanguageRuntime::ObjCISA
ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa)
{
@@ -270,10 +514,9 @@
ObjCLanguageRuntime::ClassDescriptorSP
ObjCLanguageRuntime::GetClassDescriptor (const ConstString &class_name)
{
- UpdateISAToDescriptorMap();
- for (const ISAToDescriptorMap::value_type &val : m_isa_to_descriptor_cache)
- if (val.second && val.second->GetClassName() == class_name)
- return val.second;
+ ISAToDescriptorIterator pos = GetDescriptorIterator (class_name);
+ if (pos != m_isa_to_descriptor.end())
+ return pos->second;
return ClassDescriptorSP();
}
@@ -328,8 +571,8 @@
if (isa)
{
UpdateISAToDescriptorMap();
- ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor_cache.find(isa);
- if (pos != m_isa_to_descriptor_cache.end())
+ ObjCLanguageRuntime::ISAToDescriptorIterator pos = m_isa_to_descriptor.find(isa);
+ if (pos != m_isa_to_descriptor.end())
return pos->second;
}
return ClassDescriptorSP();
Index: aze/lldb/source/Target/Platform.cpp
===================================================================
--- aze.orig/lldb/source/Target/Platform.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/Platform.cpp 2013-03-03 09:35:50.275457351 +0100
@@ -89,10 +89,10 @@
return Error();
}
-FileSpec
-Platform::LocateExecutableScriptingResource (const ModuleSpec &module_spec)
+FileSpecList
+Platform::LocateExecutableScriptingResources (Target *target, Module &module)
{
- return FileSpec();
+ return FileSpecList();
}
Error
@@ -145,12 +145,27 @@
{
uint32_t idx;
PlatformCreateInstance create_callback;
+ // First try exact arch matches across all platform plug-ins
+ bool exact = true;
for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
{
if (create_callback)
+ {
+ platform_sp.reset(create_callback(false, &arch));
+ if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
+ return platform_sp;
+ }
+ }
+ // Next try compatible arch matches across all platform plug-ins
+ exact = false;
+ for (idx = 0; (create_callback = PluginManager::GetPlatformCreateCallbackAtIndex (idx)); ++idx)
+ {
+ if (create_callback)
+ {
platform_sp.reset(create_callback(false, &arch));
- if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, platform_arch_ptr))
- return platform_sp;
+ if (platform_sp && platform_sp->IsCompatibleArchitecture(arch, exact, platform_arch_ptr))
+ return platform_sp;
+ }
}
}
else
@@ -680,19 +695,35 @@
/// architecture and the target triple contained within.
//------------------------------------------------------------------
bool
-Platform::IsCompatibleArchitecture (const ArchSpec &arch, ArchSpec *compatible_arch_ptr)
+Platform::IsCompatibleArchitecture (const ArchSpec &arch, bool exact_arch_match, ArchSpec *compatible_arch_ptr)
{
// If the architecture is invalid, we must answer true...
if (arch.IsValid())
{
ArchSpec platform_arch;
- for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
+ // Try for an exact architecture match first.
+ if (exact_arch_match)
{
- if (arch == platform_arch)
+ for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
{
- if (compatible_arch_ptr)
- *compatible_arch_ptr = platform_arch;
- return true;
+ if (arch.IsExactMatch(platform_arch))
+ {
+ if (compatible_arch_ptr)
+ *compatible_arch_ptr = platform_arch;
+ return true;
+ }
+ }
+ }
+ else
+ {
+ for (uint32_t arch_idx=0; GetSupportedArchitectureAtIndex (arch_idx, platform_arch); ++arch_idx)
+ {
+ if (arch.IsCompatibleMatch(platform_arch))
+ {
+ if (compatible_arch_ptr)
+ *compatible_arch_ptr = platform_arch;
+ return true;
+ }
}
}
}
@@ -702,6 +733,7 @@
}
+
lldb::BreakpointSP
Platform::SetThreadCreationBreakpoint (lldb_private::Target &target)
{
Index: aze/lldb/source/Target/Process.cpp
===================================================================
--- aze.orig/lldb/source/Target/Process.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/Process.cpp 2013-03-03 09:35:50.279457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Target/Process.h"
#include "lldb/lldb-private-log.h"
@@ -93,15 +95,22 @@
g_properties[] =
{
{ "disable-memory-cache" , OptionValue::eTypeBoolean, false, DISABLE_MEM_CACHE_DEFAULT, NULL, NULL, "Disable reading and caching of memory in fixed-size units." },
- { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used." },
- { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, 0, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
+ { "extra-startup-command", OptionValue::eTypeArray , false, OptionValue::eTypeString, NULL, NULL, "A list containing extra commands understood by the particular process plugin used. "
+ "For instance, to turn on debugserver logging set this to \"QSetLogging:bitmask=LOG_DEFAULT;\"" },
+ { "ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, breakpoints will be ignored during expression evaluation." },
+ { "unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, errors in expression evaluation will unwind the stack back to the state before the call." },
+ { "python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, NULL, NULL, "A path to a python OS plug-in module file that contains a OperatingSystemPlugIn class." },
+ { "stop-on-sharedlibrary-events" , OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, stop when a shared library is loaded or unloaded." },
{ NULL , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL }
};
enum {
ePropertyDisableMemCache,
ePropertyExtraStartCommand,
- ePropertyPythonOSPluginPath
+ ePropertyIgnoreBreakpointsInExpressions,
+ ePropertyUnwindOnErrorInExpressions,
+ ePropertyPythonOSPluginPath,
+ ePropertyStopOnSharedLibraryEvents
};
ProcessProperties::ProcessProperties (bool is_global) :
@@ -112,7 +121,7 @@
m_collection_sp.reset (new ProcessOptionValueProperties(ConstString("process")));
m_collection_sp->Initialize(g_properties);
m_collection_sp->AppendProperty(ConstString("thread"),
- ConstString("Settings specify to threads."),
+ ConstString("Settings specific to threads."),
true,
Thread::GetGlobalProperties()->GetValueProperties());
}
@@ -161,15 +170,58 @@
m_collection_sp->SetPropertyAtIndexAsFileSpec(NULL, idx, file);
}
+
+bool
+ProcessProperties::GetIgnoreBreakpointsInExpressions () const
+{
+ const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void
+ProcessProperties::SetIgnoreBreakpointsInExpressions (bool ignore)
+{
+ const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+}
+
+bool
+ProcessProperties::GetUnwindOnErrorInExpressions () const
+{
+ const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void
+ProcessProperties::SetUnwindOnErrorInExpressions (bool ignore)
+{
+ const uint32_t idx = ePropertyUnwindOnErrorInExpressions;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, ignore);
+}
+
+bool
+ProcessProperties::GetStopOnSharedLibraryEvents () const
+{
+ const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(NULL, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void
+ProcessProperties::SetStopOnSharedLibraryEvents (bool stop)
+{
+ const uint32_t idx = ePropertyStopOnSharedLibraryEvents;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(NULL, idx, stop);
+}
+
void
ProcessInstanceInfo::Dump (Stream &s, Platform *platform) const
{
const char *cstr;
if (m_pid != LLDB_INVALID_PROCESS_ID)
- s.Printf (" pid = %llu\n", m_pid);
+ s.Printf (" pid = %" PRIu64 "\n", m_pid);
if (m_parent_pid != LLDB_INVALID_PROCESS_ID)
- s.Printf (" parent = %llu\n", m_parent_pid);
+ s.Printf (" parent = %" PRIu64 "\n", m_parent_pid);
if (m_executable)
{
@@ -256,7 +308,7 @@
if (m_pid != LLDB_INVALID_PROCESS_ID)
{
const char *cstr;
- s.Printf ("%-6llu %-6llu ", m_pid, m_parent_pid);
+ s.Printf ("%-6" PRIu64 " %-6" PRIu64 " ", m_pid, m_parent_pid);
if (verbose)
@@ -463,7 +515,8 @@
// We have a relative path to our executable which may not work if
// we just try to run "a.out" (without it being converted to "./a.out")
const char *working_dir = GetWorkingDirectory();
- std::string new_path("PATH=");
+ // Be sure to put quotes around PATH's value in case any paths have spaces...
+ std::string new_path("PATH=\"");
const size_t empty_path_len = new_path.size();
if (working_dir && working_dir[0])
@@ -484,7 +537,7 @@
new_path += ':';
new_path += curr_path;
}
- new_path += ' ';
+ new_path += "\" ";
shell_command.PutCString(new_path.c_str());
}
@@ -668,10 +721,6 @@
file_actions, info->m_fd, info->m_path.c_str(), oflag, mode);
}
break;
-
- default:
- error.SetErrorStringWithFormat ("invalid file action: %i", info->m_action);
- break;
}
return error.Success();
}
@@ -680,7 +729,7 @@
ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
+ const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
@@ -832,7 +881,7 @@
return false;
if (m_match_info.GetArchitecture().IsValid() &&
- m_match_info.GetArchitecture() != proc_info.GetArchitecture())
+ !m_match_info.GetArchitecture().IsCompatibleMatch(proc_info.GetArchitecture()))
return false;
return true;
}
@@ -882,6 +931,8 @@
ProcessSP
Process::FindPlugin (Target &target, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path)
{
+ static uint32_t g_process_unique_id = 0;
+
ProcessSP process_sp;
ProcessCreateInstance create_callback = NULL;
if (plugin_name)
@@ -892,7 +943,11 @@
process_sp = create_callback(target, listener, crash_file_path);
if (process_sp)
{
- if (!process_sp->CanDebug(target, true))
+ if (process_sp->CanDebug(target, true))
+ {
+ process_sp->m_process_unique_id = ++g_process_unique_id;
+ }
+ else
process_sp.reset();
}
}
@@ -904,10 +959,13 @@
process_sp = create_callback(target, listener, crash_file_path);
if (process_sp)
{
- if (!process_sp->CanDebug(target, false))
- process_sp.reset();
- else
+ if (process_sp->CanDebug(target, false))
+ {
+ process_sp->m_process_unique_id = ++g_process_unique_id;
break;
+ }
+ else
+ process_sp.reset();
}
}
}
@@ -937,7 +995,9 @@
m_private_state_control_wait(),
m_private_state_thread (LLDB_INVALID_HOST_THREAD),
m_mod_id (),
+ m_process_unique_id(0),
m_thread_index_id (0),
+ m_thread_id_to_index_id_map (),
m_exit_status (-1),
m_exit_string (),
m_thread_list (this),
@@ -953,6 +1013,8 @@
m_stdio_communication_mutex (Mutex::eMutexTypeRecursive),
m_stdout_data (),
m_stderr_data (),
+ m_profile_data_comm_mutex (Mutex::eMutexTypeRecursive),
+ m_profile_data (),
m_memory_cache (*this),
m_allocated_memory_cache (*this),
m_should_detach (false),
@@ -960,7 +1022,9 @@
m_run_lock (),
m_currently_handling_event(false),
m_finalize_called(false),
- m_can_jit(eCanJITDontKnow)
+ m_last_broadcast_state (eStateInvalid),
+ m_can_jit(eCanJITDontKnow),
+ m_destroy_in_process (false)
{
CheckInWithManager ();
@@ -972,6 +1036,7 @@
SetEventName (eBroadcastBitInterrupt, "interrupt");
SetEventName (eBroadcastBitSTDOUT, "stdout-available");
SetEventName (eBroadcastBitSTDERR, "stderr-available");
+ SetEventName (eBroadcastBitProfileData, "profile-data-available");
m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" );
m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
@@ -981,7 +1046,8 @@
eBroadcastBitStateChanged |
eBroadcastBitInterrupt |
eBroadcastBitSTDOUT |
- eBroadcastBitSTDERR);
+ eBroadcastBitSTDERR |
+ eBroadcastBitProfileData);
m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
eBroadcastBitStateChanged |
@@ -1401,7 +1467,7 @@
{
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%llu, exited=%i, signal=%i, exit_status=%i)\n",
+ log->Printf ("Process::SetProcessExitStatus (baton=%p, pid=%" PRIu64 ", exited=%i, signal=%i, exit_status=%i)\n",
callback_baton,
pid,
exited,
@@ -1447,22 +1513,78 @@
// thread list, but only update if "true" is returned
if (UpdateThreadList (m_thread_list, new_thread_list))
{
- OperatingSystem *os = GetOperatingSystem ();
- if (os)
- os->UpdateThreadList (m_thread_list, new_thread_list);
- m_thread_list.Update (new_thread_list);
- m_thread_list.SetStopID (stop_id);
+ // Don't call into the OperatingSystem to update the thread list if we are shutting down, since
+ // that may call back into the SBAPI's, requiring the API lock which is already held by whoever is
+ // shutting us down, causing a deadlock.
+ if (!m_destroy_in_process)
+ {
+ OperatingSystem *os = GetOperatingSystem ();
+ if (os)
+ os->UpdateThreadList (m_thread_list, new_thread_list);
+ m_thread_list.Update (new_thread_list);
+ m_thread_list.SetStopID (stop_id);
+ }
}
}
}
}
+ThreadSP
+Process::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context)
+{
+ OperatingSystem *os = GetOperatingSystem ();
+ if (os)
+ return os->CreateThread(tid, context);
+ return ThreadSP();
+}
+
+
+
+// This is obsoleted. Staged removal for Xcode.
uint32_t
Process::GetNextThreadIndexID ()
{
return ++m_thread_index_id;
}
+uint32_t
+Process::GetNextThreadIndexID (uint64_t thread_id)
+{
+ return AssignIndexIDToThread(thread_id);
+}
+
+bool
+Process::HasAssignedIndexIDToThread(uint64_t thread_id)
+{
+ std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_index_id_map.find(thread_id);
+ if (iterator == m_thread_id_to_index_id_map.end())
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+uint32_t
+Process::AssignIndexIDToThread(uint64_t thread_id)
+{
+ uint32_t result = 0;
+ std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_index_id_map.find(thread_id);
+ if (iterator == m_thread_id_to_index_id_map.end())
+ {
+ result = ++m_thread_index_id;
+ m_thread_id_to_index_id_map[thread_id] = result;
+ }
+ else
+ {
+ result = iterator->second;
+ }
+
+ return result;
+}
+
StateType
Process::GetState()
{
@@ -1625,7 +1747,8 @@
{
ExecutionContext exe_ctx;
frame_sp->CalculateExecutionContext (exe_ctx);
- bool unwind_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
StreamString expr;
expr.Printf("dlopen (\"%s\", 2)", path);
const char *prefix = "extern \"C\" void* dlopen (const char *path, int mode);\n";
@@ -1635,6 +1758,7 @@
lldb::eLanguageTypeUnknown,
ClangUserExpression::eResultTypeAny,
unwind_on_error,
+ ignore_breakpoints,
expr.GetData(),
prefix,
result_valobj_sp,
@@ -1700,9 +1824,10 @@
{
ExecutionContext exe_ctx;
frame_sp->CalculateExecutionContext (exe_ctx);
- bool unwind_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
StreamString expr;
- expr.Printf("dlclose ((void *)0x%llx)", image_addr);
+ expr.Printf("dlclose ((void *)0x%" PRIx64 ")", image_addr);
const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
lldb::ValueObjectSP result_valobj_sp;
ClangUserExpression::Evaluate (exe_ctx,
@@ -1710,6 +1835,7 @@
lldb::eLanguageTypeUnknown,
ClangUserExpression::eResultTypeAny,
unwind_on_error,
+ ignore_breakpoints,
expr.GetData(),
prefix,
result_valobj_sp,
@@ -1829,7 +1955,7 @@
size_t num_sites = m_breakpoint_site_list.GetSize();
for (size_t i = 0; i < num_sites; i++)
{
- DisableBreakpoint (m_breakpoint_site_list.GetByIndex(i).get());
+ DisableBreakpointSite (m_breakpoint_site_list.GetByIndex(i).get());
}
}
@@ -1852,11 +1978,11 @@
if (bp_site_sp)
{
if (bp_site_sp->IsEnabled())
- error = DisableBreakpoint (bp_site_sp.get());
+ error = DisableBreakpointSite (bp_site_sp.get());
}
else
{
- error.SetErrorStringWithFormat("invalid breakpoint site ID: %llu", break_id);
+ error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64, break_id);
}
return error;
@@ -1870,11 +1996,11 @@
if (bp_site_sp)
{
if (!bp_site_sp->IsEnabled())
- error = EnableBreakpoint (bp_site_sp.get());
+ error = EnableBreakpointSite (bp_site_sp.get());
}
else
{
- error.SetErrorStringWithFormat("invalid breakpoint site ID: %llu", break_id);
+ error.SetErrorStringWithFormat("invalid breakpoint site ID: %" PRIu64, break_id);
}
return error;
}
@@ -1900,10 +2026,10 @@
}
else
{
- bp_site_sp.reset (new BreakpointSite (&m_breakpoint_site_list, owner, load_addr, LLDB_INVALID_THREAD_ID, use_hardware));
+ bp_site_sp.reset (new BreakpointSite (&m_breakpoint_site_list, owner, load_addr, use_hardware));
if (bp_site_sp)
{
- if (EnableBreakpoint (bp_site_sp.get()).Success())
+ if (EnableBreakpointSite (bp_site_sp.get()).Success())
{
owner->SetBreakpointSite (bp_site_sp);
return m_breakpoint_site_list.Add (bp_site_sp);
@@ -1922,7 +2048,7 @@
uint32_t num_owners = bp_site_sp->RemoveOwner (owner_id, owner_loc_id);
if (num_owners == 0)
{
- DisableBreakpoint(bp_site_sp.get());
+ DisableBreakpointSite (bp_site_sp.get());
m_breakpoint_site_list.RemoveByAddress(bp_site_sp->GetLoadAddress());
}
}
@@ -1978,11 +2104,11 @@
LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
const addr_t bp_addr = bp_site->GetLoadAddress();
if (log)
- log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx", bp_site->GetID(), (uint64_t)bp_addr);
+ log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64, bp_site->GetID(), (uint64_t)bp_addr);
if (bp_site->IsEnabled())
{
if (log)
- log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already enabled", bp_site->GetID(), (uint64_t)bp_addr);
+ log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- already enabled", bp_site->GetID(), (uint64_t)bp_addr);
return error;
}
@@ -1997,7 +2123,7 @@
if (bp_opcode_size == 0)
{
- error.SetErrorStringWithFormat ("Process::GetSoftwareBreakpointTrapOpcode() returned zero, unable to get breakpoint trap for address 0x%llx", bp_addr);
+ error.SetErrorStringWithFormat ("Process::GetSoftwareBreakpointTrapOpcode() returned zero, unable to get breakpoint trap for address 0x%" PRIx64, bp_addr);
}
else
{
@@ -2023,7 +2149,7 @@
bp_site->SetEnabled(true);
bp_site->SetType (BreakpointSite::eSoftware);
if (log)
- log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS",
+ log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- SUCCESS",
bp_site->GetID(),
(uint64_t)bp_addr);
}
@@ -2040,7 +2166,7 @@
error.SetErrorString("Unable to read memory at breakpoint address.");
}
if (log && error.Fail())
- log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
+ log->Printf ("Process::EnableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- FAILED: %s",
bp_site->GetID(),
(uint64_t)bp_addr,
error.AsCString());
@@ -2056,7 +2182,7 @@
addr_t bp_addr = bp_site->GetLoadAddress();
lldb::user_id_t breakID = bp_site->GetID();
if (log)
- log->Printf ("Process::DisableBreakpoint (breakID = %llu) addr = 0x%llx", breakID, (uint64_t)bp_addr);
+ log->Printf ("Process::DisableSoftwareBreakpoint (breakID = %" PRIu64 ") addr = 0x%" PRIx64, breakID, (uint64_t)bp_addr);
if (bp_site->IsHardware())
{
@@ -2110,7 +2236,7 @@
// SUCCESS
bp_site->SetEnabled(false);
if (log)
- log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- SUCCESS", bp_site->GetID(), (uint64_t)bp_addr);
+ log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- SUCCESS", bp_site->GetID(), (uint64_t)bp_addr);
return error;
}
else
@@ -2130,12 +2256,12 @@
else
{
if (log)
- log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- already disabled", bp_site->GetID(), (uint64_t)bp_addr);
+ log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- already disabled", bp_site->GetID(), (uint64_t)bp_addr);
return error;
}
if (log)
- log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%llx -- FAILED: %s",
+ log->Printf ("Process::DisableSoftwareBreakpoint (site_id = %d) addr = 0x%" PRIx64 " -- FAILED: %s",
bp_site->GetID(),
(uint64_t)bp_addr,
error.AsCString());
@@ -2419,7 +2545,7 @@
}
size_t
-Process::WriteScalarToMemory (addr_t addr, const Scalar &scalar, uint32_t byte_size, Error &error)
+Process::WriteScalarToMemory (addr_t addr, const Scalar &scalar, size_t byte_size, Error &error)
{
if (byte_size == UINT32_MAX)
byte_size = scalar.GetByteSize();
@@ -2454,7 +2580,7 @@
if (bytes_read == byte_size)
{
DataExtractor data (&uval, sizeof(uval), GetByteOrder(), GetAddressByteSize());
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (byte_size <= 4)
scalar = data.GetMaxU32 (&offset, byte_size);
else
@@ -2485,7 +2611,7 @@
addr_t allocated_addr = DoAllocateMemory (size, permissions, error);
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf("Process::AllocateMemory(size=%4zu, permissions=%s) => 0x%16.16llx (m_stop_id = %u m_memory_id = %u)",
+ log->Printf("Process::AllocateMemory(size=%4zu, permissions=%s) => 0x%16.16" PRIx64 " (m_stop_id = %u m_memory_id = %u)",
size,
GetPermissionsAsCString (permissions),
(uint64_t)allocated_addr,
@@ -2530,14 +2656,14 @@
#if defined (USE_ALLOCATE_MEMORY_CACHE)
if (!m_allocated_memory_cache.DeallocateMemory(ptr))
{
- error.SetErrorStringWithFormat ("deallocation of memory at 0x%llx failed.", (uint64_t)ptr);
+ error.SetErrorStringWithFormat ("deallocation of memory at 0x%" PRIx64 " failed.", (uint64_t)ptr);
}
#else
error = DoDeallocateMemory (ptr);
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf("Process::DeallocateMemory(addr=0x%16.16llx) => err = %s (m_stop_id = %u, m_memory_id = %u)",
+ log->Printf("Process::DeallocateMemory(addr=0x%16.16" PRIx64 ") => err = %s (m_stop_id = %u, m_memory_id = %u)",
ptr,
error.AsCString("SUCCESS"),
m_mod_id.GetStopID(),
@@ -2546,11 +2672,10 @@
return error;
}
+
ModuleSP
Process::ReadModuleFromMemory (const FileSpec& file_spec,
- lldb::addr_t header_addr,
- bool add_image_to_target,
- bool load_sections_in_target)
+ lldb::addr_t header_addr)
{
ModuleSP module_sp (new Module (file_spec, ArchSpec()));
if (module_sp)
@@ -2558,24 +2683,13 @@
Error error;
ObjectFile *objfile = module_sp->GetMemoryObjectFile (shared_from_this(), header_addr, error);
if (objfile)
- {
- if (add_image_to_target)
- {
- m_target.GetImages().Append(module_sp);
- if (load_sections_in_target)
- {
- bool changed = false;
- module_sp->SetLoadAddress (m_target, 0, changed);
- }
- }
return module_sp;
- }
}
return ModuleSP();
}
Error
-Process::EnableWatchpoint (Watchpoint *watchpoint)
+Process::EnableWatchpoint (Watchpoint *watchpoint, bool notify)
{
Error error;
error.SetErrorString("watchpoints are not supported");
@@ -2583,7 +2697,7 @@
}
Error
-Process::DisableWatchpoint (Watchpoint *watchpoint)
+Process::DisableWatchpoint (Watchpoint *watchpoint, bool notify)
{
Error error;
error.SetErrorString("watchpoints are not supported");
@@ -2952,7 +3066,7 @@
if (platform_sp)
{
const ArchSpec &target_arch = m_target.GetArchitecture();
- if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch))
+ if (target_arch.IsValid() && !platform_sp->IsCompatibleArchitecture (target_arch, false, NULL))
{
ArchSpec platform_arch;
platform_sp = platform_sp->GetPlatformForArchitecture (target_arch, &platform_arch);
@@ -2967,7 +3081,7 @@
ProcessInstanceInfo process_info;
platform_sp->GetProcessInfo (GetID(), process_info);
const ArchSpec &process_arch = process_info.GetArchitecture();
- if (process_arch.IsValid() && m_target.GetArchitecture() != process_arch)
+ if (process_arch.IsValid() && !m_target.GetArchitecture().IsExactMatch(process_arch))
m_target.SetArchitecture (process_arch);
}
}
@@ -3041,9 +3155,9 @@
Error
Process::PrivateResume ()
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_STEP));
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS|LIBLLDB_LOG_STEP));
if (log)
- log->Printf("Process::Resume() m_stop_id = %u, public state: %s private state: %s",
+ log->Printf("Process::PrivateResume() m_stop_id = %u, public state: %s private state: %s",
m_mod_id.GetStopID(),
StateAsCString(m_public_state.GetValue()),
StateAsCString(m_private_state.GetValue()));
@@ -3065,7 +3179,7 @@
// Last thing, do the PreResumeActions.
if (!RunPreResumeActions())
{
- error.SetErrorStringWithFormat ("Process::Resume PreResumeActions failed, not resuming.");
+ error.SetErrorStringWithFormat ("Process::PrivateResume PreResumeActions failed, not resuming.");
}
else
{
@@ -3092,7 +3206,7 @@
}
}
else if (log)
- log->Printf ("Process::WillResume() got an error \"%s\".", error.AsCString("<unknown error>"));
+ log->Printf ("Process::PrivateResume() got an error \"%s\".", error.AsCString("<unknown error>"));
return error;
}
@@ -3204,6 +3318,13 @@
Error
Process::Destroy ()
{
+
+ // Tell ourselves we are in the process of destroying the process, so that we don't do any unnecessary work
+ // that might hinder the destruction. Remember to set this back to false when we are done. That way if the attempt
+ // failed and the process stays around for some reason it won't be in a confused state.
+
+ m_destroy_in_process = true;
+
Error error (WillDestroy());
if (error.Success())
{
@@ -3234,6 +3355,7 @@
{
// If we exited when we were waiting for a process to stop, then
// forward the event here so we don't lose the event
+ m_destroy_in_process = false;
return error;
}
}
@@ -3242,6 +3364,7 @@
{
if (log)
log->Printf("Process::Destroy() Halt got error: %s", error.AsCString());
+ m_destroy_in_process = false;
return error;
}
}
@@ -3283,6 +3406,9 @@
// it here so when we do to tear down the process we don't get an error destroying the lock.
m_run_lock.WriteUnlock();
}
+
+ m_destroy_in_process = false;
+
return error;
}
@@ -3317,8 +3443,8 @@
{
const StateType state = Process::ProcessEventData::GetStateFromEvent (event_ptr);
bool return_value = true;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
-
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS | LIBLLDB_LOG_PROCESS));
+
switch (state)
{
case eStateConnected:
@@ -3343,7 +3469,7 @@
// stopped -> running: Report except when there is one or more no votes
// and no yes votes.
SynchronouslyNotifyStateChanged (state);
- switch (m_public_state.GetValue())
+ switch (m_last_broadcast_state)
{
case eStateRunning:
case eStateStepping:
@@ -3361,7 +3487,6 @@
// This is a transition from stop to run.
switch (m_thread_list.ShouldReportRun (event_ptr))
{
- default:
case eVoteYes:
case eVoteNoOpinion:
return_value = true;
@@ -3386,32 +3511,50 @@
if (ProcessEventData::GetInterruptedFromEvent (event_ptr))
{
if (log)
- log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s", event_ptr, StateAsCString(state));
- return true;
+ log->Printf ("Process::ShouldBroadcastEvent (%p) stopped due to an interrupt, state: %s",
+ event_ptr,
+ StateAsCString(state));
+ return_value = true;
}
else
{
-
- if (m_thread_list.ShouldStop (event_ptr) == false)
+ // It makes no sense to ask "ShouldStop" if we've already been restarted...
+ // Asking the thread list is also not likely to go well, since we are running again.
+ // So in that case just report the event.
+
+ bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr);
+ bool should_resume = false;
+ if (!was_restarted)
+ should_resume = m_thread_list.ShouldStop (event_ptr) == false;
+ if (was_restarted || should_resume)
{
- // ShouldStop may have restarted the target already. If so, don't
- // resume it twice.
- bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr);
- switch (m_thread_list.ShouldReportStop (event_ptr))
+ Vote stop_vote = m_thread_list.ShouldReportStop (event_ptr);
+ if (log)
+ log->Printf ("Process::ShouldBroadcastEvent: should_stop: %i state: %s was_restarted: %i stop_vote: %d.",
+ should_resume,
+ StateAsCString(state),
+ was_restarted,
+ stop_vote);
+
+ switch (stop_vote)
{
case eVoteYes:
- Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
- // Intentional fall-through here.
+ return_value = true;
+ break;
case eVoteNoOpinion:
case eVoteNo:
return_value = false;
break;
}
-
- if (log)
- log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process from state: %s", event_ptr, StateAsCString(state));
+
if (!was_restarted)
+ {
+ if (log)
+ log->Printf ("Process::ShouldBroadcastEvent (%p) Restarting process from state: %s", event_ptr, StateAsCString(state));
+ ProcessEventData::SetRestartedInEvent(event_ptr, true);
PrivateResume ();
+ }
+
}
else
{
@@ -3420,10 +3563,25 @@
}
}
}
+ break;
}
-
+
+ // We do some coalescing of events (for instance two consecutive running events get coalesced.)
+ // But we only coalesce against events we actually broadcast. So we use m_last_broadcast_state
+ // to track that. NB - you can't use "m_public_state.GetValue()" for that purpose, as was originally done,
+ // because the PublicState reflects the last event pulled off the queue, and there may be several
+ // events stacked up on the queue unserviced. So the PublicState may not reflect the last broadcasted event
+ // yet. m_last_broadcast_state gets updated here.
+
+ if (return_value)
+ m_last_broadcast_state = state;
+
if (log)
- log->Printf ("Process::ShouldBroadcastEvent (%p) => %s - %s", event_ptr, StateAsCString(state), return_value ? "YES" : "NO");
+ log->Printf ("Process::ShouldBroadcastEvent (%p) => new state: %s, last broadcast state: %s - %s",
+ event_ptr,
+ StateAsCString(state),
+ StateAsCString(m_last_broadcast_state),
+ return_value ? "YES" : "NO");
return return_value;
}
@@ -3444,9 +3602,9 @@
// events make it to clients (into the DCProcess event queue).
char thread_name[1024];
if (already_running)
- snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state-override(pid=%llu)>", GetID());
+ snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state-override(pid=%" PRIu64 ")>", GetID());
else
- snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%llu)>", GetID());
+ snprintf(thread_name, sizeof(thread_name), "<lldb.process.internal-state(pid=%" PRIu64 ")>", GetID());
// Create the private state thread, and start it running.
m_private_state_thread = Host::ThreadCreate (thread_name, Process::PrivateStateThread, this, NULL);
@@ -3481,7 +3639,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
- printf ("Went to stop the private state thread, but it was already invalid.");
+ log->Printf ("Went to stop the private state thread, but it was already invalid.");
}
}
@@ -3563,6 +3721,9 @@
if (m_next_event_action_ap.get() != NULL)
{
NextEventAction::EventActionResult action_result = m_next_event_action_ap->PerformAction(event_sp);
+ if (log)
+ log->Printf ("Ran next event action, result was %d.", action_result);
+
switch (action_result)
{
case NextEventAction::eEventActionSuccess:
@@ -3595,7 +3756,7 @@
{
if (log)
{
- log->Printf ("Process::%s (pid = %llu) broadcasting new state %s (old state %s) to %s",
+ log->Printf ("Process::%s (pid = %" PRIu64 ") broadcasting new state %s (old state %s) to %s",
__FUNCTION__,
GetID(),
StateAsCString(new_state),
@@ -3614,7 +3775,7 @@
{
if (log)
{
- log->Printf ("Process::%s (pid = %llu) suppressing state %s (old state %s): should_broadcast == false",
+ log->Printf ("Process::%s (pid = %" PRIu64 ") suppressing state %s (old state %s): should_broadcast == false",
__FUNCTION__,
GetID(),
StateAsCString(new_state),
@@ -3640,7 +3801,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::%s (arg = %p, pid = %llu) thread starting...", __FUNCTION__, this, GetID());
+ log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, this, GetID());
bool exit_now = false;
while (!exit_now)
@@ -3650,7 +3811,7 @@
if (event_sp->BroadcasterIs(&m_private_state_control_broadcaster))
{
if (log)
- log->Printf ("Process::%s (arg = %p, pid = %llu) got a control event: %d", __FUNCTION__, this, GetID(), event_sp->GetType());
+ log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") got a control event: %d", __FUNCTION__, this, GetID(), event_sp->GetType());
switch (event_sp->GetType())
{
@@ -3675,13 +3836,13 @@
if (m_public_state.GetValue() == eStateAttaching)
{
if (log)
- log->Printf ("Process::%s (arg = %p, pid = %llu) woke up with an interrupt while attaching - forwarding interrupt.", __FUNCTION__, this, GetID());
+ log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt while attaching - forwarding interrupt.", __FUNCTION__, this, GetID());
BroadcastEvent (eBroadcastBitInterrupt, NULL);
}
else
{
if (log)
- log->Printf ("Process::%s (arg = %p, pid = %llu) woke up with an interrupt - Halting.", __FUNCTION__, this, GetID());
+ log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") woke up with an interrupt - Halting.", __FUNCTION__, this, GetID());
Halt();
}
continue;
@@ -3699,7 +3860,7 @@
internal_state == eStateDetached )
{
if (log)
- log->Printf ("Process::%s (arg = %p, pid = %llu) about to exit with internal state %s...", __FUNCTION__, this, GetID(), StateAsCString(internal_state));
+ log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") about to exit with internal state %s...", __FUNCTION__, this, GetID(), StateAsCString(internal_state));
break;
}
@@ -3707,7 +3868,7 @@
// Verify log is still enabled before attempting to write to it...
if (log)
- log->Printf ("Process::%s (arg = %p, pid = %llu) thread exiting...", __FUNCTION__, this, GetID());
+ log->Printf ("Process::%s (arg = %p, pid = %" PRIu64 ") thread exiting...", __FUNCTION__, this, GetID());
m_private_state_control_wait.SetValue (true, eBroadcastAlways);
m_private_state_thread = LLDB_INVALID_HOST_THREAD;
@@ -3767,7 +3928,7 @@
if (m_update_state != 1)
return;
-
+
m_process_sp->SetPublicState (m_state);
// If we're stopped and haven't restarted, then do the breakpoint commands here:
@@ -3789,7 +3950,11 @@
for (idx = 0; idx < num_threads; ++idx)
thread_index_array[idx] = curr_thread_list.GetThreadAtIndex(idx)->GetIndexID();
- bool still_should_stop = true;
+ // Use this to track whether we should continue from here. We will only continue the target running if
+ // no thread says we should stop. Of course if some thread's PerformAction actually sets the target running,
+ // then it doesn't matter what the other threads say...
+
+ bool still_should_stop = false;
for (idx = 0; idx < num_threads; ++idx)
{
@@ -3818,22 +3983,31 @@
StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
if (stop_info_sp && stop_info_sp->IsValid())
{
- stop_info_sp->PerformAction(event_ptr);
- // The stop action might restart the target. If it does, then we want to mark that in the
- // event so that whoever is receiving it will know to wait for the running event and reflect
- // that state appropriately.
- // We also need to stop processing actions, since they aren't expecting the target to be running.
-
- // FIXME: we might have run.
- if (stop_info_sp->HasTargetRunSinceMe())
+ bool this_thread_wants_to_stop;
+ if (stop_info_sp->GetOverrideShouldStop())
{
- SetRestarted (true);
- break;
+ this_thread_wants_to_stop = stop_info_sp->GetOverriddenShouldStopValue();
}
- else if (!stop_info_sp->ShouldStop(event_ptr))
+ else
{
- still_should_stop = false;
+ stop_info_sp->PerformAction(event_ptr);
+ // The stop action might restart the target. If it does, then we want to mark that in the
+ // event so that whoever is receiving it will know to wait for the running event and reflect
+ // that state appropriately.
+ // We also need to stop processing actions, since they aren't expecting the target to be running.
+
+ // FIXME: we might have run.
+ if (stop_info_sp->HasTargetRunSinceMe())
+ {
+ SetRestarted (true);
+ break;
+ }
+
+ this_thread_wants_to_stop = stop_info_sp->ShouldStop(event_ptr);
}
+
+ if (still_should_stop == false)
+ still_should_stop = this_thread_wants_to_stop;
}
}
@@ -3846,7 +4020,7 @@
SetRestarted(true);
// Use the public resume method here, since this is just
// extending a public resume.
- m_process_sp->Resume();
+ m_process_sp->PrivateResume();
}
else
{
@@ -3857,7 +4031,6 @@
SetRestarted(true);
}
}
-
}
}
@@ -3865,7 +4038,7 @@
Process::ProcessEventData::Dump (Stream *s) const
{
if (m_process_sp)
- s->Printf(" process = %p (pid = %llu), ", m_process_sp.get(), m_process_sp->GetID());
+ s->Printf(" process = %p (pid = %" PRIu64 "), ", m_process_sp.get(), m_process_sp->GetID());
s->Printf("state = %s", StateAsCString(GetState()));
}
@@ -3920,6 +4093,34 @@
data->SetRestarted(new_value);
}
+size_t
+Process::ProcessEventData::GetNumRestartedReasons(const Event *event_ptr)
+{
+ ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+ if (data != NULL)
+ return data->GetNumRestartedReasons();
+ else
+ return 0;
+}
+
+const char *
+Process::ProcessEventData::GetRestartedReasonAtIndex(const Event *event_ptr, size_t idx)
+{
+ ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+ if (data != NULL)
+ return data->GetRestartedReasonAtIndex(idx);
+ else
+ return NULL;
+}
+
+void
+Process::ProcessEventData::AddRestartedReason (Event *event_ptr, const char *reason)
+{
+ ProcessEventData *data = const_cast<ProcessEventData *>(GetEventDataFromEvent (event_ptr));
+ if (data != NULL)
+ data->AddRestartedReason(reason);
+}
+
bool
Process::ProcessEventData::GetInterruptedFromEvent (const Event *event_ptr)
{
@@ -3999,6 +4200,43 @@
BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState()));
}
+void
+Process::BroadcastAsyncProfileData(const char *s, size_t len)
+{
+ Mutex::Locker locker (m_profile_data_comm_mutex);
+ m_profile_data.push_back(s);
+ BroadcastEventIfUnique (eBroadcastBitProfileData, new ProcessEventData (shared_from_this(), GetState()));
+}
+
+size_t
+Process::GetAsyncProfileData (char *buf, size_t buf_size, Error &error)
+{
+ Mutex::Locker locker(m_profile_data_comm_mutex);
+ if (m_profile_data.empty())
+ return 0;
+
+ size_t bytes_available = m_profile_data.front().size();
+ if (bytes_available > 0)
+ {
+ LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ if (log)
+ log->Printf ("Process::GetProfileData (buf = %p, size = %" PRIu64 ")", buf, (uint64_t)buf_size);
+ if (bytes_available > buf_size)
+ {
+ memcpy(buf, m_profile_data.front().data(), buf_size);
+ m_profile_data.front().erase(0, buf_size);
+ bytes_available = buf_size;
+ }
+ else
+ {
+ memcpy(buf, m_profile_data.front().data(), bytes_available);
+ m_profile_data.erase(m_profile_data.begin());
+ }
+ }
+ return bytes_available;
+}
+
+
//------------------------------------------------------------------
// Process STDIO
//------------------------------------------------------------------
@@ -4012,7 +4250,7 @@
{
LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::GetSTDOUT (buf = %p, size = %llu)", buf, (uint64_t)buf_size);
+ log->Printf ("Process::GetSTDOUT (buf = %p, size = %" PRIu64 ")", buf, (uint64_t)buf_size);
if (bytes_available > buf_size)
{
memcpy(buf, m_stdout_data.c_str(), buf_size);
@@ -4038,7 +4276,7 @@
{
LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::GetSTDERR (buf = %p, size = %llu)", buf, (uint64_t)buf_size);
+ log->Printf ("Process::GetSTDERR (buf = %p, size = %" PRIu64 ")", buf, (uint64_t)buf_size);
if (bytes_available > buf_size)
{
memcpy(buf, m_stderr_data.c_str(), buf_size);
@@ -4209,7 +4447,8 @@
lldb::ThreadPlanSP &thread_plan_sp,
bool stop_others,
bool run_others,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
uint32_t timeout_usec,
Stream &errors)
{
@@ -4249,7 +4488,19 @@
// Save the thread & frame from the exe_ctx for restoration after we run
const uint32_t thread_idx_id = thread->GetIndexID();
- StackID ctx_frame_id = thread->GetSelectedFrame()->GetStackID();
+ StackFrameSP selected_frame_sp = thread->GetSelectedFrame();
+ if (!selected_frame_sp)
+ {
+ thread->SetSelectedFrame(0);
+ selected_frame_sp = thread->GetSelectedFrame();
+ if (!selected_frame_sp)
+ {
+ errors.Printf("RunThreadPlan called without a selected frame on thread %d", thread_idx_id);
+ return eExecutionSetupError;
+ }
+ }
+
+ StackID ctx_frame_id = selected_frame_sp->GetStackID();
// N.B. Running the target may unset the currently selected thread and frame. We don't want to do that either,
// so we should arrange to reset them as well.
@@ -4280,7 +4531,7 @@
// The simplest thing to do is to spin up a temporary thread to handle private state thread events while
// we are fielding public events here.
if (log)
- log->Printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.");
+ log->Printf ("Running thread plan on private state thread, spinning up another state thread to handle the events.");
backup_private_state_thread = m_private_state_thread;
@@ -4320,7 +4571,7 @@
{
StreamString s;
thread_plan_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
- log->Printf ("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4llx to run thread plan \"%s\".",
+ log->Printf ("Process::RunThreadPlan(): Resuming thread %u - 0x%4.4" PRIx64 " to run thread plan \"%s\".",
thread->GetIndexID(),
thread->GetID(),
s.GetData());
@@ -4333,52 +4584,111 @@
TimeValue* timeout_ptr = NULL;
TimeValue real_timeout;
- bool first_timeout = true;
+ bool before_first_timeout = true; // This is set to false the first time that we have to halt the target.
bool do_resume = true;
+ bool handle_running_event = true;
const uint64_t default_one_thread_timeout_usec = 250000;
- uint64_t computed_timeout = 0;
+
+ // This is just for accounting:
+ uint32_t num_resumes = 0;
+
+ TimeValue one_thread_timeout = TimeValue::Now();
+ TimeValue final_timeout = one_thread_timeout;
+
+ if (run_others)
+ {
+ // If we are running all threads then we take half the time to run all threads, bounded by
+ // .25 sec.
+ if (timeout_usec == 0)
+ one_thread_timeout.OffsetWithMicroSeconds(default_one_thread_timeout_usec);
+ else
+ {
+ uint64_t computed_timeout = computed_timeout = timeout_usec / 2;
+ if (computed_timeout > default_one_thread_timeout_usec)
+ computed_timeout = default_one_thread_timeout_usec;
+ one_thread_timeout.OffsetWithMicroSeconds(computed_timeout);
+ }
+ final_timeout.OffsetWithMicroSeconds (timeout_usec);
+ }
+ else
+ {
+ if (timeout_usec != 0)
+ final_timeout.OffsetWithMicroSeconds(timeout_usec);
+ }
+
+ // This while loop must exit out the bottom, there's cleanup that we need to do when we are done.
+ // So don't call return anywhere within it.
while (1)
{
// We usually want to resume the process if we get to the top of the loop.
// The only exception is if we get two running events with no intervening
// stop, which can happen, we will just wait for then next stop event.
+ if (log)
+ log->Printf ("Top of while loop: do_resume: %i handle_running_event: %i before_first_timeout: %i.",
+ do_resume,
+ handle_running_event,
+ before_first_timeout);
- if (do_resume)
+ if (do_resume || handle_running_event)
{
// Do the initial resume and wait for the running event before going further.
- Error resume_error = PrivateResume ();
- if (!resume_error.Success())
+ if (do_resume)
{
- errors.Printf("Error resuming inferior: \"%s\".\n", resume_error.AsCString());
- return_value = eExecutionSetupError;
- break;
+ num_resumes++;
+ Error resume_error = PrivateResume ();
+ if (!resume_error.Success())
+ {
+ errors.Printf("Error resuming inferior the %d time: \"%s\".\n",
+ num_resumes,
+ resume_error.AsCString());
+ return_value = eExecutionSetupError;
+ break;
+ }
}
-
- real_timeout = TimeValue::Now();
- real_timeout.OffsetWithMicroSeconds(500000);
- timeout_ptr = &real_timeout;
- got_event = listener.WaitForEvent(timeout_ptr, event_sp);
+ TimeValue resume_timeout = TimeValue::Now();
+ resume_timeout.OffsetWithMicroSeconds(500000);
+
+ got_event = listener.WaitForEvent(&resume_timeout, event_sp);
if (!got_event)
{
if (log)
- log->PutCString("Process::RunThreadPlan(): didn't get any event after initial resume, exiting.");
+ log->Printf ("Process::RunThreadPlan(): didn't get any event after resume %d, exiting.",
+ num_resumes);
- errors.Printf("Didn't get any event after initial resume, exiting.");
+ errors.Printf("Didn't get any event after resume %d, exiting.", num_resumes);
return_value = eExecutionSetupError;
break;
}
stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+
if (stop_state != eStateRunning)
{
- if (log)
- log->Printf("Process::RunThreadPlan(): didn't get running event after "
- "initial resume, got %s instead.",
- StateAsCString(stop_state));
-
+ bool restarted = false;
+
+ if (stop_state == eStateStopped)
+ {
+ restarted = Process::ProcessEventData::GetRestartedFromEvent(event_sp.get());
+ if (log)
+ log->Printf("Process::RunThreadPlan(): didn't get running event after "
+ "resume %d, got %s instead (restarted: %i, do_resume: %i, handle_running_event: %i).",
+ num_resumes,
+ StateAsCString(stop_state),
+ restarted,
+ do_resume,
+ handle_running_event);
+ }
+
+ if (restarted)
+ {
+ // This is probably an overabundance of caution, I don't think I should ever get a stopped & restarted
+ // event here. But if I do, the best thing is to Halt and then get out of here.
+ Halt();
+ }
+
errors.Printf("Didn't get running event after initial resume, got %s instead.",
StateAsCString(stop_state));
return_value = eExecutionSetupError;
@@ -4392,54 +4702,35 @@
// won't be able to gather the result at this point.
// We set the timeout AFTER the resume, since the resume takes some time and we
// don't want to charge that to the timeout.
-
- if (first_timeout)
- {
- if (run_others)
- {
- // If we are running all threads then we take half the time to run all threads, bounded by
- // .25 sec.
- if (timeout_usec == 0)
- computed_timeout = default_one_thread_timeout_usec;
- else
- {
- computed_timeout = timeout_usec / 2;
- if (computed_timeout > default_one_thread_timeout_usec)
- {
- computed_timeout = default_one_thread_timeout_usec;
- }
- timeout_usec -= computed_timeout;
- }
- }
- else
- {
- computed_timeout = timeout_usec;
- }
- }
- else
- {
- computed_timeout = timeout_usec;
- }
-
- if (computed_timeout != 0)
- {
- // we have a > 0 timeout, let us set it so that we stop after the deadline
- real_timeout = TimeValue::Now();
- real_timeout.OffsetWithMicroSeconds(computed_timeout);
+ }
+ else
+ {
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): waiting for next event.");
+ }
- timeout_ptr = &real_timeout;
- }
+ if (before_first_timeout)
+ {
+ if (run_others)
+ timeout_ptr = &one_thread_timeout;
else
{
- timeout_ptr = NULL;
+ if (timeout_usec == 0)
+ timeout_ptr = NULL;
+ else
+ timeout_ptr = &final_timeout;
}
}
else
{
- if (log)
- log->PutCString ("Process::RunThreadPlan(): handled an extra running event.");
- do_resume = true;
+ if (timeout_usec == 0)
+ timeout_ptr = NULL;
+ else
+ timeout_ptr = &final_timeout;
}
+
+ do_resume = true;
+ handle_running_event = true;
// Now wait for the process to stop again:
event_sp.reset();
@@ -4448,12 +4739,9 @@
{
if (timeout_ptr)
{
- StreamString s;
- s.Printf ("about to wait - timeout is:\n ");
- timeout_ptr->Dump (&s, 120);
- s.Printf ("\nNow is:\n ");
- TimeValue::Now().Dump (&s, 120);
- log->Printf ("Process::RunThreadPlan(): %s", s.GetData());
+ log->Printf ("Process::RunThreadPlan(): about to wait - now is %" PRIu64 " - endpoint is %" PRIu64,
+ TimeValue::Now().GetAsMicroSecondsSinceJan1_1970(),
+ timeout_ptr->GetAsMicroSecondsSinceJan1_1970());
}
else
{
@@ -4471,11 +4759,11 @@
if (event_sp->GetType() == eBroadcastBitInterrupt)
{
Halt();
- keep_going = false;
return_value = eExecutionInterrupted;
errors.Printf ("Execution halted by user interrupt.");
if (log)
log->Printf ("Process::RunThreadPlan(): Got interrupted by eBroadcastBitInterrupted, exiting.");
+ break;
}
else
{
@@ -4487,7 +4775,7 @@
{
case lldb::eStateStopped:
{
- // Yay, we're done. Now make sure that our thread plan actually completed.
+ // We stopped, figure out what we are going to do now.
ThreadSP thread_sp = GetThreadList().FindThreadByIndexID (thread_idx_id);
if (!thread_sp)
{
@@ -4498,40 +4786,66 @@
}
else
{
- StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
- StopReason stop_reason = eStopReasonInvalid;
- if (stop_info_sp)
- stop_reason = stop_info_sp->GetStopReason();
- if (stop_reason == eStopReasonPlanComplete)
+ // If we were restarted, we just need to go back up to fetch another event.
+ if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
{
if (log)
- log->PutCString ("Process::RunThreadPlan(): execution completed successfully.");
- // Now mark this plan as private so it doesn't get reported as the stop reason
- // after this point.
- if (thread_plan_sp)
- thread_plan_sp->SetPrivate (orig_plan_private);
- return_value = eExecutionCompleted;
+ {
+ log->Printf ("Process::RunThreadPlan(): Got a stop and restart, so we'll continue waiting.");
+ }
+ keep_going = true;
+ do_resume = false;
+ handle_running_event = true;
+
}
else
{
- if (log)
- log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
-
- return_value = eExecutionInterrupted;
+
+ StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
+ StopReason stop_reason = eStopReasonInvalid;
+ if (stop_info_sp)
+ stop_reason = stop_info_sp->GetStopReason();
+
+
+ // FIXME: We only check if the stop reason is plan complete, should we make sure that
+ // it is OUR plan that is complete?
+ if (stop_reason == eStopReasonPlanComplete)
+ {
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): execution completed successfully.");
+ // Now mark this plan as private so it doesn't get reported as the stop reason
+ // after this point.
+ if (thread_plan_sp)
+ thread_plan_sp->SetPrivate (orig_plan_private);
+ return_value = eExecutionCompleted;
+ }
+ else
+ {
+ // Something restarted the target, so just wait for it to stop for real.
+ if (stop_reason == eStopReasonBreakpoint)
+ {
+ if (log)
+ log->Printf ("Process::RunThreadPlan() stopped for breakpoint: %s.", stop_info_sp->GetDescription());
+ return_value = eExecutionHitBreakpoint;
+ }
+ else
+ {
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): thread plan didn't successfully complete.");
+ return_value = eExecutionInterrupted;
+ }
+ }
}
}
}
break;
- case lldb::eStateCrashed:
- if (log)
- log->PutCString ("Process::RunThreadPlan(): execution crashed.");
- return_value = eExecutionInterrupted;
- break;
-
case lldb::eStateRunning:
+ // This shouldn't really happen, but sometimes we do get two running events without an
+ // intervening stop, and in that case we should just go back to waiting for the stop.
do_resume = false;
keep_going = true;
+ handle_running_event = false;
break;
default:
@@ -4565,15 +4879,15 @@
// If we didn't get an event that means we've timed out...
// We will interrupt the process here. Depending on what we were asked to do we will
// either exit, or try with all threads running for the same timeout.
- // Not really sure what to do if Halt fails here...
if (log) {
if (run_others)
{
- if (first_timeout)
- log->Printf ("Process::RunThreadPlan(): Running function with timeout: %lld timed out, "
- "trying for %d usec with all threads enabled.",
- computed_timeout, timeout_usec);
+ uint64_t remaining_time = final_timeout - TimeValue::Now();
+ if (before_first_timeout)
+ log->Printf ("Process::RunThreadPlan(): Running function with one thread timeout timed out, "
+ "running till for %" PRId64 " usec with all threads enabled.",
+ remaining_time);
else
log->Printf ("Process::RunThreadPlan(): Restarting function with all threads enabled "
"and timeout: %d timed out, abandoning execution.",
@@ -4585,150 +4899,123 @@
timeout_usec);
}
- Error halt_error = Halt();
- if (halt_error.Success())
- {
- if (log)
- log->PutCString ("Process::RunThreadPlan(): Halt succeeded.");
-
- // If halt succeeds, it always produces a stopped event. Wait for that:
-
- real_timeout = TimeValue::Now();
- real_timeout.OffsetWithMicroSeconds(500000);
-
- got_event = listener.WaitForEvent(&real_timeout, event_sp);
-
- if (got_event)
- {
- stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
- if (log)
- {
- log->Printf ("Process::RunThreadPlan(): Stopped with event: %s", StateAsCString(stop_state));
- if (stop_state == lldb::eStateStopped
- && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
- log->PutCString (" Event was the Halt interruption event.");
- }
-
- if (stop_state == lldb::eStateStopped)
- {
- // Between the time we initiated the Halt and the time we delivered it, the process could have
- // already finished its job. Check that here:
-
- if (thread->IsThreadPlanDone (thread_plan_sp.get()))
- {
- if (log)
- log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done. "
- "Exiting wait loop.");
- return_value = eExecutionCompleted;
- break;
- }
-
- if (!run_others)
- {
- if (log)
- log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
- return_value = eExecutionInterrupted;
- break;
- }
-
- if (first_timeout)
- {
- // Set all the other threads to run, and return to the top of the loop, which will continue;
- first_timeout = false;
- thread_plan_sp->SetStopOthers (false);
- if (log)
- log->PutCString ("Process::RunThreadPlan(): about to resume.");
-
- continue;
- }
- else
- {
- // Running all threads failed, so return Interrupted.
- if (log)
- log->PutCString("Process::RunThreadPlan(): running all threads timed out.");
- return_value = eExecutionInterrupted;
- break;
- }
- }
- }
- else
- { if (log)
- log->PutCString("Process::RunThreadPlan(): halt said it succeeded, but I got no event. "
- "I'm getting out of here passing Interrupted.");
- return_value = eExecutionInterrupted;
- break;
- }
- }
- else
+ // It is possible that between the time we issued the Halt, and we get around to calling Halt the target
+ // could have stopped. That's fine, Halt will figure that out and send the appropriate Stopped event.
+ // BUT it is also possible that we stopped & restarted (e.g. hit a signal with "stop" set to false.) In
+ // that case, we'll get the stopped & restarted event, and we should go back to waiting for the Halt's
+ // stopped event. That's what this while loop does.
+
+ bool back_to_top = true;
+ uint32_t try_halt_again = 0;
+ bool do_halt = true;
+ const uint32_t num_retries = 5;
+ while (try_halt_again < num_retries)
{
- // This branch is to work around some problems with gdb-remote's Halt. It is a little racy, and can return
- // an error from halt, but if you wait a bit you'll get a stopped event anyway.
- if (log)
- log->Printf ("Process::RunThreadPlan(): halt failed: error = \"%s\", I'm just going to wait a little longer and see if I get a stopped event.",
- halt_error.AsCString());
- real_timeout = TimeValue::Now();
- real_timeout.OffsetWithMicroSeconds(500000);
- timeout_ptr = &real_timeout;
- got_event = listener.WaitForEvent(&real_timeout, event_sp);
- if (!got_event || event_sp.get() == NULL)
+ Error halt_error;
+ if (do_halt)
{
- // This is not going anywhere, bag out.
if (log)
- log->PutCString ("Process::RunThreadPlan(): halt failed: and waiting for the stopped event failed.");
- return_value = eExecutionInterrupted;
- break;
+ log->Printf ("Process::RunThreadPlan(): Running Halt.");
+ halt_error = Halt();
}
- else
+ if (halt_error.Success())
{
- stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
if (log)
- log->PutCString ("Process::RunThreadPlan(): halt failed: but then I got a stopped event. Whatever...");
- if (stop_state == lldb::eStateStopped)
- {
- // Between the time we initiated the Halt and the time we delivered it, the process could have
- // already finished its job. Check that here:
+ log->PutCString ("Process::RunThreadPlan(): Halt succeeded.");
- if (thread->IsThreadPlanDone (thread_plan_sp.get()))
- {
- if (log)
- log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done. "
- "Exiting wait loop.");
- return_value = eExecutionCompleted;
- break;
- }
+ real_timeout = TimeValue::Now();
+ real_timeout.OffsetWithMicroSeconds(500000);
- if (first_timeout)
+ got_event = listener.WaitForEvent(&real_timeout, event_sp);
+
+ if (got_event)
+ {
+ stop_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+ if (log)
{
- // Set all the other threads to run, and return to the top of the loop, which will continue;
- first_timeout = false;
- thread_plan_sp->SetStopOthers (false);
- if (log)
- log->PutCString ("Process::RunThreadPlan(): About to resume.");
-
- continue;
+ log->Printf ("Process::RunThreadPlan(): Stopped with event: %s", StateAsCString(stop_state));
+ if (stop_state == lldb::eStateStopped
+ && Process::ProcessEventData::GetInterruptedFromEvent(event_sp.get()))
+ log->PutCString (" Event was the Halt interruption event.");
}
- else
+
+ if (stop_state == lldb::eStateStopped)
{
- // Running all threads failed, so return Interrupted.
- if (log)
- log->PutCString ("Process::RunThreadPlan(): running all threads timed out.");
- return_value = eExecutionInterrupted;
- break;
+ // Between the time we initiated the Halt and the time we delivered it, the process could have
+ // already finished its job. Check that here:
+
+ if (thread->IsThreadPlanDone (thread_plan_sp.get()))
+ {
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): Even though we timed out, the call plan was done. "
+ "Exiting wait loop.");
+ return_value = eExecutionCompleted;
+ back_to_top = false;
+ break;
+ }
+
+ if (Process::ProcessEventData::GetRestartedFromEvent(event_sp.get()))
+ {
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): Went to halt but got a restarted event, there must be an un-restarted stopped event so try again... "
+ "Exiting wait loop.");
+ try_halt_again++;
+ do_halt = false;
+ continue;
+ }
+
+ if (!run_others)
+ {
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): try_all_threads was false, we stopped so now we're quitting.");
+ return_value = eExecutionInterrupted;
+ back_to_top = false;
+ break;
+ }
+
+ if (before_first_timeout)
+ {
+ // Set all the other threads to run, and return to the top of the loop, which will continue;
+ before_first_timeout = false;
+ thread_plan_sp->SetStopOthers (false);
+ if (log)
+ log->PutCString ("Process::RunThreadPlan(): about to resume.");
+
+ back_to_top = true;
+ break;
+ }
+ else
+ {
+ // Running all threads failed, so return Interrupted.
+ if (log)
+ log->PutCString("Process::RunThreadPlan(): running all threads timed out.");
+ return_value = eExecutionInterrupted;
+ back_to_top = false;
+ break;
+ }
}
}
else
- {
- if (log)
- log->Printf ("Process::RunThreadPlan(): halt failed, I waited and didn't get"
- " a stopped event, instead got %s.", StateAsCString(stop_state));
+ { if (log)
+ log->PutCString("Process::RunThreadPlan(): halt said it succeeded, but I got no event. "
+ "I'm getting out of here passing Interrupted.");
return_value = eExecutionInterrupted;
- break;
+ back_to_top = false;
+ break;
}
}
+ else
+ {
+ try_halt_again++;
+ continue;
+ }
}
-
+
+ if (!back_to_top || try_halt_again > num_retries)
+ break;
+ else
+ continue;
}
-
} // END WAIT LOOP
// If we had to start up a temporary private state thread to run this thread plan, shut it down now.
@@ -4745,9 +5032,22 @@
}
+ // Restore the thread state if we are going to discard the plan execution. There are three cases where this
+ // could happen:
+ // 1) The execution successfully completed
+ // 2) We hit a breakpoint, and ignore_breakpoints was true
+ // 3) We got some other error, and discard_on_error was true
+ bool should_unwind = (return_value == eExecutionInterrupted && unwind_on_error)
+ || (return_value == eExecutionHitBreakpoint && ignore_breakpoints);
+
+ if (return_value == eExecutionCompleted
+ || should_unwind)
+ {
+ thread_plan_sp->RestoreThreadState();
+ }
// Now do some processing on the results of the run:
- if (return_value == eExecutionInterrupted)
+ if (return_value == eExecutionInterrupted || return_value == eExecutionHitBreakpoint)
{
if (log)
{
@@ -4812,11 +5112,11 @@
continue;
}
- ts.Printf("<0x%4.4llx ", thread->GetID());
+ ts.Printf("<0x%4.4" PRIx64 " ", thread->GetID());
RegisterContext *register_context = thread->GetRegisterContext().get();
if (register_context)
- ts.Printf("[ip 0x%llx] ", register_context->GetPC());
+ ts.Printf("[ip 0x%" PRIx64 "] ", register_context->GetPC());
else
ts.Printf("[ip unknown] ");
@@ -4840,7 +5140,7 @@
log->Printf("Process::RunThreadPlan(): execution interrupted: %s", s.GetData());
}
- if (discard_on_error && thread_plan_sp)
+ if (should_unwind && thread_plan_sp)
{
if (log)
log->Printf ("Process::RunThreadPlan: ExecutionInterrupted - discarding thread plans up to %p.", thread_plan_sp.get());
@@ -4858,7 +5158,7 @@
if (log)
log->PutCString("Process::RunThreadPlan(): execution set up error.");
- if (discard_on_error && thread_plan_sp)
+ if (unwind_on_error && thread_plan_sp)
{
thread->DiscardThreadPlansUpToPlan (thread_plan_sp);
thread_plan_sp->SetPrivate (orig_plan_private);
@@ -4882,10 +5182,10 @@
{
if (log)
log->PutCString("Process::RunThreadPlan(): thread plan stopped in mid course");
- if (discard_on_error && thread_plan_sp)
+ if (unwind_on_error && thread_plan_sp)
{
if (log)
- log->PutCString("Process::RunThreadPlan(): discarding thread plan 'cause discard_on_error is set.");
+ log->PutCString("Process::RunThreadPlan(): discarding thread plan 'cause unwind_on_error is set.");
thread->DiscardThreadPlansUpToPlan (thread_plan_sp);
thread_plan_sp->SetPrivate (orig_plan_private);
}
@@ -4944,6 +5244,9 @@
case eExecutionInterrupted:
result_name = "eExecutionInterrupted";
break;
+ case eExecutionHitBreakpoint:
+ result_name = "eExecutionHitBreakpoint";
+ break;
case eExecutionSetupError:
result_name = "eExecutionSetupError";
break;
@@ -4964,7 +5267,7 @@
{
int exit_status = GetExitStatus();
const char *exit_description = GetExitDescription();
- strm.Printf ("Process %llu exited with status = %i (0x%8.8x) %s\n",
+ strm.Printf ("Process %" PRIu64 " exited with status = %i (0x%8.8x) %s\n",
GetID(),
exit_status,
exit_status,
@@ -4975,12 +5278,12 @@
if (state == eStateConnected)
strm.Printf ("Connected to remote target.\n");
else
- strm.Printf ("Process %llu %s\n", GetID(), StateAsCString (state));
+ strm.Printf ("Process %" PRIu64 " %s\n", GetID(), StateAsCString (state));
}
}
else
{
- strm.Printf ("Process %llu is running.\n", GetID());
+ strm.Printf ("Process %" PRIu64 " is running.\n", GetID());
}
}
@@ -5059,3 +5362,22 @@
{
m_thread_list.Flush();
}
+
+void
+Process::DidExec ()
+{
+ Target &target = GetTarget();
+ target.CleanupProcess ();
+ ModuleList unloaded_modules (target.GetImages());
+ target.ModulesDidUnload (unloaded_modules);
+ target.GetSectionLoadList().Clear();
+ m_dynamic_checkers_ap.reset();
+ m_abi_sp.reset();
+ m_os_ap.reset();
+ m_dyld_ap.reset();
+ m_image_tokens.clear();
+ m_allocated_memory_cache.Clear();
+ m_language_runtimes.clear();
+ DoDidExec();
+ CompleteAttach ();
+}
Index: aze/lldb/source/Target/SectionLoadList.cpp
===================================================================
--- aze.orig/lldb/source/Target/SectionLoadList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/SectionLoadList.cpp 2013-03-03 09:35:50.279457351 +0100
@@ -64,7 +64,7 @@
if (log)
{
const FileSpec &module_file_spec (section->GetModule()->GetFileSpec());
- log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16llx)",
+ log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16" PRIx64 ")",
__FUNCTION__,
section.get(),
module_file_spec.GetDirectory().AsCString(),
@@ -112,7 +112,7 @@
ModuleSP curr_module_sp (ats_pos->second->GetModule());
if (curr_module_sp)
{
- module_sp->ReportWarning ("address 0x%16.16llx maps to more than one section: %s.%s and %s.%s",
+ module_sp->ReportWarning ("address 0x%16.16" PRIx64 " maps to more than one section: %s.%s and %s.%s",
load_addr,
module_sp->GetFileSpec().GetFilename().GetCString(),
section->GetName().GetCString(),
@@ -155,6 +155,7 @@
sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
if (sta_pos != m_sect_to_addr.end())
{
+ ++unload_count;
addr_t load_addr = sta_pos->second;
m_sect_to_addr.erase (sta_pos);
@@ -174,7 +175,7 @@
if (log)
{
const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
- log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16llx)",
+ log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16" PRIx64 ")",
__FUNCTION__,
section_sp.get(),
module_file_spec.GetDirectory().AsCString(),
@@ -215,9 +216,10 @@
{
if (load_addr != pos->first && pos != m_addr_to_sect.begin())
--pos;
- if (load_addr >= pos->first)
+ const addr_t pos_load_addr = pos->first;
+ if (load_addr >= pos_load_addr)
{
- addr_t offset = load_addr - pos->first;
+ addr_t offset = load_addr - pos_load_addr;
if (offset < pos->second->GetByteSize())
{
// We have found the top level section, now we need to find the
@@ -254,7 +256,7 @@
addr_to_sect_collection::const_iterator pos, end;
for (pos = m_addr_to_sect.begin(), end = m_addr_to_sect.end(); pos != end; ++pos)
{
- s.Printf("addr = 0x%16.16llx, section = %p: ", pos->first, pos->second.get());
+ s.Printf("addr = 0x%16.16" PRIx64 ", section = %p: ", pos->first, pos->second.get());
pos->second->Dump (&s, target, 0);
}
}
Index: aze/lldb/source/Target/StackFrame.cpp
===================================================================
--- aze.orig/lldb/source/Target/StackFrame.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/StackFrame.cpp 2013-03-03 09:35:50.279457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Target/StackFrame.h"
// C Includes
@@ -248,7 +250,7 @@
StackFrame::ChangePC (addr_t pc)
{
m_frame_code_addr.SetRawAddress(pc);
- m_sc.Clear();
+ m_sc.Clear(false);
m_flags.Reset(0);
ThreadSP thread_sp (GetThread());
if (thread_sp)
@@ -264,9 +266,12 @@
Target *target = exe_ctx.GetTargetPtr();
if (target)
{
+ const char *plugin_name = NULL;
+ const char *flavor = NULL;
Disassembler::Disassemble (target->GetDebugger(),
target->GetArchitecture(),
- NULL,
+ plugin_name,
+ flavor,
exe_ctx,
0,
0,
@@ -317,6 +322,17 @@
// Copy our internal symbol context into "sc".
if ((m_flags.Get() & resolve_scope) != resolve_scope)
{
+ uint32_t resolved = 0;
+
+ // If the target was requested add that:
+ if (!m_sc.target_sp)
+ {
+ m_sc.target_sp = CalculateTarget();
+ if (m_sc.target_sp)
+ resolved |= eSymbolContextTarget;
+ }
+
+
// Resolve our PC to section offset if we haven't alreday done so
// and if we don't have a module. The resolved address section will
// contain the module to which it belongs
@@ -336,7 +352,6 @@
}
- uint32_t resolved = 0;
if (m_sc.module_sp)
{
// We have something in our stack frame symbol context, lets check
@@ -420,9 +435,18 @@
m_sc.block = sc.block;
if ((resolved & eSymbolContextSymbol) && m_sc.symbol == NULL)
m_sc.symbol = sc.symbol;
- if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
+ if ((resolved & eSymbolContextLineEntry) && !m_sc.line_entry.IsValid())
+ {
m_sc.line_entry = sc.line_entry;
-
+ if (m_sc.target_sp)
+ {
+ // Be sure to apply and file remappings to our file and line
+ // entries when handing out a line entry
+ FileSpec new_file_spec;
+ if (m_sc.target_sp->GetSourcePathMap().FindFile (m_sc.line_entry.file, new_file_spec))
+ m_sc.line_entry.file = new_file_spec;
+ }
+ }
}
}
else
@@ -430,17 +454,10 @@
// If we don't have a module, then we can't have the compile unit,
// function, block, line entry or symbol, so we can safely call
// ResolveSymbolContextForAddress with our symbol context member m_sc.
- TargetSP target_sp (CalculateTarget());
- if (target_sp)
- resolved |= target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
- }
-
- // If the target was requested add that:
- if (!m_sc.target_sp)
- {
- m_sc.target_sp = CalculateTarget();
if (m_sc.target_sp)
- resolved |= eSymbolContextTarget;
+ {
+ resolved |= m_sc.target_sp->GetImages().ResolveSymbolContextForAddress (lookup_addr, resolve_scope, m_sc);
+ }
}
// Update our internal flags so we remember what we have tried to locate so
@@ -780,6 +797,7 @@
deref = false;
}
+ bool is_incomplete_array = false;
if (valobj_sp->IsPointerType ())
{
bool is_objc_pointer = true;
@@ -843,11 +861,14 @@
}
}
}
- else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL))
+ else if (ClangASTContext::IsArrayType (valobj_sp->GetClangType(), NULL, NULL, &is_incomplete_array))
{
// Pass false to dynamic_value here so we can tell the difference between
// no dynamic value and no member of this type...
child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
+ if (!child_valobj_sp && (is_incomplete_array || no_synth_child == false))
+ child_valobj_sp = valobj_sp->GetSyntheticArrayMember (child_index, true);
+
if (!child_valobj_sp)
{
valobj_sp->GetExpressionPath (var_expr_path_strm, false);
@@ -1288,7 +1309,7 @@
strm->Printf("frame #%u: ", m_frame_index);
ExecutionContext exe_ctx (shared_from_this());
Target *target = exe_ctx.GetTargetPtr();
- strm->Printf("0x%0*llx ",
+ strm->Printf("0x%0*" PRIx64 " ",
target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16,
GetFrameCodeAddress().GetLoadAddress(target));
GetSymbolContext(eSymbolContextEverything);
@@ -1408,9 +1429,12 @@
AddressRange pc_range;
pc_range.GetBaseAddress() = GetFrameCodeAddress();
pc_range.SetByteSize(disasm_lines * target_arch.GetMaximumOpcodeByteSize());
+ const char *plugin_name = NULL;
+ const char *flavor = NULL;
Disassembler::Disassemble (target->GetDebugger(),
target_arch,
- NULL,
+ plugin_name,
+ flavor,
exe_ctx,
pc_range,
disasm_lines,
Index: aze/lldb/source/Target/StackFrameList.cpp
===================================================================
--- aze.orig/lldb/source/Target/StackFrameList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/StackFrameList.cpp 2013-03-03 09:35:50.279457351 +0100
@@ -147,6 +147,7 @@
{
case eStopReasonWatchpoint:
case eStopReasonException:
+ case eStopReasonExec:
case eStopReasonSignal:
// In all these cases we want to stop in the deepest most frame.
m_current_inlined_pc = curr_pc;
@@ -205,7 +206,7 @@
m_current_inlined_depth = num_inlined_functions + 1;
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
- log->Printf ("ResetCurrentInlinedDepth: setting inlined depth: %d 0x%llx.\n", m_current_inlined_depth, curr_pc);
+ log->Printf ("ResetCurrentInlinedDepth: setting inlined depth: %d 0x%" PRIx64 ".\n", m_current_inlined_depth, curr_pc);
}
break;
@@ -370,7 +371,7 @@
//curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth;
//curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc;
- //printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%llx.\n", curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);
+ //printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc);
#if defined (DEBUG_STACK_FRAMES)
s.PutCString("\nprev_frames:\n");
Index: aze/lldb/source/Target/StackID.cpp
===================================================================
--- aze.orig/lldb/source/Target/StackID.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/StackID.cpp 2013-03-03 09:35:50.279457351 +0100
@@ -24,14 +24,14 @@
void
StackID::Dump (Stream *s)
{
- s->Printf("StackID (pc = 0x%16.16llx, cfa = 0x%16.16llx, symbol_scope = %p", (uint64_t)m_pc, (uint64_t)m_cfa, m_symbol_scope);
+ s->Printf("StackID (pc = 0x%16.16" PRIx64 ", cfa = 0x%16.16" PRIx64 ", symbol_scope = %p", (uint64_t)m_pc, (uint64_t)m_cfa, m_symbol_scope);
if (m_symbol_scope)
{
SymbolContext sc;
m_symbol_scope->CalculateSymbolContext (&sc);
if (sc.block)
- s->Printf(" (Block {0x%8.8llx})", sc.block->GetID());
+ s->Printf(" (Block {0x%8.8" PRIx64 "})", sc.block->GetID());
else if (sc.symbol)
s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID());
}
Index: aze/lldb/source/Target/StopInfo.cpp
===================================================================
--- aze.orig/lldb/source/Target/StopInfo.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/StopInfo.cpp 2013-03-03 09:35:50.279457351 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Target/StopInfo.h"
// C Includes
@@ -36,7 +38,9 @@
m_thread (thread),
m_stop_id (thread.GetProcess()->GetStopID()),
m_resume_id (thread.GetProcess()->GetResumeID()),
- m_value (value)
+ m_value (value),
+ m_override_set(false),
+ m_override_value(true)
{
}
@@ -165,7 +169,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
+ log->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
m_should_stop = true;
}
@@ -204,6 +208,22 @@
if (bp_site_sp)
{
StreamString strm;
+ // If we have just hit an internal breakpoint, and it has a kind description, print that instead of the
+ // full breakpoint printing:
+ if (bp_site_sp->IsInternal())
+ {
+ size_t num_owners = bp_site_sp->GetNumberOfOwners();
+ for (size_t idx = 0; idx < num_owners; idx++)
+ {
+ const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind();
+ if (kind != NULL)
+ {
+ m_description.assign (kind);
+ return kind;
+ }
+ }
+ }
+
strm.Printf("breakpoint ");
bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
m_description.swap (strm.GetString());
@@ -213,15 +233,34 @@
StreamString strm;
if (m_break_id != LLDB_INVALID_BREAK_ID)
{
- if (m_was_one_shot)
- strm.Printf ("one-shot breakpoint %d", m_break_id);
+ BreakpointSP break_sp = m_thread.GetProcess()->GetTarget().GetBreakpointByID(m_break_id);
+ if (break_sp)
+ {
+ if (break_sp->IsInternal())
+ {
+ const char *kind = break_sp->GetBreakpointKind();
+ if (kind)
+ strm.Printf ("internal %s breakpoint(%d).", kind, m_break_id);
+ else
+ strm.Printf ("internal breakpoint(%d).", m_break_id);
+ }
+ else
+ {
+ strm.Printf ("breakpoint %d.", m_break_id);
+ }
+ }
else
- strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
+ {
+ if (m_was_one_shot)
+ strm.Printf ("one-shot breakpoint %d", m_break_id);
+ else
+ strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
+ }
}
else if (m_address == LLDB_INVALID_ADDRESS)
- strm.Printf("breakpoint site %lli which has been deleted - unknown address", m_value);
+ strm.Printf("breakpoint site %" PRIi64 " which has been deleted - unknown address", m_value);
else
- strm.Printf("breakpoint site %lli which has been deleted - was at 0x%llx", m_value, m_address);
+ strm.Printf("breakpoint site %" PRIi64 " which has been deleted - was at 0x%" PRIx64, m_value, m_address);
m_description.swap (strm.GetString());
}
@@ -273,6 +312,47 @@
m_should_stop = false;
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process->GetModIDRef().IsLastResumeForUserExpression())
+ {
+ // If we are in the middle of evaluating an expression, don't run asynchronous breakpoint commands or
+ // expressions. That could lead to infinite recursion if the command or condition re-calls the function
+ // with this breakpoint.
+ // TODO: We can keep a list of the breakpoints we've seen while running expressions in the nested
+ // PerformAction calls that can arise when the action runs a function that hits another breakpoint,
+ // and only stop running commands when we see the same breakpoint hit a second time.
+
+ m_should_stop_is_valid = true;
+ if (log)
+ log->Printf ("StopInfoBreakpoint::PerformAction - Hit a breakpoint while running an expression,"
+ " not running commands to avoid recursion.");
+ bool ignoring_breakpoints = process->GetIgnoreBreakpointsInExpressions();
+ if (ignoring_breakpoints)
+ {
+ m_should_stop = false;
+ // Internal breakpoints will always stop.
+ for (size_t j = 0; j < num_owners; j++)
+ {
+ lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
+ if (bp_loc_sp->GetBreakpoint().IsInternal())
+ {
+ m_should_stop = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ m_should_stop = true;
+ }
+ if (log)
+ log->Printf ("StopInfoBreakpoint::PerformAction - in expression, continuing: %s.",
+ m_should_stop ? "true" : "false");
+ process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: hit breakpoint while "
+ "running function, skipping commands and conditions to prevent recursion.");
+ return;
+ }
+
StoppointCallbackContext context (event_ptr, exe_ctx, false);
for (size_t j = 0; j < num_owners; j++)
@@ -292,13 +372,15 @@
ExecutionResults result_code;
ValueObjectSP result_value_sp;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
Error error;
result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
eExecutionPolicyOnlyWhenNeeded,
lldb::eLanguageTypeUnknown,
ClangUserExpression::eResultTypeAny,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
bp_loc_sp->GetConditionText(),
NULL,
result_value_sp,
@@ -397,7 +479,7 @@
LogSP log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log_process)
- log_process->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value);
+ log_process->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
}
if (log)
log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
@@ -433,8 +515,9 @@
{
if (process && watchpoint)
{
+ const bool notify = false;
watchpoint->TurnOnEphemeralMode();
- process->DisableWatchpoint(watchpoint);
+ process->DisableWatchpoint(watchpoint, notify);
}
}
~WatchpointSentry()
@@ -442,7 +525,10 @@
if (process && watchpoint)
{
if (!watchpoint->IsDisabledDuringEphemeralMode())
- process->EnableWatchpoint(watchpoint);
+ {
+ const bool notify = false;
+ process->EnableWatchpoint(watchpoint, notify);
+ }
watchpoint->TurnOffEphemeralMode();
}
}
@@ -475,7 +561,7 @@
if (m_description.empty())
{
StreamString strm;
- strm.Printf("watchpoint %lli", m_value);
+ strm.Printf("watchpoint %" PRIi64, m_value);
m_description.swap (strm.GetString());
}
return m_description.c_str();
@@ -483,7 +569,7 @@
protected:
virtual bool
- ShouldStop (Event *event_ptr)
+ ShouldStopSynchronous (Event *event_ptr)
{
// ShouldStop() method is idempotent and should not affect hit count.
// See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
@@ -509,7 +595,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
- log->Printf ("Process::%s could not find watchpoint location id: %lld...",
+ log->Printf ("Process::%s could not find watchpoint location id: %" PRId64 "...",
__FUNCTION__, GetValue());
m_should_stop = true;
@@ -518,6 +604,15 @@
return m_should_stop;
}
+ bool
+ ShouldStop (Event *event_ptr)
+ {
+ // This just reports the work done by PerformAction or the synchronous stop. It should
+ // only ever get called after they have had a chance to run.
+ assert (m_should_stop_is_valid);
+ return m_should_stop;
+ }
+
virtual void
PerformAction (Event *event_ptr)
{
@@ -569,13 +664,15 @@
// constructor errors up to the debugger's Async I/O.
ExecutionResults result_code;
ValueObjectSP result_value_sp;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
Error error;
result_code = ClangUserExpression::EvaluateWithError (exe_ctx,
eExecutionPolicyOnlyWhenNeeded,
lldb::eLanguageTypeUnknown,
ClangUserExpression::eResultTypeAny,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
wp_sp->GetConditionText(),
NULL,
result_value_sp,
@@ -666,11 +763,13 @@
LogSP log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log_process)
- log_process->Printf ("Process::%s could not find watchpoint id: %lld...", __FUNCTION__, m_value);
+ log_process->Printf ("Process::%s could not find watchpoint id: %" PRId64 "...", __FUNCTION__, m_value);
}
if (log)
log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
+ m_should_stop_is_valid = true;
+
}
private:
@@ -706,6 +805,12 @@
}
virtual bool
+ ShouldStopSynchronous (Event *event_ptr)
+ {
+ return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
+ }
+
+ virtual bool
ShouldStop (Event *event_ptr)
{
return m_thread.GetProcess()->GetUnixSignals().GetShouldStop (m_value);
@@ -716,7 +821,16 @@
virtual bool
ShouldNotify (Event *event_ptr)
{
- return m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
+ bool should_notify = m_thread.GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
+ if (should_notify)
+ {
+ StreamString strm;
+ strm.Printf ("thread %d received signal: %s",
+ m_thread.GetIndexID(),
+ m_thread.GetProcess()->GetUnixSignals().GetSignalAsCString (m_value));
+ Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData());
+ }
+ return should_notify;
}
@@ -737,7 +851,7 @@
if (signal_name)
strm.Printf("signal %s", signal_name);
else
- strm.Printf("signal %lli", m_value);
+ strm.Printf("signal %" PRIi64, m_value);
m_description.swap (strm.GetString());
}
return m_description.c_str();
@@ -857,11 +971,63 @@
{
return m_return_valobj_sp;
}
+
+protected:
+ virtual bool
+ ShouldStop (Event *event_ptr)
+ {
+ if (m_plan_sp)
+ return m_plan_sp->ShouldStop(event_ptr);
+ else
+ return StopInfo::ShouldStop(event_ptr);
+ }
private:
ThreadPlanSP m_plan_sp;
ValueObjectSP m_return_valobj_sp;
};
+
+class StopInfoExec : public StopInfo
+{
+public:
+
+ StopInfoExec (Thread &thread) :
+ StopInfo (thread, LLDB_INVALID_UID),
+ m_performed_action (false)
+ {
+ }
+
+ virtual
+ ~StopInfoExec ()
+ {
+ }
+
+ virtual StopReason
+ GetStopReason () const
+ {
+ return eStopReasonExec;
+ }
+
+ virtual const char *
+ GetDescription ()
+ {
+ return "exec";
+ }
+protected:
+
+ virtual void
+ PerformAction (Event *event_ptr)
+ {
+ // Only perform the action once
+ if (m_performed_action)
+ return;
+ m_performed_action = true;
+ m_thread.GetProcess()->DidExec();
+ }
+
+ bool m_performed_action;
+};
+
} // namespace lldb_private
StopInfoSP
@@ -906,6 +1072,12 @@
return StopInfoSP (new StopInfoException (thread, description));
}
+StopInfoSP
+StopInfo::CreateStopReasonWithExec (Thread &thread)
+{
+ return StopInfoSP (new StopInfoExec (thread));
+}
+
ValueObjectSP
StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
{
Index: aze/lldb/source/Target/Target.cpp
===================================================================
--- aze.orig/lldb/source/Target/Target.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/Target.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Target/Target.h"
// C Includes
@@ -86,12 +88,17 @@
SetEventName (eBroadcastBitBreakpointChanged, "breakpoint-changed");
SetEventName (eBroadcastBitModulesLoaded, "modules-loaded");
SetEventName (eBroadcastBitModulesUnloaded, "modules-unloaded");
+ SetEventName (eBroadcastBitWatchpointChanged, "watchpoint-changed");
CheckInWithManager();
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("%p Target::Target()", this);
+ if (m_arch.IsValid())
+ {
+ LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::Target created with architecture %s (%s)", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+ }
}
//----------------------------------------------------------------------
@@ -130,6 +137,21 @@
}
void
+Target::CleanupProcess ()
+{
+ // Do any cleanup of the target we need to do between process instances.
+ // NB It is better to do this before destroying the process in case the
+ // clean up needs some help from the process.
+ m_breakpoint_list.ClearAllBreakpointSites();
+ m_internal_breakpoint_list.ClearAllBreakpointSites();
+ // Disable watchpoints just on the debugger side.
+ Mutex::Locker locker;
+ this->GetWatchpointList().GetListMutex(locker);
+ DisableAllWatchpoints(false);
+ ClearAllWatchpointHitCounts();
+}
+
+void
Target::DeleteCurrentProcess ()
{
if (m_process_sp.get())
@@ -140,16 +162,8 @@
m_process_sp->Finalize();
- // Do any cleanup of the target we need to do between process instances.
- // NB It is better to do this before destroying the process in case the
- // clean up needs some help from the process.
- m_breakpoint_list.ClearAllBreakpointSites();
- m_internal_breakpoint_list.ClearAllBreakpointSites();
- // Disable watchpoints just on the debugger side.
- Mutex::Locker locker;
- this->GetWatchpointList().GetListMutex(locker);
- DisableAllWatchpoints(false);
- ClearAllWatchpointHitCounts();
+ CleanupProcess ();
+
m_process_sp.reset();
}
}
@@ -527,7 +541,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS));
if (log)
- log->Printf("Target::%s (addr = 0x%8.8llx size = %llu type = %u)\n",
+ log->Printf("Target::%s (addr = 0x%8.8" PRIx64 " size = %" PRIu64 " type = %u)\n",
__FUNCTION__, addr, (uint64_t)size, kind);
WatchpointSP wp_sp;
@@ -541,7 +555,7 @@
if (size == 0)
error.SetErrorString("cannot set a watchpoint with watch_size of 0");
else
- error.SetErrorStringWithFormat("invalid watch address: %llu", addr);
+ error.SetErrorStringWithFormat("invalid watch address: %" PRIu64, addr);
return wp_sp;
}
@@ -549,6 +563,7 @@
// of watchpoints limited by the hardware which the inferior is running on.
// Grab the list mutex while doing operations.
+ const bool notify = false; // Don't notify about all the state changes we do on creating the watchpoint.
Mutex::Locker locker;
this->GetWatchpointList().GetListMutex(locker);
WatchpointSP matched_sp = m_watchpoint_list.FindByAddress(addr);
@@ -561,36 +576,33 @@
// Return the existing watchpoint if both size and type match.
if (size == old_size && kind == old_type) {
wp_sp = matched_sp;
- wp_sp->SetEnabled(false);
+ wp_sp->SetEnabled(false, notify);
} else {
// Nil the matched watchpoint; we will be creating a new one.
- m_process_sp->DisableWatchpoint(matched_sp.get());
- m_watchpoint_list.Remove(matched_sp->GetID());
+ m_process_sp->DisableWatchpoint(matched_sp.get(), notify);
+ m_watchpoint_list.Remove(matched_sp->GetID(), true);
}
}
- if (!wp_sp) {
- Watchpoint *new_wp = new Watchpoint(*this, addr, size, type);
- if (!new_wp) {
- printf("Watchpoint ctor failed, out of memory?\n");
- return wp_sp;
- }
- new_wp->SetWatchpointType(kind);
- wp_sp.reset(new_wp);
- m_watchpoint_list.Add(wp_sp);
+ if (!wp_sp)
+ {
+ wp_sp.reset(new Watchpoint(*this, addr, size, type));
+ wp_sp->SetWatchpointType(kind, notify);
+ m_watchpoint_list.Add (wp_sp, true);
}
- error = m_process_sp->EnableWatchpoint(wp_sp.get());
+ error = m_process_sp->EnableWatchpoint(wp_sp.get(), notify);
if (log)
- log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
- __FUNCTION__,
- error.Success() ? "succeeded" : "failed",
- wp_sp->GetID());
+ log->Printf("Target::%s (creation of watchpoint %s with id = %u)\n",
+ __FUNCTION__,
+ error.Success() ? "succeeded" : "failed",
+ wp_sp->GetID());
- if (error.Fail()) {
+ if (error.Fail())
+ {
// Enabling the watchpoint on the device side failed.
// Remove the said watchpoint from the list maintained by the target instance.
- m_watchpoint_list.Remove(wp_sp->GetID());
+ m_watchpoint_list.Remove (wp_sp->GetID(), true);
// See if we could provide more helpful error message.
if (!CheckIfWatchpointsExhausted(this, error))
{
@@ -726,7 +738,7 @@
log->Printf ("Target::%s\n", __FUNCTION__);
if (!end_to_end) {
- m_watchpoint_list.RemoveAll();
+ m_watchpoint_list.RemoveAll(true);
return true;
}
@@ -746,7 +758,7 @@
if (rc.Fail())
return false;
}
- m_watchpoint_list.RemoveAll ();
+ m_watchpoint_list.RemoveAll (true);
return true; // Success!
}
@@ -916,7 +928,7 @@
if (DisableWatchpointByID (watch_id))
{
- m_watchpoint_list.Remove(watch_id);
+ m_watchpoint_list.Remove(watch_id, true);
return true;
}
return false;
@@ -969,6 +981,7 @@
void
Target::SetExecutableModule (ModuleSP& executable_sp, bool get_dependent_files)
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
m_images.Clear();
m_scratch_ast_context_ap.reset();
m_scratch_ast_source_ap.reset();
@@ -985,8 +998,12 @@
// If we haven't set an architecture yet, reset our architecture based on what we found in the executable module.
if (!m_arch.IsValid())
+ {
m_arch = executable_sp->GetArchitecture();
-
+ if (log)
+ log->Printf ("Target::SetExecutableModule setting architecture to %s (%s) based on executable file", m_arch.GetArchitectureName(), m_arch.GetTriple().getTriple().c_str());
+ }
+
FileSpecList dependent_files;
ObjectFile *executable_objfile = executable_sp->GetObjectFile();
@@ -1019,18 +1036,23 @@
bool
Target::SetArchitecture (const ArchSpec &arch_spec)
{
- if (m_arch == arch_spec || !m_arch.IsValid())
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TARGET));
+ if (m_arch.IsCompatibleMatch(arch_spec) || !m_arch.IsValid())
{
// If we haven't got a valid arch spec, or the architectures are
// compatible, so just update the architecture. Architectures can be
// equal, yet the triple OS and vendor might change, so we need to do
// the assignment here just in case.
m_arch = arch_spec;
+ if (log)
+ log->Printf ("Target::SetArchitecture setting architecture to %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
return true;
}
else
{
// If we have an executable file, try to reset the executable to the desired architecture
+ if (log)
+ log->Printf ("Target::SetArchitecture changing architecture to %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
m_arch = arch_spec;
ModuleSP executable_sp = GetExecutableModule ();
m_images.Clear();
@@ -1041,6 +1063,8 @@
if (executable_sp)
{
+ if (log)
+ log->Printf("Target::SetArchitecture Trying to select executable file architecture %s (%s)", arch_spec.GetArchitectureName(), arch_spec.GetTriple().getTriple().c_str());
ModuleSpec module_spec (executable_sp->GetFileSpec(), arch_spec);
Error error = ModuleList::GetSharedModule (module_spec,
executable_sp,
@@ -1244,12 +1268,12 @@
{
ModuleSP addr_module_sp (resolved_addr.GetModule());
if (addr_module_sp && addr_module_sp->GetFileSpec())
- error.SetErrorStringWithFormat("%s[0x%llx] can't be resolved, %s in not currently loaded",
+ error.SetErrorStringWithFormat("%s[0x%" PRIx64 "] can't be resolved, %s in not currently loaded",
addr_module_sp->GetFileSpec().GetFilename().AsCString(),
resolved_addr.GetFileAddress(),
addr_module_sp->GetFileSpec().GetFilename().AsCString());
else
- error.SetErrorStringWithFormat("0x%llx can't be resolved", resolved_addr.GetFileAddress());
+ error.SetErrorStringWithFormat("0x%" PRIx64 " can't be resolved", resolved_addr.GetFileAddress());
}
else
{
@@ -1259,9 +1283,9 @@
if (error.Success())
{
if (bytes_read == 0)
- error.SetErrorStringWithFormat("read memory from 0x%llx failed", load_addr);
+ error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", load_addr);
else
- error.SetErrorStringWithFormat("only %llu of %llu bytes were read from memory at 0x%llx", (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
+ error.SetErrorStringWithFormat("only %" PRIu64 " of %" PRIu64 " bytes were read from memory at 0x%" PRIx64, (uint64_t)bytes_read, (uint64_t)dst_len, load_addr);
}
}
if (bytes_read)
@@ -1290,6 +1314,82 @@
}
size_t
+Target::ReadCStringFromMemory (const Address& addr, std::string &out_str, Error &error)
+{
+ char buf[256];
+ out_str.clear();
+ addr_t curr_addr = addr.GetLoadAddress(this);
+ Address address(addr);
+ while (1)
+ {
+ size_t length = ReadCStringFromMemory (address, buf, sizeof(buf), error);
+ if (length == 0)
+ break;
+ out_str.append(buf, length);
+ // If we got "length - 1" bytes, we didn't get the whole C string, we
+ // need to read some more characters
+ if (length == sizeof(buf) - 1)
+ curr_addr += length;
+ else
+ break;
+ address = Address(curr_addr);
+ }
+ return out_str.size();
+}
+
+
+size_t
+Target::ReadCStringFromMemory (const Address& addr, char *dst, size_t dst_max_len, Error &result_error)
+{
+ size_t total_cstr_len = 0;
+ if (dst && dst_max_len)
+ {
+ result_error.Clear();
+ // NULL out everything just to be safe
+ memset (dst, 0, dst_max_len);
+ Error error;
+ addr_t curr_addr = addr.GetLoadAddress(this);
+ Address address(addr);
+ const size_t cache_line_size = 512;
+ size_t bytes_left = dst_max_len - 1;
+ char *curr_dst = dst;
+
+ while (bytes_left > 0)
+ {
+ addr_t cache_line_bytes_left = cache_line_size - (curr_addr % cache_line_size);
+ addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
+ size_t bytes_read = ReadMemory (address, false, curr_dst, bytes_to_read, error);
+
+ if (bytes_read == 0)
+ {
+ result_error = error;
+ dst[total_cstr_len] = '\0';
+ break;
+ }
+ const size_t len = strlen(curr_dst);
+
+ total_cstr_len += len;
+
+ if (len < bytes_to_read)
+ break;
+
+ curr_dst += bytes_read;
+ curr_addr += bytes_read;
+ bytes_left -= bytes_read;
+ address = Address(curr_addr);
+ }
+ }
+ else
+ {
+ if (dst == NULL)
+ result_error.SetErrorString("invalid arguments");
+ else
+ result_error.Clear();
+ }
+ return total_cstr_len;
+}
+
+size_t
Target::ReadScalarIntegerFromMemory (const Address& addr,
bool prefer_file_cache,
uint32_t byte_size,
@@ -1305,7 +1405,7 @@
if (bytes_read == byte_size)
{
DataExtractor data (&uval, sizeof(uval), m_arch.GetByteOrder(), m_arch.GetAddressByteSize());
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (byte_size <= 4)
scalar = data.GetMaxU32 (&offset, byte_size);
else
@@ -1460,38 +1560,63 @@
// module in the list already, and if there was, let's remove it.
if (module_sp)
{
- // GetSharedModule is not guaranteed to find the old shared module, for instance
- // in the common case where you pass in the UUID, it is only going to find the one
- // module matching the UUID. In fact, it has no good way to know what the "old module"
- // relevant to this target is, since there might be many copies of a module with this file spec
- // in various running debug sessions, but only one of them will belong to this target.
- // So let's remove the UUID from the module list, and look in the target's module list.
- // Only do this if there is SOMETHING else in the module spec...
- if (!old_module_sp)
+ ObjectFile *objfile = module_sp->GetObjectFile();
+ if (objfile)
{
- if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
+ switch (objfile->GetType())
+ {
+ case ObjectFile::eTypeCoreFile: /// A core file that has a checkpoint of a program's execution state
+ case ObjectFile::eTypeExecutable: /// A normal executable
+ case ObjectFile::eTypeDynamicLinker: /// The platform's dynamic linker executable
+ case ObjectFile::eTypeObjectFile: /// An intermediate object file
+ case ObjectFile::eTypeSharedLibrary: /// A shared library that can be used during execution
+ break;
+ case ObjectFile::eTypeDebugInfo: /// An object file that contains only debug information
+ if (error_ptr)
+ error_ptr->SetErrorString("debug info files aren't valid target modules, please specify an executable");
+ return ModuleSP();
+ case ObjectFile::eTypeStubLibrary: /// A library that can be linked against but not used for execution
+ if (error_ptr)
+ error_ptr->SetErrorString("stub libraries aren't valid target modules, please specify an executable");
+ return ModuleSP();
+ default:
+ if (error_ptr)
+ error_ptr->SetErrorString("unsupported file type, please specify an executable");
+ return ModuleSP();
+ }
+ // GetSharedModule is not guaranteed to find the old shared module, for instance
+ // in the common case where you pass in the UUID, it is only going to find the one
+ // module matching the UUID. In fact, it has no good way to know what the "old module"
+ // relevant to this target is, since there might be many copies of a module with this file spec
+ // in various running debug sessions, but only one of them will belong to this target.
+ // So let's remove the UUID from the module list, and look in the target's module list.
+ // Only do this if there is SOMETHING else in the module spec...
+ if (!old_module_sp)
{
- ModuleSpec module_spec_copy(module_spec.GetFileSpec());
- module_spec_copy.GetUUID().Clear();
-
- ModuleList found_modules;
- size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
- if (num_found == 1)
+ if (module_spec.GetUUID().IsValid() && !module_spec.GetFileSpec().GetFilename().IsEmpty() && !module_spec.GetFileSpec().GetDirectory().IsEmpty())
{
- old_module_sp = found_modules.GetModuleAtIndex(0);
+ ModuleSpec module_spec_copy(module_spec.GetFileSpec());
+ module_spec_copy.GetUUID().Clear();
+
+ ModuleList found_modules;
+ size_t num_found = m_images.FindModules (module_spec_copy, found_modules);
+ if (num_found == 1)
+ {
+ old_module_sp = found_modules.GetModuleAtIndex(0);
+ }
}
}
+
+ if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
+ {
+ m_images.ReplaceModule(old_module_sp, module_sp);
+ Module *old_module_ptr = old_module_sp.get();
+ old_module_sp.reset();
+ ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
+ }
+ else
+ m_images.Append(module_sp);
}
-
- if (old_module_sp && m_images.GetIndexForModule (old_module_sp.get()) != LLDB_INVALID_INDEX32)
- {
- m_images.ReplaceModule(old_module_sp, module_sp);
- Module *old_module_ptr = old_module_sp.get();
- old_module_sp.reset();
- ModuleList::RemoveSharedModuleIfOrphaned (old_module_ptr);
- }
- else
- m_images.Append(module_sp);
}
}
if (error_ptr)
@@ -1617,7 +1742,10 @@
{
TargetPropertiesSP properties_sp(Target::GetGlobalProperties());
if (properties_sp)
+ {
+ LogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET, "Target::SetDefaultArchitecture setting target's default architecture to %s (%s)", arch.GetArchitectureName(), arch.GetTriple().getTriple().c_str());
return properties_sp->SetDefaultArchitecture(arch);
+ }
}
Target *
@@ -1657,31 +1785,10 @@
m_suppress_stop_hooks = true;
ExecutionContext exe_ctx;
-
- const size_t expr_cstr_len = ::strlen (expr_cstr);
-
+
if (frame)
{
frame->CalculateExecutionContext(exe_ctx);
- Error error;
- const uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember |
- StackFrame::eExpressionPathOptionsNoFragileObjcIvar |
- StackFrame::eExpressionPathOptionsNoSyntheticChildren;
- lldb::VariableSP var_sp;
-
- // Make sure we don't have any things that we know a variable expression
- // won't be able to deal with before calling into it
- if (::strcspn (expr_cstr, "()+*&|!~<=/^%,?") == expr_cstr_len)
- {
- result_valobj_sp = frame->GetValueForVariableExpressionPath (expr_cstr,
- options.GetUseDynamic(),
- expr_path_options,
- var_sp,
- error);
- // if this expression results in a bitfield, we give up and let the IR handle it
- if (result_valobj_sp && result_valobj_sp->IsBitfield())
- result_valobj_sp.reset();
- }
}
else if (m_process_sp)
{
@@ -1692,89 +1799,33 @@
CalculateExecutionContext(exe_ctx);
}
- if (result_valobj_sp)
+ // Make sure we aren't just trying to see the value of a persistent
+ // variable (something like "$0")
+ lldb::ClangExpressionVariableSP persistent_var_sp;
+ // Only check for persistent variables the expression starts with a '$'
+ if (expr_cstr[0] == '$')
+ persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr);
+
+ if (persistent_var_sp)
{
+ result_valobj_sp = persistent_var_sp->GetValueObject ();
execution_results = eExecutionCompleted;
- // We got a result from the frame variable expression path above...
- ConstString persistent_variable_name (m_persistent_variables.GetNextPersistentVariableName());
-
- lldb::ValueObjectSP const_valobj_sp;
-
- // Check in case our value is already a constant value
- if (result_valobj_sp->GetIsConstant())
- {
- const_valobj_sp = result_valobj_sp;
- const_valobj_sp->SetName (persistent_variable_name);
- }
- else
- {
- if (options.GetUseDynamic() != lldb::eNoDynamicValues)
- {
- ValueObjectSP dynamic_sp = result_valobj_sp->GetDynamicValue(options.GetUseDynamic());
- if (dynamic_sp)
- result_valobj_sp = dynamic_sp;
- }
-
- const_valobj_sp = result_valobj_sp->CreateConstantValue (persistent_variable_name);
- }
-
- lldb::ValueObjectSP live_valobj_sp = result_valobj_sp;
-
- result_valobj_sp = const_valobj_sp;
-
- ClangExpressionVariableSP clang_expr_variable_sp(m_persistent_variables.CreatePersistentVariable(result_valobj_sp));
- assert (clang_expr_variable_sp.get());
-
- // Set flags and live data as appropriate
-
- const Value &result_value = live_valobj_sp->GetValue();
-
- switch (result_value.GetValueType())
- {
- case Value::eValueTypeHostAddress:
- case Value::eValueTypeFileAddress:
- // we don't do anything with these for now
- break;
- case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
- clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
- clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
- break;
- case Value::eValueTypeLoadAddress:
- clang_expr_variable_sp->m_live_sp = live_valobj_sp;
- clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
- break;
- }
}
else
{
- // Make sure we aren't just trying to see the value of a persistent
- // variable (something like "$0")
- lldb::ClangExpressionVariableSP persistent_var_sp;
- // Only check for persistent variables the expression starts with a '$'
- if (expr_cstr[0] == '$')
- persistent_var_sp = m_persistent_variables.GetVariable (expr_cstr);
-
- if (persistent_var_sp)
- {
- result_valobj_sp = persistent_var_sp->GetValueObject ();
- execution_results = eExecutionCompleted;
- }
- else
- {
- const char *prefix = GetExpressionPrefixContentsAsCString();
-
- execution_results = ClangUserExpression::Evaluate (exe_ctx,
- options.GetExecutionPolicy(),
- lldb::eLanguageTypeUnknown,
- options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
- options.DoesUnwindOnError(),
- expr_cstr,
- prefix,
- result_valobj_sp,
- options.GetRunOthers(),
- options.GetTimeoutUsec());
- }
+ const char *prefix = GetExpressionPrefixContentsAsCString();
+
+ execution_results = ClangUserExpression::Evaluate (exe_ctx,
+ options.GetExecutionPolicy(),
+ lldb::eLanguageTypeUnknown,
+ options.DoesCoerceToId() ? ClangUserExpression::eResultTypeId : ClangUserExpression::eResultTypeAny,
+ options.DoesUnwindOnError(),
+ options.DoesIgnoreBreakpoints(),
+ expr_cstr,
+ prefix,
+ result_valobj_sp,
+ options.GetRunOthers(),
+ options.GetTimeoutUsec());
}
m_suppress_stop_hooks = old_suppress_value;
@@ -2015,9 +2066,9 @@
cur_hook_sp->GetCommands().GetStringAtIndex(0) :
NULL);
if (cmd)
- result.AppendMessageWithFormat("\n- Hook %llu (%s)\n", cur_hook_sp->GetID(), cmd);
+ result.AppendMessageWithFormat("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(), cmd);
else
- result.AppendMessageWithFormat("\n- Hook %llu\n", cur_hook_sp->GetID());
+ result.AppendMessageWithFormat("\n- Hook %" PRIu64 "\n", cur_hook_sp->GetID());
any_thread_matched = true;
}
@@ -2042,7 +2093,7 @@
if ((result.GetStatus() == eReturnStatusSuccessContinuingNoResult) ||
(result.GetStatus() == eReturnStatusSuccessContinuingResult))
{
- result.AppendMessageWithFormat ("Aborting stop hooks, hook %llu set the program running.", cur_hook_sp->GetID());
+ result.AppendMessageWithFormat ("Aborting stop hooks, hook %" PRIu64 " set the program running.", cur_hook_sp->GetID());
keep_going = false;
}
}
@@ -2100,7 +2151,7 @@
s->SetIndentLevel(indent_level + 2);
- s->Printf ("Hook: %llu\n", GetID());
+ s->Printf ("Hook: %" PRIu64 "\n", GetID());
if (m_active)
s->Indent ("State: enabled\n");
else
@@ -2159,6 +2210,22 @@
{ 0, NULL, NULL }
};
+typedef enum x86DisassemblyFlavor
+{
+ eX86DisFlavorDefault,
+ eX86DisFlavorIntel,
+ eX86DisFlavorATT
+} x86DisassemblyFlavor;
+
+static OptionEnumValueElement
+g_x86_dis_flavor_value_types[] =
+{
+ { eX86DisFlavorDefault, "default", "Disassembler default (currently att)."},
+ { eX86DisFlavorIntel, "intel", "Intel disassembler flavor."},
+ { eX86DisFlavorATT, "att", "AT&T disassembler flavor."},
+ { 0, NULL, NULL }
+};
+
static PropertyDefinition
g_properties[] =
{
@@ -2192,6 +2259,8 @@
"Always checking for inlined breakpoint locations can be expensive (memory and time), so we try to minimize the "
"times we look for inlined locations. This setting allows you to control exactly which strategy is used when settings "
"file and line breakpoints." },
+ // FIXME: This is the wrong way to do per-architecture settings, but we don't have a general per architecture settings system in place yet.
+ { "x86-disassembly-flavor" , OptionValue::eTypeEnum , false, eX86DisFlavorDefault, NULL, g_x86_dis_flavor_value_types, "The default disassembly flavor to use for x86 or x86-64 targets." },
{ NULL , OptionValue::eTypeInvalid , false, 0 , NULL, NULL, NULL }
};
enum
@@ -2215,7 +2284,8 @@
ePropertyErrorPath,
ePropertyDisableASLR,
ePropertyDisableSTDIO,
- ePropertyInlineStrategy
+ ePropertyInlineStrategy,
+ ePropertyDisassemblyFlavor
};
@@ -2391,6 +2461,17 @@
m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
}
+const char *
+TargetProperties::GetDisassemblyFlavor () const
+{
+ const uint32_t idx = ePropertyDisassemblyFlavor;
+ const char *return_value;
+
+ x86DisassemblyFlavor flavor_value = (x86DisassemblyFlavor) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+ return_value = g_x86_dis_flavor_value_types[flavor_value].string_value;
+ return return_value;
+}
+
InlineStrategy
TargetProperties::GetInlineStrategy () const
{
Index: aze/lldb/source/Target/TargetList.cpp
===================================================================
--- aze.orig/lldb/source/Target/TargetList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/TargetList.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
// C++ Includes
// Other libraries and framework includes
@@ -102,7 +104,7 @@
// current architecture if we have a valid architecture.
platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
- if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
+ if (arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
{
platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
}
@@ -140,7 +142,7 @@
{
if (arch.IsValid())
{
- if (!platform_sp->IsCompatibleArchitecture(arch))
+ if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
}
}
@@ -299,7 +301,7 @@
{
if (exe_arch_ptr)
{
- if (*exe_arch_ptr != exe_module->GetArchitecture())
+ if (!exe_arch_ptr->IsCompatibleMatch(exe_module->GetArchitecture()))
continue;
}
target_sp = *pos;
Index: aze/lldb/source/Target/Thread.cpp
===================================================================
--- aze.orig/lldb/source/Target/Thread.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/Thread.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/lldb-private-log.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
@@ -241,7 +243,7 @@
Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
m_process_wp (process.shared_from_this()),
m_actual_stop_info_sp (),
- m_index_id (process.GetNextThreadIndexID ()),
+ m_index_id (process.GetNextThreadIndexID(tid)),
m_reg_context_sp (),
m_state (eStateUnloaded),
m_state_mutex (Mutex::eMutexTypeRecursive),
@@ -256,11 +258,10 @@
m_unwinder_ap (),
m_destroy_called (false),
m_thread_stop_reason_stop_id (0)
-
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Thread::Thread(tid = 0x%4.4llx)", this, GetID());
+ log->Printf ("%p Thread::Thread(tid = 0x%4.4" PRIx64 ")", this, GetID());
CheckInWithManager();
QueueFundamentalPlan(true);
@@ -271,7 +272,7 @@
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
- log->Printf ("%p Thread::~Thread(tid = 0x%4.4llx)", this, GetID());
+ log->Printf ("%p Thread::~Thread(tid = 0x%4.4" PRIx64 ")", this, GetID());
/// If you hit this assert, it means your derived class forgot to call DoDestroy in its destructor.
assert (m_destroy_called);
}
@@ -322,6 +323,33 @@
return false;
}
+bool
+Thread::SetSelectedFrameByIndexNoisily (uint32_t frame_idx, Stream &output_stream)
+{
+ const bool broadcast = true;
+ bool success = SetSelectedFrameByIndex (frame_idx, broadcast);
+ if (success)
+ {
+ StackFrameSP frame_sp = GetSelectedFrame();
+ if (frame_sp)
+ {
+ bool already_shown = false;
+ SymbolContext frame_sc(frame_sp->GetSymbolContext(eSymbolContextLineEntry));
+ if (GetProcess()->GetTarget().GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
+ {
+ already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
+ }
+
+ bool show_frame_info = true;
+ bool show_source = !already_shown;
+ return frame_sp->GetStatus (output_stream, show_frame_info, show_source);
+ }
+ return false;
+ }
+ else
+ return false;
+}
+
lldb::StopInfoSP
Thread::GetStopInfo ()
@@ -396,9 +424,15 @@
}
bool
-Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
+Thread::RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
{
RestoreSaveFrameZero(saved_state.register_backup);
+ return true;
+}
+
+bool
+Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
+{
if (saved_state.stop_info_sp)
saved_state.stop_info_sp->MakeStopInfoValid();
SetStopInfo(saved_state.stop_info_sp);
@@ -538,10 +572,10 @@
if (GetResumeState () == eStateSuspended)
{
if (log)
- log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)",
+ log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
__FUNCTION__,
GetID ());
-// log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)",
+// log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
// __FUNCTION__,
// GetID (),
// GetRegisterContext()->GetPC());
@@ -551,10 +585,10 @@
if (GetTemporaryResumeState () == eStateSuspended)
{
if (log)
- log->Printf ("Thread::%s for tid = 0x%4.4llx, should_stop = 0 (ignore since thread was suspended)",
+ log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
__FUNCTION__,
GetID ());
-// log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)",
+// log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64 ", should_stop = 0 (ignore since thread was suspended)",
// __FUNCTION__,
// GetID (),
// GetRegisterContext()->GetPC());
@@ -564,7 +598,7 @@
if (ThreadStoppedForAReason() == false)
{
if (log)
- log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx, should_stop = 0 (ignore since no stop reason)",
+ log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64 ", should_stop = 0 (ignore since no stop reason)",
__FUNCTION__,
GetID (),
GetRegisterContext()->GetPC());
@@ -573,7 +607,7 @@
if (log)
{
- log->Printf ("Thread::%s for tid = 0x%4.4llx, pc = 0x%16.16llx",
+ log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64 ", pc = 0x%16.16" PRIx64,
__FUNCTION__,
GetID (),
GetRegisterContext()->GetPC());
@@ -612,7 +646,7 @@
bool done_processing_current_plan = false;
- if (!current_plan->PlanExplainsStop())
+ if (!current_plan->PlanExplainsStop(event_ptr))
{
if (current_plan->TracerExplainsStop())
{
@@ -626,7 +660,7 @@
ThreadPlan *plan_ptr = current_plan;
while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
{
- if (plan_ptr->PlanExplainsStop())
+ if (plan_ptr->PlanExplainsStop(event_ptr))
{
should_stop = plan_ptr->ShouldStop (event_ptr);
@@ -770,21 +804,21 @@
if (thread_state == eStateSuspended || thread_state == eStateInvalid)
{
if (log)
- log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
+ log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
return eVoteNoOpinion;
}
if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid)
{
if (log)
- log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
+ log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (temporary state was suspended or invalid)\n", GetID(), eVoteNoOpinion);
return eVoteNoOpinion;
}
if (!ThreadStoppedForAReason())
{
if (log)
- log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion);
+ log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i (thread didn't stop for a reason.)\n", GetID(), eVoteNoOpinion);
return eVoteNoOpinion;
}
@@ -792,14 +826,29 @@
{
// Don't use GetCompletedPlan here, since that suppresses private plans.
if (log)
- log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for complete stack's back plan\n", GetID());
+ log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote for complete stack's back plan\n", GetID());
return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
}
else
{
+ Vote thread_vote = eVoteNoOpinion;
+ ThreadPlan *plan_ptr = GetCurrentPlan();
+ while (1)
+ {
+ if (plan_ptr->PlanExplainsStop(event_ptr))
+ {
+ thread_vote = plan_ptr->ShouldReportStop(event_ptr);
+ break;
+ }
+ if (PlanIsBasePlan(plan_ptr))
+ break;
+ else
+ plan_ptr = GetPreviousPlan(plan_ptr);
+ }
if (log)
- log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4llx: returning vote for current plan\n", GetID());
- return GetCurrentPlan()->ShouldReportStop (event_ptr);
+ log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 ": returning vote %i for current plan\n", GetID(), thread_vote);
+
+ return thread_vote;
}
}
@@ -819,7 +868,7 @@
{
// Don't use GetCompletedPlan here, since that suppresses private plans.
if (log)
- log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.",
+ log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 "): %s being asked whether we should report run.",
GetIndexID(),
GetID(),
m_completed_plan_stack.back()->GetName());
@@ -829,7 +878,7 @@
else
{
if (log)
- log->Printf ("Current Plan for thread %d (0x%4.4llx): %s being asked whether we should report run.",
+ log->Printf ("Current Plan for thread %d (0x%4.4" PRIx64 "): %s being asked whether we should report run.",
GetIndexID(),
GetID(),
GetCurrentPlan()->GetName());
@@ -864,7 +913,7 @@
{
StreamString s;
thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
- log->Printf("Pushing plan: \"%s\", tid = 0x%4.4llx.",
+ log->Printf("Pushing plan: \"%s\", tid = 0x%4.4" PRIx64 ".",
s.GetData(),
thread_plan_sp->GetThread().GetID());
}
@@ -883,7 +932,7 @@
ThreadPlanSP &plan = m_plan_stack.back();
if (log)
{
- log->Printf("Popping plan: \"%s\", tid = 0x%4.4llx.", plan->GetName(), plan->GetThread().GetID());
+ log->Printf("Popping plan: \"%s\", tid = 0x%4.4" PRIx64 ".", plan->GetName(), plan->GetThread().GetID());
}
m_completed_plan_stack.push_back (plan);
plan->WillPop();
@@ -1048,7 +1097,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
{
- log->Printf("Discarding thread plans for thread tid = 0x%4.4llx, up to %p", GetID(), up_to_plan_ptr);
+ log->Printf("Discarding thread plans for thread tid = 0x%4.4" PRIx64 ", up to %p", GetID(), up_to_plan_ptr);
}
int stack_size = m_plan_stack.size();
@@ -1089,7 +1138,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
{
- log->Printf("Discarding thread plans for thread (tid = 0x%4.4llx, force %d)", GetID(), force);
+ log->Printf("Discarding thread plans for thread (tid = 0x%4.4" PRIx64 ", force %d)", GetID(), force);
}
if (force)
@@ -1158,6 +1207,28 @@
return m_plan_stack[0].get() == plan_ptr;
}
+Error
+Thread::UnwindInnermostExpression()
+{
+ Error error;
+ int stack_size = m_plan_stack.size();
+
+ // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the
+ // stack, and if so discard up to and including it.
+
+ for (int i = stack_size - 1; i > 0; i--)
+ {
+ if (m_plan_stack[i]->GetKind() == ThreadPlan::eKindCallFunction)
+ {
+ DiscardThreadPlansUpToPlan(m_plan_stack[i].get());
+ return error;
+ }
+ }
+ error.SetErrorString("No expressions currently active on this thread");
+ return error;
+}
+
+
ThreadPlan *
Thread::QueueFundamentalPlan (bool abort_other_plans)
{
@@ -1180,28 +1251,41 @@
}
ThreadPlan *
-Thread::QueueThreadPlanForStepRange
+Thread::QueueThreadPlanForStepOverRange
(
bool abort_other_plans,
- StepType type,
const AddressRange &range,
- const SymbolContext &addr_context,
+ const SymbolContext &addr_context,
+ lldb::RunMode stop_other_threads
+)
+{
+ ThreadPlanSP thread_plan_sp;
+ thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
+
+ QueueThreadPlan (thread_plan_sp, abort_other_plans);
+ return thread_plan_sp.get();
+}
+
+ThreadPlan *
+Thread::QueueThreadPlanForStepInRange
+(
+ bool abort_other_plans,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_in_target,
lldb::RunMode stop_other_threads,
bool avoid_code_without_debug_info
)
{
ThreadPlanSP thread_plan_sp;
- if (type == eStepTypeInto)
- {
- ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
- if (avoid_code_without_debug_info)
- plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
- else
- plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
- thread_plan_sp.reset (plan);
- }
+ ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
+ if (avoid_code_without_debug_info)
+ plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
else
- thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
+ plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
+ if (step_in_target)
+ plan->SetStepInTarget(step_in_target);
+ thread_plan_sp.reset (plan);
QueueThreadPlan (thread_plan_sp, abort_other_plans);
return thread_plan_sp.get();
@@ -1263,9 +1347,16 @@
Address& function,
lldb::addr_t arg,
bool stop_other_threads,
- bool discard_on_error)
+ bool unwind_on_error,
+ bool ignore_breakpoints)
{
- ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, ClangASTType(), arg, stop_other_threads, discard_on_error));
+ ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this,
+ function,
+ ClangASTType(),
+ arg,
+ stop_other_threads,
+ unwind_on_error,
+ ignore_breakpoints));
QueueThreadPlan (thread_plan_sp, abort_other_plans);
return thread_plan_sp.get();
}
@@ -1305,7 +1396,7 @@
uint32_t stack_size = m_plan_stack.size();
int i;
s->Indent();
- s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4llx, stack_size = %d\n", GetIndexID(), GetID(), stack_size);
+ s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4" PRIx64 ", stack_size = %d\n", GetIndexID(), GetID(), stack_size);
for (i = stack_size - 1; i >= 0; i--)
{
s->IndentMore();
@@ -1431,7 +1522,7 @@
if (!frame_sp)
{
- return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%llx.", frame_idx, GetID());
+ return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%" PRIx64 ".", frame_idx, GetID());
}
return ReturnFromFrame(frame_sp, return_value_sp, broadcast);
@@ -1451,6 +1542,11 @@
Thread *thread = frame_sp->GetThread().get();
uint32_t older_frame_idx = frame_sp->GetFrameIndex() + 1;
StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx);
+ if (!older_frame_sp)
+ {
+ return_error.SetErrorString("No older frame to return to.");
+ return return_error;
+ }
if (return_value_sp)
{
@@ -1492,21 +1588,29 @@
// Now write the return registers for the chosen frame:
// Note, we can't use ReadAllRegisterValues->WriteAllRegisterValues, since the read & write
- // cook their data
- bool copy_success = thread->GetStackFrameAtIndex(0)->GetRegisterContext()->CopyFromRegisterContext(older_frame_sp->GetRegisterContext());
- if (copy_success)
- {
- thread->DiscardThreadPlans(true);
- thread->ClearStackFrames();
- if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged))
- BroadcastEvent(eBroadcastBitStackChanged, new ThreadEventData (this->shared_from_this()));
- return return_error;
+ // cook their data
+
+ StackFrameSP youngest_frame_sp = thread->GetStackFrameAtIndex(0);
+ if (youngest_frame_sp)
+ {
+ bool copy_success = youngest_frame_sp->GetRegisterContext()->CopyFromRegisterContext(older_frame_sp->GetRegisterContext());
+ if (copy_success)
+ {
+ thread->DiscardThreadPlans(true);
+ thread->ClearStackFrames();
+ if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged))
+ BroadcastEvent(eBroadcastBitStackChanged, new ThreadEventData (this->shared_from_this()));
+ }
+ else
+ {
+ return_error.SetErrorString("Could not reset register values.");
+ }
}
else
{
- return_error.SetErrorString("Could not reset register values.");
- return return_error;
+ return_error.SetErrorString("Returned past top frame.");
}
+ return return_error;
}
void
@@ -1561,14 +1665,16 @@
{
switch (reason)
{
- case eStopReasonInvalid: return "invalid";
- case eStopReasonNone: return "none";
- case eStopReasonTrace: return "trace";
- case eStopReasonBreakpoint: return "breakpoint";
- case eStopReasonWatchpoint: return "watchpoint";
- case eStopReasonSignal: return "signal";
- case eStopReasonException: return "exception";
- case eStopReasonPlanComplete: return "plan complete";
+ case eStopReasonInvalid: return "invalid";
+ case eStopReasonNone: return "none";
+ case eStopReasonTrace: return "trace";
+ case eStopReasonBreakpoint: return "breakpoint";
+ case eStopReasonWatchpoint: return "watchpoint";
+ case eStopReasonSignal: return "signal";
+ case eStopReasonException: return "exception";
+ case eStopReasonExec: return "exec";
+ case eStopReasonPlanComplete: return "plan complete";
+ case eStopReasonThreadExiting: return "thread exiting";
}
@@ -1682,6 +1788,8 @@
// Clear out all stack frames as our world just changed.
ClearStackFrames();
frame_sp->GetRegisterContext()->InvalidateIfNeeded(true);
+ if (m_unwinder_ap.get())
+ m_unwinder_ap->Clear();
return ret;
}
@@ -1721,7 +1829,7 @@
m_reg_context_sp.reset();
}
-const bool
+bool
Thread::IsStillAtLastBreakpointHit ()
{
// If we are currently stopped at a breakpoint, always return that stopinfo and don't reset it.
Index: aze/lldb/source/Target/ThreadList.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadList.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadList.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -128,6 +128,29 @@
}
ThreadSP
+ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
+{
+ Mutex::Locker locker(m_threads_mutex);
+
+ if (can_update)
+ m_process->UpdateThreadListIfNeeded();
+
+ ThreadSP thread_sp;
+ uint32_t idx = 0;
+ const uint32_t num_threads = m_threads.size();
+ for (idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->GetID() == tid)
+ {
+ thread_sp = m_threads[idx];
+ m_threads.erase(m_threads.begin()+idx);
+ break;
+ }
+ }
+ return thread_sp;
+}
+
+ThreadSP
ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
{
ThreadSP thread_sp;
@@ -175,24 +198,37 @@
bool
ThreadList::ShouldStop (Event *event_ptr)
{
- Mutex::Locker locker(m_threads_mutex);
-
+ bool should_stop = false;
// Running events should never stop, obviously...
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
- bool should_stop = false;
- m_process->UpdateThreadListIfNeeded();
+ // The ShouldStop method of the threads can do a whole lot of work,
+ // running breakpoint commands & conditions, etc. So we don't want
+ // to keep the ThreadList locked the whole time we are doing this.
+ // FIXME: It is possible that running code could cause new threads
+ // to be created. If that happens we will miss asking them whether
+ // then should stop. This is not a big deal, since we haven't had
+ // a chance to hang any interesting operations on those threads yet.
+
+ collection threads_copy;
+ {
+ // Scope for locker
+ Mutex::Locker locker(m_threads_mutex);
- collection::iterator pos, end = m_threads.end();
+ m_process->UpdateThreadListIfNeeded();
+ threads_copy = m_threads;
+ }
+
+ collection::iterator pos, end = threads_copy.end();
if (log)
{
log->PutCString("");
- log->Printf ("ThreadList::%s: %llu threads", __FUNCTION__, (uint64_t)m_threads.size());
+ log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
}
- for (pos = m_threads.begin(); pos != end; ++pos)
+ for (pos = threads_copy.begin(); pos != end; ++pos)
{
ThreadSP thread_sp(*pos);
@@ -206,7 +242,7 @@
if (should_stop)
{
- for (pos = m_threads.begin(); pos != end; ++pos)
+ for (pos = threads_copy.begin(); pos != end; ++pos)
{
ThreadSP thread_sp(*pos);
thread_sp->WillStop ();
@@ -228,7 +264,7 @@
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
- log->Printf ("ThreadList::%s %llu threads", __FUNCTION__, (uint64_t)m_threads.size());
+ log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
// Run through the threads and ask whether we should report this event.
// For stopping, a YES vote wins over everything. A NO vote wins over NO opinion.
@@ -253,7 +289,7 @@
else
{
if (log)
- log->Printf ("ThreadList::%s thread 0x%4.4llx: voted %s, but lost out because result was %s",
+ log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
__FUNCTION__,
thread_sp->GetID (),
GetVoteAsCString (vote),
@@ -296,7 +332,7 @@
break;
case eVoteNo:
if (log)
- log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4llx) says don't report.",
+ log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
(*pos)->GetIndexID(),
(*pos)->GetID());
result = eVoteNo;
@@ -542,7 +578,7 @@
}
bool
-ThreadList::SetSelectedThreadByID (lldb::tid_t tid)
+ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
{
Mutex::Locker locker(m_threads_mutex);
ThreadSP selected_thread_sp(FindThreadByID(tid));
@@ -554,11 +590,14 @@
else
m_selected_tid = LLDB_INVALID_THREAD_ID;
+ if (notify)
+ NotifySelectedThreadChanged(m_selected_tid);
+
return m_selected_tid != LLDB_INVALID_THREAD_ID;
}
bool
-ThreadList::SetSelectedThreadByIndexID (uint32_t index_id)
+ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
{
Mutex::Locker locker(m_threads_mutex);
ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
@@ -570,10 +609,22 @@
else
m_selected_tid = LLDB_INVALID_THREAD_ID;
+ if (notify)
+ NotifySelectedThreadChanged(m_selected_tid);
+
return m_selected_tid != LLDB_INVALID_THREAD_ID;
}
void
+ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
+{
+ ThreadSP selected_thread_sp (FindThreadByID(tid));
+ if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
+ selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
+ new Thread::ThreadEventData(selected_thread_sp));
+}
+
+void
ThreadList::Update (ThreadList &rhs)
{
if (this != &rhs)
Index: aze/lldb/source/Target/ThreadPlanBase.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanBase.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanBase.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -68,7 +68,7 @@
}
bool
-ThreadPlanBase::PlanExplainsStop ()
+ThreadPlanBase::PlanExplainsStop (Event *event_ptr)
{
// The base plan should defer to its tracer, since by default it
// always handles the stop.
@@ -101,13 +101,13 @@
case eStopReasonBreakpoint:
case eStopReasonWatchpoint:
- if (stop_info_sp->ShouldStop(event_ptr))
+ if (stop_info_sp->ShouldStopSynchronous(event_ptr))
{
// If we are going to stop for a breakpoint, then unship the other plans
// at this point. Don't force the discard, however, so Master plans can stay
// in place if they want to.
if (log)
- log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (breakpoint hit.)", m_thread.GetID());
+ log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (breakpoint hit.)", m_thread.GetID());
m_thread.DiscardThreadPlans(false);
return true;
}
@@ -135,15 +135,24 @@
// If we crashed, discard thread plans and stop. Don't force the discard, however,
// since on rerun the target may clean up this exception and continue normally from there.
if (log)
- log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (exception.)", m_thread.GetID());
+ log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exception.)", m_thread.GetID());
+ m_thread.DiscardThreadPlans(false);
+ return true;
+
+ case eStopReasonExec:
+ // If we crashed, discard thread plans and stop. Don't force the discard, however,
+ // since on rerun the target may clean up this exception and continue normally from there.
+ if (log)
+ log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (exec.)", m_thread.GetID());
m_thread.DiscardThreadPlans(false);
return true;
+ case eStopReasonThreadExiting:
case eStopReasonSignal:
if (stop_info_sp->ShouldStop(event_ptr))
{
if (log)
- log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4llx (signal.)", m_thread.GetID());
+ log->Printf("Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64 " (signal.)", m_thread.GetID());
m_thread.DiscardThreadPlans(false);
return true;
}
Index: aze/lldb/source/Target/ThreadPlanCallFunction.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanCallFunction.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanCallFunction.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -44,6 +44,7 @@
{
SetIsMasterPlan (true);
SetOkayToDiscard (false);
+ SetPrivate (true);
ProcessSP process_sp (thread.GetProcess());
if (!process_sp)
@@ -68,7 +69,7 @@
if (!error.Success())
{
if (log)
- log->Printf ("ThreadPlanCallFunction(%p): Trying to put the stack in unreadable memory at: 0x%llx.", this, m_function_sp);
+ log->Printf ("ThreadPlanCallFunction(%p): Trying to put the stack in unreadable memory at: 0x%" PRIx64 ".", this, m_function_sp);
return false;
}
@@ -112,20 +113,18 @@
log->Printf ("ThreadPlanCallFunction(%p): Setting up ThreadPlanCallFunction, failed to checkpoint thread state.", this);
return false;
}
- // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
- thread.SetStopInfoToNothing();
-
function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
return true;
}
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
- Address &function,
+ const Address &function,
const ClangASTType &return_type,
addr_t arg,
bool stop_other_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
addr_t *this_arg,
addr_t *cmd_arg) :
ThreadPlan (ThreadPlan::eKindCallFunction, "Call function plan", thread, eVoteNoOpinion, eVoteNoOpinion),
@@ -136,7 +135,8 @@
m_return_type (return_type),
m_takedown_done (false),
m_stop_address (LLDB_INVALID_ADDRESS),
- m_discard_on_error (discard_on_error)
+ m_unwind_on_error (unwind_on_error),
+ m_ignore_breakpoints (ignore_breakpoints)
{
lldb::addr_t start_load_addr;
ABI *abi;
@@ -182,10 +182,11 @@
ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
- Address &function,
+ const Address &function,
const ClangASTType &return_type,
bool stop_other_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
addr_t *arg1_ptr,
addr_t *arg2_ptr,
addr_t *arg3_ptr,
@@ -196,10 +197,12 @@
m_valid (false),
m_stop_other_threads (stop_other_threads),
m_function_addr (function),
- m_function_sp(0),
+ m_function_sp (0),
m_return_type (return_type),
m_takedown_done (false),
- m_stop_address (LLDB_INVALID_ADDRESS)
+ m_stop_address (LLDB_INVALID_ADDRESS),
+ m_unwind_on_error (unwind_on_error),
+ m_ignore_breakpoints (ignore_breakpoints)
{
lldb::addr_t start_load_addr;
ABI *abi;
@@ -228,7 +231,7 @@
ThreadPlanCallFunction::~ThreadPlanCallFunction ()
{
- DoTakedown(true);
+ DoTakedown(PlanSucceeded());
}
void
@@ -285,11 +288,11 @@
}
}
if (log)
- log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4llx, m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
+ log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
m_takedown_done = true;
m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
m_real_stop_info_sp = GetPrivateStopReason();
- m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
+ m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
SetPlanComplete(success);
ClearBreakpoints();
if (log && log->GetVerbose())
@@ -299,14 +302,14 @@
else
{
if (log)
- log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4llx, m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
+ log->Printf ("ThreadPlanCallFunction(%p): DoTakedown called as no-op for thread 0x%4.4" PRIx64 ", m_valid: %d complete: %d.\n", this, m_thread.GetID(), m_valid, IsPlanComplete());
}
}
void
ThreadPlanCallFunction::WillPop ()
{
- DoTakedown(true);
+ DoTakedown(PlanSucceeded());
}
void
@@ -319,7 +322,7 @@
else
{
TargetSP target_sp (m_thread.CalculateTarget());
- s->Printf("Thread plan to call 0x%llx", m_function_addr.GetLoadAddress(target_sp.get()));
+ s->Printf("Thread plan to call 0x%" PRIx64, m_function_addr.GetLoadAddress(target_sp.get()));
}
}
@@ -332,15 +335,29 @@
return true;
}
+
+Vote
+ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr)
+{
+ if (m_takedown_done || IsPlanComplete())
+ return eVoteYes;
+ else
+ return ThreadPlan::ShouldReportStop(event_ptr);
+}
+
bool
-ThreadPlanCallFunction::PlanExplainsStop ()
+ThreadPlanCallFunction::PlanExplainsStop (Event *event_ptr)
{
+ LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS));
m_real_stop_info_sp = GetPrivateStopReason();
// If our subplan knows why we stopped, even if it's done (which would forward the question to us)
// we answer yes.
- if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
+ if (m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop(event_ptr))
+ {
+ SetPlanComplete();
return true;
+ }
// Check if the breakpoint is one of ours.
@@ -349,16 +366,15 @@
stop_reason = eStopReasonNone;
else
stop_reason = m_real_stop_info_sp->GetStopReason();
+ if (log)
+ log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: Got stop reason - %s.", Thread::StopReasonAsCString(stop_reason));
if (stop_reason == eStopReasonBreakpoint && BreakpointsExplainStop())
return true;
- // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
- if (!m_discard_on_error)
- return false;
-
- // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
- // If it is not an internal breakpoint, consult OkayToDiscard.
+ // We control breakpoints separately from other "stop reasons." So first,
+ // check the case where we stopped for an internal breakpoint, in that case, continue on.
+ // If it is not an internal breakpoint, consult m_ignore_breakpoints.
if (stop_reason == eStopReasonBreakpoint)
@@ -375,6 +391,8 @@
for (uint32_t i = 0; i < num_owners; i++)
{
Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+ if (log)
+ log->Printf ("ThreadPlanCallFunction::PlanExplainsStop: hit breakpoint %d while calling function", bp.GetID());
if (!bp.IsInternal())
{
@@ -383,16 +401,32 @@
}
}
if (is_internal)
+ {
+ if (log)
+ log->Printf ("ThreadPlanCallFunction::PlanExplainsStop hit an internal breakpoint, not stopping.");
return false;
+ }
}
-
- if (m_discard_on_error)
+
+ if (m_ignore_breakpoints)
{
- DoTakedown(false);
+ if (log)
+ log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
+ m_real_stop_info_sp->OverrideShouldStop(false);
return true;
}
else
+ {
+ if (log)
+ log->Printf("ThreadPlanCallFunction::PlanExplainsStop: we are not ignoring breakpoints, overriding breakpoint stop info ShouldStop, returning true");
+ m_real_stop_info_sp->OverrideShouldStop(true);
return false;
+ }
+ }
+ else if (!m_unwind_on_error)
+ {
+ // If we don't want to discard this plan, than any stop we don't understand should be propagated up the stack.
+ return false;
}
else
{
@@ -400,30 +434,38 @@
// If we want to discard the plan, then we say we explain the stop
// but if we are going to be discarded, let whoever is above us
// explain the stop.
- if (m_subplan_sp)
+ // But don't discard the plan if the stop would restart itself (for instance if it is a
+ // signal that is set not to stop. Check that here first. We just say we explain the stop
+ // but aren't done and everything will continue on from there.
+
+ if (m_real_stop_info_sp->ShouldStopSynchronous(event_ptr))
{
- if (m_discard_on_error)
+ SetPlanComplete(false);
+ if (m_subplan_sp)
{
- DoTakedown(false);
- return true;
+ if (m_unwind_on_error)
+ return true;
+ else
+ return false;
}
else
return false;
}
else
- return false;
+ return true;
}
}
bool
ThreadPlanCallFunction::ShouldStop (Event *event_ptr)
{
- if (IsPlanComplete() || PlanExplainsStop())
+ // We do some computation in PlanExplainsStop that may or may not set the plan as complete.
+ // We need to do that here to make sure our state is correct.
+ PlanExplainsStop(event_ptr);
+
+ if (IsPlanComplete())
{
ReportRegisterState ("Function completed. Register state was:");
-
- DoTakedown(true);
-
return true;
}
else
@@ -460,6 +502,11 @@
{
//#define SINGLE_STEP_EXPRESSIONS
+ // Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
+ // Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
+
+ GetThread().SetStopInfoToNothing();
+
#ifndef SINGLE_STEP_EXPRESSIONS
m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
@@ -477,10 +524,10 @@
bool
ThreadPlanCallFunction::MischiefManaged ()
{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+
if (IsPlanComplete())
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
if (log)
log->Printf("ThreadPlanCallFunction(%p): Completed call function plan.", this);
@@ -523,13 +570,21 @@
{
StopInfoSP stop_info_sp = GetPrivateStopReason();
- if (m_cxx_language_runtime &&
- m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
- return true;
-
- if (m_objc_language_runtime &&
- m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
+ if ((m_cxx_language_runtime &&
+ m_cxx_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp))
+ ||(m_objc_language_runtime &&
+ m_objc_language_runtime->ExceptionBreakpointsExplainStop(stop_info_sp)))
+ {
+ SetPlanComplete(false);
return true;
+ }
return false;
}
+
+bool
+ThreadPlanCallFunction::RestoreThreadState()
+{
+ return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
+}
+
Index: aze/lldb/source/Target/ThreadPlanCallUserExpression.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanCallUserExpression.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanCallUserExpression.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -40,11 +40,12 @@
Address &function,
lldb::addr_t arg,
bool stop_other_threads,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
lldb::addr_t *this_arg,
lldb::addr_t *cmd_arg,
ClangUserExpression::ClangUserExpressionSP &user_expression_sp) :
- ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, discard_on_error, this_arg, cmd_arg),
+ ThreadPlanCallFunction (thread, function, ClangASTType(), arg, stop_other_threads, unwind_on_error, ignore_breakpoints, this_arg, cmd_arg),
m_user_expression_sp (user_expression_sp)
{
// User expressions are generally "User generated" so we should set them up to stop when done.
Index: aze/lldb/source/Target/ThreadPlan.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlan.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlan.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Target/ThreadPlan.h"
// C Includes
@@ -139,7 +141,7 @@
addr_t pc = reg_ctx->GetPC();
addr_t sp = reg_ctx->GetSP();
addr_t fp = reg_ctx->GetFP();
- log->Printf("%s Thread #%u: tid = 0x%4.4llx, pc = 0x%8.8llx, sp = 0x%8.8llx, fp = 0x%8.8llx, "
+ log->Printf("%s Thread #%u: tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
"plan = '%s', state = %s, stop others = %d",
__FUNCTION__,
m_thread.GetIndexID(),
Index: aze/lldb/source/Target/ThreadPlanRunToAddress.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanRunToAddress.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanRunToAddress.cpp 2013-03-03 09:35:50.283457350 +0100
@@ -93,6 +93,7 @@
{
m_break_ids[i] = breakpoint->GetID();
breakpoint->SetThreadID(m_thread.GetID());
+ breakpoint->SetBreakpointKind("run-to-address");
}
}
}
@@ -187,7 +188,7 @@
}
bool
-ThreadPlanRunToAddress::PlanExplainsStop ()
+ThreadPlanRunToAddress::PlanExplainsStop (Event *event_ptr)
{
return AtOurAddress();
}
Index: aze/lldb/source/Target/ThreadPlanShouldStopHere.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanShouldStopHere.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanShouldStopHere.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -60,11 +60,11 @@
{
StreamString s;
return_plan->GetDescription (&s, lldb::eDescriptionLevelFull);
- log->Printf ("ShouldStopHere callback found a step out plan from 0x%llx: %s.", current_addr, s.GetData());
+ log->Printf ("ShouldStopHere callback found a step out plan from 0x%" PRIx64 ": %s.", current_addr, s.GetData());
}
else
{
- log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%llx.", current_addr);
+ log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%" PRIx64 ".", current_addr);
}
}
return return_plan;
Index: aze/lldb/source/Target/ThreadPlanStepInRange.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepInRange.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepInRange.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -52,6 +52,23 @@
SetFlagsToDefault ();
}
+ThreadPlanStepInRange::ThreadPlanStepInRange
+(
+ Thread &thread,
+ const AddressRange &range,
+ const SymbolContext &addr_context,
+ const char *step_into_target,
+ lldb::RunMode stop_others
+) :
+ ThreadPlanStepRange (ThreadPlan::eKindStepInRange, "Step Range stepping in", thread, range, addr_context, stop_others),
+ ThreadPlanShouldStopHere (this, ThreadPlanStepInRange::DefaultShouldStopHereCallback, NULL),
+ m_step_past_prologue (true),
+ m_virtual_step (false),
+ m_step_into_target (step_into_target)
+{
+ SetFlagsToDefault ();
+}
+
ThreadPlanStepInRange::~ThreadPlanStepInRange ()
{
}
@@ -65,6 +82,7 @@
{
s->Printf ("Stepping through range (stepping into functions): ");
DumpRanges(s);
+ s->Printf ("targeting %s.", m_step_into_target.AsCString());
}
}
@@ -140,6 +158,7 @@
}
SetPlanComplete();
+ m_no_more_plans = true;
return true;
}
@@ -279,15 +298,40 @@
}
}
- if (!should_step_out)
+ if (current_plan->GetKind() == eKindStepInRange)
{
- if (current_plan->GetKind() == eKindStepInRange)
+ ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
+ if (step_in_range_plan->m_step_into_target)
+ {
+ SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
+ if (sc.symbol != NULL)
+ {
+ // First try an exact match, since that's cheap with ConstStrings. Then do a strstr compare.
+ if (step_in_range_plan->m_step_into_target == sc.GetFunctionName())
+ {
+ should_step_out = false;
+ }
+ else
+ {
+ const char *target_name = step_in_range_plan->m_step_into_target.AsCString();
+ const char *function_name = sc.GetFunctionName().AsCString();
+
+ if (function_name == NULL)
+ should_step_out = true;
+ else if (strstr (function_name, target_name) == NULL)
+ should_step_out = true;
+ }
+ }
+ }
+
+ if (!should_step_out)
{
- ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
- should_step_out = step_in_range_plan->FrameMatchesAvoidRegexp ();
+ ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
+ should_step_out = step_in_range_plan->FrameMatchesAvoidRegexp ();
}
}
+
if (should_step_out)
{
// FIXME: Make sure the ThreadPlanForStepOut does the right thing with inlined functions.
@@ -307,14 +351,18 @@
}
bool
-ThreadPlanStepInRange::PlanExplainsStop ()
+ThreadPlanStepInRange::PlanExplainsStop (Event *event_ptr)
{
// We always explain a stop. Either we've just done a single step, in which
// case we'll do our ordinary processing, or we stopped for some
// reason that isn't handled by our sub-plans, in which case we want to just stop right
// away.
- // We also set ourselves complete when we stop for this sort of unintended reason, but mark
- // success as false so we don't end up being the reason for the stop.
+ // In general, we don't want to mark the plan as complete for unexplained stops.
+ // For instance, if you step in to some code with no debug info, so you step out
+ // and in the course of that hit a breakpoint, then you want to stop & show the user
+ // the breakpoint, but not unship the step in plan, since you still may want to complete that
+ // plan when you continue. This is particularly true when doing "step in to target function."
+ // stepping.
//
// The only variation is that if we are doing "step by running to next branch" in which case
// if we hit our branch breakpoint we don't set the plan to complete.
@@ -335,12 +383,14 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonThreadExiting:
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
- SetPlanComplete(false);
}
+ return false;
break;
default:
break;
Index: aze/lldb/source/Target/ThreadPlanStepInstruction.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepInstruction.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepInstruction.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -81,7 +81,7 @@
}
bool
-ThreadPlanStepInstruction::PlanExplainsStop ()
+ThreadPlanStepInstruction::PlanExplainsStop (Event *event_ptr)
{
StopInfoSP stop_info_sp = GetPrivateStopReason();
if (stop_info_sp)
Index: aze/lldb/source/Target/ThreadPlanStepOut.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepOut.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepOut.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -107,6 +107,7 @@
{
return_bp->SetThreadID(m_thread.GetID());
m_return_bp_id = return_bp->GetID();
+ return_bp->SetBreakpointKind ("step-out");
}
if (immediate_return_from_sp)
@@ -148,7 +149,7 @@
else if (m_step_through_inline_plan_sp)
s->Printf ("Stepping out by stepping through inlined function.");
else
- s->Printf ("Stepping out from address 0x%llx to return address 0x%llx using breakpoint site %d",
+ s->Printf ("Stepping out from address 0x%" PRIx64 " to return address 0x%" PRIx64 " using breakpoint site %d",
(uint64_t)m_step_from_insn,
(uint64_t)m_return_addr,
m_return_bp_id);
@@ -173,7 +174,7 @@
}
bool
-ThreadPlanStepOut::PlanExplainsStop ()
+ThreadPlanStepOut::PlanExplainsStop (Event *event_ptr)
{
// If one of our child plans just finished, then we do explain the stop.
if (m_step_out_plan_sp)
@@ -251,6 +252,8 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonThreadExiting:
return false;
default:
Index: aze/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -48,7 +48,7 @@
void
ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
- s->Printf("Single stepping past breakpoint site %llu at 0x%llx", m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
+ s->Printf("Single stepping past breakpoint site %" PRIu64 " at 0x%" PRIx64, m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
}
bool
@@ -58,7 +58,7 @@
}
bool
-ThreadPlanStepOverBreakpoint::PlanExplainsStop ()
+ThreadPlanStepOverBreakpoint::PlanExplainsStop (Event *event_ptr)
{
StopInfoSP stop_info_sp = GetPrivateStopReason();
if (stop_info_sp)
@@ -99,7 +99,7 @@
{
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
if (bp_site_sp && bp_site_sp->IsEnabled())
- m_thread.GetProcess()->DisableBreakpoint (bp_site_sp.get());
+ m_thread.GetProcess()->DisableBreakpointSite (bp_site_sp.get());
}
return true;
}
@@ -109,7 +109,7 @@
{
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
if (bp_site_sp)
- m_thread.GetProcess()->EnableBreakpoint (bp_site_sp.get());
+ m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get());
return true;
}
@@ -132,7 +132,7 @@
// Otherwise, re-enable the breakpoint we were stepping over, and we're done.
BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
if (bp_site_sp)
- m_thread.GetProcess()->EnableBreakpoint (bp_site_sp.get());
+ m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get());
ThreadPlan::MischiefManaged ();
return true;
}
Index: aze/lldb/source/Target/ThreadPlanStepOverRange.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepOverRange.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepOverRange.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -290,7 +290,7 @@
}
bool
-ThreadPlanStepOverRange::PlanExplainsStop ()
+ThreadPlanStepOverRange::PlanExplainsStop (Event *event_ptr)
{
// For crashes, breakpoint hits, signals, etc, let the base plan (or some plan above us)
// handle the stop. That way the user can see the stop, step around, and then when they
@@ -319,6 +319,8 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonThreadExiting:
default:
if (log)
log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step.");
Index: aze/lldb/source/Target/ThreadPlanStepRange.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepRange.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepRange.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -190,7 +190,7 @@
}
if (!ret_value && log)
- log->Printf ("Step range plan out of range to 0x%llx", pc_load_addr);
+ log->Printf ("Step range plan out of range to 0x%" PRIx64, pc_load_addr);
return ret_value;
}
@@ -265,8 +265,11 @@
{
//Disassemble the address range given:
ExecutionContext exe_ctx (m_thread.GetProcess());
+ const char *plugin_name = NULL;
+ const char *flavor = NULL;
m_instruction_ranges[i] = Disassembler::DisassembleRange(GetTarget().GetArchitecture(),
- NULL,
+ plugin_name,
+ flavor,
exe_ctx,
m_address_ranges[i]);
@@ -334,8 +337,13 @@
const bool is_internal = true;
run_to_address = instructions->GetInstructionAtIndex(branch_index)->GetAddress();
m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal);
- m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
- return true;
+ if (m_next_branch_bp_sp)
+ {
+ m_next_branch_bp_sp->SetThreadID(m_thread.GetID());
+ m_next_branch_bp_sp->SetBreakpointKind ("next-branch-location");
+ }
+ else
+ return false;
}
}
return false;
Index: aze/lldb/source/Target/ThreadPlanStepThrough.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepThrough.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepThrough.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -61,11 +61,12 @@
{
return_bp->SetThreadID(m_thread.GetID());
m_backstop_bkpt_id = return_bp->GetID();
+ return_bp->SetBreakpointKind("step-through-backstop");
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
{
- log->Printf ("Setting backstop breakpoint %d at address: 0x%llx", m_backstop_bkpt_id, m_backstop_addr);
+ log->Printf ("Setting backstop breakpoint %d at address: 0x%" PRIx64, m_backstop_bkpt_id, m_backstop_addr);
}
}
}
@@ -103,11 +104,11 @@
{
StreamString s;
m_sub_plan_sp->GetDescription(&s, lldb::eDescriptionLevelFull);
- log->Printf ("Found step through plan from 0x%llx: %s", current_address, s.GetData());
+ log->Printf ("Found step through plan from 0x%" PRIx64 ": %s", current_address, s.GetData());
}
else
{
- log->Printf ("Couldn't find step through plan from address 0x%llx.", current_address);
+ log->Printf ("Couldn't find step through plan from address 0x%" PRIx64 ".", current_address);
}
}
}
@@ -138,7 +139,7 @@
}
bool
-ThreadPlanStepThrough::PlanExplainsStop ()
+ThreadPlanStepThrough::PlanExplainsStop (Event *event_ptr)
{
// If we have a sub-plan, it will have been asked first if we explain the stop, and
// we won't get asked. The only time we would be the one directly asked this question
Index: aze/lldb/source/Target/ThreadPlanStepUntil.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanStepUntil.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanStepUntil.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -73,6 +73,7 @@
{
return_bp->SetThreadID(thread_id);
m_return_bp_id = return_bp->GetID();
+ return_bp->SetBreakpointKind ("until-return-backstop");
}
}
@@ -86,6 +87,7 @@
{
until_bp->SetThreadID(thread_id);
m_until_points[address_list[i]] = until_bp->GetID();
+ until_bp->SetBreakpointKind("until-target");
}
else
{
@@ -133,21 +135,21 @@
else
{
if (m_until_points.size() == 1)
- s->Printf ("Stepping from address 0x%llx until we reach 0x%llx using breakpoint %d",
+ s->Printf ("Stepping from address 0x%" PRIx64 " until we reach 0x%" PRIx64 " using breakpoint %d",
(uint64_t)m_step_from_insn,
(uint64_t) (*m_until_points.begin()).first,
(*m_until_points.begin()).second);
else
{
until_collection::iterator pos, end = m_until_points.end();
- s->Printf ("Stepping from address 0x%llx until we reach one of:",
+ s->Printf ("Stepping from address 0x%" PRIx64 " until we reach one of:",
(uint64_t)m_step_from_insn);
for (pos = m_until_points.begin(); pos != end; pos++)
{
- s->Printf ("\n\t0x%llx (bp: %d)", (uint64_t) (*pos).first, (*pos).second);
+ s->Printf ("\n\t0x%" PRIx64 " (bp: %d)", (uint64_t) (*pos).first, (*pos).second);
}
}
- s->Printf(" stepped out address is 0x%llx.", (uint64_t) m_return_addr);
+ s->Printf(" stepped out address is 0x%" PRIx64 ".", (uint64_t) m_return_addr);
}
}
@@ -291,6 +293,8 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonThreadExiting:
m_explains_stop = false;
break;
default:
@@ -301,7 +305,7 @@
}
bool
-ThreadPlanStepUntil::PlanExplainsStop ()
+ThreadPlanStepUntil::PlanExplainsStop (Event *event_ptr)
{
// We don't explain signals or breakpoints (breakpoints that handle stepping in or
// out will be handled by a child plan.
Index: aze/lldb/source/Target/ThreadPlanTracer.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadPlanTracer.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadPlanTracer.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Target/ThreadPlan.h"
// C Includes
@@ -118,7 +120,7 @@
ThreadPlanAssemblyTracer::GetDisassembler ()
{
if (m_disassembler_sp.get() == NULL)
- m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL);
+ m_disassembler_sp = Disassembler::FindPlugin(m_thread.GetProcess()->GetTarget().GetArchitecture(), NULL, NULL);
return m_disassembler_sp.get();
}
Index: aze/lldb/source/Target/ThreadSpec.cpp
===================================================================
--- aze.orig/lldb/source/Target/ThreadSpec.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Target/ThreadSpec.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -140,7 +140,7 @@
else
{
if (GetTID() != LLDB_INVALID_THREAD_ID)
- s->Printf("tid: 0x%llx ", GetTID());
+ s->Printf("tid: 0x%" PRIx64 " ", GetTID());
if (GetIndex() != UINT32_MAX)
s->Printf("index: %d ", GetIndex());
Index: aze/lldb/source/Utility/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Utility/CMakeLists.txt 2013-03-03 09:35:50.287457349 +0100
@@ -0,0 +1,13 @@
+set(LLVM_NO_RTTI 1)
+
+add_lldb_library(lldbUtility
+ ARM_DWARF_Registers.cpp
+ KQueue.cpp
+ PseudoTerminal.cpp
+ RefCounter.cpp
+ SharingPtr.cpp
+ StringExtractor.cpp
+ StringExtractorGDBRemote.cpp
+ TimeSpecTimeout.cpp
+ )
+
Index: aze/lldb/source/Utility/KQueue.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Utility/KQueue.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -0,0 +1,87 @@
+//===--------------------- lldb/KQueue.cpp ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "KQueue.h"
+
+#ifdef LLDB_USE_KQUEUES
+
+#include "lldb/Core/Error.h"
+
+#include "Utility/TimeSpecTimeout.h"
+
+using namespace lldb_private;
+
+int
+KQueue::GetFD (bool can_create)
+{
+ if (!IsValid () && can_create)
+ m_fd = kqueue();
+ return m_fd;
+}
+
+int
+KQueue::Close ()
+{
+ const int fd = m_fd;
+ if (fd >= 0)
+ {
+ m_fd = -1;
+ return close(fd);
+ }
+ return 0;
+}
+
+int
+KQueue::WaitForEvents (struct kevent *events, int num_events, Error &error, uint32_t timeout_usec)
+{
+ const int fd_kqueue = GetFD(false);
+ if (fd_kqueue >= 0)
+ {
+ TimeSpecTimeout timeout;
+ const struct timespec *timeout_ptr = timeout.SetRelativeTimeoutMircoSeconds32 (timeout_usec);
+ int result = ::kevent(fd_kqueue, NULL, 0, events, num_events, timeout_ptr);
+ if (result == -1)
+ error.SetErrorToErrno();
+ else
+ error.Clear();
+ return result;
+ }
+ else
+ {
+ error.SetErrorString("invalid kqueue fd");
+ }
+ return 0;
+}
+
+bool
+KQueue::AddFDEvent (int fd, bool read, bool write, bool vnode)
+{
+ const int fd_kqueue = GetFD(true);
+ if (fd_kqueue >= 0)
+ {
+ struct kevent event;
+ event.ident = fd;
+ event.filter = 0;
+ if (read)
+ event.filter |= EVFILT_READ;
+ if (write)
+ event.filter |= EVFILT_WRITE;
+ if (vnode)
+ event.filter |= EVFILT_VNODE;
+ event.flags = EV_ADD | EV_CLEAR;
+ event.fflags = 0;
+ event.data = 0;
+ event.udata = NULL;
+ int err = ::kevent(fd_kqueue, &event, 1, NULL, 0, NULL);
+ return err == 0;
+ }
+ return false;
+}
+
+#endif
Index: aze/lldb/source/Utility/KQueue.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Utility/KQueue.h 2013-03-03 09:35:50.287457349 +0100
@@ -0,0 +1,72 @@
+//===--------------------- lldb/KQueue.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_KQueue_h_
+#define utility_KQueue_h_
+
+#if defined(__APPLE__)
+#define LLDB_USE_KQUEUES
+#endif
+
+#ifdef LLDB_USE_KQUEUES
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+
+#include "lldb-defines.h"
+
+namespace lldb_private {
+
+class KQueue
+{
+public:
+ KQueue() :
+ m_fd(-1)
+ {
+ }
+
+ ~KQueue()
+ {
+ Close();
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_fd >= 0;
+ }
+
+ int
+ GetFD (bool can_create);
+
+ int
+ Close ();
+
+ bool
+ AddFDEvent (int fd,
+ bool read,
+ bool write,
+ bool vnode);
+
+ int
+ WaitForEvents (struct kevent *events,
+ int num_events,
+ Error &error,
+ uint32_t timeout_usec = UINT32_MAX); // UINT32_MAX means infinite timeout
+
+protected:
+ int m_fd; // The kqueue fd
+};
+
+} // namespace lldb_private
+
+#endif // #ifdef LLDB_USE_KQUEUES
+
+#endif // #ifndef utility_KQueue_h_
Index: aze/lldb/source/Utility/Makefile
===================================================================
--- aze.orig/lldb/source/Utility/Makefile 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Utility/Makefile 2013-03-03 09:35:50.287457349 +0100
@@ -10,5 +10,6 @@
LLDB_LEVEL := ../..
LIBRARYNAME := lldbUtility
BUILD_ARCHIVE = 1
+NO_PEDANTIC = 1
include $(LLDB_LEVEL)/Makefile
Index: aze/lldb/source/Utility/StringExtractor.cpp
===================================================================
--- aze.orig/lldb/source/Utility/StringExtractor.cpp 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Utility/StringExtractor.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -134,7 +134,7 @@
++m_index;
return ch;
}
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -148,8 +148,8 @@
uint32_t i = m_index;
if ((i + 2) <= m_packet.size())
{
- const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[m_packet[i]];
- const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[m_packet[i+1]];
+ const uint8_t hi_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i])];
+ const uint8_t lo_nibble = g_hex_ascii_to_hex_integer[static_cast<uint8_t>(m_packet[i+1])];
if (hi_nibble < 16 && lo_nibble < 16)
{
m_index += 2;
@@ -157,7 +157,7 @@
}
}
if (set_eof_on_fail || m_index >= m_packet.size())
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -195,7 +195,7 @@
// Make sure we don't exceed the size of a uint32_t...
if (nibble_count >= (sizeof(uint32_t) * 2))
{
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -227,7 +227,7 @@
// Make sure we don't exceed the size of a uint32_t...
if (nibble_count >= (sizeof(uint32_t) * 2))
{
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -257,7 +257,7 @@
// Make sure we don't exceed the size of a uint64_t...
if (nibble_count >= (sizeof(uint64_t) * 2))
{
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -289,7 +289,7 @@
// Make sure we don't exceed the size of a uint64_t...
if (nibble_count >= (sizeof(uint64_t) * 2))
{
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -341,7 +341,7 @@
// Little Endian
uint32_t shift_amount;
for (i = 0, shift_amount = 0;
- i < byte_size && m_index != UINT32_MAX;
+ i < byte_size && IsGood();
++i, shift_amount += 8)
{
result |= ((uint64_t)GetHexU8() << shift_amount);
@@ -350,14 +350,14 @@
else
{
// Big Endian
- for (i = 0; i < byte_size && m_index != UINT32_MAX; ++i)
+ for (i = 0; i < byte_size && IsGood(); ++i)
{
result <<= 8;
result |= GetHexU8();
}
}
}
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return fail_value;
}
@@ -392,6 +392,6 @@
}
}
}
- m_index = UINT32_MAX;
+ m_index = UINT64_MAX;
return false;
}
Index: aze/lldb/source/Utility/StringExtractor.h
===================================================================
--- aze.orig/lldb/source/Utility/StringExtractor.h 2013-03-03 09:35:47.783457405 +0100
+++ aze/lldb/source/Utility/StringExtractor.h 2013-03-03 09:35:50.287457349 +0100
@@ -45,10 +45,10 @@
bool
IsGood() const
{
- return m_index != UINT32_MAX;
+ return m_index != UINT64_MAX;
}
- uint32_t
+ uint64_t
GetFilePos () const
{
return m_index;
@@ -79,7 +79,7 @@
return m_packet.empty();
}
- uint32_t
+ size_t
GetBytesLeft ()
{
if (m_index < m_packet.size())
@@ -126,9 +126,9 @@
// For StringExtractor only
//------------------------------------------------------------------
std::string m_packet; // The string in which to extract data.
- uint32_t m_index; // When extracting data from a packet, this index
+ uint64_t m_index; // When extracting data from a packet, this index
// will march along as things get extracted. If set
- // to UINT32_MAX the end of the packet data was
+ // to UINT64_MAX the end of the packet data was
// reached when decoding information
};
Index: aze/lldb/source/Utility/TimeSpecTimeout.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Utility/TimeSpecTimeout.cpp 2013-03-03 09:35:50.287457349 +0100
@@ -0,0 +1,48 @@
+//===--------------------- lldb/TimeSpecTimeout.cpp ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TimeSpecTimeout.h"
+
+using namespace lldb_private;
+
+const struct timespec *
+TimeSpecTimeout::SetAbsoluteTimeoutMircoSeconds32 (uint32_t timeout_usec)
+{
+ if (timeout_usec == UINT32_MAX)
+ {
+ m_infinite = true;
+ }
+ else
+ {
+ m_infinite = false;
+ TimeValue time_value(TimeValue::Now());
+ time_value.OffsetWithMicroSeconds(timeout_usec);
+ m_timespec = time_value.GetAsTimeSpec();
+ }
+ return GetTimeSpecPtr ();
+}
+
+const struct timespec *
+TimeSpecTimeout::SetRelativeTimeoutMircoSeconds32 (uint32_t timeout_usec)
+{
+ if (timeout_usec == UINT32_MAX)
+ {
+ m_infinite = true;
+ }
+ else
+ {
+ m_infinite = false;
+ TimeValue time_value;
+ time_value.OffsetWithMicroSeconds(timeout_usec);
+ m_timespec = time_value.GetAsTimeSpec();
+ }
+ return GetTimeSpecPtr ();
+}
+
+
Index: aze/lldb/source/Utility/TimeSpecTimeout.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/source/Utility/TimeSpecTimeout.h 2013-03-03 09:35:50.287457349 +0100
@@ -0,0 +1,90 @@
+//===--------------------- lldb/TimeSpecTimeout.h --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef utility_TimeSpecTimeout_h_
+#define utility_TimeSpecTimeout_h_
+
+#include "lldb/Host/TimeValue.h"
+
+namespace lldb_private {
+
+class TimeSpecTimeout
+{
+public:
+ TimeSpecTimeout() :
+ m_infinite (false)
+ {
+ m_timespec.tv_sec = 0;
+ m_timespec.tv_nsec = 0;
+ }
+ ~TimeSpecTimeout()
+ {
+ }
+
+ //----------------------------------------------------------------------
+ /// Sets the timespec pointer correctly given a timeout relative to the
+ /// current time. This function should be called immediately prior to
+ /// calling the function you will use this timeout with since time can
+ /// elapse between when this function is called and when the timeout is
+ /// used.
+ ///
+ /// @param[in] timeout_usec
+ /// The timeout in micro seconds. If timeout_usec is UINT32_MAX, the
+ /// timeout should be set to INFINITE. Otherwise the current time is
+ /// filled into the timespec and \a timeout_usec is added to the
+ /// current time.
+ ///
+ /// @return
+ /// If the timeout is INFINITE, then return NULL, otherwise return
+ /// a pointer to the timespec with the appropriate timeout value.
+ //----------------------------------------------------------------------
+ const struct timespec *
+ SetAbsoluteTimeoutMircoSeconds32 (uint32_t timeout_usec);
+
+ //----------------------------------------------------------------------
+ /// Sets the timespec pointer correctly given a relative time in micro
+ /// seconds.
+ ///
+ /// @param[in] timeout_usec
+ /// The timeout in micro seconds. If timeout_usec is UINT32_MAX, the
+ /// timeout should be set to INFINITE. Otherwise \a timeout_usec
+ /// is correctly placed into the timespec.
+ ///
+ /// @return
+ /// If the timeout is INFINITE, then return NULL, otherwise return
+ /// a pointer to the timespec with the appropriate timeout value.
+ //----------------------------------------------------------------------
+ const struct timespec *
+ SetRelativeTimeoutMircoSeconds32 (uint32_t timeout_usec);
+
+ //----------------------------------------------------------------------
+ /// Gets the timespec pointer that is appropriate for the timeout
+ /// specified. This function should only be used after a call to
+ /// SetRelativeTimeoutXXX() functions.
+ ///
+ /// @return
+ /// If the timeout is INFINITE, then return NULL, otherwise return
+ /// a pointer to the timespec with the appropriate timeout value.
+ //----------------------------------------------------------------------
+ const struct timespec *
+ GetTimeSpecPtr () const
+ {
+ if (m_infinite)
+ return NULL;
+ return &m_timespec;
+ }
+
+protected:
+ struct timespec m_timespec;
+ bool m_infinite;
+};
+
+} // namespace lldb_private
+
+#endif // #ifndef utility_TimeSpecTimeout_h_
Index: aze/lldb/test/api/check_public_api_headers/Makefile
===================================================================
--- aze.orig/lldb/test/api/check_public_api_headers/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/api/check_public_api_headers/Makefile 2013-03-03 09:35:50.291457349 +0100
@@ -6,7 +6,7 @@
ifeq "$(MY_OS)" "Darwin"
LD_EXTRAS ?= -framework LLDB
else
- LD_EXTRAS ?= $(LLDB_BUILD_DIR)/_lldb.so
+ LD_EXTRAS ?= $(LLDB_LIB_DIR)/liblldb.so
endif
# Example dictionary to pass to the Python build method:
Index: aze/lldb/test/api/check_public_api_headers/TestPublicAPIHeaders.py
===================================================================
--- aze.orig/lldb/test/api/check_public_api_headers/TestPublicAPIHeaders.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/api/check_public_api_headers/TestPublicAPIHeaders.py 2013-03-03 09:35:50.291457349 +0100
@@ -14,21 +14,21 @@
def setUp(self):
TestBase.setUp(self)
- self.build_dir = os.environ["LLDB_BUILD_DIR"]
+ self.lib_dir = os.environ["LLDB_LIB_DIR"]
self.template = 'main.cpp.template'
self.source = 'main.cpp'
def test_sb_api_directory(self):
"""Test the SB API directory and make sure there's no unwanted stuff."""
- if sys.platform.startswith("darwin") and self.getArchitecture() == "i386":
- self.skipTest("LLDB.framework built 64-bit")
+ if self.getArchitecture() == "i386":
+ self.skipTest("LLDB is 64-bit and cannot be linked to 32-bit test program.")
# Call the program generator to produce main.cpp.
self.generate_main_cpp()
if sys.platform.startswith("darwin"):
- d = {'FRAMEWORK_INCLUDES' : "-F%s" % self.build_dir}
+ d = {'FRAMEWORK_INCLUDES' : "-F%s" % self.lib_dir}
if sys.platform.startswith("linux") or os.environ.get('LLDB_BUILD_TYPE') == 'Makefile':
d = {'FRAMEWORK_INCLUDES' : "-I%s" % os.path.join(os.environ["LLDB_SRC"], "include")}
self.buildDefault(dictionary=d)
@@ -69,18 +69,14 @@
self.line_to_break = line_number(self.source, '// Set breakpoint here.')
- if sys.platform.startswith("darwin"):
- env_var = 'DYLD_FRAMEWORK_PATH'
- env_val = self.build_dir
- if sys.platform.startswith("linux"):
- env_var = 'LD_LIBRARY_PATH'
- env_val = self.build_dir
+ existing_library_path = os.environ[self.dylibPath] if self.dylibPath in os.environ else None
- env_cmd = "settings set target.env-vars %s=%s" %(env_var, env_val)
+ env_val = self.lib_dir if not existing_library_path else "%s:%s" % (existing_library_path, self.lib_dir)
+ env_cmd = "settings set target.env-vars %s=%s" %(self.dylibPath, env_val)
if self.TraceOn():
print "Set environment to: ", env_cmd
self.runCmd(env_cmd)
- self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars %s" % env_var))
+ self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars %s" % self.dylibPath))
lldbutil.run_break_set_by_file_and_line (self, self.source, self.line_to_break, num_expected_locations = -1)
Index: aze/lldb/test/argparse_compat.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/argparse_compat.py 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+"""
+Compatibility module to use the lldb test-suite with Python 2.6.
+
+Warning: This may be buggy. It has not been extensively tested and should only
+be used when it is impossible to use a newer Python version.
+It is also a special-purpose class for lldb's test-suite.
+"""
+
+import sys
+
+if sys.version_info >= (2, 7):
+ raise "This module shouldn't be used when argparse is available (Python >= 2.7)"
+else:
+ print "Using Python 2.6 compatibility layer. Some command line options may not be supported"
+
+
+import optparse
+
+
+class ArgumentParser(object):
+ def __init__(self, description="My program's description", prefix_chars='-', add_help=True):
+ self.groups = []
+ self.parser = optparse.OptionParser(description=description, add_help_option=add_help)
+ self.prefix_chars = prefix_chars
+
+ def add_argument_group(self, name):
+ group = optparse.OptionGroup(self.parser, name)
+ # Hack around our test directories argument (what's left after the
+ # options)
+ if name != 'Test directories':
+ self.groups.append(group)
+ return ArgumentGroup(group)
+
+ def add_argument(self, *opt_strs, **kwargs):
+ self.parser.add_option(*opt_strs, **kwargs)
+ # def add_argument(self, opt_str, action='store', dest=None, metavar=None, help=''):
+ # if dest is None and metavar is None:
+ # self.parser.add_argument(opt_str, action=action, help=help)
+
+ def parse_args(self, arguments=sys.argv[1:]):
+ map(lambda g: self.parser.add_option_group(g), self.groups)
+ (options, args) = self.parser.parse_args(arguments)
+ d = vars(options)
+ d['args'] = args
+ return Namespace(d)
+
+ def print_help(self):
+ self.parser.print_help()
+
+
+class ArgumentGroup(object):
+ def __init__(self, option_group):
+ self.option_group = option_group
+
+ def add_argument(self, *opt_strs, **kwargs):
+ # Hack around our positional argument (the test directories)
+ if opt_strs == ('args',):
+ return
+
+ # Hack around the options that start with '+'
+ if len(opt_strs) == 1 and opt_strs[0] == '+a':
+ opt_strs = ('--plus_a',)
+ if len(opt_strs) == 1 and opt_strs[0] == '+b':
+ opt_strs = ('--plus_b',)
+ self.option_group.add_option(*opt_strs, **kwargs)
+
+
+class Namespace(object):
+ def __init__(self, d):
+ self.__dict__ = d
+
+ def __str__(self):
+ strings = []
+ for (k, v) in self.__dict__.iteritems():
+ strings.append(str(k) + '=' + str(v))
+ strings.sort()
+
+ return self.__class__.__name__ + '(' + ', '.join(strings) + ')'
Index: aze/lldb/test/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/CMakeLists.txt 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,51 @@
+function(add_python_test_target name test_script args comment)
+ set(PYTHON_TEST_COMMAND
+ ${PYTHON_EXECUTABLE}
+ ${test_script}
+ ${args}
+ )
+
+ add_custom_target(${name}
+ COMMAND ${PYTHON_TEST_COMMAND} ${ARG_DEFAULT_ARGS}
+ COMMENT "${comment}"
+ )
+endfunction()
+
+# Users can override LLDB_TEST_ARGS to modify the way LLDB tests are run. See help below.
+set(LLDB_TEST_ARGS
+ -C
+ ${CMAKE_C_COMPILER}
+ CACHE STRING "Specify compiler(s) and architecture(s) with which run LLDB tests. For example: '-C gcc -C clang -A i386 -A x86_64'"
+ )
+string(REPLACE " " ";" LLDB_TEST_ARGS ${LLDB_TEST_ARGS})
+
+set(LLDB_TRACE_DIR "${CMAKE_BINARY_DIR}/lldb-test-traces"
+ CACHE STRING "Set directory to output LLDB test traces (for tests that do not pass.)"
+ )
+
+set(LLDB_COMMON_TEST_ARGS
+ #--headers
+ #${LLDB_SOURCE_DIR}/include
+ --executable
+ ${CMAKE_BINARY_DIR}/bin/lldb
+ -s
+ ${LLDB_TRACE_DIR}
+ )
+
+add_python_test_target(check-lldb-single
+ ${LLDB_SOURCE_DIR}/test/dotest.py
+ "${LLDB_COMMON_TEST_ARGS};${LLDB_TEST_ARGS}"
+ "Testing LLDB with args: ${LLDB_COMMON_TEST_ARGS};${LLDB_TEST_ARGS}"
+ )
+
+set(LLDB_DOSEP_ARGS
+ -o;\"-q;${LLDB_COMMON_TEST_ARGS};${LLDB_TEST_ARGS}\"
+ )
+
+# If tests crash cause LLDB to crash, or things are otherwise unstable, or if machine-parsable
+# output is desired (i.e. in continuous integration contexts) check-lldb-sep is a better target.
+add_python_test_target(check-lldb
+ ${LLDB_SOURCE_DIR}/test/dosep.ty
+ "${LLDB_DOSEP_ARGS}"
+ "Testing LLDB (with a separate subprocess per test) with args: ${LLDB_COMMON_TEST_ARGS};${LLDB_TEST_ARGS}"
+ )
Index: aze/lldb/test/dosep.ty
===================================================================
--- aze.orig/lldb/test/dosep.ty 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/dosep.ty 2013-03-03 09:35:50.291457349 +0100
@@ -12,6 +12,8 @@
def walk_and_invoke(test_root, dotest_options):
"""Look for matched file and invoke test driver on it."""
+ failed = []
+ passed = []
for root, dirs, files in os.walk(test_root, topdown=False):
for name in files:
path = os.path.join(root, name)
@@ -26,7 +28,11 @@
command = template % (test_root, dotest_options if dotest_options else "", name, root)
print "Running %s" % (command)
- os.system(command)
+ if 0 != os.system(command):
+ failed.append(name)
+ else:
+ passed.append(name)
+ return (failed, passed)
def main():
test_root = sys.path[0]
@@ -44,8 +50,15 @@
print "dotest.py options:", dotest_options
- walk_and_invoke(test_root, dotest_options)
-
+ (failed, passed) = walk_and_invoke(test_root, dotest_options)
+ num_tests = len(failed) + len(passed)
+ print "Ran %d tests." % num_tests
+ if len(failed) > 0:
+ print "Failing Tests (%d)" % len(failed)
+ for f in failed:
+ print "\tLLDB :: %s" % f
+ sys.exit(1)
+ sys.exit(0)
if __name__ == '__main__':
main()
Index: aze/lldb/test/dotest.py
===================================================================
--- aze.orig/lldb/test/dotest.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/dotest.py 2013-03-03 09:35:50.291457349 +0100
@@ -20,7 +20,6 @@
for available options.
"""
-import argparse
import os
import platform
import signal
@@ -29,6 +28,12 @@
import textwrap
import time
import unittest2
+import progress
+
+if sys.version_info >= (2, 7):
+ argparse = __import__('argparse')
+else:
+ argparse = __import__('argparse_compat')
def is_exe(fpath):
"""Returns true if fpath is an executable."""
@@ -74,7 +79,8 @@
'dataformatters':'Tests related to the type command and the data formatters subsystem',
'expression':'Tests related to the expression parser',
'objc':'Tests related to the Objective-C programming language support',
-'pyapi':'Tests related to the Python API'
+'pyapi':'Tests related to the Python API',
+'basic_process': 'Basic process execution sniff tests.'
}
# The test suite.
@@ -95,7 +101,7 @@
# Use @dsym_test or @dwarf_test decorators, defined in lldbtest.py, to mark a test
# as a dsym or dwarf test. Use '-N dsym' or '-N dwarf' to exclude dsym or dwarf
# tests from running.
-dont_do_dsym_test = False
+dont_do_dsym_test = "linux" in sys.platform
dont_do_dwarf_test = False
# The blacklist is optional (-b blacklistFile) and allows a central place to skip
@@ -132,7 +138,7 @@
# The 'archs' and 'compilers' can be specified via either command line or configFile,
# with the command line overriding the configFile. The corresponding options can be
-# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
+# specified more than once. For example, "-A x86_64 -A i386" => archs=['x86_64', 'i386']
# and "-C gcc -C clang" => compilers=['gcc', 'clang'].
archs = None # Must be initialized after option parsing
compilers = None # Must be initialized after option parsing
@@ -186,6 +192,10 @@
# turn it off.
noHeaders = False
+# Parsable mode silences headers, and any other output this script might generate, and instead
+# prints machine-readable output similar to what clang tests produce.
+parsable = False
+
# The regular expression pattern to match against eligible filenames as our test cases.
regexp = None
@@ -206,11 +216,8 @@
# svn_info stores the output from 'svn info lldb.base.dir'.
svn_info = ''
-# The environment variables to unset before running the test cases.
-unsets = []
-
# Default verbosity is 0.
-verbose = 0
+verbose = 1
# Set to True only if verbose is 0 and LLDB trace mode is off.
progress_bar = False
@@ -221,6 +228,7 @@
# Separator string.
separator = '-' * 70
+failed = False
def usage(parser):
parser.print_help()
@@ -343,10 +351,10 @@
global skip_build_and_cleanup
global skip_long_running_test
global noHeaders
+ global parsable
global regexp
global rdir
global sdir_name
- global unsets
global verbose
global testdirs
@@ -377,7 +385,7 @@
X('+a', "Just do lldb Python API tests. Do not specify along with '+a'", dest='plus_a')
X('+b', 'Just do benchmark tests', dest='plus_b')
group.add_argument('-b', metavar='blacklist', help='Read a blacklist file specified after this option')
- group.add_argument('-f', metavar='filterspec', help='Specify a filter, which consists of the test class name, a dot, followed by the test method, to only admit such test into the test suite') # FIXME: Example?
+ group.add_argument('-f', metavar='filterspec', action='append', help='Specify a filter, which consists of the test class name, a dot, followed by the test method, to only admit such test into the test suite') # FIXME: Example?
X('-g', 'If specified, the filterspec by -f is not exclusive, i.e., if a test module does not match the filterspec (testclass.testmethod), the whole module is still admitted to the test suite')
X('-l', "Don't skip long running tests")
group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
@@ -404,9 +412,11 @@
X('-F', 'Fail fast. Stop the test suite on the first error/failure')
X('-i', "Ignore (don't bailout) if 'lldb.py' module cannot be located in the build tree relative to this script; use PYTHONPATH to locate the module")
X('-n', "Don't print the headers like build dir, lldb version, and svn info at all")
+ X('-P', "Use the graphic progress bar.")
+ X('-q', "Don't print extra output from this script.")
X('-S', "Skip the build and cleanup while running the test. Use this option with care as you would need to build the inferior(s) by hand and build the executable(s) with the correct name(s). This can be used with '-# n' to stress test certain test cases for n number of times")
X('-t', 'Turn on tracing of lldb command and other detailed test executions')
- group.add_argument('-u', metavar='variable', action='append', help='Specify an environment variable to unset before running the test cases. e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble')
+ group.add_argument('-u', dest='unset_env_varnames', metavar='variable', action='append', help='Specify an environment variable to unset before running the test cases. e.g., -u DYLD_INSERT_LIBRARIES -u MallocScribble')
X('-v', 'Do verbose mode of unittest framework (print out each test case invocation)')
X('-w', 'Insert some wait time (currently 0.5 sec) between consecutive test cases')
@@ -420,8 +430,16 @@
platform_system = platform.system()
platform_machine = platform.machine()
- # only print the args if being verbose
- if args.v:
+ if args.unset_env_varnames:
+ for env_var in args.unset_env_varnames:
+ if env_var in os.environ:
+ # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
+ # is automatically translated into a corresponding call to unsetenv().
+ del os.environ[env_var]
+ #os.unsetenv(env_var)
+
+ # only print the args if being verbose (and parsable is off)
+ if args.v and not args.q:
print args
if args.h:
@@ -510,9 +528,9 @@
failfast = True
if args.f:
- if args.f.startswith('-'):
+ if any([x.startswith('-') for x in args.f]):
usage(parser)
- filters.append(args.f)
+ filters.extend(args.f)
if args.g:
fs4all = False
@@ -540,6 +558,14 @@
usage(parser)
regexp = args.p
+ if args.q:
+ noHeaders = True
+ parsable = True
+
+ if args.P:
+ progress_bar = True
+ verbose = 0
+
if args.R:
if args.R.startswith('-'):
usage(parser)
@@ -568,9 +594,6 @@
if args.t:
os.environ['LLDB_COMMAND_TRACE'] = 'YES'
- if args.u:
- unsets.extend(args.u)
-
if args.v:
verbose = 2
@@ -602,10 +625,6 @@
if dont_do_python_api_test and just_do_python_api_test:
usage(parser)
- # The simple progress bar is turned on only if verbose == 0 and LLDB_COMMAND_TRACE is not 'YES'
- if ("LLDB_COMMAND_TRACE" not in os.environ or os.environ["LLDB_COMMAND_TRACE"] != "YES") and verbose == 0:
- progress_bar = True
-
# Gather all the dirs passed on the command line.
if len(args.args) > 0:
testdirs = map(os.path.abspath, args.args)
@@ -797,12 +816,14 @@
lldbExec = which('lldb')
if lldbHere and not lldbExec:
lldbExec = lldbHere
+ if lldbExec and not lldbHere:
+ lldbHere = lldbExec
if lldbHere:
os.environ["LLDB_HERE"] = lldbHere
- os.environ["LLDB_BUILD_DIR"] = os.path.split(lldbHere)[0]
+ os.environ["LLDB_LIB_DIR"] = os.path.split(lldbHere)[0]
if not noHeaders:
- print "LLDB build dir:", os.environ["LLDB_BUILD_DIR"]
+ print "LLDB library dir:", os.environ["LLDB_LIB_DIR"]
os.system('%s -v' % lldbHere)
if not lldbExec:
@@ -834,38 +855,62 @@
# The '-i' option is used to skip looking for lldb.py in the build tree.
if ignore:
return
+
+ # If our lldb supports the -P option, use it to find the python path:
+ init_in_python_dir = 'lldb/__init__.py'
+ import pexpect
+ lldb_dash_p_result = None
+
+ if lldbHere:
+ lldb_dash_p_result = pexpect.run("%s -P"%(lldbHere))
+ elif lldbExec:
+ lldb_dash_p_result = pexpect.run("%s -P"%(lldbExec))
+
+ if lldb_dash_p_result and not lldb_dash_p_result.startswith(("<", "lldb: invalid option:")):
+ lines = lldb_dash_p_result.splitlines()
+ if len(lines) == 1 and os.path.isfile(os.path.join(lines[0], init_in_python_dir)):
+ lldbPath = lines[0]
+ if "linux" in sys.platform:
+ os.environ['LLDB_LIB_DIR'] = os.path.join(lldbPath, '..', '..')
+
+ if not lldbPath:
+ dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
+ dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
+ dbcPath = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
+ dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
+ relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
+ relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
+ baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
+ baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
- dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
- dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
- dbcPath = os.path.join(base, *(xcode3_build_dir + dbc + python_resource_dir))
- dbcPath2 = os.path.join(base, *(xcode4_build_dir + dbc + python_resource_dir))
- relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
- relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
- baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
- baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
-
- if os.path.isfile(os.path.join(dbgPath, 'lldb/__init__.py')):
- lldbPath = dbgPath
- elif os.path.isfile(os.path.join(dbgPath2, 'lldb/__init__.py')):
- lldbPath = dbgPath2
- elif os.path.isfile(os.path.join(dbcPath, 'lldb/__init__.py')):
- lldbPath = dbcPath
- elif os.path.isfile(os.path.join(dbcPath2, 'lldb/__init__.py')):
- lldbPath = dbcPath2
- elif os.path.isfile(os.path.join(relPath, 'lldb/__init__.py')):
- lldbPath = relPath
- elif os.path.isfile(os.path.join(relPath2, 'lldb/__init__.py')):
- lldbPath = relPath2
- elif os.path.isfile(os.path.join(baiPath, 'lldb/__init__.py')):
- lldbPath = baiPath
- elif os.path.isfile(os.path.join(baiPath2, 'lldb/__init__.py')):
- lldbPath = baiPath2
-
+ if os.path.isfile(os.path.join(dbgPath, init_in_python_dir)):
+ lldbPath = dbgPath
+ elif os.path.isfile(os.path.join(dbgPath2, init_in_python_dir)):
+ lldbPath = dbgPath2
+ elif os.path.isfile(os.path.join(dbcPath, init_in_python_dir)):
+ lldbPath = dbcPath
+ elif os.path.isfile(os.path.join(dbcPath2, init_in_python_dir)):
+ lldbPath = dbcPath2
+ elif os.path.isfile(os.path.join(relPath, init_in_python_dir)):
+ lldbPath = relPath
+ elif os.path.isfile(os.path.join(relPath2, init_in_python_dir)):
+ lldbPath = relPath2
+ elif os.path.isfile(os.path.join(baiPath, init_in_python_dir)):
+ lldbPath = baiPath
+ elif os.path.isfile(os.path.join(baiPath2, init_in_python_dir)):
+ lldbPath = baiPath2
+
if not lldbPath:
print 'This script requires lldb.py to be in either ' + dbgPath + ',',
print relPath + ', or ' + baiPath
sys.exit(-1)
+ # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
+ # If the path we've constructed looks like that, then we'll strip out the Versions/A part.
+ (before, frameWithVersion, after) = lldbPath.rpartition("LLDB.framework/Versions/A")
+ if frameWithVersion != "" :
+ lldbPath = before + "LLDB.framework" + after
+
# If tests need to find LLDB_FRAMEWORK, now they can do it
os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPath))
@@ -1083,8 +1128,9 @@
except:
return repr(obj)
-print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
-print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
+if not noHeaders:
+ print "lldb.pre_flight:", getsource_if_available(lldb.pre_flight)
+ print "lldb.post_flight:", getsource_if_available(lldb.post_flight)
# Put all these test decorators in the lldb namespace.
lldb.dont_do_python_api_test = dont_do_python_api_test
@@ -1137,16 +1183,6 @@
print >> f, "Command invoked: %s\n" % getMyCommandLine()
#
-# If we have environment variables to unset, do it here before we invoke the test runner.
-#
-for env_var in unsets :
- if env_var in os.environ:
- # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
- # is automatically translated into a corresponding call to unsetenv().
- del os.environ[env_var]
- #os.unsetenv(env_var)
-
-#
# Invoke the default TextTestRunner to run the test suite, possibly iterating
# over different configurations.
#
@@ -1182,7 +1218,8 @@
compilers[i] = cmd_output.split('\n')[0]
print "'xcrun -find %s' returning %s" % (c, compilers[i])
-print "compilers=%s" % str(compilers)
+if not parsable:
+ print "compilers=%s" % str(compilers)
if not compilers or len(compilers) == 0:
print "No eligible compiler found, exiting."
@@ -1262,16 +1299,18 @@
sys.path = [x.replace(rdir, newrdir, 1) for x in old_sys_path]
# Output the configuration.
- sys.stderr.write("\nConfiguration: " + configString + "\n")
+ if not parsable:
+ sys.stderr.write("\nConfiguration: " + configString + "\n")
#print "sys.stderr name is", sys.stderr.name
#print "sys.stdout name is", sys.stdout.name
# First, write out the number of collected test cases.
- sys.stderr.write(separator + "\n")
- sys.stderr.write("Collected %d test%s\n\n"
- % (suite.countTestCases(),
- suite.countTestCases() != 1 and "s" or ""))
+ if not parsable:
+ sys.stderr.write(separator + "\n")
+ sys.stderr.write("Collected %d test%s\n\n"
+ % (suite.countTestCases(),
+ suite.countTestCases() != 1 and "s" or ""))
class LLDBTestResult(unittest2.TextTestResult):
"""
@@ -1285,6 +1324,30 @@
__singleton__ = None
__ignore_singleton__ = False
+ @staticmethod
+ def getTerminalSize():
+ import os
+ env = os.environ
+ def ioctl_GWINSZ(fd):
+ try:
+ import fcntl, termios, struct, os
+ cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
+ '1234'))
+ except:
+ return
+ return cr
+ cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
+ if not cr:
+ try:
+ fd = os.open(os.ctermid(), os.O_RDONLY)
+ cr = ioctl_GWINSZ(fd)
+ os.close(fd)
+ except:
+ pass
+ if not cr:
+ cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
+ return int(cr[1]), int(cr[0])
+
def __init__(self, *args):
if not LLDBTestResult.__ignore_singleton__ and LLDBTestResult.__singleton__:
raise Exception("LLDBTestResult instantiated more than once")
@@ -1299,6 +1362,19 @@
self.indentation = ' ' * (counterWidth + 2)
# This counts from 1 .. suite.countTestCases().
self.counter = 0
+ (width, height) = LLDBTestResult.getTerminalSize()
+ self.progressbar = None
+ global progress_bar
+ if width > 10 and not parsable and progress_bar:
+ try:
+ self.progressbar = progress.ProgressWithEvents(stdout=self.stream,start=0,end=suite.countTestCases(),width=width-10)
+ except:
+ self.progressbar = None
+
+ def _config_string(self, test):
+ compiler = getattr(test, "getCompiler", None)
+ arch = getattr(test, "getArchitecture", None)
+ return "%s-%s" % (compiler() if compiler else "", arch() if arch else "")
def _exc_info_to_string(self, err, test):
"""Overrides superclass TestResult's method in order to append
@@ -1316,7 +1392,14 @@
return str(test)
def getCategoriesForTest(self,test):
- if hasattr(test,"getCategories"):
+ if hasattr(test,"_testMethodName"):
+ test_method = getattr(test,"_testMethodName")
+ test_method = getattr(test,test_method)
+ else:
+ test_method = None
+ if test_method != None and hasattr(test_method,"getCategories"):
+ test_categories = test_method.getCategories(test)
+ elif hasattr(test,"getCategories"):
test_categories = test.getCategories()
elif inspect.ismethod(test) and test.__self__ != None and hasattr(test.__self__,"getCategories"):
test_categories = test.__self__.getCategories()
@@ -1348,22 +1431,34 @@
self.stream.write(self.fmt % self.counter)
super(LLDBTestResult, self).startTest(test)
+ def addSuccess(self, test):
+ global parsable
+ super(LLDBTestResult, self).addSuccess(test)
+ if parsable:
+ self.stream.write("PASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
+
def addError(self, test, err):
global sdir_has_content
+ global parsable
sdir_has_content = True
super(LLDBTestResult, self).addError(test, err)
method = getattr(test, "markError", None)
if method:
method()
+ if parsable:
+ self.stream.write("ERROR: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
def addFailure(self, test, err):
global sdir_has_content
global failuresPerCategory
+ global parsable
sdir_has_content = True
super(LLDBTestResult, self).addFailure(test, err)
method = getattr(test, "markFailure", None)
if method:
method()
+ if parsable:
+ self.stream.write("FAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
if useCategories:
test_categories = self.getCategoriesForTest(test)
for category in test_categories:
@@ -1372,34 +1467,50 @@
else:
failuresPerCategory[category] = 1
- def addExpectedFailure(self, test, err):
+ def addExpectedFailure(self, test, err, bugnumber):
global sdir_has_content
+ global parsable
sdir_has_content = True
- super(LLDBTestResult, self).addExpectedFailure(test, err)
+ super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
method = getattr(test, "markExpectedFailure", None)
if method:
- method()
+ method(err, bugnumber)
+ if parsable:
+ self.stream.write("XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
def addSkip(self, test, reason):
global sdir_has_content
+ global parsable
sdir_has_content = True
super(LLDBTestResult, self).addSkip(test, reason)
method = getattr(test, "markSkippedTest", None)
if method:
method()
+ if parsable:
+ self.stream.write("UNSUPPORTED: LLDB (%s) :: %s (%s) \n" % (self._config_string(test), str(test), reason))
- def addUnexpectedSuccess(self, test):
+ def addUnexpectedSuccess(self, test, bugnumber):
global sdir_has_content
+ global parsable
sdir_has_content = True
- super(LLDBTestResult, self).addUnexpectedSuccess(test)
+ super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
method = getattr(test, "markUnexpectedSuccess", None)
if method:
- method()
+ method(bugnumber)
+ if parsable:
+ self.stream.write("XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)))
+
+ if parsable:
+ v = 0
+ elif progress_bar:
+ v = 1
+ else:
+ v = verbose
# Invoke the test runner.
if count == 1:
result = unittest2.TextTestRunner(stream=sys.stderr,
- verbosity=(1 if progress_bar else verbose),
+ verbosity=v,
failfast=failfast,
resultclass=LLDBTestResult).run(suite)
else:
@@ -1408,13 +1519,15 @@
# not enforced.
LLDBTestResult.__ignore_singleton__ = True
for i in range(count):
+
result = unittest2.TextTestRunner(stream=sys.stderr,
- verbosity=(1 if progress_bar else verbose),
+ verbosity=v,
failfast=failfast,
resultclass=LLDBTestResult).run(suite)
+ failed = failed or not result.wasSuccessful()
-if sdir_has_content:
+if sdir_has_content and not parsable:
sys.stderr.write("Session logs for test failures/errors/unexpected successes"
" can be found in directory '%s'\n" % sdir_name)
@@ -1434,4 +1547,4 @@
subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
# Exiting.
-sys.exit(not result.wasSuccessful)
+sys.exit(failed)
Index: aze/lldb/test/expression_command/call-function/TestCallStdStringFunction.py
===================================================================
--- aze.orig/lldb/test/expression_command/call-function/TestCallStdStringFunction.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/call-function/TestCallStdStringFunction.py 2013-03-03 09:35:50.291457349 +0100
@@ -26,16 +26,18 @@
self.call_function()
@dwarf_test
+ @expectedFailureGcc # bugzilla 14437, fails with GCC 4.6.3 and 4.7.2
def test_with_dwarf(self):
"""Test calling std::String member function."""
- self.buildDsym()
+ self.buildDwarf()
self.call_function()
def call_function(self):
"""Test calling std::String member function."""
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, loc_exact=True)
+ # Some versions of GCC encode two locations for the 'return' statement in main.cpp
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
Index: aze/lldb/test/expression_command/call-restarts/lotta-signals.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/expression_command/call-restarts/lotta-signals.c 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,59 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+
+static int sigchld_no;
+static int nosig_no;
+static int weird_value;
+
+void
+sigchld_handler (int signo)
+{
+ sigchld_no++;
+ printf ("Got sigchld %d.\n", sigchld_no);
+}
+
+int
+call_me (int some_value)
+{
+ int ret_val = 0;
+ for (int i = 0; i < some_value; i++)
+ {
+ int result = 0;
+ if (i%2 == 0)
+ result = kill (getpid(), SIGCHLD);
+ else
+ sigchld_no++;
+
+ usleep(1000);
+ if (result == 0)
+ ret_val++;
+ }
+ usleep (10000);
+ return ret_val;
+}
+
+int
+call_me_nosig (int some_value)
+{
+ int ret_val = 0;
+ for (int i = 0; i < some_value; i++)
+ weird_value += i % 4;
+
+ nosig_no += some_value;
+ return some_value;
+}
+
+int
+main ()
+{
+ int ret_val;
+ signal (SIGCHLD, sigchld_handler);
+
+ ret_val = call_me (2); // Stop here in main.
+
+ ret_val = call_me_nosig (10);
+
+ return 0;
+
+}
Index: aze/lldb/test/expression_command/call-restarts/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/expression_command/call-restarts/Makefile 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := lotta-signals.c
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/expression_command/call-restarts/TestCallThatRestarts.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/expression_command/call-restarts/TestCallThatRestarts.py 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,149 @@
+"""
+Test calling a function that hits a signal set to auto-restart, make sure the call completes.
+"""
+
+import unittest2
+import lldb
+import lldbutil
+from lldbtest import *
+
+class ExprCommandWithTimeoutsTestCase(TestBase):
+
+ mydir = os.path.join("expression_command", "call-restarts")
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ self.main_source = "lotta-signals.c"
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test calling std::String member function."""
+ self.buildDsym()
+ self.call_function()
+
+ @skipOnLinux # PR-15278: handle expressions that generate signals on Linux
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test calling std::String member function."""
+ self.buildDwarf()
+ self.call_function()
+
+ def check_after_call (self, num_sigchld):
+ after_call = self.sigchld_no.GetValueAsSigned(-1)
+ self.assertTrue (after_call - self.start_sigchld_no == num_sigchld, "Really got %d SIGCHLD signals through the call."%(num_sigchld))
+ self.start_sigchld_no = after_call
+
+ # Check that we are back where we were before:
+ frame = self.thread.GetFrameAtIndex(0)
+ self.assertTrue (self.orig_frame_pc == frame.GetPC(), "Restored the zeroth frame correctly")
+
+
+ def call_function(self):
+ """Test calling function with timeout."""
+ exe_name = "a.out"
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+ empty = lldb.SBFileSpec()
+ breakpoint = target.BreakpointCreateBySourceRegex('Stop here in main.',self.main_source_spec)
+ self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be at our breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
+
+ self.assertTrue(len(threads) == 1)
+ self.thread = threads[0]
+
+ # Make sure the SIGCHLD behavior is pass/no-stop/no-notify:
+ return_obj = lldb.SBCommandReturnObject()
+ self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 0", return_obj)
+ self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop")
+
+ # The sigchld_no variable should be 0 at this point.
+ self.sigchld_no = target.FindFirstGlobalVariable("sigchld_no")
+ self.assertTrue (self.sigchld_no.IsValid(), "Got a value for sigchld_no")
+
+ self.start_sigchld_no = self.sigchld_no.GetValueAsSigned (-1)
+ self.assertTrue (self.start_sigchld_no != -1, "Got an actual value for sigchld_no")
+
+ options = lldb.SBExpressionOptions()
+ options.SetUnwindOnError(True)
+
+ frame = self.thread.GetFrameAtIndex(0)
+ # Store away the PC to check that the functions unwind to the right place after calls
+ self.orig_frame_pc = frame.GetPC()
+
+ num_sigchld = 30
+ value = frame.EvaluateExpression ("call_me (%d)"%(num_sigchld), options)
+ self.assertTrue (value.IsValid())
+ self.assertTrue (value.GetError().Success() == True)
+ self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
+
+ self.check_after_call(num_sigchld)
+
+ # Okay, now try with a breakpoint in the called code in the case where
+ # we are ignoring breakpoint hits.
+ handler_bkpt = target.BreakpointCreateBySourceRegex("Got sigchld %d.", self.main_source_spec)
+ self.assertTrue (handler_bkpt.GetNumLocations() > 0)
+ options.SetIgnoreBreakpoints(True)
+ options.SetUnwindOnError(True)
+
+ value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)
+
+ self.assertTrue (value.IsValid() and value.GetError().Success() == True)
+ self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
+ self.check_after_call(num_sigchld)
+
+ # Now set the signal to print but not stop and make sure that calling still works:
+ self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj)
+ self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify")
+
+ value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)
+
+ self.assertTrue (value.IsValid() and value.GetError().Success() == True)
+ self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
+ self.check_after_call(num_sigchld)
+
+ # Now set this unwind on error to false, and make sure that we still complete the call:
+ options.SetUnwindOnError(False)
+ value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)
+
+ self.assertTrue (value.IsValid() and value.GetError().Success() == True)
+ self.assertTrue (value.GetValueAsSigned(-1) == num_sigchld)
+ self.check_after_call(num_sigchld)
+
+ # Okay, now set UnwindOnError to true, and then make the signal behavior to stop
+ # and see that now we do stop at the signal point:
+
+ self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 1 -p 1 -n 1", return_obj)
+ self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, stop, notify")
+
+ value = frame.EvaluateExpression("call_me (%d)"%(num_sigchld), options)
+ self.assertTrue (value.IsValid() and value.GetError().Success() == False)
+
+ # Set signal handling back to no-stop, and continue and we should end up back in out starting frame:
+ self.dbg.GetCommandInterpreter().HandleCommand("process handle SIGCHLD -s 0 -p 1 -n 1", return_obj)
+ self.assertTrue (return_obj.Succeeded() == True, "Set SIGCHLD to pass, no-stop, notify")
+
+ error = process.Continue()
+ self.assertTrue (error.Success(), "Continuing after stopping for signal succeeds.")
+
+ frame = self.thread.GetFrameAtIndex(0)
+ self.assertTrue (frame.GetPC() == self.orig_frame_pc, "Continuing returned to the place we started.")
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/expression_command/call-throws/call-throws.m
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/expression_command/call-throws/call-throws.m 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,32 @@
+#import <Foundation/Foundation.h>
+
+@interface MyClass : NSObject
+{
+}
+- (int) callMeIThrow;
+@end
+
+@implementation MyClass
+- (int) callMeIThrow
+{
+ NSException *e = [NSException
+ exceptionWithName:@"JustForTheHeckOfItException"
+ reason:@"I felt like it"
+ userInfo:nil];
+ @throw e;
+ return 56;
+}
+@end
+
+int
+main ()
+{
+ int return_value;
+ MyClass *my_class = [[MyClass alloc] init];
+
+ NSLog (@"I am about to throw.");
+
+ return_value = [my_class callMeIThrow];
+
+ return return_value;
+}
Index: aze/lldb/test/expression_command/call-throws/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/expression_command/call-throws/Makefile 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,6 @@
+LEVEL = ../../make
+
+OBJC_SOURCES := call-throws.m
+
+include $(LEVEL)/Makefile.rules
+LDFLAGS += -framework Foundation
Index: aze/lldb/test/expression_command/call-throws/TestCallThatThrows.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/expression_command/call-throws/TestCallThatThrows.py 2013-03-03 09:35:50.291457349 +0100
@@ -0,0 +1,101 @@
+"""
+Test calling a function that hits a signal set to auto-restart, make sure the call completes.
+"""
+
+import unittest2
+import lldb
+import lldbutil
+from lldbtest import *
+
+class ExprCommandWithTimeoutsTestCase(TestBase):
+
+ mydir = os.path.join("expression_command", "call-throws")
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ self.main_source = "call-throws.m"
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test calling std::String member function."""
+ self.buildDsym()
+ self.call_function()
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin due to ObjC test case")
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test calling std::String member function."""
+ self.buildDwarf()
+ self.call_function()
+
+ def check_after_call (self):
+ # Check that we are back where we were before:
+ frame = self.thread.GetFrameAtIndex(0)
+ self.assertTrue (self.orig_frame_pc == frame.GetPC(), "Restored the zeroth frame correctly")
+
+
+ def call_function(self):
+ """Test calling function with timeout."""
+ exe_name = "a.out"
+ exe = os.path.join(os.getcwd(), exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateBySourceRegex('I am about to throw.',self.main_source_spec)
+ self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)
+
+ # Launch the process, and do not stop at the entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # Frame #0 should be at our breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
+
+ self.assertTrue(len(threads) == 1)
+ self.thread = threads[0]
+
+ options = lldb.SBExpressionOptions()
+ options.SetUnwindOnError(True)
+
+ frame = self.thread.GetFrameAtIndex(0)
+ # Store away the PC to check that the functions unwind to the right place after calls
+ self.orig_frame_pc = frame.GetPC()
+
+ value = frame.EvaluateExpression ("[my_class callMeIThrow]", options)
+ self.assertTrue (value.IsValid())
+ self.assertTrue (value.GetError().Success() == False)
+
+ self.check_after_call()
+
+ # Okay, now try with a breakpoint in the called code in the case where
+ # we are ignoring breakpoint hits.
+ handler_bkpt = target.BreakpointCreateBySourceRegex("I felt like it", self.main_source_spec)
+ self.assertTrue (handler_bkpt.GetNumLocations() > 0)
+ options.SetIgnoreBreakpoints(True)
+ options.SetUnwindOnError(True)
+
+ value = frame.EvaluateExpression ("[my_class callMeIThrow]", options)
+
+ self.assertTrue (value.IsValid() and value.GetError().Success() == False)
+ self.check_after_call()
+
+ # Now set this unwind on error to false, and make sure that we stop where the exception was thrown
+ options.SetUnwindOnError(False)
+ value = frame.EvaluateExpression ("[my_class callMeIThrow]", options)
+
+
+ self.assertTrue (value.IsValid() and value.GetError().Success() == False)
+ self.check_after_call()
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/expression_command/formatters/TestFormatters.py
===================================================================
--- aze.orig/lldb/test/expression_command/formatters/TestFormatters.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/formatters/TestFormatters.py 2013-03-03 09:35:50.291457349 +0100
@@ -28,7 +28,7 @@
@dwarf_test
def test_with_dwarf(self):
"""Test expr + formatters for good interoperability."""
- self.buildDsym()
+ self.buildDwarf()
self.do_my_test()
def do_my_test(self):
@@ -51,11 +51,11 @@
self.runCmd("script import formatters")
self.runCmd("script import foosynth")
- self.runCmd("frame variable foo1 -T")
- self.runCmd("frame variable foo1.b -T")
- self.runCmd("frame variable foo1.b.b_ref -T")
+ self.runCmd("frame variable foo1 --show-types")
+ self.runCmd("frame variable foo1.b --show-types")
+ self.runCmd("frame variable foo1.b.b_ref --show-types")
- self.expect("expression *(new foo(47))",
+ self.expect("expression --show-types -- *(new foo(47))",
substrs = ['(int) a = 47', '(bar) b = {', '(int) i = 94', '(baz) b = {', '(int) k = 99'])
self.runCmd("type summary add -F formatters.foo_SummaryProvider foo")
@@ -93,7 +93,7 @@
self.runCmd("type summary delete foo")
self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo")
- self.expect("expression $" + object_name,
+ self.expect("expression --show-types -- $" + object_name,
substrs = ['(foo) $', ' = {', '(int) *i_ptr = 243'])
self.runCmd("n")
@@ -117,7 +117,7 @@
self.runCmd("type summary delete foo")
self.runCmd("type synthetic add --python-class foosynth.FooSyntheticProvider foo")
- self.expect("expression $" + object_name,
+ self.expect("expression --show-types -- $" + object_name,
substrs = ['(foo) $', ' = {', '(int) *i_ptr = 8888'])
self.runCmd("n")
Index: aze/lldb/test/expression_command/issue_11588/Test11588.py
===================================================================
--- aze.orig/lldb/test/expression_command/issue_11588/Test11588.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/issue_11588/Test11588.py 2013-03-03 09:35:50.291457349 +0100
@@ -40,7 +40,7 @@
self.runCmd("command script import --allow-reload s11588.py")
self.runCmd("type synthetic add --python-class s11588.Issue11581SyntheticProvider StgClosure")
- self.expect("print *((StgClosure*)(r14-1))",
+ self.expect("expr --show-types -- *((StgClosure*)(r14-1))",
substrs = ["(StgClosure) $",
"(StgClosure *) &$","0x",
"addr = ",
@@ -60,11 +60,11 @@
self.runCmd("register write r14 %d" % addr)
self.expect("register read r14",
substrs = ["0x",hex(addr)[2:].rstrip("L")]) # Remove trailing 'L' if it exists
- self.expect("print *(StgClosure*)$r14",
+ self.expect("expr --show-types -- *(StgClosure*)$r14",
substrs = ["(StgClosure) $",
"(StgClosure *) &$","0x",
- "(long) addr = ",
- "(long) load_address = ",
+ "addr = ",
+ "load_address = ",
hex(addr)[2:].rstrip("L"),
str(addr)])
Index: aze/lldb/test/expression_command/radar_9673664/TestExprHelpExamples.py
===================================================================
--- aze.orig/lldb/test/expression_command/radar_9673664/TestExprHelpExamples.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/radar_9673664/TestExprHelpExamples.py 2013-03-03 09:35:50.291457349 +0100
@@ -20,6 +20,7 @@
self.line = line_number(self.main_source, '// Set breakpoint here.')
# rdar://problem/9673664
+ @skipOnLinux # PR-14805: expressions that require memory allocation evaluate incorrectly on Linux
def test_expr_commands(self):
"""The following expression commands should just work."""
self.buildDefault()
Index: aze/lldb/test/expression_command/test/main.cpp
===================================================================
--- aze.orig/lldb/test/expression_command/test/main.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/test/main.cpp 2013-03-03 09:35:50.291457349 +0100
@@ -1,5 +1,14 @@
#include <stdio.h>
+static int static_value = 0;
+
+int
+a_function_to_call()
+{
+ static_value++;
+ return static_value;
+}
+
int main (int argc, char const *argv[])
{
printf ("Hello world!\n");
@@ -29,5 +38,7 @@
expression printf ("two: %llu, one: %i\n", 2ull, 1)
expression random() % 255l
#endif
+
+ a_function_to_call();
return 0;
}
Index: aze/lldb/test/expression_command/test/TestExprs.py
===================================================================
--- aze.orig/lldb/test/expression_command/test/TestExprs.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/test/TestExprs.py 2013-03-03 09:35:50.291457349 +0100
@@ -28,6 +28,11 @@
self.line = line_number('main.cpp',
'// Please test many expressions while stopped at this line:')
+ # Disable confirmation prompt to avoid infinite wait
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
+
def test_many_expr_commands(self):
"""These basic expression commands should work as expected."""
self.buildDefault()
@@ -157,6 +162,22 @@
startstr = "'Z'")
self.DebugSBValue(val)
+ callee_break = target.BreakpointCreateByName ("a_function_to_call", None)
+ self.assertTrue(callee_break.GetNumLocations() > 0)
+
+ # Make sure ignoring breakpoints works from the command line:
+ self.expect("expression -i true -- a_function_to_call()",
+ substrs = ['(int) $', ' 1'])
+ self.assertTrue (callee_break.GetHitCount() == 1)
+
+ # Now try ignoring breakpoints using the SB API's:
+ options = lldb.SBExpressionOptions()
+ options.SetIgnoreBreakpoints(True)
+ value = frame.EvaluateExpression('a_function_to_call()', options)
+ self.assertTrue (value.IsValid())
+ self.assertTrue (value.GetValueAsSigned(0) == 2)
+ self.assertTrue (callee_break.GetHitCount() == 2)
+
# rdar://problem/8686536
# CommandInterpreter::HandleCommand is stripping \'s from input for WantsRawCommand commands
def test_expr_commands_can_handle_quotes(self):
@@ -207,7 +228,6 @@
substrs = ['(int) $',
'6'])
-
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
Index: aze/lldb/test/expression_command/timeout/TestCallWithTimeout.py
===================================================================
--- aze.orig/lldb/test/expression_command/timeout/TestCallWithTimeout.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/timeout/TestCallWithTimeout.py 2013-03-03 09:35:50.295457350 +0100
@@ -29,7 +29,7 @@
@dwarf_test
def test_with_dwarf(self):
"""Test calling std::String member function."""
- self.buildDsym()
+ self.buildDwarf()
self.call_function()
def call_function(self):
Index: aze/lldb/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py
===================================================================
--- aze.orig/lldb/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/expression_command/two-files/TestObjCTypeQueryFromOtherCompileUnit.py 2013-03-03 09:35:50.295457350 +0100
@@ -27,6 +27,7 @@
self.buildDsym()
self.type_query_from_other_cu()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dwarf_test
def test_with_dwarf(self):
"""The expression parser's type search should be wider than the current compilation unit."""
Index: aze/lldb/test/functionalities/abbreviation/TestAbbreviations.py
===================================================================
--- aze.orig/lldb/test/functionalities/abbreviation/TestAbbreviations.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/abbreviation/TestAbbreviations.py 2013-03-03 09:35:50.295457350 +0100
@@ -148,11 +148,9 @@
if self.getArchitecture() in ["", 'x86_64', 'i386']:
self.expect("dis -f",
startstr = "a.out`sum(int, int)",
- substrs = [' push',
- ' mov',
+ substrs = [' mov',
' addl ',
- 'ret'],
- patterns = ['(leave|popq|popl)'])
+ 'ret'])
self.expect("i d l main.cpp",
patterns = ["Line table for .*main.cpp in `a.out"])
@@ -170,7 +168,6 @@
self.expect("i li",
substrs = [ 'a.out',
'/usr/lib/dyld',
- '/usr/lib/libstdc++',
'/usr/lib/libSystem.B.dylib'])
Index: aze/lldb/test/functionalities/alias/TestAliases.py
===================================================================
--- aze.orig/lldb/test/functionalities/alias/TestAliases.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/alias/TestAliases.py 2013-03-03 09:35:50.295457350 +0100
@@ -142,16 +142,16 @@
"= 0x000004d2" ])
self.expect ('exprf2 c "Hi there!"',
- substrs = [ "(const char) [0] = 'H'",
- "(const char) [1] = 'i'",
- "(const char) [2] = ' '",
- "(const char) [3] = 't'",
- "(const char) [4] = 'h'",
- "(const char) [5] = 'e'",
- "(const char) [6] = 'r'",
- "(const char) [7] = 'e'",
- "(const char) [8] = '!'",
- "(const char) [9] = '\\0'" ])
+ substrs = [ "[0] = 'H'",
+ "[1] = 'i'",
+ "[2] = ' '",
+ "[3] = 't'",
+ "[4] = 'h'",
+ "[5] = 'e'",
+ "[6] = 'r'",
+ "[7] = 'e'",
+ "[8] = '!'",
+ "[9] = '\\0'" ])
self.expect ("exprf x 1234",
Index: aze/lldb/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
===================================================================
--- aze.orig/lldb/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py 2013-03-03 09:35:50.295457350 +0100
@@ -38,6 +38,9 @@
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
def breakpoint_command_sequence(self):
"""Test a sequence of breakpoint command add, list, and delete."""
@@ -51,7 +54,7 @@
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=True)
# Now add callbacks for the breakpoints just created.
- self.runCmd("breakpoint command add -s command -o 'frame variable -T -s' 1")
+ self.runCmd("breakpoint command add -s command -o 'frame variable --show-types --scope' 1")
self.runCmd("breakpoint command add -s python -o 'here = open(\"output.txt\", \"w\"); print >> here, \"lldb\"; here.close()' 2")
self.runCmd("breakpoint command add --python-function bktptcmd.function 3")
@@ -70,7 +73,7 @@
self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
substrs = ["Breakpoint commands:",
- "frame variable -T -s"])
+ "frame variable --show-types --scope"])
self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
substrs = ["Breakpoint commands:",
"here = open",
Index: aze/lldb/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py
===================================================================
--- aze.orig/lldb/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/breakpoint/breakpoint_conditions/TestBreakpointConditions.py 2013-03-03 09:35:50.295457350 +0100
@@ -82,8 +82,8 @@
self.expect("process status", PROCESS_STOPPED,
patterns = ['Process .* stopped'])
- # 'frame variable -T val' should return 3 due to breakpoint condition.
- self.expect("frame variable -T val", VARIABLES_DISPLAYED_CORRECTLY,
+ # 'frame variable --show-types val' should return 3 due to breakpoint condition.
+ self.expect("frame variable --show-types val", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(int) val = 3')
# Also check the hit count, which should be 3, by design.
@@ -113,8 +113,8 @@
self.expect("process status", PROCESS_STOPPED,
patterns = ['Process .* stopped'])
- # 'frame variable -T val' should return 1 since it is the first breakpoint hit.
- self.expect("frame variable -T val", VARIABLES_DISPLAYED_CORRECTLY,
+ # 'frame variable --show-types val' should return 1 since it is the first breakpoint hit.
+ self.expect("frame variable --show-types val", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(int) val = 1')
Index: aze/lldb/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py
===================================================================
--- aze.orig/lldb/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/command_script/import/rdar-12586188/TestRdar12586188.py 2013-03-03 09:35:50.295457350 +0100
@@ -24,7 +24,7 @@
self.expect("command script import ./fail12586188.py --allow-reload",
error=True, substrs = ['error: module importing failed: I do not want to be imported'])
self.expect("command script import ./fail212586188.py --allow-reload",
- error=True, substrs = ['error: module importing failed: Python raised an error while importing module'])
+ error=True, substrs = ['error: module importing failed: Python error raised while importing module: I do not want to be imported'])
if __name__ == '__main__':
import atexit
Index: aze/lldb/test/functionalities/command_script/main.cpp
===================================================================
--- aze.orig/lldb/test/functionalities/command_script/main.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/command_script/main.cpp 2013-03-03 09:35:50.295457350 +0100
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include <cstdlib>
+#include <cstring>
#include <string>
#include <fstream>
#include <iostream>
Index: aze/lldb/test/functionalities/command_script/mysto.py
===================================================================
--- aze.orig/lldb/test/functionalities/command_script/mysto.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/command_script/mysto.py 2013-03-03 09:35:50.295457350 +0100
@@ -11,7 +11,7 @@
print type(arg_split)
count = int(arg_split[0])
for i in range(0,count):
- lldb.thread.StepOver(lldb.eOnlyThisThread)
+ debugger.GetSelectedTarget().GetProcess().GetSelectedThread().StepOver(lldb.eOnlyThisThread)
print "step<%d>"%i
def __lldb_init_module(debugger, session_dict):
Index: aze/lldb/test/functionalities/command_script/TestCommandScript.py
===================================================================
--- aze.orig/lldb/test/functionalities/command_script/TestCommandScript.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/command_script/TestCommandScript.py 2013-03-03 09:35:50.295457350 +0100
@@ -44,6 +44,9 @@
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
+ # Interact with debugger in synchronous mode
+ self.setAsync(False)
+
# We don't want to display the stdout if not in TraceOn() mode.
if not self.TraceOn():
self.HideStdout()
@@ -106,11 +109,22 @@
self.expect("tell_async",
substrs = ['running async'])
self.expect("tell_curr",
- substrs = ['I am running','sync'])
+ substrs = ['I am running sync'])
+ # Test that a python command can redefine itself
+ self.expect('command script add -f foobar welcome')
self.runCmd("command script clear")
+ # Test that re-defining an existing command works
+ self.runCmd('command script add my_command --function welcome.welcome_impl')
+ self.expect('my_command Blah', substrs = ['Hello Blah, welcome to LLDB'])
+
+ self.runCmd('command script add my_command --function welcome.target_name_impl')
+ self.expect('my_command', substrs = ['a.out'])
+
+ self.runCmd("command script clear")
+
self.expect('command script list', matching=False,
substrs = ['targetname',
'longwait'])
Index: aze/lldb/test/functionalities/completion/TestCompletion.py
===================================================================
--- aze.orig/lldb/test/functionalities/completion/TestCompletion.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/completion/TestCompletion.py 2013-03-03 09:35:50.295457350 +0100
@@ -29,11 +29,13 @@
"""Test that 'de' completes to 'detach '."""
self.complete_from_to('de', 'detach ')
+ @expectedFailureLinux # PR-14425: completion broken for strings that begin with --
def test_process_attach_dash_dash_con(self):
"""Test that 'process attach --con' completes to 'process attach --continue '."""
self.complete_from_to('process attach --con', 'process attach --continue ')
# <rdar://problem/11052829>
+ @skipOnLinux # PR-14637: this test case fails (with GCC 4.6 but not clang) because the input prompt "(lldb)" is missing
def test_infinite_loop_while_completing(self):
"""Test that 'process print hello\' completes to itself and does not infinite loop."""
self.complete_from_to('process print hello\\', 'process print hello\\',
Index: aze/lldb/test/functionalities/conditional_break/conditional_break.py
===================================================================
--- aze.orig/lldb/test/functionalities/conditional_break/conditional_break.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/conditional_break/conditional_break.py 2013-03-03 09:35:50.295457350 +0100
@@ -32,6 +32,7 @@
should_stop = False
dbg.SetAsync(old_async)
+ print >> sys.stdout, "stop_if_called_from_a returning: ", should_stop
return should_stop
Index: aze/lldb/test/functionalities/conditional_break/TestConditionalBreak.py
===================================================================
--- aze.orig/lldb/test/functionalities/conditional_break/TestConditionalBreak.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/conditional_break/TestConditionalBreak.py 2013-03-03 09:35:50.295457350 +0100
@@ -40,6 +40,7 @@
self.simulate_conditional_break_by_user()
@dwarf_test
+ @skipOnLinux # due to two assertion failures introduced by r174793: ProcessPOSIX.cpp:223 (assertion 'state == eStateStopped || state == eStateCrashed') and POSIXThread.cpp:254 (assertion 'bp_site')
def test_with_dwarf_command(self):
"""Simulate a user using lldb commands to break on c() if called from a()."""
self.buildDwarf()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-advanced/TestDataFormatterAdv.py 2013-03-03 09:35:50.295457350 +0100
@@ -284,7 +284,7 @@
'i_2',
'k_2',
'o_2'])
- self.expect('frame variable a_long_guy -A', matching=False,
+ self.expect('frame variable a_long_guy --show-all-children', matching=False,
substrs = ['...'])
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py 2013-03-03 09:35:50.295457350 +0100
@@ -94,9 +94,10 @@
substrs = ['Second: x=65',
'y=0x'])
- self.expect("frame variable second --summary NoSuchSummary",
- substrs = ['Second: x=65',
- 'y=0x'])
+ # <rdar://problem/11576143> decided that invalid summaries will raise an error
+ # instead of just defaulting to the base summary
+ self.expect("frame variable second --summary NoSuchSummary",error=True,
+ substrs = ['must specify a valid named summary'])
self.runCmd("thread step-over")
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-objc/.categories
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-objc/.categories 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-objc/.categories 2013-03-03 09:35:50.295457350 +0100
@@ -1 +1 @@
-dataformatter,objc
+dataformatters,objc
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-objc/main.m 2013-03-03 09:35:50.295457350 +0100
@@ -507,6 +507,9 @@
CFURLRef cfchildurl_ref = CFURLCreateWithString(NULL, CFSTR("page.html"), cfurl_ref);
CFURLRef cfgchildurl_ref = CFURLCreateWithString(NULL, CFSTR("?whatever"), cfchildurl_ref);
+ NSDictionary *error_userInfo = @{@"a": @1, @"b" : @2};
+ NSError *nserror = [[NSError alloc] initWithDomain:@"Foobar" code:12 userInfo:error_userInfo];
+
NSBundle* bundle_string = [[NSBundle alloc] initWithPath:@"/System/Library/Frameworks/Accelerate.framework"];
NSBundle* bundle_url = [[NSBundle alloc] initWithURL:[[NSURL alloc] initWithString:@"file://localhost/System/Library/Frameworks/Cocoa.framework"]];
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-objc/TestDataFormatterObjC.py 2013-03-03 09:35:50.295457350 +0100
@@ -90,8 +90,6 @@
"""Test common cases of expression parser <--> formatters interaction."""
self.buildDsym()
self.expr_objc_data_formatter_commands()
- def getCategories(self):
- return ['dataformatters','expression','objc']
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dwarf_test
@@ -99,8 +97,6 @@
"""Test common cases of expression parser <--> formatters interaction."""
self.buildDwarf()
self.expr_objc_data_formatter_commands()
- def getCategories(self):
- return ['dataformatters','expression','objc']
def setUp(self):
# Call super's setUp().
@@ -270,7 +266,7 @@
'(NSAttributedString *) mutableAttrString = ',' @"hello world from foo"',
'(NSString *) mutableGetConst = ',' @"foo said this string needs to be very long so much longer than whatever other string has been seen ever before by anyone of the mankind that of course this is still not long enough given what foo our friend foo our lovely dearly friend foo desired of us so i am adding more stuff here for the sake of it and for the joy of our friend who is named guess what just foo. hence, dear friend foo, stay safe, your string is now long enough to accommodate your testing need and I will make sure that if not we extend it with even more fuzzy random meaningless words pasted one after the other from a long tiresome friday evening spent working in my office. my office mate went home but I am still randomly typing just for the fun of seeing what happens of the length of a Mutable String in Cocoa if it goes beyond one byte.. so be it, dear foo"'])
- self.expect('frame variable -d run-target path',substrs = ['usr/blah/stuff'])
+ self.expect('expr -d run-target -- path',substrs = ['usr/blah/stuff'])
self.expect('frame variable path',substrs = ['usr/blah/stuff'])
self.expect('frame variable immutableData mutableData data_ref mutable_data_ref mutable_string_ref',
@@ -295,6 +291,15 @@
'(NSURL *) nsurl2 =','@"page.html -- http://www.foo.bar',
'(NSURL *) nsurl3 = ','@"?whatever -- http://www.foo.bar/page.html"'])
+ self.expect('frame variable nserror',
+ substrs = ['domain: @"Foobar" - code: 12'])
+
+ self.expect('frame variable nserror->_userInfo',
+ substrs = ['2 key/value pairs'])
+
+ self.expect('frame variable nserror->_userInfo --ptr-depth 1 -d run-target',
+ substrs = ['@"a"','@"b"',"1","2"])
+
self.expect('frame variable bundle_string bundle_url main_bundle',
substrs = ['(NSBundle *) bundle_string = ',' @"/System/Library/Frameworks/Accelerate.framework"',
'(NSBundle *) bundle_url = ',' @"/System/Library/Frameworks/Cocoa.framework"',
@@ -371,7 +376,7 @@
self.expect('frame variable myclass4',
substrs = ['(Class) myclass4 = NSMutableArray'])
self.expect('frame variable myclass5',
- substrs = ['(Class) myclass5 = <error: unknown Class>'])
+ substrs = ['(Class) myclass5 = nil'])
def expr_objc_data_formatter_commands(self):
@@ -402,18 +407,18 @@
self.expect('expression ((id)@"Hello")', matching=False,
substrs = ['Hello'])
- self.expect('expression -d true -- ((id)@"Hello")',
+ self.expect('expression -d run -- ((id)@"Hello")',
substrs = ['Hello'])
- self.expect('expr -d true -- label1',
+ self.expect('expr -d run -- label1',
substrs = ['Process Name'])
- self.expect('expr -d true -- @"Hello"',
+ self.expect('expr -d run -- @"Hello"',
substrs = ['Hello'])
- self.expect('expr -d true -o -- @"Hello"',
+ self.expect('expr -d run --object-description -- @"Hello"',
substrs = ['Hello'])
- self.expect('expr -d true -o -- @"Hello"', matching=False,
+ self.expect('expr -d run --object-description -- @"Hello"', matching=False,
substrs = ['@"Hello" Hello'])
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-python-synth/TestDataFormatterPythonSynth.py 2013-03-03 09:35:50.295457350 +0100
@@ -126,7 +126,7 @@
'a = 280']);
# check that expanding a pointer does the right thing
- self.expect("frame variable -P 1 f00_ptr",
+ self.expect("frame variable --ptr-depth 1 f00_ptr",
substrs = ['r = 45',
'fake_a = 218103808',
'a = 12'])
@@ -139,7 +139,7 @@
self.expect('frame variable f00_1', matching=False,
substrs = ['b = 1',
'j = 17'])
- self.expect("frame variable -P 1 f00_ptr",
+ self.expect("frame variable --ptr-depth 1 f00_ptr",
substrs = ['r = 45',
'fake_a = 218103808',
'a = 12'])
@@ -151,7 +151,7 @@
self.expect('frame variable f00_1',
substrs = ['b = 1',
'j = 17'])
- self.expect("frame variable -P 1 f00_ptr", matching=False,
+ self.expect("frame variable --ptr-depth 1 f00_ptr", matching=False,
substrs = ['r = 45',
'fake_a = 218103808',
'a = 12'])
@@ -176,7 +176,7 @@
self.expect('frame variable f00_1', matching=False,
substrs = ['b = 1',
'j = 17'])
- self.expect("frame variable -P 1 f00_ptr",
+ self.expect("frame variable --ptr-depth 1 f00_ptr",
substrs = ['r = 45',
'fake_a = 218103808',
'a = 12'])
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-skip-summary/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -3,3 +3,6 @@
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libstdc++ -O0
+LDFLAGS += -stdlib=libstdc++
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-skip-summary/TestDataFormatterSkipSummary.py 2013-03-03 09:35:50.299457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
@@ -74,7 +75,7 @@
'}'])
# Skip the default (should be 1) levels of summaries
- self.expect('frame variable -Y',
+ self.expect('frame variable --no-summary-depth',
substrs = ['(DeepData_1) data1 = {',
'm_child1 = 0x',
'}',
@@ -86,7 +87,7 @@
'}'])
# Now skip 2 levels of summaries
- self.expect('frame variable -Y2',
+ self.expect('frame variable --no-summary-depth=2',
substrs = ['(DeepData_1) data1 = {',
'm_child1 = 0x',
'}',
@@ -99,15 +100,15 @@
'}'])
# Check that no "Level 3" comes out
- self.expect('frame variable data1.m_child1 -Y2', matching=False,
+ self.expect('frame variable data1.m_child1 --no-summary-depth=2', matching=False,
substrs = ['Level 3'])
# Now expand a pointer with 2 level of skipped summaries
- self.expect('frame variable data1.m_child1 -Y2',
+ self.expect('frame variable data1.m_child1 --no-summary-depth=2',
substrs = ['(DeepData_2 *) data1.m_child1 = 0x'])
# Deref and expand said pointer
- self.expect('frame variable *data1.m_child1 -Y2',
+ self.expect('frame variable *data1.m_child1 --no-summary-depth=2',
substrs = ['(DeepData_2) *data1.m_child1 = {',
'm_child2 = {',
'm_child1 = 0x',
@@ -115,7 +116,7 @@
'}'])
# Expand an expression, skipping 2 layers of summaries
- self.expect('frame variable data1.m_child1->m_child2 -Y2',
+ self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=2',
substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
'm_child2 = {',
'm_child1 = Level 5',
@@ -124,7 +125,7 @@
'}'])
# Expand same expression, skipping only 1 layer of summaries
- self.expect('frame variable data1.m_child1->m_child2 -Y1',
+ self.expect('frame variable data1.m_child1->m_child2 --no-summary-depth=1',
substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
'm_child1 = 0x',
'Level 4',
@@ -148,14 +149,14 @@
self.skipTest("rdar://problem/9804600 wrong namespace for std::string in debug info")
# Expand same expression, skipping 3 layers of summaries
- self.expect('frame variable data1.m_child1->m_child2 -T -Y3',
+ self.expect('frame variable data1.m_child1->m_child2 --show-types --no-summary-depth=3',
substrs = ['(DeepData_3) data1.m_child1->m_child2 = {',
'm_some_text = "Just a test"',
'm_child2 = {',
'm_some_text = "Just a test"'])
# Expand within a standard string (might depend on the implementation of the C++ stdlib you use)
- self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 -Y2',
+ self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=2',
substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
'm_some_text = {',
'_M_dataplus = {',
@@ -163,18 +164,18 @@
'"Just a test"'])
# Repeat the above, but only skip 1 level of summaries
- self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 -Y1',
+ self.expect('frame variable data1.m_child1->m_child2.m_child1.m_child2 --no-summary-depth=1',
substrs = ['(DeepData_5) data1.m_child1->m_child2.m_child1.m_child2 = {',
'm_some_text = "Just a test"',
'}'])
- # Change summary and expand, first without -Y then with -Y
+ # Change summary and expand, first without --no-summary-depth then with --no-summary-depth
self.runCmd("type summary add --summary-string \"${var.m_some_text}\" DeepData_5")
self.expect('fr var data2.m_child4.m_child2.m_child2',
substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = "Just a test"'])
- self.expect('fr var data2.m_child4.m_child2.m_child2 -Y',
+ self.expect('fr var data2.m_child4.m_child2.m_child2 --no-summary-depth',
substrs = ['(DeepData_5) data2.m_child4.m_child2.m_child2 = {',
'm_some_text = "Just a test"',
'}'])
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/main.cpp 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,42 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+#include <map>
+#include <vector>
+
+typedef std::map<int, int> intint_map;
+typedef std::map<std::string, int> strint_map;
+
+typedef std::vector<int> int_vector;
+typedef std::vector<std::string> string_vector;
+
+typedef intint_map::iterator iimter;
+typedef strint_map::iterator simter;
+
+typedef int_vector::iterator ivter;
+typedef string_vector::iterator svter;
+
+int main()
+{
+ intint_map iim;
+ iim[0] = 12;
+
+ strint_map sim;
+ sim["world"] = 42;
+
+ int_vector iv;
+ iv.push_back(3);
+
+ string_vector sv;
+ sv.push_back("hello");
+
+ iimter iimI = iim.begin();
+ simter simI = sim.begin();
+
+ ivter ivI = iv.begin();
+ svter svI = sv.begin();
+
+ return 0; // Set break point at this line.
+}
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libc++ -O0
+LDFLAGS += -stdlib=libc++
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/iterator/TestDataFormatterLibccIterator.py 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,78 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class LibcxxIteratorDataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "iterator")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that libc++ iterators format properly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib'])
+
+ self.expect('frame variable ivI', substrs = ['item = 3'])
+ self.expect('expr ivI', substrs = ['item = 3'])
+
+ self.expect('frame variable iimI', substrs = ['first = 0','second = 12'])
+ self.expect('expr iimI', substrs = ['first = 0','second = 12'])
+
+ self.expect('frame variable simI', substrs = ['first = "world"','second = 42'])
+ self.expect('expr simI', substrs = ['first = "world"','second = 42'])
+
+ self.expect('frame variable svI', substrs = ['item = "hello"'])
+ self.expect('expr svI', substrs = ['item = "hello"'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/list/TestDataFormatterLibcxxList.py 2013-03-03 09:35:50.299457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
@@ -58,7 +59,7 @@
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
- self.runCmd("frame variable numbers_list -T")
+ self.runCmd("frame variable numbers_list --show-types")
self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e")
self.runCmd("type format add -f hex int")
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py 2013-03-03 09:35:50.299457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
@@ -58,7 +59,7 @@
self.expect('image list',substrs=['libc++.1.dylib','libc++abi.dylib'])
- self.runCmd("frame variable ii -T")
+ self.runCmd("frame variable ii --show-types")
self.runCmd("type summary add -x \"std::__1::map<\" --summary-string \"map has ${svar%#} items\" -e")
@@ -135,7 +136,7 @@
substrs = ['map has 0 items',
'{}'])
- self.runCmd("frame variable si -T")
+ self.runCmd("frame variable si --show-types")
self.expect('frame variable si',
substrs = ['map has 0 items',
@@ -206,7 +207,7 @@
'{}'])
self.runCmd("n")
- self.runCmd("frame variable is -T")
+ self.runCmd("frame variable is --show-types")
self.expect('frame variable is',
substrs = ['map has 0 items',
@@ -267,7 +268,7 @@
'{}'])
self.runCmd("n");self.runCmd("n");
- self.runCmd("frame variable ss -T")
+ self.runCmd("frame variable ss --show-types")
self.expect('frame variable ss',
substrs = ['map has 0 items',
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/main.cpp 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,12 @@
+#include <string>
+
+int main()
+{
+ std::wstring s(L"hello world! מזל טוב!");
+ std::wstring S(L"!!!!");
+ const wchar_t *mazeltov = L"מזל טוב";
+ std::string q("hello world");
+ std::string Q("quite a long std::strin with lots of info inside it");
+ S.assign(L"!!!!!"); // Set break point at this line.
+ return 0;
+}
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libc++ -O0
+LDFLAGS += -stdlib=libc++
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/string/TestDataFormatterLibcxxString.py 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,81 @@
+#coding=utf8
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class LibcxxStringDataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "string")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect("frame variable",
+ substrs = ['(std::__1::wstring) s = L"hello world! מזל טוב!"',
+ '(std::__1::wstring) S = L"!!!!"',
+ '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
+ '(std::__1::string) q = "hello world"',
+ '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"'])
+
+ self.runCmd("n")
+
+ self.expect("frame variable",
+ substrs = ['(std::__1::wstring) s = L"hello world! מזל טוב!"',
+ '(std::__1::wstring) S = L"!!!!!"',
+ '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
+ '(std::__1::string) q = "hello world"',
+ '(std::__1::string) Q = "quite a long std::strin with lots of info inside it"'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/main.cpp 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,69 @@
+#include <string>
+#ifdef _LIBCPP_INLINE_VISIBILITY
+#undef _LIBCPP_INLINE_VISIBILITY
+#endif
+#define _LIBCPP_INLINE_VISIBILITY
+
+#include <vector>
+
+int main()
+{
+ std::vector<bool> vBool;
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(true);
+
+ return 0; // Set break point at this line.
+}
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libc++ -O0
+LDFLAGS += -stdlib=libc++
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vbool/TestDataFormatterLibcxxVBool.py 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,70 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class LibcxxVBoolDataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libcxx", "vbool")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect("frame variable vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
+
+ self.expect("expr vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libcxx/vector/TestDataFormatterLibcxxVector.py 2013-03-03 09:35:50.299457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/main.cpp 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,38 @@
+#include <string>
+#include <map>
+#include <vector>
+
+typedef std::map<int, int> intint_map;
+typedef std::map<std::string, int> strint_map;
+
+typedef std::vector<int> int_vector;
+typedef std::vector<std::string> string_vector;
+
+typedef intint_map::iterator iimter;
+typedef strint_map::iterator simter;
+
+typedef int_vector::iterator ivter;
+typedef string_vector::iterator svter;
+
+int main()
+{
+ intint_map iim;
+ iim[0] = 12;
+
+ strint_map sim;
+ sim["world"] = 42;
+
+ int_vector iv;
+ iv.push_back(3);
+
+ string_vector sv;
+ sv.push_back("hello");
+
+ iimter iimI = iim.begin();
+ simter simI = sim.begin();
+
+ ivter ivI = iv.begin();
+ svter svI = sv.begin();
+
+ return 0; // Set break point at this line.
+}
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libstdc++ -O0
+LDFLAGS += -stdlib=libstdc++
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/iterator/TestDataFormatterStdIterator.py 2013-03-03 09:35:50.299457351 +0100
@@ -0,0 +1,76 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class StdIteratorDataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libstdcpp", "iterator")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that libstdcpp iterators format properly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect('frame variable ivI', substrs = ['item = 3'])
+ self.expect('expr ivI', substrs = ['item = 3'])
+
+ self.expect('frame variable iimI', substrs = ['first = 0','second = 12'])
+ self.expect('expr iimI', substrs = ['first = 0','second = 12'])
+
+ self.expect('frame variable simI', substrs = ['first = "world"','second = 42'])
+ self.expect('expr simI', substrs = ['first = "world"','second = 42'])
+
+ self.expect('frame variable svI', substrs = ['item = "hello"'])
+ self.expect('expr svI', substrs = ['item = "hello"'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -3,3 +3,6 @@
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libstdc++ -O0
+LDFLAGS += -stdlib=libstdc++
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/list/TestDataFormatterStdList.py 2013-03-03 09:35:50.299457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
@@ -56,7 +57,7 @@
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
- self.runCmd("frame variable numbers_list -T")
+ self.runCmd("frame variable numbers_list --show-types")
#self.runCmd("type synth add std::int_list std::string_list int_list string_list -l StdListSynthProvider")
self.runCmd("type summary add std::int_list std::string_list int_list string_list --summary-string \"list has ${svar%#} items\" -e")
self.runCmd("type format add -f hex int")
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/Makefile 2013-03-03 09:35:50.299457351 +0100
@@ -3,3 +3,6 @@
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libstdc++ -O0
+LDFLAGS += -stdlib=libstdc++
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/map/TestDataFormatterStdMap.py 2013-03-03 09:35:50.303457351 +0100
@@ -19,6 +19,9 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
+ @skipIfGcc # bugzilla 15036: When built with GCC, this test causes lldb to crash with
+ # assert DeclCXX.h:554 queried property of class with no definition
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
@@ -56,7 +59,7 @@
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
- self.runCmd("frame variable ii -T")
+ self.runCmd("frame variable ii --show-types")
self.runCmd("type summary add -x \"std::map<\" --summary-string \"map has ${svar%#} items\" -e")
@@ -136,7 +139,7 @@
'{}'])
self.runCmd("n")
- self.runCmd("frame variable si -T")
+ self.runCmd("frame variable si --show-types")
self.expect('frame variable si',
substrs = ['map has 0 items',
@@ -211,7 +214,7 @@
'{}'])
self.runCmd("n")
- self.runCmd("frame variable is -T")
+ self.runCmd("frame variable is --show-types")
self.expect('frame variable is',
substrs = ['map has 0 items',
@@ -272,7 +275,7 @@
'{}'])
self.runCmd("n")
- self.runCmd("frame variable ss -T")
+ self.runCmd("frame variable ss --show-types")
self.expect('frame variable ss',
substrs = ['map has 0 items',
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/main.cpp 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,12 @@
+#include <string>
+
+int main()
+{
+ std::wstring s(L"hello world! מזל טוב!");
+ std::wstring S(L"!!!!");
+ const wchar_t *mazeltov = L"מזל טוב";
+ std::string q("hello world");
+ std::string Q("quite a long std::strin with lots of info inside it");
+ S.assign(L"!!!!!"); // Set break point at this line.
+ return 0;
+}
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/Makefile 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libstdc++ -O0
+LDFLAGS += -stdlib=libstdc++
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/string/TestDataFormatterStdString.py 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,81 @@
+#coding=utf8
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class StdStringDataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libstdcpp", "string")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @skipOnLinux # No standard locations for libc++ on Linux, so skip for now
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect("frame variable",
+ substrs = ['(std::wstring) s = L"hello world! מזל טוב!"',
+ '(std::wstring) S = L"!!!!"',
+ '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
+ '(std::string) q = "hello world"',
+ '(std::string) Q = "quite a long std::strin with lots of info inside it"'])
+
+ self.runCmd("n")
+
+ self.expect("frame variable",
+ substrs = ['(std::wstring) s = L"hello world! מזל טוב!"',
+ '(std::wstring) S = L"!!!!!"',
+ '(const wchar_t *) mazeltov = 0x','L"מזל טוב"',
+ '(std::string) q = "hello world"',
+ '(std::string) Q = "quite a long std::strin with lots of info inside it"'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/main.cpp 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,63 @@
+#include <vector>
+
+int main()
+{
+ std::vector<bool> vBool;
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(false);
+ vBool.push_back(true);
+ vBool.push_back(true);
+
+ return 0; // Set break point at this line.
+}
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/Makefile 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,11 @@
+LEVEL = ../../../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -O0
+ifeq (,$(findstring gcc,$(CC)))
+CXXFLAGS += -stdlib=libstdc++
+LDFLAGS += -stdlib=libstdc++
+endif
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vbool/TestDataFormatterStdVBool.py 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,70 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class StdVBoolDataFormatterTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "data-formatter-stl", "libstdcpp", "vbool")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ @expectedFailureGcc # PR-15301: lldb does not print the correct sizes of STL containers when building with GCC
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=-1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type filter clear', check=False)
+ self.runCmd('type synth clear', check=False)
+ self.runCmd("settings set target.max-children-count 256", check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.expect("frame variable vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
+
+ self.expect("expr vBool",
+ substrs = ['size=49','[0] = false','[1] = true','[18] = false','[27] = true','[36] = false','[47] = true','[48] = true'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/Makefile 2013-03-03 09:35:50.303457351 +0100
@@ -3,3 +3,6 @@
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
+
+CXXFLAGS += -stdlib=libstdc++ -O0
+LDFLAGS += -stdlib=libstdc++
\ No newline at end of file
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-stl/libstdcpp/vector/TestDataFormatterStdVector.py 2013-03-03 09:35:50.303457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
Index: aze/lldb/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/data-formatter-synth/TestDataFormatterSynth.py 2013-03-03 09:35:50.303457351 +0100
@@ -71,7 +71,7 @@
'z = 8'])
# if we skip synth and summary show y
- self.expect("frame variable int_bag -S false -Y1",
+ self.expect("frame variable int_bag --synthetic-type false --no-summary-depth=1",
substrs = ['x = 6',
'y = 7',
'z = 8'])
@@ -97,7 +97,7 @@
'z = 8'])
# If I skip summaries, still give me the artificial children
- self.expect("frame variable int_bag -Y1",
+ self.expect("frame variable int_bag --no-summary-depth=1",
substrs = ['x = 6',
'z = 8'])
@@ -135,14 +135,14 @@
# ...even bitfields
self.runCmd("type filter add BagOfBags --child x.y --child \"y->z[1-2]\"")
- self.expect('frame variable bag_bag -T',
+ self.expect('frame variable bag_bag --show-types',
substrs = ['x.y = 70',
'(int:2) y->z[1-2] = 2'])
# ...even if we format the bitfields
self.runCmd("type filter add BagOfBags --child x.y --child \"y->y[0-0]\"")
self.runCmd("type format add \"int:1\" -f bool")
- self.expect('frame variable bag_bag -T',
+ self.expect('frame variable bag_bag --show-types',
substrs = ['x.y = 70',
'(int:1) y->y[0-0] = true'])
@@ -167,7 +167,7 @@
'array[2] = 3'])
# skip synthetic children
- self.expect('frame variable plenty_of_stuff -S no',
+ self.expect('frame variable plenty_of_stuff --synthetic-type no',
substrs = ['some_values = 0x0',
'array = 0x',
'array_size = 5'])
@@ -180,19 +180,19 @@
'*(plenty_of_stuff.array) = 3'])
# check that we do not lose location information for our children
- self.expect('frame variable plenty_of_stuff -L',
+ self.expect('frame variable plenty_of_stuff --location',
substrs = ['0x',
': bitfield = 17'])
# check we work across pointer boundaries
- self.expect('frame variable plenty_of_stuff.some_values -P1',
+ self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
'x = 5',
'z = 7'])
# but not if we don't want to
self.runCmd("type filter add BagOfInts --child x --child z -p")
- self.expect('frame variable plenty_of_stuff.some_values -P1',
+ self.expect('frame variable plenty_of_stuff.some_values --ptr-depth=1',
substrs = ['(BagOfInts *) plenty_of_stuff.some_values',
'x = 5',
'y = 6',
Index: aze/lldb/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/rdar-10642615/Test-rdar-10642615.py 2013-03-03 09:35:50.303457351 +0100
@@ -20,6 +20,7 @@
self.buildDsym()
self.data_formatter_commands()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test data formatter commands."""
Index: aze/lldb/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/rdar-10887661/TestRdar10887661.py 2013-03-03 09:35:50.303457351 +0100
@@ -13,7 +13,6 @@
mydir = os.path.join("functionalities", "data-formatter", "rdar-10887661")
# rdar://problem/10887661
- @unittest2.expectedFailure
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym_and_run_command(self):
@@ -22,7 +21,6 @@
self.capping_test_commands()
# rdar://problem/10887661
- @unittest2.expectedFailure
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Check for an issue where capping does not work because the Target pointer appears to be changing behind our backs."""
Index: aze/lldb/test/functionalities/data-formatter/rdar-11988289/main.m
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/rdar-11988289/main.m 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/rdar-11988289/main.m 2013-03-03 09:35:50.303457351 +0100
@@ -18,11 +18,11 @@
NSArray* keys = @[@"foo",@"bar",@"baz"];
NSArray* values = @[@"hello",@[@"X",@"Y"],@{@1 : @"one",@2 : @"two"}];
NSDictionary* dictionary = [NSDictionary dictionaryWithObjects:values forKeys:keys];
- NSMutableDictionary* mutable = [NSMutableDictionary dictionaryWithCapacity:5];
- [mutable setObject:@"123" forKey:@23];
- [mutable setObject:[NSURL URLWithString:@"http://www.apple.com"] forKey:@"foobar"];
- [mutable setObject:@[@"a",@12] forKey:@57];
- [mutable setObject:dictionary forKey:@"puartist"];
+ NSMutableDictionary* mutabledict = [NSMutableDictionary dictionaryWithCapacity:5];
+ [mutabledict setObject:@"123" forKey:@23];
+ [mutabledict setObject:[NSURL URLWithString:@"http://www.apple.com"] forKey:@"foobar"];
+ [mutabledict setObject:@[@"a",@12] forKey:@57];
+ [mutabledict setObject:dictionary forKey:@"puartist"];
[pool drain];// Set break point at this line.
return 0;
Index: aze/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/rdar-11988289/TestRdar 11988289.py 2013-03-03 09:35:50.303457351 +0100
@@ -59,23 +59,23 @@
# Now check that we are displaying Cocoa classes correctly
self.expect('frame variable dictionary',
substrs = ['3 key/value pairs'])
- self.expect('frame variable mutable',
+ self.expect('frame variable mutabledict',
substrs = ['4 key/value pairs'])
self.expect('frame variable dictionary --ptr-depth 1',
substrs = ['3 key/value pairs','[0] = {','key = 0x','value = 0x','[1] = {','[2] = {'])
- self.expect('frame variable mutable --ptr-depth 1',
+ self.expect('frame variable mutabledict --ptr-depth 1',
substrs = ['4 key/value pairs','[0] = {','key = 0x','value = 0x','[1] = {','[2] = {','[3] = {'])
- self.expect('frame variable dictionary --ptr-depth 1 -d no-run-target',
+ self.expect('frame variable dictionary --ptr-depth 1 --dynamic-type no-run-target',
substrs = ['3 key/value pairs','@"bar"','@"2 objects"','@"baz"','2 key/value pairs'])
- self.expect('frame variable mutable --ptr-depth 1 -d no-run-target',
+ self.expect('frame variable mutabledict --ptr-depth 1 --dynamic-type no-run-target',
substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs'])
- self.expect('frame variable mutable --ptr-depth 2 -d no-run-target',
+ self.expect('frame variable mutabledict --ptr-depth 2 --dynamic-type no-run-target',
substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"'])
- self.expect('frame variable mutable --ptr-depth 3 -d no-run-target',
+ self.expect('frame variable mutabledict --ptr-depth 3 --dynamic-type no-run-target',
substrs = ['4 key/value pairs','(int)23','@"123"','@"http://www.apple.com"','@"puartist"','3 key/value pairs {','@"bar"','@"2 objects"','(int)1','@"two"'])
self.assertTrue(self.frame().FindVariable("dictionary").MightHaveChildren(), "dictionary says it does not have children!")
- self.assertTrue(self.frame().FindVariable("mutable").MightHaveChildren(), "mutable says it does not have children!")
+ self.assertTrue(self.frame().FindVariable("mutabledict").MightHaveChildren(), "mutable says it does not have children!")
if __name__ == '__main__':
Index: aze/lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py
===================================================================
--- aze.orig/lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/data-formatter/rdar-12437442/TestRdar12437442.py 2013-03-03 09:35:50.303457351 +0100
@@ -64,18 +64,19 @@
id_x.SetPreferSyntheticValue(True)
if self.TraceOn():
- self.runCmd("frame variable x -d run-target --ptr-depth 1")
-
+ self.runCmd("expr --dynamic-type run-target --ptr-depth 1 -- x")
+
self.assertTrue(id_x.GetSummary() == '@"5 objects"', "array does not get correct summary")
self.runCmd("next")
+ self.runCmd("frame select 0")
id_x = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable("x")
id_x.SetPreferDynamicValue(lldb.eDynamicCanRunTarget)
id_x.SetPreferSyntheticValue(True)
if self.TraceOn():
- self.runCmd("frame variable x -d run-target --ptr-depth 1")
+ self.runCmd("expr --dynamic-type run-target --ptr-depth 1 -- x")
self.assertTrue(id_x.GetNumChildren() == 7, "dictionary does not have 7 children")
id_x.SetPreferSyntheticValue(False)
Index: aze/lldb/test/functionalities/data-formatter/rdar-12529957/main.m
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/rdar-12529957/main.m 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,34 @@
+//===-- main.m ------------------------------------------------*- ObjC -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#import <Foundation/Foundation.h>
+
+int main (int argc, const char * argv[])
+{
+
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ NSSet* set = [NSSet setWithArray:@[@1,@"hello",@2,@"world"]];
+ NSMutableSet* mutable = [NSMutableSet setWithCapacity:5];
+ [mutable addObject:@1];
+ [mutable addObject:@2];
+ [mutable addObject:@3];
+ [mutable addObject:@4];
+ [mutable addObject:@5];
+ [mutable addObject:[NSURL URLWithString:@"www.apple.com"]];
+ [mutable addObject:@[@1,@2,@3]];
+ [mutable unionSet:set];
+ [mutable removeAllObjects]; // Set break point at this line.
+ [mutable unionSet:set];
+ [mutable addObject:@1];
+
+ [pool drain];
+ return 0;
+}
+
Index: aze/lldb/test/functionalities/data-formatter/rdar-12529957/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/rdar-12529957/Makefile 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,9 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+CFLAGS_EXTRAS += -w
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
Index: aze/lldb/test/functionalities/data-formatter/rdar-12529957/TestRdar12529957.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/data-formatter/rdar-12529957/TestRdar12529957.py 2013-03-03 09:35:50.303457351 +0100
@@ -0,0 +1,89 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import datetime
+import lldbutil
+
+class DataFormatterRdar12529957TestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "data-formatter", "rdar-12529957")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_rdar12529957_with_dsym_and_run_command(self):
+ """Test that NSSet reports its synthetic children properly."""
+ self.buildDsym()
+ self.rdar12529957_tester()
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dwarf_test
+ def test_rdar12529957_with_dwarf_and_run_command(self):
+ """Test that NSSet reports its synthetic children properly."""
+ self.buildDwarf()
+ self.rdar12529957_tester()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.m', '// Set break point at this line.')
+
+ def rdar12529957_tester(self):
+ """Test that NSSet reports its synthetic children properly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.m", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+ self.runCmd('type synth clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ # Now check that we are displaying Cocoa classes correctly
+ self.expect('frame variable set',
+ substrs = ['4 objects'])
+ self.expect('frame variable mutable',
+ substrs = ['9 objects'])
+ self.expect('frame variable set --ptr-depth 1 -d run -T',
+ substrs = ['4 objects','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
+ self.expect('frame variable mutable --ptr-depth 1 -d run -T',
+ substrs = ['9 objects','(int)5','@"3 objects"','@"www.apple.com"','(int)3','@"world"','(int)4'])
+
+ self.runCmd("next")
+ self.expect('frame variable mutable',
+ substrs = ['0 objects'])
+
+ self.runCmd("next")
+ self.expect('frame variable mutable',
+ substrs = ['4 objects'])
+ self.expect('frame variable mutable --ptr-depth 1 -d run -T',
+ substrs = ['4 objects','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
+
+ self.runCmd("next")
+ self.expect('frame variable mutable',
+ substrs = ['4 objects'])
+ self.expect('frame variable mutable --ptr-depth 1 -d run -T',
+ substrs = ['4 objects','[0]','[1]','[2]','[3]','hello','world','(int)1','(int)2'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/dead-strip/TestDeadStrip.py
===================================================================
--- aze.orig/lldb/test/functionalities/dead-strip/TestDeadStrip.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/dead-strip/TestDeadStrip.py 2013-03-03 09:35:50.303457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.dead_strip()
+ @skipOnLinux # The -dead_strip linker option isn't supported on Linux versions of ld.
@dwarf_test
def test_with_dwarf(self):
"""Test breakpoint works correctly with dead-code stripping."""
@@ -31,13 +32,13 @@
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Break by function name f1 (live code).
- lldbutil.run_break_set_by_symbol (self, "f1", extra_options="-s a.out", num_expected_locations=1, module_name="a.out")
+ lldbutil.run_break_set_by_symbol (self, "f1", num_expected_locations=1, module_name="a.out")
# Break by function name f2 (dead code).
- lldbutil.run_break_set_by_symbol (self, "f2", extra_options="-s a.out", num_expected_locations=0)
+ lldbutil.run_break_set_by_symbol (self, "f2", num_expected_locations=0, module_name="a.out")
# Break by function name f3 (live code).
- lldbutil.run_break_set_by_symbol (self, "f3", extra_options="-s a.out", num_expected_locations=1, module_name="a.out")
+ lldbutil.run_break_set_by_symbol (self, "f3", num_expected_locations=1, module_name="a.out")
self.runCmd("run", RUN_SUCCEEDED)
Index: aze/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py
===================================================================
--- aze.orig/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/embedded_interpreter/TestConvenienceVariables.py 2013-03-03 09:35:50.303457351 +0100
@@ -18,6 +18,7 @@
self.convenience_variables()
@dwarf_test
+ @skipOnLinux # PR-14637: this test case fails sometimes because the input prompt "(lldb)" is missing
def test_with_dwarf_and_run_commands(self):
"""Test convenience variables lldb.debugger, lldb.target, lldb.process, lldb.thread, and lldb.frame."""
self.buildDwarf()
Index: aze/lldb/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py
===================================================================
--- aze.orig/lldb/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/expr-doesnt-deadlock/TestExprDoesntBlock.py 2013-03-03 09:35:50.303457351 +0100
@@ -10,6 +10,9 @@
class ExprDoesntDeadlockTestCase(TestBase):
+ def getCategories(self):
+ return ['basic_process']
+
mydir = os.path.join("functionalities", "expr-doesnt-deadlock")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@@ -20,6 +23,7 @@
self.expr_doesnt_deadlock()
@dwarf_test
+ @skipOnLinux # PR-15258: disabled due to assertion failure in ProcessMonitor::GetCrashReasonForSIGSEGV:
def test_with_dwarf_and_run_command(self):
"""Test that expr will time out and allow other threads to run if it blocks."""
self.buildDwarf()
@@ -61,7 +65,7 @@
var = frame0.EvaluateExpression ("call_me_to_get_lock()")
self.assertTrue (var.IsValid())
self.assertTrue (var.GetValueAsSigned (0) == 567)
-
+
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
Index: aze/lldb/test/functionalities/inferior-changed/TestInferiorChanged.py
===================================================================
--- aze.orig/lldb/test/functionalities/inferior-changed/TestInferiorChanged.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/inferior-changed/TestInferiorChanged.py 2013-03-03 09:35:50.303457351 +0100
@@ -21,6 +21,7 @@
self.setTearDownCleanup(dictionary=d)
self.inferior_not_crashing()
+ @expectedFailureLinux # bugzilla 14662 - POSIX dynamic loader asserts on re-launch
def test_inferior_crashing_dwarf(self):
"""Test lldb reloads the inferior after it was changed during the session."""
self.buildDwarf()
@@ -45,11 +46,13 @@
self.runCmd("run", RUN_SUCCEEDED)
+ # FIXME: This expected stop reason is Darwin-specific
# The stop reason of the thread should be a bad access exception.
self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
substrs = ['stopped',
'stop reason = EXC_BAD_ACCESS'])
+ # FIXME: This expected stop reason is Darwin-specific
# And it should report the correct line number.
self.expect("thread backtrace all",
substrs = ['stop reason = EXC_BAD_ACCESS',
@@ -61,6 +64,7 @@
self.runCmd("run", RUN_SUCCEEDED)
self.runCmd("process status")
+ # FIXME: This unexpected stop reason is Darwin-specific
if 'EXC_BAD_ACCESS' in self.res.GetOutput():
self.fail("Inferior changed, but lldb did not perform a reload")
Index: aze/lldb/test/functionalities/inferior-crashing/TestInferiorCrashing.py
===================================================================
--- aze.orig/lldb/test/functionalities/inferior-crashing/TestInferiorCrashing.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/inferior-crashing/TestInferiorCrashing.py 2013-03-03 09:35:50.307457351 +0100
@@ -39,14 +39,19 @@
self.runCmd("run", RUN_SUCCEEDED)
+ if sys.platform.startswith("darwin"):
+ stop_reason = 'stop reason = EXC_BAD_ACCESS'
+ else:
+ stop_reason = 'stop reason = invalid address'
+
# The stop reason of the thread should be a bad access exception.
self.expect("thread list", STOPPED_DUE_TO_EXC_BAD_ACCESS,
substrs = ['stopped',
- 'stop reason = EXC_BAD_ACCESS'])
+ stop_reason])
# And it should report the correct line number.
self.expect("thread backtrace all",
- substrs = ['stop reason = EXC_BAD_ACCESS',
+ substrs = [stop_reason,
'main.c:%d' % self.line])
def inferior_crashing_python(self):
Index: aze/lldb/test/functionalities/inline-stepping/TestInlineStepping.py
===================================================================
--- aze.orig/lldb/test/functionalities/inline-stepping/TestInlineStepping.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/inline-stepping/TestInlineStepping.py 2013-03-03 09:35:50.307457351 +0100
@@ -18,6 +18,9 @@
self.buildDsym()
self.inline_stepping()
+ @expectedFailureGcc # Some versions of GCC emit DWARF that considers functions to start at the line with the '{' whereas this test
+ # expects the first line of a function to be the first line of source (i.e. what clang does). As such, this test
+ # fails with some versions of GCC.
@python_api_test
@dwarf_test
def test_with_dwarf_and_python_api(self):
@@ -33,6 +36,9 @@
self.buildDsym()
self.inline_stepping_step_over()
+ @expectedFailureGcc # Some versions of GCC emit DWARF that considers functions to start at the line with the '{' whereas this test
+ # expects the first line of a function to be the first line of source (i.e. what clang does). As such, this test
+ # fails with some versions of GCC.
@python_api_test
@dwarf_test
def test_step_over_with_dwarf_and_python_api(self):
Index: aze/lldb/test/functionalities/load_unload/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/load_unload/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/load_unload/Makefile 2013-03-03 09:35:50.307457351 +0100
@@ -4,7 +4,7 @@
ifeq "$(ARCH)" ""
ARCH = x86_64
endif
-CFLAGS ?=-arch $(ARCH) -gdwarf-2 -O0
+CFLAGS ?=-arch $(ARCH) -g -O0
CWD := $(shell pwd)
all: a.out hidden/libd.dylib
Index: aze/lldb/test/functionalities/load_unload/TestLoadUnload.py
===================================================================
--- aze.orig/lldb/test/functionalities/load_unload/TestLoadUnload.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/load_unload/TestLoadUnload.py 2013-03-03 09:35:50.307457351 +0100
@@ -11,6 +11,9 @@
class LoadUnloadTestCase(TestBase):
+ def getCategories (self):
+ return ['basic_process']
+
mydir = os.path.join("functionalities", "load_unload")
def setUp(self):
@@ -22,6 +25,7 @@
self.line_d_function = line_number('d.c',
'// Find this line number within d_dunction().')
+ @skipOnLinux # bugzilla 14424 - missing linux Makefiles/testcase support
def test_modules_search_paths(self):
"""Test target modules list after loading a different copy of the library libd.dylib, and verifies that it works with 'target modules search-paths add'."""
@@ -30,7 +34,6 @@
if sys.platform.startswith("darwin"):
dylibName = 'libd.dylib'
- dylibPath = 'DYLD_LIBRARY_PATH'
# The directory with the dynamic library we did not link to.
new_dir = os.path.join(os.getcwd(), "hidden")
@@ -61,13 +64,13 @@
# Obliterate traces of libd from the old location.
os.remove(old_dylib)
# Inform dyld of the new path, too.
- env_cmd_string = "settings set target.env-vars " + dylibPath + "=" + new_dir
+ env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + new_dir
if self.TraceOn():
print "Set environment to: ", env_cmd_string
self.runCmd(env_cmd_string)
self.runCmd("settings show target.env-vars")
- remove_dyld_path_cmd = "settings remove target.env-vars " + dylibPath
+ remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
self.addTearDownHook(lambda: self.runCmd(remove_dyld_path_cmd))
self.runCmd("run")
@@ -75,7 +78,7 @@
self.expect("target modules list", "LLDB successfully locates the relocated dynamic library",
substrs = [new_dylib])
-
+ @skipOnLinux # bugzilla 14424 - missing linux Makefiles/testcase support
def test_dyld_library_path(self):
"""Test DYLD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
@@ -88,7 +91,6 @@
if sys.platform.startswith("darwin"):
dylibName = 'libd.dylib'
dsymName = 'libd.dylib.dSYM'
- dylibPath = 'DYLD_LIBRARY_PATH'
# The directory to relocate the dynamic library and its debugging info.
special_dir = "hidden"
@@ -104,13 +106,13 @@
# Try running with the DYLD_LIBRARY_PATH environment variable set, make sure
# we pick up the hidden dylib.
- env_cmd_string = "settings set target.env-vars " + dylibPath + "=" + new_dir
+ env_cmd_string = "settings set target.env-vars " + self.dylibPath + "=" + new_dir
if self.TraceOn():
print "Set environment to: ", env_cmd_string
self.runCmd(env_cmd_string)
self.runCmd("settings show target.env-vars")
- remove_dyld_path_cmd = "settings remove target.env-vars " + dylibPath
+ remove_dyld_path_cmd = "settings remove target.env-vars " + self.dylibPath
self.addTearDownHook(lambda: self.runCmd(remove_dyld_path_cmd))
lldbutil.run_break_set_by_file_and_line (self, "d.c", self.line_d_function, num_expected_locations=1, loc_exact=True)
@@ -130,6 +132,7 @@
self.expect("target modules list",
substrs = [special_dir, os.path.basename(new_dylib)])
+ @skipOnLinux # bugzilla 14424 - missing linux Makefiles/testcase support
def test_lldb_process_load_and_unload_commands(self):
"""Test that lldb process load/unload command work correctly."""
@@ -176,6 +179,7 @@
self.runCmd("process continue")
+ @skipOnLinux # bugzilla 14424 - missing linux Makefiles/testcase support
def test_load_unload(self):
"""Test breakpoint by name works correctly with dlopen'ing."""
@@ -215,6 +219,7 @@
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
substrs = [' resolved, hit count = 2'])
+ @skipOnLinux # bugzilla 14424 - missing linux Makefiles/testcase support
def test_step_over_load (self):
"""Test stepping over code that loads a shared library works correctly."""
Index: aze/lldb/test/functionalities/platform/TestPlatformCommand.py
===================================================================
--- aze.orig/lldb/test/functionalities/platform/TestPlatformCommand.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/platform/TestPlatformCommand.py 2013-03-03 09:35:50.307457351 +0100
@@ -18,6 +18,7 @@
self.expect("platform list",
patterns = ['^Available platforms:'])
+ @expectedFailureLinux # due to bugzilla 14541 -- Cannot list processes on Linux
def test_process_list(self):
self.expect("platform process list",
substrs = ['PID', 'ARCH', 'NAME'])
@@ -27,6 +28,7 @@
self.expect("platform process info", error=True,
substrs = ['one or more process id(s) must be specified'])
+ @expectedFailureLinux # due to bugzilla 14806 -- "platform status" prints more information on Mac OS X than on Linux
def test_status(self):
self.expect("platform status",
substrs = ['Platform', 'Triple', 'OS Version', 'Kernel', 'Hostname'])
Index: aze/lldb/test/functionalities/process_launch/TestProcessLaunch.py
===================================================================
--- aze.orig/lldb/test/functionalities/process_launch/TestProcessLaunch.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/process_launch/TestProcessLaunch.py 2013-03-03 09:35:50.307457351 +0100
@@ -11,6 +11,13 @@
mydir = os.path.join("functionalities", "process_launch")
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_io_with_dsym (self):
@@ -145,7 +152,7 @@
err_file_path)
self.expect(launch_command, error=True,
- startstr = "error: No such file or directory: %sz" % my_working_dir_path)
+ patterns = ["error:.* No such file or directory: %sz" % my_working_dir_path])
# Really launch the process
launch_command = "process launch -w %s -o %s -e %s" % (my_working_dir_path,
Index: aze/lldb/test/functionalities/register/TestRegisters.py
===================================================================
--- aze.orig/lldb/test/functionalities/register/TestRegisters.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/register/TestRegisters.py 2013-03-03 09:35:50.307457351 +0100
@@ -20,6 +20,7 @@
self.buildDefault()
self.register_commands()
+ @expectedFailureLinux # bugzilla 14600 - Convenience registers not supported on Linux
def test_convenience_registers(self):
"""Test convenience registers."""
if not self.getArchitecture() in ['x86_64']:
@@ -27,6 +28,7 @@
self.buildDefault()
self.convenience_registers()
+ @expectedFailureLinux # bugzilla 14600 - Convenience registers not supported on Linux
def test_convenience_registers_with_process_attach(self):
"""Test convenience registers after a 'process attach'."""
if not self.getArchitecture() in ['x86_64']:
@@ -34,6 +36,7 @@
self.buildDefault()
self.convenience_registers_with_process_attach()
+ @expectedFailureLinux # bugzilla 14661 - Expressions involving XMM registers fail on Linux
def register_commands(self):
"""Test commands related to registers, in particular xmm registers."""
exe = os.path.join(os.getcwd(), "a.out")
@@ -97,18 +100,14 @@
"""Test convenience registers after a 'process attach'."""
exe = self.lldbHere
- # Spawn a new process and don't display the stdout if not in TraceOn() mode.
- import subprocess
- popen = subprocess.Popen([exe, self.lldbOption],
- stdout = open(os.devnull, 'w') if not self.TraceOn() else None)
- if self.TraceOn():
- print "pid of spawned process: %d" % popen.pid
+ # Spawn a new process
+ proc = self.spawnSubprocess(exe, [self.lldbOption])
+ self.addTearDownHook(self.cleanupSubprocesses)
- self.runCmd("process attach -p %d" % popen.pid)
+ if self.TraceOn():
+ print "pid of spawned process: %d" % proc.pid
- # Add a hook to kill the child process during teardown.
- self.addTearDownHook(
- lambda: popen.kill())
+ self.runCmd("process attach -p %d" % proc.pid)
# Check that "register read eax" works.
self.runCmd("register read eax")
Index: aze/lldb/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py
===================================================================
--- aze.orig/lldb/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/single-quote-in-filename-to-lldb/TestSingleQuoteInFilename.py 2013-03-03 09:35:50.307457351 +0100
@@ -23,6 +23,7 @@
except:
pass
+ @skipOnLinux # PR-14637: this test case fails sometimes because the input prompt "(lldb)" is missing
def test_lldb_invocation_with_single_quote_in_filename(self):
"""Test that 'lldb my_file_name' works where my_file_name is a string with a single quote char in it."""
self.buildDefault()
Index: aze/lldb/test/functionalities/stop-hook/multiple_threads/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/stop-hook/multiple_threads/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/stop-hook/multiple_threads/Makefile 2013-03-03 09:35:50.307457351 +0100
@@ -1,6 +1,6 @@
LEVEL = ../../../make
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py
===================================================================
--- aze.orig/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/stop-hook/multiple_threads/TestStopHookMultipleThreads.py 2013-03-03 09:35:50.307457351 +0100
@@ -21,6 +21,7 @@
self.stop_hook_multiple_threads()
@dwarf_test
+ @skipOnLinux # due to bugzilla 14323
def test_stop_hook_multiple_threads_with_dwarf(self):
"""Test that lldb stop-hook works for multiple threads."""
self.buildDwarf(dictionary=self.d)
@@ -61,7 +62,7 @@
# Now run the program, expect to stop at the the first breakpoint which is within the stop-hook range.
child.sendline('run')
child.expect_exact(prompt)
- child.sendline('target stop-hook add -o "frame variable -g g_val"')
+ child.sendline('target stop-hook add -o "frame variable --show-globals g_val"')
child.expect_exact(prompt)
# Continue and expect to find the output emitted by the firing of our stop hook.
Index: aze/lldb/test/functionalities/stop-hook/TestStopHookMechanism.py
===================================================================
--- aze.orig/lldb/test/functionalities/stop-hook/TestStopHookMechanism.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/stop-hook/TestStopHookMechanism.py 2013-03-03 09:35:50.307457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.stop_hook_firing()
+ @skipOnLinux # PR-15037: stop-hooks sometimes fail to fire on Linux (disabled to avoid needless noise)
@dwarf_test
def test_with_dwarf(self):
"""Test the stop-hook mechanism."""
Index: aze/lldb/test/functionalities/thread/main.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/thread/main.c 2013-03-03 09:35:50.307457351 +0100
@@ -0,0 +1,58 @@
+#include <pthread.h>
+
+pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t mutex3 = PTHREAD_MUTEX_INITIALIZER;
+
+void *
+thread3 (void *input)
+{
+ pthread_mutex_unlock(&mutex2); // Set break point at this line.
+ pthread_mutex_unlock(&mutex1);
+ return NULL;
+}
+
+void *
+thread2 (void *input)
+{
+ pthread_mutex_unlock(&mutex3);
+ pthread_mutex_lock(&mutex2);
+ pthread_mutex_unlock(&mutex2);
+
+ return NULL;
+}
+
+void *
+thread1 (void *input)
+{
+ pthread_t thread_2;
+ pthread_create (&thread_2, NULL, thread2, NULL);
+
+ pthread_mutex_lock(&mutex1);
+ pthread_mutex_unlock(&mutex1);
+
+ pthread_join(thread_2, NULL);
+
+ return NULL;
+}
+
+int main ()
+{
+ pthread_t thread_1;
+ pthread_t thread_3;
+
+ pthread_mutex_lock (&mutex1);
+ pthread_mutex_lock (&mutex2);
+ pthread_mutex_lock (&mutex3);
+
+ pthread_create (&thread_1, NULL, thread1, NULL);
+
+ pthread_mutex_lock(&mutex3);
+ pthread_create (&thread_3, NULL, thread3, NULL);
+
+ pthread_join (thread_1, NULL);
+ pthread_join (thread_3, NULL);
+
+ return 0;
+
+}
Index: aze/lldb/test/functionalities/thread/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/thread/Makefile 2013-03-03 09:35:50.307457351 +0100
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c
+LD_EXTRAS := -lpthread
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/functionalities/thread/TestNumThreads.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/thread/TestNumThreads.py 2013-03-03 09:35:50.307457351 +0100
@@ -0,0 +1,66 @@
+"""
+Test number of threads.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class NumberOfThreadsTestCase(TestBase):
+
+ mydir = os.path.join("functionalities", "thread")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test number of threads."""
+ self.buildDsym()
+ self.number_of_threads_test()
+
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test number of threads."""
+ self.buildDwarf()
+ self.number_of_threads_test()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break inside main().
+ self.line = line_number('main.c', '// Set break point at this line.')
+
+ def number_of_threads_test(self):
+ """Test number of threads."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # This should create a breakpoint with 1 location.
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1)
+
+ # The breakpoint list should show 3 locations.
+ self.expect("breakpoint list -f", "Breakpoint location shown correctly",
+ substrs = ["1: file ='main.c', line = %d, locations = 1" % self.line])
+
+ # Run the program.
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # Stopped once.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ["stop reason = breakpoint 1."])
+
+ # Get the target process
+ target = self.dbg.GetSelectedTarget()
+ process = target.GetProcess()
+
+ # Get the number of threads
+ num_threads = process.GetNumThreads()
+
+ self.assertTrue(num_threads == 4, 'Number of expected threads and actual threads do not match.')
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/type_completion/TestTypeCompletion.py
===================================================================
--- aze.orig/lldb/test/functionalities/type_completion/TestTypeCompletion.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/type_completion/TestTypeCompletion.py 2013-03-03 09:35:50.307457351 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.type_completion_commands()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Check that types only get completed when necessary."""
Index: aze/lldb/test/functionalities/watchpoint/hello_watchlocation/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/hello_watchlocation/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/hello_watchlocation/Makefile 2013-03-03 09:35:50.307457351 +0100
@@ -1,6 +1,6 @@
LEVEL = ../../../make
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/hello_watchlocation/TestWatchLocation.py 2013-03-03 09:35:50.307457351 +0100
@@ -21,6 +21,8 @@
self.setTearDownCleanup(dictionary=self.d)
self.hello_watchlocation()
+ #@expectedFailureLinux # bugzilla 14416
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_hello_watchlocation_with_dwarf(self):
"""Test watching a location with '-x size' option."""
Index: aze/lldb/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py 2013-03-03 09:35:50.307457351 +0100
@@ -10,6 +10,9 @@
class HelloWatchpointTestCase(TestBase):
+ def getCategories (self):
+ return ['basic_process']
+
mydir = os.path.join("functionalities", "watchpoint", "hello_watchpoint")
@dsym_test
@@ -19,6 +22,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.hello_watchpoint()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_hello_watchpoint_with_dwarf_using_watchpoint_set(self):
"""Test a simple sequence of watchpoint creation and watchpoint hit."""
Index: aze/lldb/test/functionalities/watchpoint/multiple_threads/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/multiple_threads/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/multiple_threads/Makefile 2013-03-03 09:35:50.307457351 +0100
@@ -1,6 +1,6 @@
LEVEL = ../../../make
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/multiple_threads/TestWatchpointMultipleThreads.py 2013-03-03 09:35:50.307457351 +0100
@@ -21,6 +21,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.hello_multiple_threads()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_multiple_threads_with_dwarf(self):
"""Test that lldb watchpoint works for multiple threads."""
@@ -36,6 +37,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.hello_multiple_threads_wp_set_and_then_delete()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_multiple_threads_wp_set_and_then_delete_with_dwarf(self):
"""Test that lldb watchpoint works for multiple threads, and after the watchpoint is deleted, the watchpoint event should no longer fires."""
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandLLDB.py 2013-03-03 09:35:50.311457351 +0100
@@ -33,6 +33,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.watchpoint_command()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_command_with_dwarf(self):
"""Test 'watchpoint command'."""
@@ -48,6 +49,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.watchpoint_command_can_disable_a_watchpoint()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_command_can_disable_a_watchpoint_with_dwarf(self):
"""Test that 'watchpoint command' action can disable a watchpoint after it is triggered."""
@@ -101,7 +103,7 @@
'new value:', ' = 1'])
# The watchpoint command "forced" our global variable 'cookie' to become 777.
- self.expect("frame variable -g cookie",
+ self.expect("frame variable --show-globals cookie",
substrs = ['(int32_t)', 'cookie = 777'])
def watchpoint_command_can_disable_a_watchpoint(self):
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_commands/command/TestWatchpointCommandPython.py 2013-03-03 09:35:50.311457351 +0100
@@ -33,6 +33,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.watchpoint_command()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_command_with_dwarf(self):
"""Test 'watchpoint command'."""
@@ -89,7 +90,7 @@
'new value:', ' = 1'])
# The watchpoint command "forced" our global variable 'cookie' to become 777.
- self.expect("frame variable -g cookie",
+ self.expect("frame variable --show-globals cookie",
substrs = ['(int32_t)', 'cookie = 777'])
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_commands/condition/TestWatchpointConditionCmd.py 2013-03-03 09:35:50.311457351 +0100
@@ -33,6 +33,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.watchpoint_condition()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_cond_with_dwarf(self):
"""Test watchpoint condition."""
@@ -76,7 +77,7 @@
# The stop reason of the thread should be watchpoint.
self.expect("thread backtrace", STOPPED_DUE_TO_WATCHPOINT,
substrs = ['stop reason = watchpoint'])
- self.expect("frame variable -g global",
+ self.expect("frame variable --show-globals global",
substrs = ['(int32_t)', 'global = 5'])
# Use the '-v' option to do verbose listing of the watchpoint.
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_commands/TestWatchpointCommands.py 2013-03-03 09:35:50.311457351 +0100
@@ -34,6 +34,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.normal_read_write_watchpoint()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_rw_watchpoint_with_dwarf(self):
"""Test read_write watchpoint and expect to stop two times."""
@@ -49,6 +50,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.delete_read_write_watchpoint()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_rw_watchpoint_delete_with_dwarf(self):
"""Test delete watchpoint and expect not to stop for watchpoint."""
@@ -64,6 +66,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.ignore_read_write_watchpoint()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_rw_watchpoint_set_ignore_count_with_dwarf(self):
"""Test watchpoint ignore count and expect to not to stop at all."""
@@ -79,6 +82,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.read_write_watchpoint_disable_after_first_stop()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_rw_disable_after_first_stop__with_dwarf(self):
"""Test read_write watchpoint but disable it after the first stop."""
@@ -94,6 +98,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.read_write_watchpoint_disable_then_enable()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_rw_disable_then_enable_with_dwarf(self):
"""Test read_write watchpoint, disable initially, then enable it."""
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_events/main.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_events/main.c 2013-03-03 09:35:50.311457351 +0100
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+main (int argc, char **argv)
+{
+ int local_var = 10;
+ printf ("local_var is: %d.\n", local_var++); // Put a breakpoint here.
+ return local_var;
+}
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_events/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_events/Makefile 2013-03-03 09:35:50.311457351 +0100
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_events/TestWatchpointEvents.py 2013-03-03 09:35:50.311457351 +0100
@@ -0,0 +1,103 @@
+"""Test that adding, deleting and modifying watchpoints sends the appropriate events."""
+
+import os, time
+import unittest2
+import lldb
+import lldbutil
+from lldbtest import *
+
+class TestWatchpointEvents (TestBase):
+
+ mydir = os.path.join("functionalities", "watchpoint", "watchpoint_events")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_with_dsym_and_python_api(self):
+ """Test that adding, deleting and modifying watchpoints sends the appropriate events."""
+ self.buildDsym()
+ self.step_over_stepping()
+
+ @expectedFailureLinux # bugzilla 14437
+ @python_api_test
+ @dwarf_test
+ def test_with_dwarf_and_python_api(self):
+ """Test that adding, deleting and modifying watchpoints sends the appropriate events."""
+ self.buildDwarf()
+ self.step_over_stepping()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers that we will step to in main:
+ self.main_source = "main.c"
+
+ def GetWatchpointEvent (self, event_type):
+ # We added a watchpoint so we should get a watchpoint added event.
+ event = lldb.SBEvent()
+ success = self.listener.WaitForEvent (1, event)
+ self.assertTrue(success == True, "Successfully got watchpoint event")
+ self.assertTrue (lldb.SBWatchpoint.EventIsWatchpointEvent(event), "Event is a watchpoint event.")
+ found_type = lldb.SBWatchpoint.GetWatchpointEventTypeFromEvent (event)
+ self.assertTrue (found_type == event_type, "Event is not correct type, expected: %d, found: %d"%(event_type, found_type))
+ # There shouldn't be another event waiting around:
+ found_event = self.listener.PeekAtNextEventForBroadcasterWithType (self.target_bcast, lldb.SBTarget.eBroadcastBitBreakpointChanged, event)
+ if found_event:
+ print "Found an event I didn't expect: ", event
+
+ self.assertTrue (not found_event, "Only one event per change.")
+
+ def step_over_stepping(self):
+ """Use Python APIs to test stepping over and hitting breakpoints."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+
+ break_in_main = target.BreakpointCreateBySourceRegex ('// Put a breakpoint here.', self.main_source_spec)
+ self.assertTrue(break_in_main, VALID_BREAKPOINT)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple (None, None, os.getcwd())
+
+ self.assertTrue(process, PROCESS_IS_VALID)
+
+ # The stop reason of the thread should be breakpoint.
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main)
+
+ if len(threads) != 1:
+ self.fail ("Failed to stop at first breakpoint in main.")
+
+ thread = threads[0]
+ frame = thread.GetFrameAtIndex(0)
+ local_var = frame.FindVariable ("local_var")
+ self.assertTrue (local_var.IsValid())
+
+ self.listener = lldb.SBListener("com.lldb.testsuite_listener")
+ self.target_bcast = target.GetBroadcaster()
+ self.target_bcast.AddListener (self.listener, lldb.SBTarget.eBroadcastBitWatchpointChanged)
+ self.listener.StartListeningForEvents (self.target_bcast, lldb.SBTarget.eBroadcastBitWatchpointChanged)
+
+ error = lldb.SBError()
+ local_watch = local_var.Watch(True, True, True, error)
+ if not error.Success():
+ self.fail ("Failed to make watchpoint for local_var: %s"%(error.GetCString()))
+
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeAdded)
+ # Now change some of the features of this watchpoint and make sure we get events:
+ local_watch.SetEnabled(False)
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeDisabled)
+
+ local_watch.SetIgnoreCount(10)
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeIgnoreChanged)
+
+ local_watch.SetCondition ("1 == 2")
+ self.GetWatchpointEvent (lldb.eWatchpointEventTypeConditionChanged)
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_set_command/Makefile
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_set_command/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_set_command/Makefile 2013-03-03 09:35:50.311457351 +0100
@@ -1,6 +1,6 @@
LEVEL = ../../../make
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_set_command/TestWatchLocationWithWatchSet.py 2013-03-03 09:35:50.311457351 +0100
@@ -20,6 +20,8 @@
self.setTearDownCleanup(dictionary=self.d)
self.watchlocation_using_watchpoint_set()
+ #@expectedFailureLinux # bugzilla 14416
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_watchlocation_with_dwarf_using_watchpoint_set(self):
"""Test watching a location with 'watchpoint set expression -w write -x size' option."""
Index: aze/lldb/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
===================================================================
--- aze.orig/lldb/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py 2013-03-03 09:35:50.311457351 +0100
@@ -12,6 +12,7 @@
mydir = os.path.join("functionalities", "watchpoint", "watchpoint_set_command")
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
def test_error_cases_with_watchpoint_set(self):
"""Test error cases with the 'watchpoint set' command."""
self.buildDwarf(dictionary=self.d)
@@ -58,16 +59,12 @@
# 'watchpoint set expression' with '-w' or '-x' specified now needs
# an option terminator and a raw expression after that.
self.expect("watchpoint set expression -w write --", error=True,
- startstr = 'error: required argument missing; specify an expression to evaulate into the addres to watch for')
+ startstr = 'error: ')
# It's an error if the expression did not evaluate to an address.
self.expect("watchpoint set expression MyAggregateDataType", error=True,
startstr = 'error: expression did not evaluate to an address')
- # Check for missing option terminator '--'.
- self.expect("watchpoint set expression -w write -x 1 g_char_ptr", error=True,
- startstr = 'error: did you forget to enter the option terminator string "--"?')
-
# Wrong size parameter is an error.
self.expect("watchpoint set variable -x -128", error=True,
substrs = ['invalid enumeration value'])
Index: aze/lldb/test/help/TestHelp.py
===================================================================
--- aze.orig/lldb/test/help/TestHelp.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/help/TestHelp.py 2013-03-03 09:35:50.311457351 +0100
@@ -77,8 +77,13 @@
version_str = self.version_number_string()
import re
match = re.match('[0-9]+', version_str)
+ if sys.platform.startswith("darwin"):
+ search_regexp = ['LLDB-' + (version_str if match else '[0-9]+')]
+ else:
+ search_regexp = ['lldb version (\d|\.)+.*$']
+
self.expect("version",
- patterns = ['LLDB-' + (version_str if match else '[0-9]+')])
+ patterns = search_regexp)
def test_help_should_not_crash_lldb(self):
"""Command 'help disasm' should not crash lldb."""
Index: aze/lldb/test/lang/c/anonymous/TestAnonymous.py
===================================================================
--- aze.orig/lldb/test/lang/c/anonymous/TestAnonymous.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/anonymous/TestAnonymous.py 2013-03-03 09:35:50.311457351 +0100
@@ -15,6 +15,7 @@
self.buildDsym()
self.expr()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_expr_with_dwarf(self):
self.buildDwarf()
Index: aze/lldb/test/lang/c/array_types/TestArrayTypes.py
===================================================================
--- aze.orig/lldb/test/lang/c/array_types/TestArrayTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/array_types/TestArrayTypes.py 2013-03-03 09:35:50.311457351 +0100
@@ -71,7 +71,7 @@
# Issue 'variable list' command on several array-type variables.
- self.expect("frame variable -T strings", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types strings", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(char *[4])',
substrs = ['(char *) [0]',
'(char *) [1]',
@@ -82,14 +82,14 @@
'Bonjour',
'Guten Tag'])
- self.expect("frame variable -T char_16", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types char_16", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['(char) [0]',
'(char) [15]'])
- self.expect("frame variable -T ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types ushort_matrix", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(unsigned short [2][3])')
- self.expect("frame variable -T long_6", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types long_6", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(long [6])')
def array_types_python(self):
Index: aze/lldb/test/lang/c/bitfields/main.c
===================================================================
--- aze.orig/lldb/test/lang/c/bitfields/main.c 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/bitfields/main.c 2013-03-03 09:35:50.311457351 +0100
@@ -45,6 +45,23 @@
bits.b7 = i; //// break $source:$line
for (i=0; i<(1<<4); i++)
bits.four = i; //// break $source:$line
+
+ struct MoreBits
+ {
+ uint32_t a : 3;
+ uint8_t : 1;
+ uint8_t b : 1;
+ uint8_t c : 1;
+ uint8_t d : 1;
+ };
+
+ struct MoreBits more_bits;
+
+ more_bits.a = 3;
+ more_bits.b = 0;
+ more_bits.c = 1;
+ more_bits.d = 0;
+
return 0; //// Set break point at this line.
}
Index: aze/lldb/test/lang/c/bitfields/TestBitfields.py
===================================================================
--- aze.orig/lldb/test/lang/c/bitfields/TestBitfields.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/bitfields/TestBitfields.py 2013-03-03 09:35:50.311457351 +0100
@@ -33,6 +33,7 @@
@python_api_test
@dwarf_test
+ @expectedFailureGcc # GCC (4.6/4.7) generates incorrect code with unnamed bitfields.
def test_with_dwarf_and_python_api(self):
"""Use Python APIs to inspect a bitfields variable."""
self.buildDwarf()
@@ -64,7 +65,7 @@
substrs = [' resolved, hit count = 1'])
# This should display correctly.
- self.expect("frame variable -T bits", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types bits", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['(uint32_t:1) b1 = 1',
'(uint32_t:2) b2 = 3',
'(uint32_t:3) b3 = 7',
@@ -76,7 +77,7 @@
# And so should this.
# rdar://problem/8348251
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['(uint32_t:1) b1 = 1',
'(uint32_t:2) b2 = 3',
'(uint32_t:3) b3 = 7',
@@ -86,6 +87,38 @@
'(uint32_t:7) b7 = 127',
'(uint32_t:4) four = 15'])
+ self.expect("expr (bits.b1)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '1'])
+ self.expect("expr (bits.b2)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '3'])
+ self.expect("expr (bits.b3)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '7'])
+ self.expect("expr (bits.b4)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '15'])
+ self.expect("expr (bits.b5)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '31'])
+ self.expect("expr (bits.b6)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '63'])
+ self.expect("expr (bits.b7)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '127'])
+ self.expect("expr (bits.four)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '15'])
+
+ self.expect("frame variable --show-types more_bits", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(uint32_t:3) a = 3',
+ '(uint8_t:1) b = \'\\0\'',
+ '(uint8_t:1) c = \'\\x01\'',
+ '(uint8_t:1) d = \'\\0\''])
+
+ self.expect("expr (more_bits.a)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint32_t', '3'])
+ self.expect("expr (more_bits.b)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint8_t', '\\0'])
+ self.expect("expr (more_bits.c)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint8_t', '\\x01'])
+ self.expect("expr (more_bits.d)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['uint8_t', '\\0'])
+
def bitfields_variable_python(self):
"""Use Python APIs to inspect a bitfields variable."""
exe = os.path.join(os.getcwd(), "a.out")
Index: aze/lldb/test/lang/c/const_variables/functions.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/c/const_variables/functions.c 2013-03-03 09:35:50.311457351 +0100
@@ -0,0 +1,18 @@
+#include <stdio.h>
+
+void foo()
+{
+ printf("foo()\n");
+}
+
+int bar()
+{
+ int ret = 3;
+ printf("bar()->%d\n", ret);
+ return ret;
+}
+
+void baaz(int i)
+{
+ printf("baaz(%d)\n", i);
+}
Index: aze/lldb/test/lang/c/const_variables/main.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/c/const_variables/main.c 2013-03-03 09:35:50.311457351 +0100
@@ -0,0 +1,19 @@
+#include <stdint.h>
+
+extern int foo();
+extern int bar();
+extern int baaz(int i);
+
+int main()
+{
+ int32_t index;
+
+ foo();
+
+ index = 512;
+
+ if (bar())
+ index = 256;
+
+ baaz(index);
+}
Index: aze/lldb/test/lang/c/const_variables/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/c/const_variables/Makefile 2013-03-03 09:35:50.311457351 +0100
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c functions.c
+
+CFLAGS ?= -g -O3
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/c/const_variables/TestConstVariables.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/c/const_variables/TestConstVariables.py 2013-03-03 09:35:50.315457350 +0100
@@ -0,0 +1,69 @@
+"""Check that compiler-generated constant values work correctly"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class ConstVariableTestCase(TestBase):
+
+ mydir = os.path.join("lang", "c", "const_variables")
+
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test interpreted and JITted expressions on constant values."""
+ self.buildDsym()
+ self.const_variable()
+
+ @expectedFailureLinux # Fix in review; test marked XFAIL to see if there's any other problems in buildbots
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test interpreted and JITted expressions on constant values."""
+ self.buildDwarf()
+ self.const_variable()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+
+ def const_variable(self):
+ """Test interpreted and JITted expressions on constant values."""
+ exe = os.path.join(os.getcwd(), "a.out")
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Break inside the main.
+ lldbutil.run_break_set_by_symbol (self, "main", num_expected_locations=1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ # The breakpoint should have a hit count of 1.
+ self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
+ substrs = [' resolved, hit count = 1'])
+
+ self.runCmd("next")
+
+ # Try frame variable.
+ self.expect("frame variable index", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int32_t) index = 512'])
+
+ # Try an interpreted expression.
+ self.expect("expr (index + 512)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int) $0 = 1024'])
+
+ # Try a JITted expression.
+ self.expect("expr (int)getpid(); (index - 256)", VARIABLES_DISPLAYED_CORRECTLY,
+ substrs = ['(int) $1 = 256'])
+
+ self.runCmd("kill")
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/c/forward/TestForwardDeclaration.py
===================================================================
--- aze.orig/lldb/test/lang/c/forward/TestForwardDeclaration.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/forward/TestForwardDeclaration.py 2013-03-03 09:35:50.315457350 +0100
@@ -48,13 +48,13 @@
# This should display correctly.
# Note that the member fields of a = 1 and b = 2 is by design.
- self.expect("frame variable -T *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['(bar) *bar_ptr = ',
'(int) a = 1',
'(int) b = 2'])
# And so should this.
- self.expect("expression *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expression --show-types -- *bar_ptr", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['(bar)',
'(int) a = 1',
'(int) b = 2'])
Index: aze/lldb/test/lang/c/function_types/TestFunctionTypes.py
===================================================================
--- aze.orig/lldb/test/lang/c/function_types/TestFunctionTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/function_types/TestFunctionTypes.py 2013-03-03 09:35:50.315457350 +0100
@@ -66,7 +66,7 @@
self.runToBreakpoint()
# Check that the 'callback' variable display properly.
- self.expect("frame variable -T callback", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types callback", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(int (*)(const char *)) callback =')
# And that we can break on the callback function.
Index: aze/lldb/test/lang/c/global_variables/TestGlobalVariables.py
===================================================================
--- aze.orig/lldb/test/lang/c/global_variables/TestGlobalVariables.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/global_variables/TestGlobalVariables.py 2013-03-03 09:35:50.315457350 +0100
@@ -13,13 +13,13 @@
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym(self):
- """Test 'frame variable -s -a' which omits args and shows scopes."""
+ """Test 'frame variable --scope --no-args' which omits args and shows scopes."""
self.buildDsym()
self.global_variables()
@dwarf_test
def test_with_dwarf(self):
- """Test 'frame variable -s -a' which omits args and shows scopes."""
+ """Test 'frame variable --scope --no-args' which omits args and shows scopes."""
self.buildDwarf()
self.global_variables()
@@ -28,9 +28,13 @@
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set break point at this line.')
+ if sys.platform.startswith("linux"):
+ # On Linux, LD_LIBRARY_PATH must be set so the shared libraries are found on startup
+ self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd())
+ self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath))
def global_variables(self):
- """Test 'frame variable -s -a' which omits args and shows scopes."""
+ """Test 'frame variable --scope --no-args' which omits args and shows scopes."""
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
@@ -49,7 +53,7 @@
substrs = [' resolved, hit count = 1'])
# Check that GLOBAL scopes are indicated for the variables.
- self.expect("frame variable -T -s -g -a", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types --scope --show-globals --no-args", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['GLOBAL: (int) g_file_global_int = 42',
'GLOBAL: (const char *) g_file_global_cstr',
'"g_file_global_cstr"',
Index: aze/lldb/test/lang/c/set_values/TestSetValues.py
===================================================================
--- aze.orig/lldb/test/lang/c/set_values/TestSetValues.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/set_values/TestSetValues.py 2013-03-03 09:35:50.315457350 +0100
@@ -61,63 +61,63 @@
substrs = [' resolved, hit count = 1'])
# main.c:15
- # Check that 'frame variable -T' displays the correct data type and value.
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ # Check that 'frame variable --show-types' displays the correct data type and value.
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(char) i = 'a'")
# Now set variable 'i' and check that it is correctly displayed.
self.runCmd("expression i = 'b'")
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(char) i = 'b'")
self.runCmd("continue")
# main.c:36
- # Check that 'frame variable -T' displays the correct data type and value.
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ # Check that 'frame variable --show-types' displays the correct data type and value.
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
patterns = ["\((short unsigned int|unsigned short)\) i = 33"])
# Now set variable 'i' and check that it is correctly displayed.
self.runCmd("expression i = 333")
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
patterns = ["\((short unsigned int|unsigned short)\) i = 333"])
self.runCmd("continue")
# main.c:57
- # Check that 'frame variable -T' displays the correct data type and value.
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ # Check that 'frame variable --show-types' displays the correct data type and value.
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(long) i = 33")
# Now set variable 'i' and check that it is correctly displayed.
self.runCmd("expression i = 33333")
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(long) i = 33333")
self.runCmd("continue")
# main.c:78
- # Check that 'frame variable -T' displays the correct data type and value.
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ # Check that 'frame variable --show-types' displays the correct data type and value.
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(double) i = 3.14159")
# Now set variable 'i' and check that it is correctly displayed.
self.runCmd("expression i = 3.14")
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(double) i = 3.14")
self.runCmd("continue")
# main.c:85
- # Check that 'frame variable -T' displays the correct data type and value.
+ # Check that 'frame variable --show-types' displays the correct data type and value.
# rdar://problem/8422727
# set_values test directory: 'frame variable' shows only (long double) i =
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(long double) i = 3.14159")
# Now set variable 'i' and check that it is correctly displayed.
self.runCmd("expression i = 3.1")
- self.expect("frame variable -T", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(long double) i = 3.1")
Index: aze/lldb/test/lang/c/shared_lib/TestSharedLib.py
===================================================================
--- aze.orig/lldb/test/lang/c/shared_lib/TestSharedLib.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/shared_lib/TestSharedLib.py 2013-03-03 09:35:50.315457350 +0100
@@ -39,6 +39,9 @@
TestBase.setUp(self)
# Find the line number to break inside main().
self.line = line_number('main.c', '// Set breakpoint 0 here.')
+ if sys.platform.startswith("linux"):
+ self.runCmd("settings set target.env-vars " + self.dylibPath + "=" + os.getcwd())
+ self.addTearDownHook(lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath))
def common_setup(self):
exe = os.path.join(os.getcwd(), "a.out")
@@ -63,7 +66,7 @@
self.common_setup()
# This should display correctly.
- self.expect("expression *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expression --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["(foo)", "(sub_foo)", "other_element = 3"])
@unittest2.expectedFailure
@@ -73,7 +76,7 @@
self.common_setup()
# This should display correctly.
- self.expect("frame variable *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types -- *my_foo_ptr", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["(foo)", "(sub_foo)", "other_element = 3"])
if __name__ == '__main__':
Index: aze/lldb/test/lang/c/stepping/main.c
===================================================================
--- aze.orig/lldb/test/lang/c/stepping/main.c 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/stepping/main.c 2013-03-03 09:35:50.315457350 +0100
@@ -11,10 +11,11 @@
int a(int);
int b(int);
int c(int);
+const char *print_string = "aaaaaaaaaa\n";
int a(int val)
{
- int return_value = val;
+ int return_value = val; // basic break at the start of b
if (val <= 1)
{
@@ -39,6 +40,11 @@
return val + 3; // Find the line number of function "c" here.
}
+int complex (int first, int second, int third)
+{
+ return first + second + third; // Step in targetting complex should stop here
+}
+
int main (int argc, char const *argv[])
{
int A1 = a(1); // frame select 2, thread step-out while stopped at "c(1)"
@@ -50,5 +56,14 @@
int A3 = a(3); // frame select 1, thread step-out while stopped at "c(3)"
printf("a(3) returns %d\n", A3);
+ int A4 = complex (a(1), b(2), c(3)); // Stop here to try step in targetting b.
+
+ int A5 = complex (a(2), b(3), c(4)); // Stop here to try step in targetting complex.
+
+ int A6 = complex (a(4), b(5), c(6)); // Stop here to step targetting b and hitting breakpoint.
+
+ int A7 = complex (a(5), b(6), c(7)); // Stop here to make sure bogus target steps over.
+
+ printf ("I am using print_string: %s.\n", print_string);
return 0;
}
Index: aze/lldb/test/lang/c/stepping/TestStepAndBreakpoints.py
===================================================================
--- aze.orig/lldb/test/lang/c/stepping/TestStepAndBreakpoints.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/stepping/TestStepAndBreakpoints.py 2013-03-03 09:35:50.315457350 +0100
@@ -10,6 +10,9 @@
mydir = os.path.join("lang", "c", "stepping")
+ def getCategories(self):
+ return ['basic_process']
+
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
@@ -18,6 +21,7 @@
self.buildDsym()
self.step_over_stepping()
+ @expectedFailureLinux # bugzilla 14437
@python_api_test
@dwarf_test
def test_with_dwarf_and_python_api(self):
@@ -71,6 +75,9 @@
thread = threads[0]
+ # Get the stop id and for fun make sure it increases:
+ old_stop_id = process.GetStopID()
+
# Now step over, which should cause us to hit the breakpoint in "a"
thread.StepOver()
@@ -79,6 +86,10 @@
if len(threads) != 1:
self.fail ("Failed to stop at breakpoint in a.")
+ # Check that the stop ID increases:
+ new_stop_id = process.GetStopID()
+ self.assertTrue(new_stop_id > old_stop_id, "Stop ID increases monotonically.")
+
thread = threads[0]
# Step over, and we should hit the breakpoint in b:
@@ -98,13 +109,25 @@
current_bp.append(thread.GetStopReasonDataAtIndex(0))
current_bp.append(thread.GetStopReasonDataAtIndex(1))
- frame.EvaluateExpression ('(int) printf ("aaaaaaaaaa\n")')
+ stop_id_before_expression = process.GetStopID()
+ stop_id_before_including_expressions = process.GetStopID(True)
+
+ frame.EvaluateExpression ("(int) printf (print_string)")
frame = thread.GetFrameAtIndex(0)
self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.")
self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.")
self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.")
self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.")
+
+ # Also make sure running the expression didn't change the public stop id
+ # but did change if we are asking for expression stops as well.
+ stop_id_after_expression = process.GetStopID()
+ stop_id_after_including_expressions = process.GetStopID(True)
+
+ self.assertTrue (stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID")
+
+ self.assertTrue (stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.")
# Do the same thing with an expression that's going to crash, and make sure we are still unchanged.
@@ -160,6 +183,71 @@
self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == current_line)
self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec() == current_file)
+ # Now we are going to test step in targetting a function:
+
+ break_in_b.SetEnabled (False)
+
+ break_before_complex_1 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targetting b.', self.main_source_spec)
+ self.assertTrue(break_before_complex_1, VALID_BREAKPOINT)
+
+ break_before_complex_2 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targetting complex.', self.main_source_spec)
+ self.assertTrue(break_before_complex_2, VALID_BREAKPOINT)
+
+ break_before_complex_3 = target.BreakpointCreateBySourceRegex ('// Stop here to step targetting b and hitting breakpoint.', self.main_source_spec)
+ self.assertTrue(break_before_complex_3, VALID_BREAKPOINT)
+
+ break_before_complex_4 = target.BreakpointCreateBySourceRegex ('// Stop here to make sure bogus target steps over.', self.main_source_spec)
+ self.assertTrue(break_before_complex_4, VALID_BREAKPOINT)
+
+ threads = lldbutil.continue_to_breakpoint(process, break_before_complex_1)
+ self.assertTrue (len(threads) == 1)
+ thread = threads[0]
+ break_before_complex_1.SetEnabled(False)
+
+ thread.StepInto ("b")
+ self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b")
+
+ # Now continue out and stop at the next call to complex. This time step all the way into complex:
+ threads = lldbutil.continue_to_breakpoint (process, break_before_complex_2)
+ self.assertTrue (len(threads) == 1)
+ thread = threads[0]
+ break_before_complex_2.SetEnabled(False)
+
+ thread.StepInto ("complex")
+ self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "complex")
+
+ # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targetting b:
+ threads = lldbutil.continue_to_breakpoint (process, break_before_complex_3)
+ self.assertTrue (len(threads) == 1)
+ thread = threads[0]
+ break_before_complex_3.SetEnabled(False)
+
+ break_at_start_of_a = target.BreakpointCreateByName ('a')
+ break_at_start_of_c = target.BreakpointCreateByName ('c')
+
+ thread.StepInto ("b")
+ threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint);
+
+ self.assertTrue (len(threads) == 1)
+ thread = threads[0]
+ stop_break_id = thread.GetStopReasonDataAtIndex(0)
+ self.assertTrue(stop_break_id == break_at_start_of_a.GetID() or stop_break_id == break_at_start_of_c.GetID())
+
+ break_at_start_of_a.SetEnabled(False)
+ break_at_start_of_c.SetEnabled(False)
+
+ process.Continue()
+ self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b")
+
+ # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targetting b:
+ threads = lldbutil.continue_to_breakpoint (process, break_before_complex_4)
+ self.assertTrue (len(threads) == 1)
+ thread = threads[0]
+ break_before_complex_4.SetEnabled(False)
+
+ thread.StepInto("NoSuchFunction")
+ self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main")
+
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
Index: aze/lldb/test/lang/c/strings/TestCStrings.py
===================================================================
--- aze.orig/lldb/test/lang/c/strings/TestCStrings.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/strings/TestCStrings.py 2013-03-03 09:35:50.315457350 +0100
@@ -42,6 +42,7 @@
self.expect("expression -- z[2]",
startstr = "(const char) $1 = 'x'")
+ # On Linux, the expression below will test GNU indirect function calls.
self.expect("expression -- (int)strlen(\"hello\")",
startstr = "(int) $2 = 5")
@@ -52,9 +53,9 @@
startstr = "(const char) $4 = '\\0'")
self.expect("p \"hello\"",
- substrs = ['(const char [6]) $', 'hello',
- '(const char) [0] = \'h\'',
- '(const char) [5] = \'\\0\''])
+ substrs = ['[6]) $', 'hello',
+ '[0] = \'h\'',
+ '[5] = \'\\0\''])
self.expect("p (char*)\"hello\"",
substrs = ['(char *) $', ' = 0x',
Index: aze/lldb/test/lang/c/struct_types/main.c
===================================================================
--- aze.orig/lldb/test/lang/c/struct_types/main.c 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/struct_types/main.c 2013-03-03 09:35:50.315457350 +0100
@@ -20,5 +20,5 @@
};
struct point_tag pt = { 2, 3, {} }; // This is the first executable statement.
struct rect_tag rect = {{1, 2, {}}, {3, 4, {}}};
- return 0;
+ return 0; // This is the return statement.
}
Index: aze/lldb/test/lang/c/struct_types/TestStructTypes.py
===================================================================
--- aze.orig/lldb/test/lang/c/struct_types/TestStructTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/c/struct_types/TestStructTypes.py 2013-03-03 09:35:50.315457350 +0100
@@ -14,6 +14,7 @@
mydir = os.path.join("lang", "c", "struct_types")
+ # rdar://problem/12566646
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_with_dsym(self):
@@ -21,6 +22,7 @@
self.buildDsym()
self.struct_types()
+ # rdar://problem/12566646
@dwarf_test
def test_with_dwarf(self):
"""Test that break on a struct declaration has no effect."""
@@ -31,19 +33,31 @@
# Call super's setUp().
TestBase.setUp(self)
# Find the line number to break for main.c.
- self.line = line_number('main.c', '// Set break point at this line.')
- self.first_executable_line = line_number('main.c',
+ self.source = 'main.c'
+ self.line = line_number(self.source, '// Set break point at this line.')
+ self.first_executable_line = line_number(self.source,
'// This is the first executable statement.')
+ self.return_line = line_number(self.source, '// This is the return statement.')
def struct_types(self):
- """Test that break on a struct declaration has no effect."""
+ """Test that break on a struct declaration has no effect and test structure access for zero sized arrays."""
exe = os.path.join(os.getcwd(), "a.out")
- self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
# Break on the struct declration statement in main.c.
lldbutil.run_break_set_by_file_and_line (self, "main.c", self.line, num_expected_locations=1, loc_exact=False)
+ lldbutil.run_break_set_by_file_and_line (self, "main.c", self.return_line, num_expected_locations=1, loc_exact=True)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
- self.runCmd("run", RUN_SUCCEEDED)
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
# We should be stopped on the first executable statement within the
# function where the original breakpoint was attempted.
@@ -55,10 +69,26 @@
self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
substrs = [' resolved, hit count = 1'])
+ process.Continue()
+ thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
+
+ # Test zero length array access and make sure it succeeds with "frame variable"
+ self.expect("frame variable pt.padding[0]",
+ DATA_TYPES_DISPLAYED_CORRECTLY,
+ substrs = ["pt.padding[0] = '"])
+ self.expect("frame variable pt.padding[1]",
+ DATA_TYPES_DISPLAYED_CORRECTLY,
+ substrs = ["pt.padding[1] = '"])
+ # Test zero length array access and make sure it succeeds with "expression"
+ self.expect("expression -- (pt.padding[0])",
+ DATA_TYPES_DISPLAYED_CORRECTLY,
+ substrs = ["(char)", " = '"])
+
# The padding should be an array of size 0
self.expect("image lookup -t point_tag",
DATA_TYPES_DISPLAYED_CORRECTLY,
- substrs = ['padding[0]'])
+ substrs = ['padding[]']) # Once rdar://problem/12566646 is fixed, this should display correctly
+
if __name__ == '__main__':
Index: aze/lldb/test/lang/cpp/bool/TestCPPBool.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/bool/TestCPPBool.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/bool/TestCPPBool.py 2013-03-03 09:35:50.315457350 +0100
@@ -26,7 +26,8 @@
TestBase.setUp(self)
def set_breakpoint(self, line):
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line, num_expected_locations=1, loc_exact=False)
+ locs = 4 if "gcc" in self.getCompiler() else 1
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line, num_expected_locations=locs, loc_exact=False)
def static_method_commands(self):
"""Test that bool types work in the expression parser"""
Index: aze/lldb/test/lang/cpp/char1632_t/.categories
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/char1632_t/.categories 2013-03-03 09:35:50.315457350 +0100
@@ -0,0 +1 @@
+dataformatters
Index: aze/lldb/test/lang/cpp/char1632_t/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/char1632_t/main.cpp 2013-03-03 09:35:50.315457350 +0100
@@ -0,0 +1,21 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+int main (int argc, char const *argv[])
+{
+ auto cs16 = u"hello world ྒྙྐ";
+ auto cs32 = U"hello world ྒྙྐ";
+ char16_t *s16 = (char16_t *)u"ﺸﺵۻ";
+ char32_t *s32 = (char32_t *)U"ЕЙРГЖО";
+ s32 = nullptr; // Set break point at this line.
+ s32 = (char32_t *)U"෴";
+ s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ";
+ return 0;
+}
Index: aze/lldb/test/lang/cpp/char1632_t/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/char1632_t/Makefile 2013-03-03 09:35:50.315457350 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+CFLAGS :=-g -O0 -std=c++11
+
+clean: OBJECTS+=$(wildcard main.d.*)
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/cpp/char1632_t/TestChar1632T.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/char1632_t/TestChar1632T.py 2013-03-03 09:35:50.315457350 +0100
@@ -0,0 +1,86 @@
+# coding=utf8
+"""
+Test that the C++11 support for char16_t and char32_t works correctly.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class Char1632TestCase(TestBase):
+
+ mydir = os.path.join("lang", "cpp", "char1632_t")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test that the C++11 support for char16_t and char32_t works correctly."""
+ self.buildDsym()
+ self.char1632()
+
+ @expectedFailureLinux # bugzilla 15038: missing wide char support on Linux
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test that the C++11 support for char16_t and char32_t works correctly."""
+ self.buildDwarf()
+ self.char1632()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.cpp.
+ self.source = 'main.cpp'
+ self.line = line_number(self.source, '// Set break point at this line.')
+
+ def char1632(self):
+ """Test that the C++11 support for char16_t and char32_t works correctly."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Break on the struct declration statement in main.cpp.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ if self.TraceOn():
+ self.runCmd("frame variable")
+
+ # Check that we correctly report the const types
+ self.expect("frame variable cs16 cs32",
+ substrs = ['(const char16_t *) cs16 = ','(const char32_t *) cs32 = ','u"hello world ྒྙྐ"','U"hello world ྒྙྐ"'])
+
+ # Check that we correctly report the non-const types
+ self.expect("frame variable s16 s32",
+ substrs = ['(char16_t *) s16 = ','(char32_t *) s32 = ','u"ﺸﺵۻ"','U"ЕЙРГЖО"'])
+
+ self.runCmd("next") # step to after the string is nullified
+
+ # check that we don't crash on NULL
+ self.expect("frame variable s32",
+ substrs = ['(char32_t *) s32 = 0x00000000'])
+
+ self.runCmd("next")
+ self.runCmd("next")
+
+ # check that the new strings show
+ self.expect("frame variable s16 s32",
+ substrs = ['(char16_t *) s16 = 0x','(char32_t *) s32 = ','"色ハ匂ヘト散リヌルヲ"','"෴"'])
+
+ # Check that we can run expressions that return charN_t
+ self.expect("expression u'a'",substrs = ['(char16_t) $',"61 u'a'"])
+ self.expect("expression U'a'",substrs = ['(char32_t) $',"61 U'a'"])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/cpp/class_static/TestStaticVariables.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/class_static/TestStaticVariables.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/class_static/TestStaticVariables.py 2013-03-03 09:35:50.315457350 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.static_variable_commands()
+ @expectedFailureLinux # PR-15261: lldb on Linux does not display the size of (class or file)static arrays
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test that file and class static variables display correctly."""
@@ -26,8 +27,8 @@
self.static_variable_commands()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
- #rdar://problem/9980907
- @expectedFailureClang
+ @expectedFailureClang(9980907)
+ @expectedFailureGcc(9980907)
@python_api_test
@dsym_test
def test_with_dsym_and_python_api(self):
@@ -35,8 +36,8 @@
self.buildDsym()
self.static_variable_python()
- #rdar://problem/9980907
- @expectedFailureClang
+ @expectedFailureClang(9980907)
+ @expectedFailureGcc(9980907)
@python_api_test
@dwarf_test
def test_with_dwarf_and_python_api(self):
Index: aze/lldb/test/lang/cpp/class_types/TestClassTypesDisassembly.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/class_types/TestClassTypesDisassembly.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/class_types/TestClassTypesDisassembly.py 2013-03-03 09:35:50.315457350 +0100
@@ -20,6 +20,7 @@
self.disassemble_call_stack()
@dwarf_test
+ @expectedFailureLinux # due to bugzilla 14540
def test_with_dwarf_and_run_command(self):
"""Disassemble each call frame when stopped on C's constructor."""
self.buildDwarf()
@@ -35,6 +36,7 @@
@python_api_test
@dwarf_test
+ @expectedFailureLinux # due to bugzilla 14540
def test_with_dwarf_and_python_api(self):
"""Disassemble each call frame when stopped on C's constructor."""
self.buildDwarf()
Index: aze/lldb/test/lang/cpp/class_types/TestClassTypes.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/class_types/TestClassTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/class_types/TestClassTypes.py 2013-03-03 09:35:50.315457350 +0100
@@ -92,7 +92,7 @@
substrs = [' resolved, hit count = 1'])
# We should be stopped on the ctor function of class C.
- self.expect("frame variable -T this", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types this", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['C *',
' this = '])
@@ -188,10 +188,10 @@
self.expect("frame variable this",VARIABLES_DISPLAYED_CORRECTLY,
substrs = ['C *'])
- # Verify that frame variable -T this->m_c_int behaves correctly.
+ # Verify that frame variable --show-types this->m_c_int behaves correctly.
self.runCmd("register read pc")
self.runCmd("expr m_c_int")
- self.expect("frame variable -T this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types this->m_c_int", VARIABLES_DISPLAYED_CORRECTLY,
startstr = '(int) this->m_c_int = 66')
# Verify that 'expression this' gets the data type correct.
Index: aze/lldb/test/lang/cpp/namespace/TestNamespace.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/namespace/TestNamespace.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/namespace/TestNamespace.py 2013-03-03 09:35:50.315457350 +0100
@@ -21,6 +21,7 @@
self.namespace_variable_commands()
# rdar://problem/8668674
+ @expectedFailureGcc # PR-15302: lldb does not print 'anonymous namespace' when the inferior is built with GCC (4.7)
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test that anonymous and named namespace variables display correctly."""
@@ -66,12 +67,12 @@
substrs = slist)
# 'frame variable' with basename 'i' should work.
- self.expect("frame variable -c -g i",
+ self.expect("frame variable --show-declaration --show-globals i",
startstr = "main.cpp:%d: (int) (anonymous namespace)::i = 3" % self.line_var_i)
# main.cpp:12: (int) (anonymous namespace)::i = 3
# 'frame variable' with basename 'j' should work, too.
- self.expect("frame variable -c -g j",
+ self.expect("frame variable --show-declaration --show-globals j",
startstr = "main.cpp:%d: (int) A::B::j = 4" % self.line_var_j)
# main.cpp:19: (int) A::B::j = 4
Index: aze/lldb/test/lang/cpp/rdar12991846/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/rdar12991846/main.cpp 2013-03-03 09:35:50.315457350 +0100
@@ -0,0 +1,21 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+int main (int argc, char const *argv[])
+{
+ auto cs16 = u"hello world ྒྙྐ";
+ auto cs32 = U"hello world ྒྙྐ";
+ char16_t *s16 = (char16_t *)u"ﺸﺵۻ";
+ char32_t *s32 = (char32_t *)U"ЕЙРГЖО";
+ s32 = nullptr; // Set break point at this line.
+ s32 = (char32_t *)U"෴";
+ s16 = (char16_t *)u"色ハ匂ヘト散リヌルヲ";
+ return 0;
+}
Index: aze/lldb/test/lang/cpp/rdar12991846/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/rdar12991846/Makefile 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+CFLAGS := -g -O0 -std=c++11
+
+clean: OBJECTS+=$(wildcard main.d.*)
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/cpp/rdar12991846/TestRdar12991846.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/rdar12991846/TestRdar12991846.py 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,84 @@
+# coding=utf8
+"""
+Test that the expression parser returns proper Unicode strings.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+# this test case fails because of rdar://12991846
+# the expression parser does not deal correctly with Unicode expressions
+# e.g.
+#(lldb) expr L"Hello"
+#(const wchar_t [6]) $0 = {
+# [0] = \0\0\0\0
+# [1] = \0\0\0\0
+# [2] = \0\0\0\0
+# [3] = \0\0\0\0
+# [4] = H\0\0\0
+# [5] = e\0\0\0
+#}
+
+class Rdar12991846TestCase(TestBase):
+
+ mydir = os.path.join("lang", "cpp", "rdar12991846")
+
+ @unittest2.expectedFailure
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test that the expression parser returns proper Unicode strings."""
+ self.buildDsym()
+ self.rdar12991846()
+
+ @unittest2.expectedFailure
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test that the expression parser returns proper Unicode strings."""
+ self.buildDwarf()
+ self.rdar12991846()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.cpp.
+ self.source = 'main.cpp'
+ self.line = line_number(self.source, '// Set break point at this line.')
+
+ def rdar12991846(self):
+ """Test that the expression parser returns proper Unicode strings."""
+ if self.getArchitecture() in ['i386']:
+ self.skipTest("Skipping because this test is known to crash on i386")
+
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Break on the struct declration statement in main.cpp.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ self.expect('expression L"hello"',
+ substrs = ['hello'])
+
+ self.expect('expression u"hello"',
+ substrs = ['hello'])
+
+ self.expect('expression U"hello"',
+ substrs = ['hello'])
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/cpp/rvalue-references/TestRvalueReferences.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/rvalue-references/TestRvalueReferences.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/rvalue-references/TestRvalueReferences.py 2013-03-03 09:35:50.319457349 +0100
@@ -21,6 +21,7 @@
#rdar://problem/11479676
@expectedFailureClang
+ @expectedFailureGcc # GCC (4.7) does not emit correct DWARF tags for rvalue-references
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test that rvalues are supported in the C++ expression parser"""
Index: aze/lldb/test/lang/cpp/signed_types/TestSignedTypes.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/signed_types/TestSignedTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/signed_types/TestSignedTypes.py 2013-03-03 09:35:50.319457349 +0100
@@ -54,7 +54,7 @@
self.runCmd("thread step-over")
# Test that signed types display correctly.
- self.expect("frame variable -T -a", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types --no-args", VARIABLES_DISPLAYED_CORRECTLY,
patterns = ["\((short int|short)\) the_signed_short = 99"],
substrs = ["(signed char) the_signed_char = 'c'",
"(int) the_signed_int = 99",
Index: aze/lldb/test/lang/cpp/static_members/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/static_members/main.cpp 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,36 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+
+struct A
+{
+ short m_a;
+ static long s_b;
+ char m_c;
+ static int s_d;
+
+ long access() {
+ return m_a + s_b + m_c + s_d; // breakpoint 2
+ }
+};
+
+long A::s_b = 2;
+int A::s_d = 4;
+
+int main()
+{
+ A my_a;
+ my_a.m_a = 1;
+ my_a.m_c = 3;
+
+ my_a.access(); // breakpoint 1
+ return 0;
+}
+
Index: aze/lldb/test/lang/cpp/static_members/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/static_members/Makefile 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/cpp/static_members/TestCPPStaticMembers.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/static_members/TestCPPStaticMembers.py 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,75 @@
+"""
+Tests that C++ member and static variables have correct layout and scope.
+"""
+import lldb
+from lldbtest import *
+import lldbutil
+
+class CPPStaticMembersTestCase(TestBase):
+
+ mydir = os.path.join("lang", "cpp", "static_members")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @unittest2.expectedFailure # llvm.org/pr15401
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test that member variables have the correct layout, scope and qualifiers when stopped inside and outside C++ methods"""
+ self.buildDsym()
+ self.static_member_commands()
+
+ @unittest2.expectedFailure # llvm.org/pr15401
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test that member variables have the correct layout, scope and qualifiers when stopped inside and outside C++ methods"""
+ self.buildDwarf()
+ self.static_member_commands()
+
+ def setUp(self):
+ TestBase.setUp(self)
+
+ def set_breakpoint(self, line):
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", line, num_expected_locations=1, loc_exact=False)
+
+ def static_member_commands(self):
+ """Test that member variables have the correct layout, scope and qualifiers when stopped inside and outside C++ methods"""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ self.set_breakpoint(line_number('main.cpp', '// breakpoint 1'))
+ self.set_breakpoint(line_number('main.cpp', '// breakpoint 2'))
+
+ self.runCmd("process launch", RUN_SUCCEEDED)
+ self.expect("expression my_a.access()",
+ startstr = "(long) $0 = 10")
+
+ self.expect("expression my_a.m_a",
+ startstr = "(short) $1 = 1")
+
+ # Note: SymbolFileDWARF::ParseChildMembers doesn't call AddFieldToRecordType, consistent with clang's AST layout.
+ self.expect("expression my_a.s_d",
+ startstr = "(int) $2 = 4")
+
+ self.expect("expression my_a.s_b",
+ startstr = "(long) $3 = 2")
+
+ self.expect("expression A::s_b",
+ startstr = "(long) $4 = 2")
+
+ # should not be available in global scope
+ self.expect("expression s_d",
+ startstr = "error: use of undeclared identifier 's_d'")
+
+ self.runCmd("process continue")
+ self.expect("expression m_c",
+ startstr = "(char) $5 = \'\\x03\'")
+
+ self.expect("expression s_b",
+ startstr = "(long) $6 = 2")
+
+ self.runCmd("process continue")
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/cpp/stl/main.cpp
===================================================================
--- aze.orig/lldb/test/lang/cpp/stl/main.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/stl/main.cpp 2013-03-03 09:35:50.319457349 +0100
@@ -6,6 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+#include <cstdio>
#include <iostream>
#include <string>
#include <map>
Index: aze/lldb/test/lang/cpp/stl/Makefile
===================================================================
--- aze.orig/lldb/test/lang/cpp/stl/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/stl/Makefile 2013-03-03 09:35:50.319457349 +0100
@@ -1,7 +1,7 @@
LEVEL = ../../../make
CXX_SOURCES := main.cpp
-CFLAGS :=-arch x86_64 -gdwarf-2 -O0
+CFLAGS := -g -O0
clean: OBJECTS+=$(wildcard main.d.*)
Index: aze/lldb/test/lang/cpp/stl/TestSTL.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/stl/TestSTL.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/stl/TestSTL.py 2013-03-03 09:35:50.319457349 +0100
@@ -22,6 +22,7 @@
self.step_stl_exprs()
# rdar://problem/10400981
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@unittest2.expectedFailure
@dwarf_test
def test_with_dwarf(self):
@@ -36,6 +37,7 @@
self.buildDsym()
self.sbtype_template_apis()
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@python_api_test
@dwarf_test
def test_SBType_template_aspects_with_dwarf(self):
Index: aze/lldb/test/lang/cpp/this/main.cpp
===================================================================
--- aze.orig/lldb/test/lang/cpp/this/main.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/this/main.cpp 2013-03-03 09:35:50.319457349 +0100
@@ -9,45 +9,45 @@
#include <stdio.h>
-class A
+template <class T> class A
{
public:
- void accessMember(int a);
- int accessMemberConst() const;
+ void accessMember(T a);
+ T accessMemberConst() const;
static int accessStaticMember();
- void accessMemberInline(int a) __attribute__ ((always_inline))
+ void accessMemberInline(T a) __attribute__ ((always_inline))
{
m_a = a; // breakpoint 4
}
- int m_a;
+ T m_a;
static int s_a;
};
-int A::s_a = 5;
+template <class T> int A<T>::s_a = 5;
-void A::accessMember(int a)
+template <class T> void A<T>::accessMember(T a)
{
m_a = a; // breakpoint 1
}
-int A::accessMemberConst() const
+template <class T> T A<T>::accessMemberConst() const
{
return m_a; // breakpoint 2
}
-int A::accessStaticMember()
+template <class T> int A<T>::accessStaticMember()
{
return s_a; // breakpoint 3
}
int main()
{
- A my_a;
+ A<int> my_a;
my_a.accessMember(3);
my_a.accessMemberConst();
- A::accessStaticMember();
+ A<int>::accessStaticMember();
my_a.accessMemberInline(5);
}
Index: aze/lldb/test/lang/cpp/this/TestCPPThis.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/this/TestCPPThis.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/this/TestCPPThis.py 2013-03-03 09:35:50.319457349 +0100
@@ -20,6 +20,7 @@
#rdar://problem/9962849
#@expectedFailureClang
+ @skipOnLinux #PR-15256: assertion failure in RecordLayoutBuilder::updateExternalFieldOffset
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test that the appropriate member variables are available when stopped in C++ static, inline, and const methods"""
Index: aze/lldb/test/lang/cpp/unique-types/TestUniqueTypes.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/unique-types/TestUniqueTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/unique-types/TestUniqueTypes.py 2013-03-03 09:35:50.319457349 +0100
@@ -33,10 +33,16 @@
def unique_types(self):
"""Test for unique types of std::vector<long> and std::vector<short>."""
+
+ if "clang" in self.getCompiler() and int(self.getCompilerVersion().split('.')[0]) < 3:
+ self.skipTest("rdar://problem/9173060 lldb hangs while running unique-types for clang version < 3")
+
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+ # GCC 4.6.3 (but not 4.4, 4.6.5 or 4.7) encodes two locations for the 'return 0' statement in main.cpp
+ locs = 2 if "gcc" in self.getCompiler() and "4.6.3" in self.getCompilerVersion() else 1
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=locs, loc_exact=True)
self.runCmd("run", RUN_SUCCEEDED)
@@ -45,35 +51,22 @@
substrs = ['stopped',
'stop reason = breakpoint'])
- if self.getCompiler().endswith('clang'):
- import re
- clang_version_output = system([lldbutil.which(self.getCompiler()), "-v"])[1]
- #print "my output:", clang_version_output
- for line in clang_version_output.split(os.linesep):
- m = re.search('clang version ([0-9]+)\.', line)
- #print "line:", line
- if m:
- clang_version = int(m.group(1))
- #print "clang version:", clang_version
- if clang_version < 3:
- self.skipTest("rdar://problem/9173060 lldb hangs while running unique-types for clang version < 3")
-
- # Do a "frame variable -T longs" and verify "long" is in each line of output.
- self.runCmd("frame variable -T longs")
+ # Do a "frame variable --show-types longs" and verify "long" is in each line of output.
+ self.runCmd("frame variable --show-types longs")
output = self.res.GetOutput()
for x in [line.strip() for line in output.split(os.linesep)]:
- # Skip empty line or closing brace.
- if not x or x == '}':
+ # Skip empty line, closing brace, and messages about more variables than can be displayed.
+ if not x or x == '}' or x == '...' or "Some of your variables have more members than the debugger will show by default" in x:
continue
self.expect(x, "Expect type 'long'", exe=False,
substrs = ['long'])
- # Do a "frame variable -T shorts" and verify "short" is in each line of output.
- self.runCmd("frame variable -T shorts")
+ # Do a "frame variable --show-types shorts" and verify "short" is in each line of output.
+ self.runCmd("frame variable --show-types shorts")
output = self.res.GetOutput()
for x in [line.strip() for line in output.split(os.linesep)]:
- # Skip empty line or closing brace.
- if not x or x == '}':
+ # Skip empty line, closing brace, and messages about more variables than can be displayed.
+ if not x or x == '}' or x == '...' or "Some of your variables have more members than the debugger will show by default" in x:
continue
self.expect(x, "Expect type 'short'", exe=False,
substrs = ['short'])
Index: aze/lldb/test/lang/cpp/unsigned_types/TestUnsignedTypes.py
===================================================================
--- aze.orig/lldb/test/lang/cpp/unsigned_types/TestUnsignedTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/cpp/unsigned_types/TestUnsignedTypes.py 2013-03-03 09:35:50.319457349 +0100
@@ -37,8 +37,11 @@
exe = os.path.join(os.getcwd(), "a.out")
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+ # GCC puts a breakpoint on the last line of a multi-line expression, so
+ # if GCC is the target compiler, we cannot rely on an exact line match.
+ need_exact = "gcc" not in self.getCompiler()
# Break on line 19 in main() aftre the variables are assigned values.
- lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=need_exact)
self.runCmd("run", RUN_SUCCEEDED)
@@ -51,7 +54,7 @@
substrs = [' resolved, hit count = 1'])
# Test that unsigned types display correctly.
- self.expect("frame variable -T -a", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types --no-args", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(unsigned char) the_unsigned_char = 'c'",
patterns = ["\((short unsigned int|unsigned short)\) the_unsigned_short = 99"],
substrs = ["(unsigned int) the_unsigned_int = 99",
Index: aze/lldb/test/lang/cpp/wchar_t/.categories
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/wchar_t/.categories 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1 @@
+dataformatters
Index: aze/lldb/test/lang/cpp/wchar_t/main.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/wchar_t/main.cpp 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,28 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+class Foo
+{
+public:
+ Foo () : object() {}
+ Foo (T x) : object(x) {}
+ T getObject() { return object; }
+private:
+ T object;
+};
+
+
+int main (int argc, char const *argv[])
+{
+ Foo<int> foo_x('a');
+ Foo<wchar_t> foo_y(L'a');
+ const wchar_t *mazeltov = L"מזל טוב";
+ return 0; // Set break point at this line.
+}
Index: aze/lldb/test/lang/cpp/wchar_t/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/wchar_t/Makefile 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+CFLAGS := -g -O0
+
+clean: OBJECTS+=$(wildcard main.d.*)
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/cpp/wchar_t/TestCxxWCharT.py 2013-03-03 09:35:50.319457349 +0100
@@ -0,0 +1,82 @@
+#coding=utf8
+"""
+Test that C++ supports wchar_t correctly.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class CxxWCharTTestCase(TestBase):
+
+ mydir = os.path.join("lang", "cpp", "wchar_t")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym(self):
+ """Test that C++ supports wchar_t correctly."""
+ self.buildDsym()
+ self.wchar_t()
+
+ @expectedFailureLinux # bugzilla 15038: missing wide char support on Linux
+ @dwarf_test
+ def test_with_dwarf(self):
+ """Test that C++ supports wchar_t correctly."""
+ self.buildDwarf()
+ self.wchar_t()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break for main.cpp.
+ self.source = 'main.cpp'
+ self.line = line_number(self.source, '// Set break point at this line.')
+
+ def wchar_t(self):
+ """Test that C++ supports wchar_t correctly."""
+ exe = os.path.join(os.getcwd(), "a.out")
+
+ # Create a target by the debugger.
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ # Break on the struct declration statement in main.cpp.
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line)
+
+ # Now launch the process, and do not stop at entry point.
+ process = target.LaunchSimple(None, None, os.getcwd())
+
+ if not process:
+ self.fail("SBTarget.Launch() failed")
+
+ # Check that we correctly report templates on wchar_t
+ self.expect("frame variable foo_y",
+ substrs = ['(Foo<wchar_t>) foo_y = '])
+
+ # Check that we correctly report templates on int
+ self.expect("frame variable foo_x",
+ substrs = ['(Foo<int>) foo_x = '])
+
+ # Check that we correctly report wchar_t
+ self.expect("frame variable foo_y.object",
+ substrs = ['(wchar_t) foo_y.object = '])
+
+ # Check that we correctly report int
+ self.expect("frame variable foo_x.object",
+ substrs = ['(int) foo_x.object = '])
+
+ # Check that we can run expressions that return wchar_t
+ self.expect("expression L'a'",substrs = ['(wchar_t) $',"61 L'a'"])
+
+ # Mazel Tov if this works!
+ self.expect("frame variable mazeltov",
+ substrs = ['(const wchar_t *) mazeltov = ','L"מזל טוב"'])
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/objc/blocks/ivars-in-blocks.h
===================================================================
--- aze.orig/lldb/test/lang/objc/blocks/ivars-in-blocks.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/blocks/ivars-in-blocks.h 2013-03-03 09:35:50.319457349 +0100
@@ -5,6 +5,7 @@
@public
int blocky_ivar;
}
++ (void) classMethod;
- (IAmBlocky *) init;
- (int) callABlock: (int) block_value;
@end
Index: aze/lldb/test/lang/objc/blocks/ivars-in-blocks.m
===================================================================
--- aze.orig/lldb/test/lang/objc/blocks/ivars-in-blocks.m 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/blocks/ivars-in-blocks.m 2013-03-03 09:35:50.319457349 +0100
@@ -11,7 +11,22 @@
@end
@implementation IAmBlocky
+
++ (int) addend
+{
+ return 3;
+}
++ (void) classMethod
+{
+ int (^my_block)(int) = ^(int foo)
+ {
+ int ret = foo + [self addend];
+ return ret; // Break here inside the class method block.
+ };
+ printf("%d\n", my_block(2));
+}
+
- (void) makeBlockPtr;
{
_block_ptr = ^(int inval)
@@ -34,7 +49,9 @@
{
if (_block_ptr == NULL)
[self makeBlockPtr];
- return _block_ptr (block_value);
+ int ret = _block_ptr (block_value);
+ [IAmBlocky classMethod];
+ return ret;
}
@end
Index: aze/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py
===================================================================
--- aze.orig/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/blocks/TestObjCIvarsInBlocks.py 2013-03-03 09:35:50.319457349 +0100
@@ -20,6 +20,7 @@
self.buildDsym()
self.ivars_in_blocks()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
# This test requires the 2.0 runtime, so it will fail on i386.
@expectedFailurei386
@@ -47,6 +48,9 @@
breakpoint = target.BreakpointCreateBySourceRegex ('// Break here inside the block.', self.class_source_file_spec)
self.assertTrue(breakpoint, VALID_BREAKPOINT)
+ breakpoint_two = target.BreakpointCreateBySourceRegex ('// Break here inside the class method block.', self.class_source_file_spec)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
process = target.LaunchSimple (None, None, os.getcwd())
self.assertTrue (process, "Created a process.")
self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped it too.")
@@ -93,6 +97,21 @@
self.assertTrue (error.Success(), "Got value from indirect access using the expression parser")
self.assertTrue (direct_value == indirect_value, "Direct ivar access and indirect through expression parser produce same value.")
+
+ process.Continue()
+ self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped at the second breakpoint.")
+
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint_two)
+ self.assertTrue (len(thread_list) == 1)
+ thread = thread_list[0]
+
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue (frame, "frame 0 is valid")
+
+ expr = frame.EvaluateExpression("(ret)")
+ self.assertTrue (expr, "Successfully got a local variable in a block in a class method.")
+
+ self.assertTrue (expr.GetValueAsSigned (error) == 5, "The local variable in the block was what we expected.")
if __name__ == '__main__':
import atexit
Index: aze/lldb/test/lang/objc/forward-decl/Makefile
===================================================================
--- aze.orig/lldb/test/lang/objc/forward-decl/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/forward-decl/Makefile 2013-03-03 09:35:50.319457349 +0100
@@ -4,6 +4,6 @@
DYLIB_OBJC_SOURCES := Container.m
OBJC_SOURCES := main.m
-LDFLAGS = -framework Foundation
-
include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation
Index: aze/lldb/test/lang/objc/foundation/TestFoundationDisassembly.py
===================================================================
--- aze.orig/lldb/test/lang/objc/foundation/TestFoundationDisassembly.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/foundation/TestFoundationDisassembly.py 2013-03-03 09:35:50.319457349 +0100
@@ -81,7 +81,7 @@
lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True)
# Stop at the "description" selector.
- lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1)
+ lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out')
# Stop at -[NSAutoreleasePool release].
break_results = lldbutil.run_break_set_command (self, "_regexp-break -[NSAutoreleasePool release]")
Index: aze/lldb/test/lang/objc/foundation/TestObjCMethods2.py
===================================================================
--- aze.orig/lldb/test/lang/objc/foundation/TestObjCMethods2.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/foundation/TestObjCMethods2.py 2013-03-03 09:35:50.319457349 +0100
@@ -133,8 +133,7 @@
self.runCmd("process continue")
- @unittest2.expectedFailure
- # <rdar://problem/8741897> Expressions should support properties
+ @unittest2.expectedFailure(8741897)
def NSArray_expr(self):
"""Test expression commands for NSArray."""
exe = os.path.join(os.getcwd(), "a.out")
@@ -160,8 +159,7 @@
patterns = ["\(int\) \$.* = 3"])
self.runCmd("process continue")
- @unittest2.expectedFailure
- # <rdar://problem/8741897> Expressions should support properties
+ @unittest2.expectedFailure(8741897)
def NSString_expr(self):
"""Test expression commands for NSString."""
exe = os.path.join(os.getcwd(), "a.out")
@@ -200,7 +198,7 @@
self.runCmd("run", RUN_SUCCEEDED)
- self.expect("expression *my",
+ self.expect("expression --show-types -- *my",
patterns = ["\(MyString\) \$.* = ", "\(MyBase\)", "\(NSObject\)", "\(Class\)"])
self.runCmd("process continue")
@@ -216,7 +214,7 @@
self.runCmd("run", RUN_SUCCEEDED)
self.expect("po [NSError errorWithDomain:@\"Hello\" code:35 userInfo:nil]",
- substrs = ["$", "= 0x", "Error Domain=Hello", "Code=35", "be completed."])
+ substrs = ["Error Domain=Hello", "Code=35", "be completed."])
self.runCmd("process continue")
def NSError_p(self):
@@ -230,7 +228,7 @@
self.runCmd("run", RUN_SUCCEEDED)
- self.expect("p [NSError errorWithDomain:@\"Hello\" code:35 userInfo:nil]",
+ self.expect("p [NSError thisMethodIsntImplemented:0]",
error = True,
patterns = ["no known method", "cast the message send to the method's return type"])
self.runCmd("process continue")
Index: aze/lldb/test/lang/objc/foundation/TestObjCMethods.py
===================================================================
--- aze.orig/lldb/test/lang/objc/foundation/TestObjCMethods.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/foundation/TestObjCMethods.py 2013-03-03 09:35:50.323457348 +0100
@@ -69,7 +69,7 @@
lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True)
# Stop at the "description" selector.
- lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1)
+ lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out')
# Stop at -[NSAutoreleasePool release].
break_results = lldbutil.run_break_set_command(self, "_regexp-break -[NSAutoreleasePool release]")
@@ -146,7 +146,7 @@
'NSString * str;',
'NSDate * date;'])
- self.expect("frame variable -T -s", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types --scope", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["ARG: (MyString *) self"],
patterns = ["ARG: \(.*\) _cmd",
"(objc_selector *)|(SEL)"])
@@ -158,16 +158,16 @@
# rdar://problem/8492646
# test/foundation fails after updating to tot r115023
# self->str displays nothing as output
- self.expect("frame variable -T self->str", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types self->str", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(NSString *) self->str")
# rdar://problem/8447030
# 'frame variable self->date' displays the wrong data member
- self.expect("frame variable -T self->date", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types self->date", VARIABLES_DISPLAYED_CORRECTLY,
startstr = "(NSDate *) self->date")
# This should display the str and date member fields as well.
- self.expect("frame variable -T *self", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("frame variable --show-types *self", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["(MyString) *self",
"(NSString *) str",
"(NSDate *) date"])
@@ -204,7 +204,7 @@
#
# Test new feature with r115115:
# Add "-o" option to "expression" which prints the object description if available.
- self.expect("expression -o -- my", "Object description displayed correctly",
+ self.expect("expression --object-description -- my", "Object description displayed correctly",
patterns = ["Hello from.*a.out.*with timestamp: "])
# See: <rdar://problem/8717050> lldb needs to use the ObjC runtime symbols for ivar offsets
Index: aze/lldb/test/lang/objc/foundation/TestObjectDescriptionAPI.py
===================================================================
--- aze.orig/lldb/test/lang/objc/foundation/TestObjectDescriptionAPI.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/foundation/TestObjectDescriptionAPI.py 2013-03-03 09:35:50.323457348 +0100
@@ -24,6 +24,7 @@
self.find_global_variables_then_object_description('a.out')
# rdar://problem/10857337
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_find_global_variables_then_object_description_with_dwarf(self):
Index: aze/lldb/test/lang/objc/objc++/TestObjCXX.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc++/TestObjCXX.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc++/TestObjCXX.py 2013-03-03 09:35:50.323457348 +0100
@@ -20,6 +20,7 @@
self.buildDsym()
self.do_testObjCXXClasses()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dwarf_test
def test_break_with_dwarf(self):
"""Test ivars of Objective-C++ classes"""
Index: aze/lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-builtin-types/TestObjCBuiltinTypes.py 2013-03-03 09:35:50.323457348 +0100
@@ -62,7 +62,7 @@
self.expect("expr (foo)", patterns = ["\(ns::id\) \$.* = 0"])
- self.expect("expr id my_id = 0; my_id", patterns = ["\(id\) \$.* = 0x0"])
+ self.expect("expr id my_id = 0; my_id", patterns = ["\(id\) \$.* = nil"])
if __name__ == '__main__':
import atexit
Index: aze/lldb/test/lang/objc/objc-checker/TestObjCCheckers.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-checker/TestObjCCheckers.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-checker/TestObjCCheckers.py 2013-03-03 09:35:50.323457348 +0100
@@ -22,6 +22,7 @@
self.buildDsym()
self.do_test_checkers()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_objc_checker_with_dwarf(self):
Index: aze/lldb/test/lang/objc/objc-class-method/TestObjCClassMethod.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-class-method/TestObjCClassMethod.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-class-method/TestObjCClassMethod.py 2013-03-03 09:35:50.323457348 +0100
@@ -20,6 +20,7 @@
self.buildDsym()
self.objc_class_method()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@expectedFailurei386
@python_api_test
@dwarf_test
Index: aze/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py 2013-03-03 09:35:50.323457348 +0100
@@ -23,6 +23,7 @@
self.buildDsym()
self.do_get_dynamic_vals()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_get_objc_dynamic_vals_with_dwarf(self):
@@ -115,10 +116,10 @@
# check that our ObjC GetISA() does a good job at hiding KVO swizzled classes
self.expect('frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden',
- substrs = ['dynamic type: SourceDerived'])
+ substrs = ['SourceDerived'])
self.expect('frame var -d run-target myObserver->_source -T', 'the KVO-ed class is hidden', matching = False,
- substrs = ['dynamic type: NSKVONotify'])
+ substrs = ['NSKVONotify'])
# This test is not entirely related to the main thrust of this test case, but since we're here,
# try stepping into setProperty, and make sure we get into the version in Source:
Index: aze/lldb/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-ivar-offsets/TestObjCIvarOffsets.py 2013-03-03 09:35:50.323457348 +0100
@@ -18,6 +18,7 @@
self.buildDsym()
self.objc_ivar_offsets()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_with_dwarf_and_python_api(self):
Index: aze/lldb/test/lang/objc/objc-ivar-stripped/main.m
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/objc/objc-ivar-stripped/main.m 2013-03-03 09:35:50.323457348 +0100
@@ -0,0 +1,33 @@
+#import <Foundation/Foundation.h>
+
+@interface MyClass : NSObject {
+@public
+ int _foo;
+};
+
+-(id)init;
+@end
+
+@implementation MyClass
+
+-(id)init
+{
+ if ([super init])
+ {
+ _foo = 3;
+ }
+
+ return self;
+}
+
+@end
+
+int main ()
+{
+ @autoreleasepool
+ {
+ MyClass *mc = [[MyClass alloc] init];
+
+ NSLog(@"%d", mc->_foo); // Set breakpoint here.
+ }
+}
Index: aze/lldb/test/lang/objc/objc-ivar-stripped/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/objc/objc-ivar-stripped/Makefile 2013-03-03 09:35:50.323457348 +0100
@@ -0,0 +1,15 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+LDFLAGS = $(CFLAGS) -lobjc -framework Foundation
+
+default: a.out.stripped
+
+a.out.stripped: a.out.dSYM
+ strip -o a.out.stripped a.out
+
+clean::
+ rm -f a.out.stripped
+ rm -rf a.out.stripped.dSYM
+
+include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/objc/objc-ivar-stripped/TestObjCIvarStripped.py 2013-03-03 09:35:50.323457348 +0100
@@ -0,0 +1,63 @@
+"""Test printing ObjC objects that use unbacked properties - so that the static ivar offsets are incorrect."""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class TestObjCIvarStripped(TestBase):
+
+ mydir = os.path.join("lang", "objc", "objc-ivar-stripped")
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @python_api_test
+ @dsym_test
+ def test_with_dsym_and_python_api(self):
+ """Test that we can find stripped Objective-C ivars in the runtime"""
+ self.buildDsym()
+ self.objc_ivar_offsets()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line numbers to break inside main().
+ self.main_source = "main.m"
+ self.stop_line = line_number(self.main_source, '// Set breakpoint here.')
+
+ def objc_ivar_offsets(self):
+ """Test that we can find stripped Objective-C ivars in the runtime"""
+ exe = os.path.join(os.getcwd(), "a.out.stripped")
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ breakpoint = target.BreakpointCreateByLocation(self.main_source, self.stop_line)
+ self.assertTrue(breakpoint, VALID_BREAKPOINT)
+
+ process = target.LaunchSimple (None, None, os.getcwd())
+ self.assertTrue (process, "Created a process.")
+ self.assertTrue (process.GetState() == lldb.eStateStopped, "Stopped it too.")
+
+ thread_list = lldbutil.get_threads_stopped_at_breakpoint (process, breakpoint)
+ self.assertTrue (len(thread_list) == 1)
+ thread = thread_list[0]
+
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue (frame, "frame 0 is valid")
+
+ # Test the expression for mc->_foo
+
+ error = lldb.SBError()
+
+ ivar = frame.EvaluateExpression ("(mc->_foo)")
+ self.assertTrue(ivar, "Got result for mc->_foo")
+ ivar_value = ivar.GetValueAsSigned (error)
+ self.assertTrue (error.Success())
+ self.assertTrue (ivar_value == 3)
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py 2013-03-03 09:35:50.323457348 +0100
@@ -64,62 +64,62 @@
self.common_setup()
- self.expect("expr -o -- immutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- immutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["foo"])
- self.expect("expr -o -- mutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- mutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["foo"])
- self.expect("expr -o -- mutable_array[0] = @\"bar\"", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- mutable_array[0] = @\"bar\"", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["bar"])
- self.expect("expr -o -- mutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- mutable_array[0]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["bar"])
- self.expect("expr -o -- immutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- immutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["value"])
- self.expect("expr -o -- mutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- mutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["value"])
- self.expect("expr -o -- mutable_dictionary[@\"key\"] = @\"object\"", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- mutable_dictionary[@\"key\"] = @\"object\"", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["object"])
- self.expect("expr -o -- mutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- mutable_dictionary[@\"key\"]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["object"])
- self.expect("expr -o -- @[ @\"foo\", @\"bar\" ]", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @[ @\"foo\", @\"bar\" ]", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSArray", "foo", "bar"])
- self.expect("expr -o -- @{ @\"key\" : @\"object\" }", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @{ @\"key\" : @\"object\" }", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSDictionary", "key", "object"])
- self.expect("expr -o -- @'a'", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @'a'", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", str(ord('a'))])
- self.expect("expr -o -- @1", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @1", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "1"])
- self.expect("expr -o -- @1l", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @1l", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "1"])
- self.expect("expr -o -- @1ul", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @1ul", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "1"])
- self.expect("expr -o -- @1ll", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @1ll", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "1"])
- self.expect("expr -o -- @1ull", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @1ull", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "1"])
- self.expect("expr -o -- @123.45", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @123.45", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "123.45"])
- self.expect("expr -o -- @123.45f", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @123.45f", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "123.45"])
- self.expect("expr -o -- @( 1 + 3 )", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @( 1 + 3 )", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSNumber", "4"])
- self.expect("expr -o -- @(\"Hello world\" + 6)", VARIABLES_DISPLAYED_CORRECTLY,
+ self.expect("expr --object-description -- @(\"Hello world\" + 6)", VARIABLES_DISPLAYED_CORRECTLY,
substrs = ["NSString", "world"])
Index: aze/lldb/test/lang/objc/objc-optimized/Makefile
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-optimized/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-optimized/Makefile 2013-03-03 09:35:50.323457348 +0100
@@ -2,7 +2,7 @@
OBJC_SOURCES := main.m
-CFLAGS ?= -arch $(ARCH) -gdwarf-2 -O2
+CFLAGS ?= -arch $(ARCH) -g -O2
LDFLAGS = $(CFLAGS) -lobjc -framework Foundation
include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/lang/objc/objc-optimized/TestObjcOptimized.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-optimized/TestObjcOptimized.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-optimized/TestObjcOptimized.py 2013-03-03 09:35:50.323457348 +0100
@@ -12,6 +12,7 @@
import lldb
from lldbtest import *
import lldbutil
+import re
# rdar://problem/9087739
# test failure: objc_optimized does not work for "-C clang -A i386"
@@ -50,8 +51,21 @@
self.expect('expression member',
startstr = "(int) $0 = 5")
- self.expect('expression self',
- startstr = "(%s *) $1 = " % self.myclass)
+ # <rdar://problem/12693963>
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ interp.HandleCommand('frame variable self', result)
+ output = result.GetOutput()
+
+ desired_pointer = "0x0"
+
+ mo = re.search("0x[0-9a-f]+", output)
+
+ if mo:
+ desired_pointer = mo.group(0)
+
+ self.expect('expression (self)',
+ substrs = [("(%s *) $1 = " % self.myclass), desired_pointer])
self.expect('expression self->non_member', error=True,
substrs = ["does not have a member named 'non_member'"])
Index: aze/lldb/test/lang/objc/objc-property/main.m
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-property/main.m 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-property/main.m 2013-03-03 09:35:50.323457348 +0100
@@ -1,5 +1,11 @@
#import <Foundation/Foundation.h>
+@protocol MyProtocol
+
+-(const char *)hello;
+
+@end
+
@interface BaseClass : NSObject
{
int _backedInt;
@@ -18,6 +24,7 @@
@property(getter=myGetUnbackedInt,setter=mySetUnbackedInt:) int unbackedInt;
@property int backedInt;
+@property (nonatomic, assign) id <MyProtocol> idWithProtocol;
@end
@implementation BaseClass
@@ -79,6 +86,8 @@
int unbackedInt = mine.unbackedInt;
+ id idWithProtocol = mine.idWithProtocol;
+
NSLog (@"Results for %p: nonexistant: %d backed: %d unbacked: %d accessCount: %d.",
mine,
nonexistant,
Index: aze/lldb/test/lang/objc/objc-property/TestObjCProperty.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-property/TestObjCProperty.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-property/TestObjCProperty.py 2013-03-03 09:35:50.323457348 +0100
@@ -22,6 +22,7 @@
self.buildDsym()
self.do_test_properties()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_objc_properties_with_dwarf(self):
@@ -123,6 +124,11 @@
unbacked_value = frame.EvaluateExpression("mine.unbackedInt", False)
unbacked_error = unbacked_value.GetError()
self.assertTrue (unbacked_error.Success())
+
+ idWithProtocol_value = frame.EvaluateExpression("mine.idWithProtocol", False)
+ idWithProtocol_error = idWithProtocol_value.GetError()
+ self.assertTrue (idWithProtocol_error.Success())
+ self.assertTrue (idWithProtocol_value.GetTypeName() == "id")
if __name__ == '__main__':
import atexit
Index: aze/lldb/test/lang/objc/objc-static-method/TestObjCStaticMethod.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-static-method/TestObjCStaticMethod.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-static-method/TestObjCStaticMethod.py 2013-03-03 09:35:50.323457348 +0100
@@ -19,6 +19,7 @@
self.buildDsym()
self.objc_static_method()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
#<rdar://problem/9745789> "expression" can't call functions in class methods
@dwarf_test
Index: aze/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py
===================================================================
--- aze.orig/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py 2013-03-03 09:35:50.323457348 +0100
@@ -8,6 +8,9 @@
class TestObjCStepping(TestBase):
+ def getCategories (self):
+ return ['basic_process']
+
mydir = os.path.join("lang", "objc", "objc-stepping")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@@ -18,6 +21,7 @@
self.buildDsym()
self.objc_stepping()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_with_dwarf_and_python_api(self):
Index: aze/lldb/test/lang/objc/rdar-11355592/TestRdar11355592.py
===================================================================
--- aze.orig/lldb/test/lang/objc/rdar-11355592/TestRdar11355592.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/rdar-11355592/TestRdar11355592.py 2013-03-03 09:35:50.323457348 +0100
@@ -48,30 +48,30 @@
self.runCmd("run", RUN_SUCCEEDED)
# check that we correctly see the const char*, even with dynamic types on
self.expect("frame variable my_string", substrs = ['const char *'])
- self.expect("frame variable my_string -d run-target", substrs = ['const char *'])
+ self.expect("frame variable my_string --dynamic-type run-target", substrs = ['const char *'])
# check that expr also gets it right
self.expect("expr my_string", substrs = ['const char *'])
- self.expect("expr -d true -- my_string", substrs = ['const char *'])
+ self.expect("expr -d run -- my_string", substrs = ['const char *'])
# but check that we get the real Foolie as such
self.expect("frame variable my_foolie", substrs = ['FoolMeOnce *'])
- self.expect("frame variable my_foolie -d run-target", substrs = ['FoolMeOnce *'])
+ self.expect("frame variable my_foolie --dynamic-type run-target", substrs = ['FoolMeOnce *'])
# check that expr also gets it right
self.expect("expr my_foolie", substrs = ['FoolMeOnce *'])
- self.expect("expr -d true -- my_foolie", substrs = ['FoolMeOnce *'])
+ self.expect("expr -d run -- my_foolie", substrs = ['FoolMeOnce *'])
# now check that assigning a true string does not break anything
self.runCmd("next")
# check that we correctly see the const char*, even with dynamic types on
self.expect("frame variable my_string", substrs = ['const char *'])
- self.expect("frame variable my_string -d run-target", substrs = ['const char *'])
+ self.expect("frame variable my_string --dynamic-type run-target", substrs = ['const char *'])
# check that expr also gets it right
self.expect("expr my_string", substrs = ['const char *'])
- self.expect("expr -d true -- my_string", substrs = ['const char *'])
+ self.expect("expr -d run -- my_string", substrs = ['const char *'])
# but check that we get the real Foolie as such
self.expect("frame variable my_foolie", substrs = ['FoolMeOnce *'])
- self.expect("frame variable my_foolie -d run-target", substrs = ['FoolMeOnce *'])
+ self.expect("frame variable my_foolie --dynamic-type run-target", substrs = ['FoolMeOnce *'])
# check that expr also gets it right
self.expect("expr my_foolie", substrs = ['FoolMeOnce *'])
- self.expect("expr -d true -- my_foolie", substrs = ['FoolMeOnce *'])
+ self.expect("expr -d run -- my_foolie", substrs = ['FoolMeOnce *'])
if __name__ == '__main__':
import atexit
Index: aze/lldb/test/lang/objc/rdar-12408181/main.m
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/objc/rdar-12408181/main.m 2013-03-03 09:35:50.323457348 +0100
@@ -0,0 +1,14 @@
+#import <Foundation/Foundation.h>
+#import <Cocoa/Cocoa.h>
+
+int main (int argc, char const *argv[])
+{
+ NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
+
+ [NSApplication sharedApplication];
+ NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0,100,100) styleMask:NSBorderlessWindowMask backing:NSBackingStoreRetained defer:NO];
+ [window setCanHide:YES];
+ [pool release]; // Set breakpoint here.
+ return 0;
+}
+
Index: aze/lldb/test/lang/objc/rdar-12408181/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/objc/rdar-12408181/Makefile 2013-03-03 09:35:50.323457348 +0100
@@ -0,0 +1,7 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+
+include $(LEVEL)/Makefile.rules
+
+LDFLAGS += -framework Foundation -framework Cocoa
Index: aze/lldb/test/lang/objc/rdar-12408181/TestRdar12408181.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/lang/objc/rdar-12408181/TestRdar12408181.py 2013-03-03 09:35:50.323457348 +0100
@@ -0,0 +1,60 @@
+"""
+Test that we are able to find out how many children NSWindow has
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+class Rdar12408181TestCase(TestBase):
+
+ mydir = os.path.join("lang", "objc", "rdar-12408181")
+
+ @dsym_test
+ def test_nswindow_count_with_dsym(self):
+ """Test that we are able to find out how many children NSWindow has."""
+ d = {'EXE': self.exe_name}
+ self.buildDsym(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.nswindow_count(self.exe_name)
+
+ @dwarf_test
+ def test_nswindow_count_with_dwarf(self):
+ """Test that we are able to find out how many children NSWindow has."""
+ d = {'EXE': self.exe_name}
+ self.buildDwarf(dictionary=d)
+ self.setTearDownCleanup(dictionary=d)
+ self.nswindow_count(self.exe_name)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # We'll use the test method name as the exe_name.
+ self.exe_name = self.testMethodName
+ # Find the line number to break inside main().
+ self.main_source = "main.m"
+ self.line = line_number(self.main_source, '// Set breakpoint here.')
+
+ def nswindow_count(self, exe_name):
+ """Test that we are able to find out how many children NSWindow has."""
+ exe = os.path.join(os.getcwd(), exe_name)
+ self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, self.main_source, self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+ window = self.frame().FindVariable("window")
+ window_dynamic = window.GetDynamicValue(lldb.eDynamicCanRunTarget)
+ self.assertTrue(window.GetNumChildren() > 1, "NSWindow (static) only has 1 child!")
+ self.assertTrue(window_dynamic.GetNumChildren() > 1, "NSWindow (dynamic) only has 1 child!")
+ self.assertTrue(window.GetChildAtIndex(0).IsValid(), "NSWindow (static) has an invalid child")
+ self.assertTrue(window_dynamic.GetChildAtIndex(0).IsValid(), "NSWindow (dynamic) has an invalid child")
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
Index: aze/lldb/test/lang/objc/self/TestObjCSelf.py
===================================================================
--- aze.orig/lldb/test/lang/objc/self/TestObjCSelf.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lang/objc/self/TestObjCSelf.py 2013-03-03 09:35:50.327457348 +0100
@@ -16,6 +16,7 @@
self.buildDsym()
self.self_commands()
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dwarf_test
def test_with_dwarf_and_run_command(self):
"""Test that the appropriate member variables are available when stopped in Objective-C class and instance methods"""
Index: aze/lldb/test/lldbtest.py
===================================================================
--- aze.orig/lldb/test/lldbtest.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lldbtest.py 2013-03-03 09:35:50.327457348 +0100
@@ -368,46 +368,179 @@
wrapper.__dwarf_test__ = True
return wrapper
-def expectedFailureClang(func):
- """Decorate the item as a Clang only expectedFailure."""
+def expectedFailureGcc(bugnumber=None):
+ if callable(bugnumber):
+ @wraps(bugnumber)
+ def expectedFailureGcc_easy_wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ test_compiler = self.getCompiler()
+ try:
+ bugnumber(*args, **kwargs)
+ except Exception:
+ if "gcc" in test_compiler:
+ raise case._ExpectedFailure(sys.exc_info(),None)
+ else:
+ raise
+ if "gcc" in test_compiler:
+ raise case._UnexpectedSuccess(sys.exc_info(),None)
+ return expectedFailureGcc_easy_wrapper
+ else:
+ def expectedFailureGcc_impl(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ test_compiler = self.getCompiler()
+ try:
+ func(*args, **kwargs)
+ except Exception:
+ if "gcc" in test_compiler:
+ raise case._ExpectedFailure(sys.exc_info(),bugnumber)
+ else:
+ raise
+ if "gcc" in test_compiler:
+ raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
+ return wrapper
+ return expectedFailureGcc_impl
+
+def expectedFailureClang(bugnumber=None):
+ if callable(bugnumber):
+ @wraps(bugnumber)
+ def expectedFailureClang_easy_wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ test_compiler = self.getCompiler()
+ try:
+ bugnumber(*args, **kwargs)
+ except Exception:
+ if "clang" in test_compiler:
+ raise case._ExpectedFailure(sys.exc_info(),None)
+ else:
+ raise
+ if "clang" in test_compiler:
+ raise case._UnexpectedSuccess(sys.exc_info(),None)
+ return expectedFailureClang_easy_wrapper
+ else:
+ def expectedFailureClang_impl(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ test_compiler = self.getCompiler()
+ try:
+ func(*args, **kwargs)
+ except Exception:
+ if "clang" in test_compiler:
+ raise case._ExpectedFailure(sys.exc_info(),bugnumber)
+ else:
+ raise
+ if "clang" in test_compiler:
+ raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
+ return wrapper
+ return expectedFailureClang_impl
+
+
+def expectedFailurei386(bugnumber=None):
+ if callable(bugnumber):
+ @wraps(bugnumber)
+ def expectedFailurei386_easy_wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ arch = self.getArchitecture()
+ try:
+ bugnumber(*args, **kwargs)
+ except Exception:
+ if "i386" in arch:
+ raise case._ExpectedFailure(sys.exc_info(),None)
+ else:
+ raise
+ if "i386" in arch:
+ raise case._UnexpectedSuccess(sys.exc_info(),None)
+ return expectedFailurei386_easy_wrapper
+ else:
+ def expectedFailurei386_impl(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ arch = self.getArchitecture()
+ try:
+ func(*args, **kwargs)
+ except Exception:
+ if "i386" in arch:
+ raise case._ExpectedFailure(sys.exc_info(),bugnumber)
+ else:
+ raise
+ if "i386" in arch:
+ raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
+ return wrapper
+ return expectedFailurei386_impl
+
+def expectedFailureLinux(bugnumber=None):
+ if callable(bugnumber):
+ @wraps(bugnumber)
+ def expectedFailureLinux_easy_wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ platform = sys.platform
+ try:
+ bugnumber(*args, **kwargs)
+ except Exception:
+ if "linux" in platform:
+ raise case._ExpectedFailure(sys.exc_info(),None)
+ else:
+ raise
+ if "linux" in platform:
+ raise case._UnexpectedSuccess(sys.exc_info(),None)
+ return expectedFailureLinux_easy_wrapper
+ else:
+ def expectedFailureLinux_impl(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ from unittest2 import case
+ self = args[0]
+ platform = sys.platform
+ try:
+ func(*args, **kwargs)
+ except Exception:
+ if "linux" in platform:
+ raise case._ExpectedFailure(sys.exc_info(),bugnumber)
+ else:
+ raise
+ if "linux" in platform:
+ raise case._UnexpectedSuccess(sys.exc_info(),bugnumber)
+ return wrapper
+ return expectedFailureLinux_impl
+
+def skipOnLinux(func):
+ """Decorate the item to skip tests that should be skipped on Linux."""
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@expectedFailureClang can only be used to decorate a test method")
+ raise Exception("@skipOnLinux can only be used to decorate a test method")
@wraps(func)
def wrapper(*args, **kwargs):
from unittest2 import case
self = args[0]
- compiler = self.getCompiler()
- try:
+ platform = sys.platform
+ if "linux" in platform:
+ self.skipTest("skip on linux")
+ else:
func(*args, **kwargs)
- except Exception:
- if "clang" in compiler:
- raise case._ExpectedFailure(sys.exc_info())
- else:
- raise
-
- if "clang" in compiler:
- raise case._UnexpectedSuccess
return wrapper
-def expectedFailurei386(func):
- """Decorate the item as an i386 only expectedFailure."""
+def skipIfGcc(func):
+ """Decorate the item to skip tests that should be skipped if building with gcc ."""
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
- raise Exception("@expectedFailurei386 can only be used to decorate a test method")
+ raise Exception("@skipIfGcc can only be used to decorate a test method")
@wraps(func)
def wrapper(*args, **kwargs):
from unittest2 import case
self = args[0]
- arch = self.getArchitecture()
- try:
+ compiler = self.getCompiler()
+ if "gcc" in compiler:
+ self.skipTest("skipping because gcc is the test compiler")
+ else:
func(*args, **kwargs)
- except Exception:
- if "i386" in arch:
- raise case._ExpectedFailure(sys.exc_info())
- else:
- raise
-
- if "i386" in arch:
- raise case._UnexpectedSuccess
return wrapper
class Base(unittest2.TestCase):
@@ -562,6 +695,9 @@
self.dicts = []
self.doTearDownCleanups = False
+ # List of spawned subproces.Popen objects
+ self.subprocesses = []
+
# Create a string buffer to record the session info, to be dumped into a
# test case specific file if test failure is encountered.
self.session = StringIO.StringIO()
@@ -585,6 +721,12 @@
# See HideStdout(self).
self.sys_stdout_hidden = False
+ # set environment variable names for finding shared libraries
+ if sys.platform.startswith("darwin"):
+ self.dylibPath = 'DYLD_LIBRARY_PATH'
+ elif sys.platform.startswith("linux") or sys.platform.startswith("freebsd"):
+ self.dylibPath = 'LD_LIBRARY_PATH'
+
def runHooks(self, child=None, child_prompt=None, use_cmd_api=False):
"""Perform the run hooks to bring lldb debugger to the desired state.
@@ -609,6 +751,37 @@
child.sendline(hook)
child.expect_exact(child_prompt)
+ def setAsync(self, value):
+ """ Sets async mode to True/False and ensures it is reset after the testcase completes."""
+ old_async = self.dbg.GetAsync()
+ self.dbg.SetAsync(value)
+ self.addTearDownHook(lambda: self.dbg.SetAsync(old_async))
+
+ def cleanupSubprocesses(self):
+ # Ensure any subprocesses are cleaned up
+ for p in self.subprocesses:
+ if p.poll() == None:
+ p.terminate()
+ del p
+ del self.subprocesses[:]
+
+ def spawnSubprocess(self, executable, args=[]):
+ """ Creates a subprocess.Popen object with the specified executable and arguments,
+ saves it in self.subprocesses, and returns the object.
+ NOTE: if using this function, ensure you also call:
+
+ self.addTearDownHook(self.cleanupSubprocesses)
+
+ otherwise the test suite will leak processes.
+ """
+
+ # Don't display the stdout if not in TraceOn() mode.
+ proc = Popen([executable] + args,
+ stdout = open(os.devnull) if not self.TraceOn() else None,
+ stdin = PIPE)
+ self.subprocesses.append(proc)
+ return proc
+
def HideStdout(self):
"""Hide output to stdout from the user.
@@ -672,14 +845,17 @@
if self.child and self.child.isalive():
with recording(self, traceAlways) as sbuf:
print >> sbuf, "tearing down the child process...."
- if self.child_in_script_interpreter:
- self.child.sendline('quit()')
- self.child.expect_exact(self.child_prompt)
- self.child.sendline('quit')
try:
+ if self.child_in_script_interpreter:
+ self.child.sendline('quit()')
+ self.child.expect_exact(self.child_prompt)
+ self.child.sendline('settings set interpreter.prompt-on-quit false')
+ self.child.sendline('quit')
self.child.expect(pexpect.EOF)
- except:
+ except ValueError, ExceptionPexpect:
+ # child is already terminated
pass
+
# Give it one final blow to make sure the child is terminated.
self.child.close()
@@ -724,14 +900,17 @@
# Once by the Python unittest framework, and a second time by us.
print >> sbuf, "FAIL"
- def markExpectedFailure(self):
+ def markExpectedFailure(self,err,bugnumber):
"""Callback invoked when an expected failure/error occurred."""
self.__expected__ = True
with recording(self, False) as sbuf:
# False because there's no need to write "expected failure" to the
# stderr twice.
# Once by the Python unittest framework, and a second time by us.
- print >> sbuf, "expected failure"
+ if bugnumber == None:
+ print >> sbuf, "expected failure"
+ else:
+ print >> sbuf, "expected failure (problem id:" + str(bugnumber) + ")"
def markSkippedTest(self):
"""Callback invoked when a test is skipped."""
@@ -742,14 +921,17 @@
# Once by the Python unittest framework, and a second time by us.
print >> sbuf, "skipped test"
- def markUnexpectedSuccess(self):
+ def markUnexpectedSuccess(self, bugnumber):
"""Callback invoked when an unexpected success occurred."""
self.__unexpected__ = True
with recording(self, False) as sbuf:
# False because there's no need to write "unexpected success" to the
# stderr twice.
# Once by the Python unittest framework, and a second time by us.
- print >> sbuf, "unexpected success"
+ if bugnumber == None:
+ print >> sbuf, "unexpected success"
+ else:
+ print >> sbuf, "unexpected success (problem id:" + str(bugnumber) + ")"
def dumpSessionInfo(self):
"""
@@ -832,6 +1014,25 @@
module = builder_module()
return module.getCompiler()
+ def getCompilerVersion(self):
+ """ Returns a string that represents the compiler version.
+ Supports: llvm, clang.
+ """
+ from lldbutil import which
+ version = 'unknown'
+
+ compiler = self.getCompiler()
+ version_output = system([which(compiler), "-v"])[1]
+ for line in version_output.split(os.linesep):
+ compiler_shortname = 'invalid'
+ for c in ["clang", "LLVM", "gcc"]:
+ if c in compiler:
+ compiler_shortname = c
+ m = re.search('%s version ([0-9\.]+)' % compiler_shortname, line)
+ if m:
+ version = m.group(1)
+ return version
+
def getRunOptions(self):
"""Command line option for -A and -C to run this test again, called from
self.dumpSessionInfo()."""
Index: aze/lldb/test/lldbutil.py
===================================================================
--- aze.orig/lldb/test/lldbutil.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/lldbutil.py 2013-03-03 09:35:50.327457348 +0100
@@ -275,6 +275,9 @@
else:
command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number)
+ if module_name:
+ command += " --shlib '%s'" % (module_name)
+
if extra_options:
command += " " + extra_options
@@ -292,6 +295,10 @@
If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
command = 'breakpoint set -n "%s"'%(symbol)
+
+ if module_name:
+ command += " --shlib '%s'" % (module_name)
+
if extra_options:
command += " " + extra_options
@@ -307,7 +314,11 @@
def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None):
"""Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
- command = 'breakpoint set -S "%s"'%(selector)
+ command = 'breakpoint set -S "%s"' % (selector)
+
+ if module_name:
+ command += ' --shlib "%s"' % (module_name)
+
if extra_options:
command += " " + extra_options
Index: aze/lldb/test/logging/TestLogging.py
===================================================================
--- aze.orig/lldb/test/logging/TestLogging.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/logging/TestLogging.py 2013-03-03 09:35:50.327457348 +0100
@@ -28,13 +28,13 @@
patterns = [ "Current executable set to .*a.out" ])
log_file = os.path.join (os.getcwd(), "lldb-commands-log-%s-%s-%s.txt" % (type,
- self.getCompiler(),
+ os.path.basename(self.getCompiler()),
self.getArchitecture()))
if (os.path.exists (log_file)):
os.remove (log_file)
- self.runCmd ("log enable lldb commands -f " + log_file)
+ self.runCmd ("log enable -f '%s' lldb commands" % (log_file))
self.runCmd ("command alias bp breakpoint")
@@ -43,24 +43,24 @@
self.runCmd ("bp l")
expected_log_lines = [
- "com.apple.main-thread Processing command: command alias bp breakpoint\n",
- "com.apple.main-thread HandleCommand, cmd_obj : 'command alias'\n",
- "com.apple.main-thread HandleCommand, revised_command_line: 'command alias bp breakpoint'\n",
- "com.apple.main-thread HandleCommand, wants_raw_input:'True'\n",
- "com.apple.main-thread HandleCommand, command line after removing command name(s): 'bp breakpoint'\n",
- "com.apple.main-thread HandleCommand, command succeeded\n",
- "com.apple.main-thread Processing command: bp set -n main\n",
- "com.apple.main-thread HandleCommand, cmd_obj : 'breakpoint set'\n",
- "com.apple.main-thread HandleCommand, revised_command_line: 'breakpoint set -n main'\n",
- "com.apple.main-thread HandleCommand, wants_raw_input:'False'\n",
- "com.apple.main-thread HandleCommand, command line after removing command name(s): '-n main'\n",
- "com.apple.main-thread HandleCommand, command succeeded\n",
- "com.apple.main-thread Processing command: bp l\n",
- "com.apple.main-thread HandleCommand, cmd_obj : 'breakpoint list'\n",
- "com.apple.main-thread HandleCommand, revised_command_line: 'breakpoint l'\n",
- "com.apple.main-thread HandleCommand, wants_raw_input:'False'\n",
- "com.apple.main-thread HandleCommand, command line after removing command name(s): ''\n",
- "com.apple.main-thread HandleCommand, command succeeded\n",
+ "Processing command: command alias bp breakpoint\n",
+ "HandleCommand, cmd_obj : 'command alias'\n",
+ "HandleCommand, revised_command_line: 'command alias bp breakpoint'\n",
+ "HandleCommand, wants_raw_input:'True'\n",
+ "HandleCommand, command line after removing command name(s): 'bp breakpoint'\n",
+ "HandleCommand, command succeeded\n",
+ "Processing command: bp set -n main\n",
+ "HandleCommand, cmd_obj : 'breakpoint set'\n",
+ "HandleCommand, revised_command_line: 'breakpoint set -n main'\n",
+ "HandleCommand, wants_raw_input:'False'\n",
+ "HandleCommand, command line after removing command name(s): '-n main'\n",
+ "HandleCommand, command succeeded\n",
+ "Processing command: bp l\n",
+ "HandleCommand, cmd_obj : 'breakpoint list'\n",
+ "HandleCommand, revised_command_line: 'breakpoint l'\n",
+ "HandleCommand, wants_raw_input:'False'\n",
+ "HandleCommand, command line after removing command name(s): ''\n",
+ "HandleCommand, command succeeded\n",
]
self.assertTrue (os.path.isfile (log_file))
Index: aze/lldb/test/make/Makefile.rules
===================================================================
--- aze.orig/lldb/test/make/Makefile.rules 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/make/Makefile.rules 2013-03-03 09:35:50.327457348 +0100
@@ -54,26 +54,49 @@
endif
#----------------------------------------------------------------------
+# ARCHFLAG is the flag used to tell the compiler which architecture
+# to compile for. The default is the flag that clang accepts.
+#----------------------------------------------------------------------
+ARCHFLAG ?= -arch
+
+#----------------------------------------------------------------------
# Change any build/tool options needed
#----------------------------------------------------------------------
-CFLAGS ?= -gdwarf-2 -O0
-CFLAGS += $(FRAMEWORK_INCLUDES) $(CFLAGS_EXTRAS)
ifeq "$(OS)" "Darwin"
- CFLAGS += -arch $(ARCH)
DS := dsymutil
DSFLAGS =
DSYM = $(EXE).dSYM
AR := libtool
ARFLAGS := -static -o
+else
+ # On non-Apple platforms, -arch becomes -m
+ ARCHFLAG := -m
+
+ # i386 becomes 32, and x86_64 becomes 64
+ ifeq "$(ARCH)" "x86_64"
+ override ARCH := $(subst x86_64,64,$(ARCH))
+ endif
+ ifeq "$(ARCH)" "i386"
+ override ARCH := $(subst i386,32,$(ARCH))
+ endif
endif
+CFLAGS ?= -g -O0
+CFLAGS += $(ARCHFLAG)$(ARCH) $(FRAMEWORK_INCLUDES) $(CFLAGS_EXTRAS)
+
CXXFLAGS +=$(CFLAGS)
LD = $(CC)
LDFLAGS ?= $(CFLAGS)
-LDFLAGS += $(LD_EXTRAS) -arch $(ARCH)
+LDFLAGS += $(LD_EXTRAS)
OBJECTS =
EXE ?= a.out
+ifneq (,$(findstring g++,$(CXX)))
+ # GCC 4.6 cannot handle -std=c++11, so replace it with -std=c++0x
+ # instead. FIXME: remove once GCC version is upgraded.
+ override CXXFLAGS := $(subst -std=c++11,-std=c++0x,$(CXXFLAGS))
+endif
+
ifneq "$(DYLIB_NAME)" ""
ifeq "$(OS)" "Darwin"
DYLIB_FILENAME = lib$(DYLIB_NAME).dylib
@@ -208,7 +231,7 @@
endif
else
$(EXE) : $(OBJECTS) $(ARCHIVE_NAME)
- $(LD) $(LDFLAGS) $(OBJECTS) $(ARCHIVE_NAME) -o "$(EXE)"
+ $(LD) $(OBJECTS) $(LDFLAGS) $(ARCHIVE_NAME) -o "$(EXE)"
endif
#----------------------------------------------------------------------
Index: aze/lldb/test/Makefile
===================================================================
--- aze.orig/lldb/test/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/Makefile 2013-03-03 09:35:50.327457348 +0100
@@ -29,10 +29,5 @@
# Run the tests
#----------------------------------------------------------------------
check-local::
- rm -rf ../test-rdir
- env PATH="$(ToolDir):$(PATH)" \
- PYTHONPATH="$(shell python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True, False, \"$(LibDir)/..\")" )" \
- LLDB_EXEC=$(ToolDir)/lldb \
- LLDB_BUILD_TYPE=Makefile \
- $(SHLIBPATH_VAR)=$(LibDir):$($(SHLIBPATH_VAR)) \
- python $(PROJ_SRC_DIR)/dotest.py -i -v -r ../test-rdir
+ rm -rf lldb-test-traces
+ python $(PROJ_SRC_DIR)/dosep.ty -o "--executable $(ToolDir)/lldb -q -s lldb-test-traces -C $(subst ccache,,$(CC))"
Index: aze/lldb/test/plugins/builder_base.py
===================================================================
--- aze.orig/lldb/test/plugins/builder_base.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/plugins/builder_base.py 2013-03-03 09:35:50.327457348 +0100
@@ -23,6 +23,20 @@
"""Returns the compiler in effect the test suite is running with."""
return os.environ["CC"] if "CC" in os.environ else "clang"
+def getArchFlag():
+ """Returns the flag required to specify the arch"""
+ compiler = getCompiler()
+ if compiler is None:
+ return ""
+ elif "gcc" in compiler:
+ archflag = "-m"
+ elif "clang" in compiler:
+ archflag = "-arch "
+ else:
+ archflag = None
+
+ return (" ARCHFLAG=" + archflag) if archflag else ""
+
def getArchSpec(architecture):
"""
Helper function to return the key-value string to specify the architecture
Index: aze/lldb/test/progress.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/test/progress.py 2013-03-03 09:35:50.327457348 +0100
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+
+import sys
+import time
+
+class ProgressBar(object):
+ """ProgressBar class holds the options of the progress bar.
+ The options are:
+ start State from which start the progress. For example, if start is
+ 5 and the end is 10, the progress of this state is 50%
+ end State in which the progress has terminated.
+ width --
+ fill String to use for "filled" used to represent the progress
+ blank String to use for "filled" used to represent remaining space.
+ format Format
+ incremental
+ """
+ light_block = unichr(0x2591).encode("utf-8")
+ solid_block = unichr(0x2588).encode("utf-8")
+ solid_right_arrow = unichr(0x25BA).encode("utf-8")
+
+ def __init__(self,
+ start=0,
+ end=10,
+ width=12,
+ fill=unichr(0x25C9).encode("utf-8"),
+ blank=unichr(0x25CC).encode("utf-8"),
+ marker=unichr(0x25CE).encode("utf-8"),
+ format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%',
+ incremental=True):
+ super(ProgressBar, self).__init__()
+
+ self.start = start
+ self.end = end
+ self.width = width
+ self.fill = fill
+ self.blank = blank
+ self.marker = marker
+ self.format = format
+ self.incremental = incremental
+ self.step = 100 / float(width) #fix
+ self.reset()
+
+ def __add__(self, increment):
+ increment = self._get_progress(increment)
+ if 100 > self.progress + increment:
+ self.progress += increment
+ else:
+ self.progress = 100
+ return self
+
+ def complete(self):
+ self.progress = 100
+ return self
+
+ def __str__(self):
+ progressed = int(self.progress / self.step) #fix
+ fill = progressed * self.fill
+ blank = (self.width - progressed) * self.blank
+ return self.format % {'fill': fill, 'blank': blank, 'marker': self.marker, 'progress': int(self.progress)}
+
+ __repr__ = __str__
+
+ def _get_progress(self, increment):
+ return float(increment * 100) / self.end
+
+ def reset(self):
+ """Resets the current progress to the start point"""
+ self.progress = self._get_progress(self.start)
+ return self
+
+
+class AnimatedProgressBar(ProgressBar):
+ """Extends ProgressBar to allow you to use it straighforward on a script.
+ Accepts an extra keyword argument named `stdout` (by default use sys.stdout)
+ and may be any file-object to which send the progress status.
+ """
+ def __init__(self,
+ start=0,
+ end=10,
+ width=12,
+ fill=unichr(0x25C9).encode("utf-8"),
+ blank=unichr(0x25CC).encode("utf-8"),
+ marker=unichr(0x25CE).encode("utf-8"),
+ format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%',
+ incremental=True,
+ stdout=sys.stdout):
+ super(AnimatedProgressBar, self).__init__(start,end,width,fill,blank,marker,format,incremental)
+ self.stdout = stdout
+
+ def show_progress(self):
+ if hasattr(self.stdout, 'isatty') and self.stdout.isatty():
+ self.stdout.write('\r')
+ else:
+ self.stdout.write('\n')
+ self.stdout.write(str(self))
+ self.stdout.flush()
+
+class ProgressWithEvents(AnimatedProgressBar):
+ """Extends AnimatedProgressBar to allow you to track a set of events that
+ cause the progress to move. For instance, in a deletion progress bar, you
+ can track files that were nuked and files that the user doesn't have access to
+ """
+ def __init__(self,
+ start=0,
+ end=10,
+ width=12,
+ fill=unichr(0x25C9).encode("utf-8"),
+ blank=unichr(0x25CC).encode("utf-8"),
+ marker=unichr(0x25CE).encode("utf-8"),
+ format='[%(fill)s%(marker)s%(blank)s] %(progress)s%%',
+ incremental=True,
+ stdout=sys.stdout):
+ super(ProgressWithEvents, self).__init__(start,end,width,fill,blank,marker,format,incremental,stdout)
+ self.events = {}
+
+ def add_event(self,event):
+ if event in self.events:
+ self.events[event] += 1
+ else:
+ self.events[event] = 1
+
+ def show_progress(self):
+ isatty = hasattr(self.stdout, 'isatty') and self.stdout.isatty()
+ if isatty:
+ self.stdout.write('\r')
+ else:
+ self.stdout.write('\n')
+ self.stdout.write(str(self))
+ if len(self.events) == 0:
+ return
+ self.stdout.write('\n')
+ for key in self.events.keys():
+ self.stdout.write(str(key) + ' = ' + str(self.events[key]) + ' ')
+ if isatty:
+ self.stdout.write('\033[1A')
+ self.stdout.flush()
+
+
+if __name__ == '__main__':
+ p = AnimatedProgressBar(end=200, width=200)
+
+ while True:
+ p + 5
+ p.show_progress()
+ time.sleep(0.3)
+ if p.progress == 100:
+ break
+ print #new line
\ No newline at end of file
Index: aze/lldb/test/python_api/hello_world/TestHelloWorld.py
===================================================================
--- aze.orig/lldb/test/python_api/hello_world/TestHelloWorld.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/hello_world/TestHelloWorld.py 2013-03-03 09:35:50.327457348 +0100
@@ -67,6 +67,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.hello_world_attach_with_name_api()
+ @expectedFailureLinux # due to bugzilla 14541
@python_api_test
@dwarf_test
def test_with_dwarf_and_attach_to_process_with_name_api(self):
@@ -134,11 +135,9 @@
target = self.dbg.CreateTarget(self.exe)
- # Spawn a new process and don't display the stdout if not in TraceOn() mode.
- import subprocess
- popen = subprocess.Popen([self.exe, "abc", "xyz"],
- stdout = open(os.devnull, 'w') if not self.TraceOn() else None)
- #print "pid of spawned process: %d" % popen.pid
+ # Spawn a new process
+ popen = self.spawnSubprocess(self.exe, ["abc", "xyz"])
+ self.addTearDownHook(self.cleanupSubprocesses)
listener = lldb.SBListener("my.attach.listener")
error = lldb.SBError()
@@ -158,11 +157,9 @@
target = self.dbg.CreateTarget(self.exe)
- # Spawn a new process and don't display the stdout if not in TraceOn() mode.
- import subprocess
- popen = subprocess.Popen([self.exe, "abc", "xyz"],
- stdout = open(os.devnull, 'w') if not self.TraceOn() else None)
- #print "pid of spawned process: %d" % popen.pid
+ # Spawn a new process
+ popen = self.spawnSubprocess(self.exe, ["abc", "xyz"])
+ self.addTearDownHook(self.cleanupSubprocesses)
listener = lldb.SBListener("my.attach.listener")
error = lldb.SBError()
Index: aze/lldb/test/python_api/lldbutil/iter/Makefile
===================================================================
--- aze.orig/lldb/test/python_api/lldbutil/iter/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/lldbutil/iter/Makefile 2013-03-03 09:35:50.327457348 +0100
@@ -1,7 +1,7 @@
LEVEL = ../../../make
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
Index: aze/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py
===================================================================
--- aze.orig/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py 2013-03-03 09:35:50.327457348 +0100
@@ -18,6 +18,7 @@
# Find the line number to break inside main().
self.line1 = line_number('main.cpp', '// Set break point at this line.')
+ @expectedFailureLinux # bugzilla 14600 - Exception state registers not supported on Linux
@python_api_test
def test_iter_registers(self):
"""Test iterator works correctly for lldbutil.iter_registers()."""
Index: aze/lldb/test/python_api/lldbutil/process/Makefile
===================================================================
--- aze.orig/lldb/test/python_api/lldbutil/process/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/lldbutil/process/Makefile 2013-03-03 09:35:50.327457348 +0100
@@ -1,7 +1,7 @@
LEVEL = ../../../make
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
MAKE_DSYM :=NO
Index: aze/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py
===================================================================
--- aze.orig/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py 2013-03-03 09:35:50.327457348 +0100
@@ -18,6 +18,7 @@
# Find the line number to break inside main().
self.line = line_number('main.cpp', '// Set break point at this line.')
+ @expectedFailureLinux # bugzilla 14323
@python_api_test
def test_stack_traces(self):
"""Test SBprocess and SBThread APIs with printing of the stack traces."""
Index: aze/lldb/test/python_api/module_section/Makefile
===================================================================
--- aze.orig/lldb/test/python_api/module_section/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/module_section/Makefile 2013-03-03 09:35:50.327457348 +0100
@@ -1,7 +1,7 @@
LEVEL = ../../make
CFLAGS_EXTRAS := -D__STDC_LIMIT_MACROS
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp b.cpp c.cpp
MAKE_DSYM :=NO
Index: aze/lldb/test/python_api/process/io/TestProcessIO.py
===================================================================
--- aze.orig/lldb/test/python_api/process/io/TestProcessIO.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/process/io/TestProcessIO.py 2013-03-03 09:35:50.327457348 +0100
@@ -35,7 +35,9 @@
target = self.dbg.CreateTarget(self.exe)
- self.dbg.SetAsync(True)
+ # Perform synchronous interaction with the debugger.
+ self.setAsync(True)
+
process = target.LaunchSimple(None, None, os.getcwd())
if self.TraceOn():
print "process launched."
Index: aze/lldb/test/python_api/sbdata/TestSBData.py
===================================================================
--- aze.orig/lldb/test/python_api/sbdata/TestSBData.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/sbdata/TestSBData.py 2013-03-03 09:35:50.327457348 +0100
@@ -33,6 +33,19 @@
# Find the line number to break on inside main.cpp.
self.line = line_number('main.cpp', '// set breakpoint here')
+ def assert_data(self, func, arg, expected):
+ """ Asserts func(SBError error, arg) == expected. """
+ error = lldb.SBError()
+ result = func(error, arg)
+ if not error.Success():
+ stream = lldb.SBStream()
+ error.GetDescription(stream)
+ self.assertTrue(error.Success(),
+ "%s(error, %s) did not succeed: %s" % (func.__name__,
+ arg,
+ stream.GetData()))
+ self.assertTrue(expected == result, "%s(error, %s) == %s != %s" % (func.__name__, arg, result, expected))
+
def data_api(self):
"""Test the SBData APIs."""
self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
@@ -68,35 +81,40 @@
offset = 0
error = lldb.SBError()
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'foo[0].a == 1')
+ self.assert_data(data.GetUnsignedInt32, offset, 1)
offset += 4
low = data.GetSignedInt16(error, offset)
+ self.assertTrue(error.Success())
offset += 2
high = data.GetSignedInt16(error, offset)
+ self.assertTrue(error.Success())
offset += 2
self.assertTrue ((low == 9 and high == 0) or (low == 0 and high == 9), 'foo[0].b == 9')
self.assertTrue( fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[0].c == 3.14')
+ self.assertTrue(error.Success())
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'foo[1].a == 8')
+ self.assert_data(data.GetUnsignedInt32, offset, 8)
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 5, 'foo[1].b == 5')
+ self.assert_data(data.GetUnsignedInt32, offset, 5)
offset += 4
self.runCmd("n")
offset = 16
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 5, 'saved foo[1].b == 5')
+ self.assert_data(data.GetUnsignedInt32, offset, 5)
data = foobar.GetPointeeData(1, 1)
offset = 0
- self.assertTrue(data.GetSignedInt32(error, offset) == 8, 'new foo[1].a == 8')
+ self.assert_data(data.GetSignedInt32, offset, 8)
offset += 4
- self.assertTrue(data.GetSignedInt32(error, offset) == 7, 'new foo[1].a == 7')
+ self.assert_data(data.GetSignedInt32, offset, 7)
offset += 8
self.assertTrue(data.GetUnsignedInt32(error, offset) == 0, 'do not read beyond end')
+ self.assertTrue(not error.Success())
+ error.Clear() # clear the error for the next test
star_foobar = foobar.Dereference()
self.assertTrue(star_foobar.IsValid())
@@ -107,9 +125,9 @@
print data
offset = 0
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'foo[0].a == 1')
+ self.assert_data(data.GetUnsignedInt32, offset, 1)
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 9, 'foo[0].b == 9')
+ self.assert_data(data.GetUnsignedInt32, offset, 9)
foobar_addr = star_foobar.GetLoadAddress()
foobar_addr += 12
@@ -136,11 +154,12 @@
self.runCmd("n")
offset = 0
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'then foo[1].a == 8')
+ self.assert_data(data.GetUnsignedInt32, offset, 8)
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 7, 'then foo[1].b == 7')
+ self.assert_data(data.GetUnsignedInt32, offset, 7)
offset += 4
self.assertTrue(fabs(data.GetFloat(error, offset) - 3.14) < 1, 'foo[1].c == 3.14')
+ self.assertTrue(error.Success())
data = new_foobar.GetData()
@@ -148,11 +167,12 @@
print data
offset = 0
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 8, 'finally foo[1].a == 8')
+ self.assert_data(data.GetUnsignedInt32, offset, 8)
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 7, 'finally foo[1].b == 7')
+ self.assert_data(data.GetUnsignedInt32, offset, 7)
offset += 4
self.assertTrue(fabs(data.GetFloat(error, offset) - 6.28) < 1, 'foo[1].c == 6.28')
+ self.assertTrue(error.Success())
self.runCmd("n")
@@ -167,17 +187,19 @@
print data
offset = 0
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 1, 'barfoo[0].a = 1')
+ self.assert_data(data.GetUnsignedInt32, offset, 1)
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 2, 'barfoo[0].b == 2')
+ self.assert_data(data.GetUnsignedInt32, offset, 2)
offset += 4
self.assertTrue(fabs(data.GetFloat(error, offset) - 3) < 1, 'barfoo[0].c == 3')
+ self.assertTrue(error.Success())
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 4, 'barfoo[1].a = 4')
+ self.assert_data(data.GetUnsignedInt32, offset, 4)
offset += 4
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 5, 'barfoo[1].b == 5')
+ self.assert_data(data.GetUnsignedInt32, offset, 5)
offset += 4
self.assertTrue(fabs(data.GetFloat(error, offset) - 6) < 1, 'barfoo[1].c == 6')
+ self.assertTrue(error.Success())
new_object = barfoo.CreateValueFromData("new_object",data,barfoo.GetType().GetBasicType(lldb.eBasicTypeInt))
@@ -191,9 +213,11 @@
self.assertTrue(new_object.GetValue() == "1", 'new_object == 1')
data.SetData(error, 'A\0\0\0', data.GetByteOrder(), data.GetAddressByteSize())
+ self.assertTrue(error.Success())
data2 = lldb.SBData()
data2.SetData(error, 'BCD', data.GetByteOrder(), data.GetAddressByteSize())
+ self.assertTrue(error.Success())
data.Append(data2)
@@ -202,33 +226,34 @@
# this breaks on EBCDIC
offset = 0
- self.assertTrue(data.GetUnsignedInt32(error, offset) == 65, 'made-up data == 65')
+ self.assert_data(data.GetUnsignedInt32, offset, 65)
offset += 4
- self.assertTrue(data.GetUnsignedInt8(error, offset) == 66, 'made-up data == 66')
+ self.assert_data(data.GetUnsignedInt8, offset, 66)
offset += 1
- self.assertTrue(data.GetUnsignedInt8(error, offset) == 67, 'made-up data == 67')
+ self.assert_data(data.GetUnsignedInt8, offset, 67)
offset += 1
- self.assertTrue(data.GetUnsignedInt8(error, offset) == 68, 'made-up data == 68')
+ self.assert_data(data.GetUnsignedInt8, offset, 68)
offset += 1
# check the new API calls introduced per LLVM bugzilla enhancement request
# 11619 (Allow creating SBData values from arrays or primitives in Python)
- data2 = lldb.SBData.CreateDataFromCString(process.GetByteOrder(),process.GetAddressByteSize(),'hello!')
+ hello_str = "hello!"
+ data2 = lldb.SBData.CreateDataFromCString(process.GetByteOrder(),process.GetAddressByteSize(),hello_str)
+ self.assertTrue(len(data2.uint8) == len(hello_str))
self.assertTrue(data2.uint8[0] == 104, 'h == 104')
self.assertTrue(data2.uint8[1] == 101, 'e == 101')
self.assertTrue(data2.uint8[2] == 108, 'l == 108')
- self.assertTrue(data2.GetUnsignedInt8(error,3) == 108, 'l == 108')
+ self.assert_data(data2.GetUnsignedInt8, 3, 108) # l
self.assertTrue(data2.uint8[4] == 111, 'o == 111')
- self.assertTrue(data2.GetUnsignedInt8(error,5) == 33, '! == 33')
- self.assertTrue(data2.uint8[6] == 0, 'binary 0 terminator')
+ self.assert_data(data2.GetUnsignedInt8, 5, 33) # !
data2 = lldb.SBData.CreateDataFromUInt64Array(process.GetByteOrder(),process.GetAddressByteSize(),[1,2,3,4,5])
- self.assertTrue(data2.GetUnsignedInt64(error,0) == 1, 'data2[0] = 1')
- self.assertTrue(data2.GetUnsignedInt64(error,8) == 2, 'data2[1] = 2')
- self.assertTrue(data2.GetUnsignedInt64(error,16) == 3, 'data2[2] = 3')
- self.assertTrue(data2.GetUnsignedInt64(error,24) == 4, 'data2[3] = 4')
- self.assertTrue(data2.GetUnsignedInt64(error,32) == 5, 'data2[4] = 5')
+ self.assert_data(data2.GetUnsignedInt64, 0, 1)
+ self.assert_data(data2.GetUnsignedInt64, 8, 2)
+ self.assert_data(data2.GetUnsignedInt64, 16, 3)
+ self.assert_data(data2.GetUnsignedInt64, 24, 4)
+ self.assert_data(data2.GetUnsignedInt64, 32, 5)
self.assertTrue(data2.uint64s == [1,2,3,4,5], 'read_data_helper failure: data2 == [1,2,3,4,5]')
@@ -236,39 +261,42 @@
self.assertTrue(data2.sint32[0:2] == [2,-2], 'signed32 data2 = [2,-2]')
data2.Append(lldb.SBData.CreateDataFromSInt64Array(process.GetByteOrder(),process.GetAddressByteSize(),[2, -2]))
- self.assertTrue(data2.GetSignedInt32(error,0) == 2, 'signed32 data2[0] = 2')
- self.assertTrue(data2.GetSignedInt32(error,4) == -2, 'signed32 data2[1] = -2')
+ self.assert_data(data2.GetSignedInt32, 0, 2)
+ self.assert_data(data2.GetSignedInt32, 4, -2)
self.assertTrue(data2.sint64[1:3] == [2,-2], 'signed64 data2 = [2,-2]')
data2 = lldb.SBData.CreateDataFromUInt32Array(process.GetByteOrder(),process.GetAddressByteSize(),[1,2,3,4,5])
- self.assertTrue(data2.GetUnsignedInt32(error,0) == 1, '32-bit data2[0] = 1')
- self.assertTrue(data2.GetUnsignedInt32(error,4) == 2, '32-bit data2[1] = 2')
- self.assertTrue(data2.GetUnsignedInt32(error,8) == 3, '32-bit data2[2] = 3')
- self.assertTrue(data2.GetUnsignedInt32(error,12) == 4, '32-bit data2[3] = 4')
- self.assertTrue(data2.GetUnsignedInt32(error,16) == 5, '32-bit data2[4] = 5')
+ self.assert_data(data2.GetUnsignedInt32,0, 1)
+ self.assert_data(data2.GetUnsignedInt32,4, 2)
+ self.assert_data(data2.GetUnsignedInt32,8, 3)
+ self.assert_data(data2.GetUnsignedInt32,12, 4)
+ self.assert_data(data2.GetUnsignedInt32,16, 5)
data2 = lldb.SBData.CreateDataFromDoubleArray(process.GetByteOrder(),process.GetAddressByteSize(),[3.14,6.28,2.71])
self.assertTrue( fabs(data2.GetDouble(error,0) - 3.14) < 0.5, 'double data2[0] = 3.14')
+ self.assertTrue(error.Success())
self.assertTrue( fabs(data2.GetDouble(error,8) - 6.28) < 0.5, 'double data2[1] = 6.28')
+ self.assertTrue(error.Success())
self.assertTrue( fabs(data2.GetDouble(error,16) - 2.71) < 0.5, 'double data2[2] = 2.71')
+ self.assertTrue(error.Success())
data2 = lldb.SBData()
- data2.SetDataFromCString('hello!')
- self.assertTrue(data2.GetUnsignedInt8(error,0) == 104, 'set h == 104')
- self.assertTrue(data2.GetUnsignedInt8(error,1) == 101, 'set e == 101')
- self.assertTrue(data2.GetUnsignedInt8(error,2) == 108, 'set l == 108')
- self.assertTrue(data2.GetUnsignedInt8(error,3) == 108, 'set l == 108')
- self.assertTrue(data2.GetUnsignedInt8(error,4) == 111, 'set o == 111')
- self.assertTrue(data2.GetUnsignedInt8(error,5) == 33, 'set ! == 33')
- self.assertTrue(data2.GetUnsignedInt8(error,6) == 0, 'set binary 0 terminator')
+ data2.SetDataFromCString(hello_str)
+ self.assertTrue(len(data2.uint8) == len(hello_str))
+ self.assert_data(data2.GetUnsignedInt8, 0, 104)
+ self.assert_data(data2.GetUnsignedInt8, 1, 101)
+ self.assert_data(data2.GetUnsignedInt8, 2, 108)
+ self.assert_data(data2.GetUnsignedInt8, 3, 108)
+ self.assert_data(data2.GetUnsignedInt8, 4, 111)
+ self.assert_data(data2.GetUnsignedInt8, 5, 33)
data2.SetDataFromUInt64Array([1,2,3,4,5])
- self.assertTrue(data2.GetUnsignedInt64(error,0) == 1, 'set data2[0] = 1')
- self.assertTrue(data2.GetUnsignedInt64(error,8) == 2, 'set data2[1] = 2')
- self.assertTrue(data2.GetUnsignedInt64(error,16) == 3, 'set data2[2] = 3')
- self.assertTrue(data2.GetUnsignedInt64(error,24) == 4, 'set data2[3] = 4')
- self.assertTrue(data2.GetUnsignedInt64(error,32) == 5, 'set data2[4] = 5')
+ self.assert_data(data2.GetUnsignedInt64, 0, 1)
+ self.assert_data(data2.GetUnsignedInt64, 8, 2)
+ self.assert_data(data2.GetUnsignedInt64, 16, 3)
+ self.assert_data(data2.GetUnsignedInt64, 24, 4)
+ self.assert_data(data2.GetUnsignedInt64, 32, 5)
self.assertTrue(data2.uint64[0] == 1, 'read_data_helper failure: set data2[0] = 1')
self.assertTrue(data2.uint64[1] == 2, 'read_data_helper failure: set data2[1] = 2')
@@ -279,19 +307,19 @@
self.assertTrue(data2.uint64[0:2] == [1,2], 'read_data_helper failure: set data2[0:2] = [1,2]')
data2.SetDataFromSInt32Array([2, -2])
- self.assertTrue(data2.GetSignedInt32(error,0) == 2, 'set signed32 data2[0] = 2')
- self.assertTrue(data2.GetSignedInt32(error,4) == -2, 'set signed32 data2[1] = -2')
+ self.assert_data(data2.GetSignedInt32, 0, 2)
+ self.assert_data(data2.GetSignedInt32, 4, -2)
data2.SetDataFromSInt64Array([2, -2])
- self.assertTrue(data2.GetSignedInt32(error,0) == 2, 'set signed64 data2[0] = 2')
- self.assertTrue(data2.GetSignedInt32(error,8) == -2, 'set signed64 data2[1] = -2')
+ self.assert_data(data2.GetSignedInt32, 0, 2)
+ self.assert_data(data2.GetSignedInt32, 8, -2)
data2.SetDataFromUInt32Array([1,2,3,4,5])
- self.assertTrue(data2.GetUnsignedInt32(error,0) == 1, 'set 32-bit data2[0] = 1')
- self.assertTrue(data2.GetUnsignedInt32(error,4) == 2, 'set 32-bit data2[1] = 2')
- self.assertTrue(data2.GetUnsignedInt32(error,8) == 3, 'set 32-bit data2[2] = 3')
- self.assertTrue(data2.GetUnsignedInt32(error,12) == 4, 'set 32-bit data2[3] = 4')
- self.assertTrue(data2.GetUnsignedInt32(error,16) == 5, 'set 32-bit data2[4] = 5')
+ self.assert_data(data2.GetUnsignedInt32, 0, 1)
+ self.assert_data(data2.GetUnsignedInt32, 4, 2)
+ self.assert_data(data2.GetUnsignedInt32, 8, 3)
+ self.assert_data(data2.GetUnsignedInt32, 12, 4)
+ self.assert_data(data2.GetUnsignedInt32, 16, 5)
self.assertTrue(data2.uint32[0] == 1, 'read_data_helper failure: set 32-bit data2[0] = 1')
self.assertTrue(data2.uint32[1] == 2, 'read_data_helper failure: set 32-bit data2[1] = 2')
Index: aze/lldb/test/python_api/thread/TestThreadAPI.py
===================================================================
--- aze.orig/lldb/test/python_api/thread/TestThreadAPI.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/thread/TestThreadAPI.py 2013-03-03 09:35:50.327457348 +0100
@@ -74,6 +74,7 @@
self.setTearDownCleanup(dictionary=d)
self.step_out_of_malloc_into_function_b(self.exe_name)
+ @expectedFailureLinux # bugzilla 14416
@python_api_test
@dwarf_test
def test_step_out_of_malloc_into_function_b_with_dwarf(self):
Index: aze/lldb/test/python_api/type/TestTypeList.py
===================================================================
--- aze.orig/lldb/test/python_api/type/TestTypeList.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/type/TestTypeList.py 2013-03-03 09:35:50.331457349 +0100
@@ -66,7 +66,7 @@
type_list = target.FindTypes('Task')
if self.TraceOn():
print "Size of type_list from target.FindTypes('Task') query: %d" % type_list.GetSize()
- self.assertTrue(len(type_list) == 1)
+ self.assertTrue(len(type_list) >= 1) # a second Task make be scared up by the Objective-C runtime
for type in type_list:
self.assertTrue(type)
self.DebugSBType(type)
Index: aze/lldb/test/python_api/value/change_values/TestChangeValueAPI.py
===================================================================
--- aze.orig/lldb/test/python_api/value/change_values/TestChangeValueAPI.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/value/change_values/TestChangeValueAPI.py 2013-03-03 09:35:50.331457349 +0100
@@ -40,6 +40,7 @@
self.line = line_number('main.c', '// Stop here and set values')
self.end_line = line_number ('main.c', '// Set a breakpoint here at the end')
+ @expectedFailureGcc # PR-15039: If GCC is the test compiler, stdout is not available via lldb.SBProcess.GetSTDOUT()
def change_value_api(self, exe_name):
"""Exercise some SBValue APIs."""
exe = os.path.join(os.getcwd(), exe_name)
Index: aze/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/condition/TestWatchpointConditionAPI.py 2013-03-03 09:35:50.331457349 +0100
@@ -33,6 +33,7 @@
self.setTearDownCleanup(dictionary=self.d)
self.watchpoint_condition_api()
+ @expectedFailureLinux # bugzilla 14416
@dwarf_test
def test_watchpoint_cond_api_with_dwarf(self):
"""Test watchpoint condition API."""
Index: aze/lldb/test/python_api/watchpoint/TestSetWatchpoint.py
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/TestSetWatchpoint.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/TestSetWatchpoint.py 2013-03-03 09:35:50.331457349 +0100
@@ -28,6 +28,7 @@
self.buildDsym()
self.do_set_watchpoint()
+ @expectedFailureLinux # bugzilla 14416
@python_api_test
@dwarf_test
def test_watch_val_with_dwarf(self):
Index: aze/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/TestWatchpointIgnoreCount.py 2013-03-03 09:35:50.331457349 +0100
@@ -28,6 +28,7 @@
self.buildDsym()
self.do_watchpoint_ignore_count()
+ @expectedFailureLinux # bugzilla 14416
@python_api_test
@dwarf_test
def test_set_watch_ignore_count_with_dwarf(self):
Index: aze/lldb/test/python_api/watchpoint/TestWatchpointIter.py
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/TestWatchpointIter.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/TestWatchpointIter.py 2013-03-03 09:35:50.331457349 +0100
@@ -28,6 +28,7 @@
self.buildDsym()
self.do_watchpoint_iter()
+ @expectedFailureLinux # bugzilla 14416
@python_api_test
@dwarf_test
def test_watch_iter_with_dwarf(self):
Index: aze/lldb/test/python_api/watchpoint/watchlocation/Makefile
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/watchlocation/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/watchlocation/Makefile 2013-03-03 09:35:50.331457349 +0100
@@ -1,6 +1,6 @@
LEVEL = ../../../make
-LDFLAGS := -lpthread
+LD_EXTRAS := -lpthread
CXX_SOURCES := main.cpp
include $(LEVEL)/Makefile.rules
Index: aze/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/watchlocation/TestSetWatchlocation.py 2013-03-03 09:35:50.331457349 +0100
@@ -30,6 +30,7 @@
self.buildDsym()
self.do_set_watchlocation()
+ @expectedFailureLinux # bugzilla 14416
@python_api_test
@dwarf_test
def test_watch_location_with_dwarf(self):
Index: aze/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py
===================================================================
--- aze.orig/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py 2013-03-03 09:35:50.331457349 +0100
@@ -30,6 +30,7 @@
self.buildDsym()
self.do_set_watchaddress()
+ @expectedFailureLinux # bugzilla 14416
@python_api_test
@dwarf_test
def test_watch_address_with_dwarf(self):
Index: aze/lldb/test/source-manager/TestSourceManager.py
===================================================================
--- aze.orig/lldb/test/source-manager/TestSourceManager.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/source-manager/TestSourceManager.py 2013-03-03 09:35:50.331457349 +0100
@@ -105,7 +105,7 @@
substrs = [os.getcwd(), os.path.join(os.getcwd(), "hidden")])
# Display main() and verify that the source mapping has been kicked in.
- self.expect("list -n main", SOURCE_DISPLAYED_CORRECTLY,
+ self.expect("source list -n main", SOURCE_DISPLAYED_CORRECTLY,
substrs = ['Hello world'])
def modify_source_file_while_debugging(self):
@@ -124,14 +124,14 @@
'stop reason = breakpoint'])
# Display some source code.
- self.expect("list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY,
+ self.expect("source list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY,
substrs = ['Hello world'])
# The '-b' option shows the line table locations from the debug information
# that indicates valid places to set source level breakpoints.
# The file to display is implicit in this case.
- self.runCmd("list -l %d -c 3 -b" % self.line)
+ self.runCmd("source list -l %d -c 3 -b" % self.line)
output = self.res.GetOutput().splitlines()[0]
# If the breakpoint set command succeeded, we should expect a positive number
@@ -178,7 +178,7 @@
self.addTearDownHook(restore_file)
# Display the source code again. We should see the updated line.
- self.expect("list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY,
+ self.expect("source list -f main.c -l %d" % self.line, SOURCE_DISPLAYED_CORRECTLY,
substrs = ['Hello lldb'])
Index: aze/lldb/test/types/AbstractBase.py
===================================================================
--- aze.orig/lldb/test/types/AbstractBase.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/types/AbstractBase.py 2013-03-03 09:35:50.331457349 +0100
@@ -10,7 +10,7 @@
def Msg(var, val, using_frame_variable):
return "'%s %s' matches the output (from compiled code): %s" % (
- 'frame variable -T' if using_frame_variable else 'expression' ,var, val)
+ 'frame variable --show-types' if using_frame_variable else 'expression' ,var, val)
class GenericTester(TestBase):
@@ -116,7 +116,7 @@
lambda: self.runCmd("settings set target.inline-breakpoint-strategy headers"))
# Bring the program to the point where we can issue a series of
- # 'frame variable -T' command.
+ # 'frame variable --show-types' command.
if blockCaptured:
break_line = line_number ("basic_type.cpp", "// Break here to test block captured variables.")
else:
@@ -128,19 +128,19 @@
substrs = [" at basic_type.cpp:%d" % break_line,
"stop reason = breakpoint"])
- #self.runCmd("frame variable -T")
+ #self.runCmd("frame variable --show-types")
# Now iterate through the golden list, comparing against the output from
- # 'frame variable -T var'.
+ # 'frame variable --show-types var'.
for var, val in gl:
- self.runCmd("frame variable -T %s" % var)
+ self.runCmd("frame variable --show-types %s" % var)
output = self.res.GetOutput()
# The input type is in a canonical form as a set of named atoms.
# The display type string must conatin each and every element.
#
# Example:
- # runCmd: frame variable -T a_array_bounded[0]
+ # runCmd: frame variable --show-types a_array_bounded[0]
# output: (char) a_array_bounded[0] = 'a'
#
try:
@@ -209,7 +209,7 @@
substrs = [" at basic_type.cpp:%d" % break_line,
"stop reason = breakpoint"])
- #self.runCmd("frame variable -T")
+ #self.runCmd("frame variable --show-types")
# Now iterate through the golden list, comparing against the output from
# 'expr var'.
Index: aze/lldb/test/types/TestFloatTypesExpr.py
===================================================================
--- aze.orig/lldb/test/types/TestFloatTypesExpr.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/types/TestFloatTypesExpr.py 2013-03-03 09:35:50.331457349 +0100
@@ -15,6 +15,13 @@
# rdar://problem/8493023
# test/types failures for Test*TypesExpr.py: element offset computed wrong and sign error?
+ def setUp(self):
+ # Call super's setUp().
+ AbstractBase.GenericTester.setUp(self)
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_float_type_with_dsym(self):
Index: aze/lldb/test/types/TestFloatTypes.py
===================================================================
--- aze.orig/lldb/test/types/TestFloatTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/types/TestFloatTypes.py 2013-03-03 09:35:50.331457349 +0100
@@ -12,6 +12,13 @@
mydir = "types"
+ def setUp(self):
+ # Call super's setUp().
+ AbstractBase.GenericTester.setUp(self)
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_float_type_with_dsym(self):
Index: aze/lldb/test/types/TestIntegerTypesExpr.py
===================================================================
--- aze.orig/lldb/test/types/TestIntegerTypesExpr.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/types/TestIntegerTypesExpr.py 2013-03-03 09:35:50.331457349 +0100
@@ -12,6 +12,13 @@
mydir = "types"
+ def setUp(self):
+ # Call super's setUp().
+ AbstractBase.GenericTester.setUp(self)
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_char_type_with_dsym(self):
Index: aze/lldb/test/types/TestIntegerTypes.py
===================================================================
--- aze.orig/lldb/test/types/TestIntegerTypes.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/types/TestIntegerTypes.py 2013-03-03 09:35:50.331457349 +0100
@@ -12,6 +12,13 @@
mydir = "types"
+ def setUp(self):
+ # Call super's setUp().
+ AbstractBase.GenericTester.setUp(self)
+ # disable "There is a running process, kill it and restart?" prompt
+ self.runCmd("settings set auto-confirm true")
+ self.addTearDownHook(lambda: self.runCmd("settings clear auto-confirm"))
+
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@dsym_test
def test_char_type_with_dsym(self):
Index: aze/lldb/test/unittest2/case.py
===================================================================
--- aze.orig/lldb/test/unittest2/case.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/unittest2/case.py 2013-03-03 09:35:50.331457349 +0100
@@ -36,16 +36,23 @@
This is an implementation detail.
"""
- def __init__(self, exc_info):
+ def __init__(self, exc_info, bugnumber=None):
# can't use super because Python 2.4 exceptions are old style
Exception.__init__(self)
self.exc_info = exc_info
+ self.bugnumber = bugnumber
class _UnexpectedSuccess(Exception):
"""
The test was supposed to fail, but it didn't!
"""
+ def __init__(self, exc_info, bugnumber=None):
+ # can't use super because Python 2.4 exceptions are old style
+ Exception.__init__(self)
+ self.exc_info = exc_info
+ self.bugnumber = bugnumber
+
def _id(obj):
return obj
@@ -81,17 +88,27 @@
return skip(reason)
return _id
-
-def expectedFailure(func):
- @wraps(func)
- def wrapper(*args, **kwargs):
- try:
- func(*args, **kwargs)
- except Exception:
- raise _ExpectedFailure(sys.exc_info())
- raise _UnexpectedSuccess
- return wrapper
-
+def expectedFailure(bugnumber=None):
+ if callable(bugnumber):
+ @wraps(bugnumber)
+ def expectedFailure_easy_wrapper(*args, **kwargs):
+ try:
+ bugnumber(*args, **kwargs)
+ except Exception:
+ raise _ExpectedFailure(sys.exc_info(),None)
+ raise _UnexpectedSuccess(sys.exc_info(),None)
+ return expectedFailure_easy_wrapper
+ else:
+ def expectedFailure_impl(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ try:
+ func(*args, **kwargs)
+ except Exception:
+ raise _ExpectedFailure(sys.exc_info(),bugnumber)
+ raise _UnexpectedSuccess(sys.exc_info(),bugnumber)
+ return wrapper
+ return expectedFailure_impl
class _AssertRaisesContext(object):
"""A context manager used to implement TestCase.assertRaises* methods."""
@@ -343,15 +360,15 @@
except _ExpectedFailure, e:
addExpectedFailure = getattr(result, 'addExpectedFailure', None)
if addExpectedFailure is not None:
- addExpectedFailure(self, e.exc_info)
+ addExpectedFailure(self, e.exc_info, e.bugnumber)
else:
warnings.warn("Use of a TestResult without an addExpectedFailure method is deprecated",
DeprecationWarning)
result.addSuccess(self)
- except _UnexpectedSuccess:
+ except _UnexpectedSuccess, x:
addUnexpectedSuccess = getattr(result, 'addUnexpectedSuccess', None)
if addUnexpectedSuccess is not None:
- addUnexpectedSuccess(self)
+ addUnexpectedSuccess(self, x.bugnumber)
else:
warnings.warn("Use of a TestResult without an addUnexpectedSuccess method is deprecated",
DeprecationWarning)
Index: aze/lldb/test/unittest2/result.py
===================================================================
--- aze.orig/lldb/test/unittest2/result.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/unittest2/result.py 2013-03-03 09:35:50.331457349 +0100
@@ -123,13 +123,13 @@
"""Called when a test is skipped."""
self.skipped.append((test, reason))
- def addExpectedFailure(self, test, err):
+ def addExpectedFailure(self, test, err, bugnumber):
"""Called when an expected failure/error occured."""
self.expectedFailures.append(
(test, self._exc_info_to_string(err, test)))
@failfast
- def addUnexpectedSuccess(self, test):
+ def addUnexpectedSuccess(self, test, bugnumber):
"""Called when a test was expected to fail, but succeed."""
self.unexpectedSuccesses.append(test)
Index: aze/lldb/test/unittest2/runner.py
===================================================================
--- aze.orig/lldb/test/unittest2/runner.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/unittest2/runner.py 2013-03-03 09:35:50.331457349 +0100
@@ -3,6 +3,7 @@
import sys
import time
import unittest
+import progress
from unittest2 import result
@@ -45,6 +46,7 @@
self.showAll = verbosity > 1
self.dots = verbosity == 1
self.descriptions = descriptions
+ self.progressbar = None
def getDescription(self, test):
doc_first_line = test.shortDescription()
@@ -60,55 +62,48 @@
self.stream.write(" ... ")
self.stream.flush()
- def addSuccess(self, test):
- super(TextTestResult, self).addSuccess(test)
+ def newTestResult(self,test,result_short,result_long):
if self.showAll:
- self.stream.writeln("ok")
+ self.stream.writeln(result_long)
+ elif self.progressbar:
+ self.progressbar.__add__(1)
+ self.progressbar.add_event(result_short)
+ self.progressbar.show_progress()
elif self.dots:
- self.stream.write('.')
+ self.stream.write(result_short)
self.stream.flush()
+ def addSuccess(self, test):
+ super(TextTestResult, self).addSuccess(test)
+ if self.progressbar:
+ self.newTestResult(test,"ok","ok")
+ else:
+ self.newTestResult(test,".","ok")
+
def addError(self, test, err):
super(TextTestResult, self).addError(test, err)
- if self.showAll:
- self.stream.writeln("ERROR")
- elif self.dots:
- self.stream.write('E')
- self.stream.flush()
+ self.newTestResult(test,"E","ERROR")
def addFailure(self, test, err):
super(TextTestResult, self).addFailure(test, err)
- if self.showAll:
- self.stream.writeln("FAIL")
- elif self.dots:
- self.stream.write('F')
- self.stream.flush()
+ self.newTestResult(test,"F","FAILURE")
def addSkip(self, test, reason):
super(TextTestResult, self).addSkip(test, reason)
- if self.showAll:
- self.stream.writeln("skipped %r" % (reason,))
- elif self.dots:
- self.stream.write("s")
- self.stream.flush()
+ self.newTestResult(test,"s","skipped %r" % (reason,))
- def addExpectedFailure(self, test, err):
- super(TextTestResult, self).addExpectedFailure(test, err)
- if self.showAll:
- self.stream.writeln("expected failure")
- elif self.dots:
- self.stream.write("x")
- self.stream.flush()
-
- def addUnexpectedSuccess(self, test):
- super(TextTestResult, self).addUnexpectedSuccess(test)
- if self.showAll:
- self.stream.writeln("unexpected success")
- elif self.dots:
- self.stream.write("u")
- self.stream.flush()
+ def addExpectedFailure(self, test, err, bugnumber):
+ super(TextTestResult, self).addExpectedFailure(test, err, bugnumber)
+ self.newTestResult(test,"x","expected failure")
+
+ def addUnexpectedSuccess(self, test, bugnumber):
+ super(TextTestResult, self).addUnexpectedSuccess(test, bugnumber)
+ self.newTestResult(test,"u","unexpected success")
def printErrors(self):
+ if self.progressbar:
+ self.progressbar.complete()
+ self.progressbar.show_progress()
if self.dots or self.showAll:
self.stream.writeln()
self.printErrorList('ERROR', self.errors)
Index: aze/lldb/test/warnings/uuid/TestAddDsymCommand.py
===================================================================
--- aze.orig/lldb/test/warnings/uuid/TestAddDsymCommand.py 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/test/warnings/uuid/TestAddDsymCommand.py 2013-03-03 09:35:50.335457350 +0100
@@ -81,7 +81,7 @@
right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name)
self.expect("add-dsym " + right_path, error=True,
- substrs = ['symbol file', 'with UUID', 'does not match'])
+ substrs = ['symbol file', 'does not match'])
def do_add_dsym_with_success(self, exe_name):
"""Test that the 'add-dsym' command informs the user about success."""
@@ -90,8 +90,7 @@
# This time, the UUID should match and we expect some feedback from lldb.
right_path = os.path.join("%s.dSYM" % exe_name, "Contents", "Resources", "DWARF", exe_name)
self.expect("add-dsym " + right_path,
- substrs = ['symbol file', 'with UUID', 'has been successfully added to the',
- 'module'])
+ substrs = ['symbol file', 'has been added to'])
def do_add_dsym_with_dSYM_bundle(self, exe_name):
"""Test that the 'add-dsym' command informs the user about success when loading files in bundles."""
@@ -100,8 +99,7 @@
# This time, the UUID should be found inside the bundle
right_path = "%s.dSYM" % exe_name
self.expect("add-dsym " + right_path,
- substrs = ['symbol file', 'with UUID', 'has been successfully added to the',
- 'module'])
+ substrs = ['symbol file', 'has been added to'])
if __name__ == '__main__':
Index: aze/lldb/test/warnings/uuid/TestUUIDMismatchWanring.py
===================================================================
--- aze.orig/lldb/test/warnings/uuid/TestUUIDMismatchWanring.py 2013-03-03 09:35:47.779457405 +0100
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,113 +0,0 @@
-"""Test that the 'warning: UUID mismatch detected ...' message is emitted if a
-dsym in vicinity of the executable does not match its UUID."""
-
-import os, time
-import unittest2
-import lldb
-import pexpect
-from lldbtest import *
-
-@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
-class UUIDMismatchWarningCase(TestBase):
-
- mydir = os.path.join("warnings", "uuid")
-
- @classmethod
- def classCleanup(cls):
- """Cleanup the test byproducts."""
- cls.RemoveTempFile("child_send.txt")
- cls.RemoveTempFile("child_read.txt")
-
- def setUp(self):
- TestBase.setUp(self)
- self.template = 'main.cpp.template'
- self.source = 'main.cpp'
- self.teardown_hook_added = False
-
- def test_uuid_mismatch_warning(self):
- """Test that the 'warning: UUID mismatch detected ...' message is emitted."""
-
- # Call the program generator to produce main.cpp, version 1.
- self.generate_main_cpp(version=1)
- self.line_to_break = line_number(self.source, '// Set breakpoint here.')
- self.buildDsym(clean=True)
-
- # Insert some delay and then call the program generator to produce main.cpp, version 2.
- time.sleep(5)
- self.generate_main_cpp(version=101)
- # Now call make again, but this time don't generate the dSYM.
- self.buildDwarf(clean=False)
-
- self.exe_name = 'a.out'
- self.check_executable_and_dsym(self.exe_name)
-
- def generate_main_cpp(self, version=0):
- """Generate main.cpp from main.cpp.template."""
- temp = os.path.join(os.getcwd(), self.template)
- with open(temp, 'r') as f:
- content = f.read()
-
- new_content = content.replace('%ADD_EXTRA_CODE%',
- 'printf("This is version %d\\n");' % version)
- src = os.path.join(os.getcwd(), self.source)
- with open(src, 'w') as f:
- f.write(new_content)
-
- # The main.cpp has been generated, add a teardown hook to remove it.
- if not self.teardown_hook_added:
- self.addTearDownHook(lambda: os.remove(src))
- self.teardown_hook_added = True
-
- def check_executable_and_dsym(self, exe_name):
- """Sanity check executable compiled from the auto-generated program."""
-
- # The default lldb prompt.
- prompt = "(lldb) "
-
- # So that the child gets torn down after the test.
- self.child = pexpect.spawn('%s %s' % (self.lldbHere, self.lldbOption))
- child = self.child
- # Turn on logging for input/output to/from the child.
- with open('child_send.txt', 'w') as f_send:
- with open('child_read.txt', 'w') as f_read:
- child.logfile_send = f_send
- child.logfile_read = f_read
-
- child.expect_exact(prompt)
- child.setecho(True)
-
- # Execute the file command, followed by a breakpoint set, the
- # UUID mismatch warning should be generated by then.
-
- child.sendline("file %s" % exe_name)
- child.expect_exact(prompt)
- child.sendline("breakpoint set -f %s -l %d" % (self.source, self.line_to_break))
- child.expect_exact(prompt)
- child.sendline("run")
- child.expect_exact(prompt)
-
- # Now that the necessary logging is done, restore logfile to None to
- # stop further logging.
- child.logfile_send = None
- child.logfile_read = None
-
- with open('child_send.txt', 'r') as fs:
- if self.TraceOn():
- print "\n\nContents of child_send.txt:"
- print fs.read()
- with open('child_read.txt', 'r') as fr:
- from_child = fr.read()
- if self.TraceOn():
- print "\n\nContents of child_read.txt:"
- print from_child
-
- # Test that lldb emits the "UUID mismatch detected" message.
- self.expect(from_child, msg="UUID mismatch expected!", exe=False,
- substrs = ['warning: UUID mismatch detected'])
-
-
-if __name__ == '__main__':
- import atexit
- lldb.SBDebugger.Initialize()
- atexit.register(lambda: lldb.SBDebugger.Terminate())
- unittest2.main()
Index: aze/lldb/tools/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/tools/CMakeLists.txt 2013-03-03 09:35:50.335457350 +0100
@@ -0,0 +1,2 @@
+#add_subdirectory(debugserver)
+add_subdirectory(driver)
Index: aze/lldb/tools/darwin-threads/examine-threads.c
===================================================================
--- aze.orig/lldb/tools/darwin-threads/examine-threads.c 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/darwin-threads/examine-threads.c 2013-03-03 09:35:50.335457350 +0100
@@ -152,6 +152,53 @@
return tident;
}
+
+/* Given a mach port # (in the examine-threads mach port namespace) for a thread,
+ find the mach port # in the inferior program's port namespace.
+ Sets inferior_port if successful.
+ Returns true if successful, false if unable to find the port number. */
+
+bool
+inferior_namespace_mach_port_num (task_t task, thread_t examine_threads_port, thread_t *inferior_port)
+{
+ kern_return_t retval;
+ mach_port_name_array_t names;
+ mach_msg_type_number_t nameslen;
+ mach_port_type_array_t types;
+ mach_msg_type_number_t typeslen;
+
+ if (inferior_port == NULL)
+ return false;
+
+ retval = mach_port_names (task, &names, &nameslen, &types, &typeslen);
+ if (retval != KERN_SUCCESS)
+ {
+ printf ("Error - unable to get mach port names for inferior.\n");
+ return false;
+ }
+ int i = 0;
+ for (i = 0; i < nameslen; i++)
+ {
+ mach_port_t local_name;
+ mach_msg_type_name_t local_type;
+ retval = mach_port_extract_right (task, names[i], MACH_MSG_TYPE_COPY_SEND, &local_name, &local_type);
+ if (retval == KERN_SUCCESS)
+ {
+ mach_port_deallocate (mach_task_self(), local_name);
+ if (local_name == examine_threads_port)
+ {
+ *inferior_port = names[i];
+ vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t));
+ vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t));
+ return true;
+ }
+ }
+ }
+ vm_deallocate (mach_task_self (), (vm_address_t) names, nameslen * sizeof (mach_port_t));
+ vm_deallocate (mach_task_self (), (vm_address_t) types, typeslen * sizeof (mach_port_t));
+ return false;
+}
+
/* Get the current pc value for a given thread. */
uint64_t
@@ -353,7 +400,7 @@
int wordsize;
uint64_t pc = get_current_pc (thread_list[i], &wordsize);
- printf ("thread #%d, unique tid %lld, suspend count is %d, ", i,
+ printf ("thread #%d, system-wide-unique-tid %lld, suspend count is %d, ", i,
identifier_info.thread_id,
basic_info->suspend_count);
if (wordsize == 8)
@@ -371,18 +418,19 @@
}
if (verbose)
{
- printf (" ");
- printf ("mach thread #0x%4.4x ", (int) thread_list[i]);
- printf ("pthread handle id 0x%llx ", (uint64_t) identifier_info.thread_handle);
+ printf (" (examine-threads port namespace) mach port # 0x%4.4x\n", (int) thread_list[i]);
+ thread_t mach_port_inferior_namespace;
+ if (inferior_namespace_mach_port_num (task, thread_list[i], &mach_port_inferior_namespace))
+ printf (" (inferior port namepsace) mach port # 0x%4.4x\n", (int) mach_port_inferior_namespace);
+ printf (" pthread handle id 0x%llx\n", (uint64_t) identifier_info.thread_handle);
struct proc_threadinfo pth;
int proc_threadinfo_succeeded = get_proc_threadinfo (pid, identifier_info.thread_handle, &pth);
if (proc_threadinfo_succeeded && pth.pth_name[0] != '\0')
- printf ("thread name '%s' ", pth.pth_name);
+ printf (" thread name '%s' ", pth.pth_name);
- printf ("\n ");
- printf ("user %d.%06ds, system %d.%06ds",
+ printf (" user %d.%06ds, system %d.%06ds",
basic_info->user_time.seconds, basic_info->user_time.microseconds,
basic_info->system_time.seconds, basic_info->system_time.microseconds);
if (basic_info->cpu_usage > 0)
Index: aze/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
===================================================================
--- aze.orig/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj 2013-03-03 09:35:50.335457350 +0100
@@ -390,7 +390,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0430;
+ LastUpgradeCheck = 0500;
};
buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "debugserver" */;
compatibilityVersion = "Xcode 3.2";
@@ -485,10 +485,16 @@
x86_64,
i386,
);
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 193;
+ CURRENT_PROJECT_VERSION = 198;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = "";
@@ -507,10 +513,16 @@
armv7s,
);
"ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD_64_BIT)";
- CURRENT_PROJECT_VERSION = 193;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CURRENT_PROJECT_VERSION = 198;
DEAD_CODE_STRIPPING = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = "";
@@ -533,10 +545,16 @@
x86_64,
i386,
);
- CURRENT_PROJECT_VERSION = 193;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CURRENT_PROJECT_VERSION = 198;
DEAD_CODE_STRIPPING = YES;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
SDKROOT = "";
STRIPFLAGS = "-x";
@@ -554,14 +572,14 @@
CLANG_CXX_LIBRARY = "libc++";
"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist";
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 193;
+ CURRENT_PROJECT_VERSION = 198;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=iphoneos*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
"$(SDKROOT)/Developer/Library/PrivateFrameworks",
);
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=macosx*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_BUILDANDINTEGRATION;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -570,21 +588,21 @@
"INSTALL_PATH[sdk=iphoneos*]" = /Developer/usr/bin/;
LLDB_DEBUGSERVER = 1;
OTHER_CFLAGS = "-Wparentheses";
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
+ "OTHER_CFLAGS[arch=*][sdk=iphoneos*]" = (
"-Wparentheses",
"-DWITH_LOCKDOWN",
"-DWITH_SPRINGBOARD",
"-DUSE_ARM_DISASSEMBLER_FRAMEWORK",
"-DOS_OBJECT_USE_OBJC=0",
);
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
+ "OTHER_CPLUSPLUSFLAGS[arch=*][sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"-sectcreate",
__TEXT,
__info_plist,
"$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
);
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
+ "OTHER_LDFLAGS[arch=*][sdk=iphoneos*]" = (
"-framework",
SpringBoardServices,
"-framework",
@@ -610,13 +628,13 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 193;
+ CURRENT_PROJECT_VERSION = 198;
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=iphoneos*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
"$(SDKROOT)/Developer/Library/PrivateFrameworks",
);
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=macosx*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@@ -625,21 +643,21 @@
INSTALL_PATH = /usr/bin;
LLDB_DEBUGSERVER = 1;
OTHER_CFLAGS = "-Wparentheses";
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
+ "OTHER_CFLAGS[arch=*][sdk=iphoneos*]" = (
"-Wparentheses",
"-DWITH_LOCKDOWN",
"-DWITH_SPRINGBOARD",
"-DUSE_ARM_DISASSEMBLER_FRAMEWORK",
"-DOS_OBJECT_USE_OBJC=0",
);
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
+ "OTHER_CPLUSPLUSFLAGS[arch=*][sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"-sectcreate",
__TEXT,
__info_plist,
"$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
);
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
+ "OTHER_LDFLAGS[arch=*][sdk=iphoneos*]" = (
"-framework",
SpringBoardServices,
"-framework",
@@ -665,14 +683,14 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign;
COPY_PHASE_STRIP = YES;
- CURRENT_PROJECT_VERSION = 193;
+ CURRENT_PROJECT_VERSION = 198;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
- "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*][arch=*]" = (
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=iphoneos*]" = (
"$(SDKROOT)/System/Library/PrivateFrameworks",
"$(SDKROOT)/Developer/Library/PrivateFrameworks",
);
- "FRAMEWORK_SEARCH_PATHS[sdk=macosx*][arch=*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=macosx*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_RELEASE;
GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
@@ -680,21 +698,21 @@
INSTALL_PATH = /usr/bin;
LLDB_DEBUGSERVER = 1;
OTHER_CFLAGS = "-Wparentheses";
- "OTHER_CFLAGS[sdk=iphoneos*][arch=*]" = (
+ "OTHER_CFLAGS[arch=*][sdk=iphoneos*]" = (
"-Wparentheses",
"-DWITH_LOCKDOWN",
"-DWITH_SPRINGBOARD",
"-DUSE_ARM_DISASSEMBLER_FRAMEWORK",
"-DOS_OBJECT_USE_OBJC=0",
);
- "OTHER_CPLUSPLUSFLAGS[sdk=iphoneos*][arch=*]" = "$(OTHER_CFLAGS)";
+ "OTHER_CPLUSPLUSFLAGS[arch=*][sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"-sectcreate",
__TEXT,
__info_plist,
"$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
);
- "OTHER_LDFLAGS[sdk=iphoneos*][arch=*]" = (
+ "OTHER_LDFLAGS[arch=*][sdk=iphoneos*]" = (
"-framework",
SpringBoardServices,
"-framework",
@@ -711,6 +729,92 @@
};
name = Release;
};
+ 4968B7A916657FAE00741ABB /* DebugClang */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ "ARCHS[sdk=iphoneos*]" = (
+ armv7,
+ armv7s,
+ );
+ "ARCHS[sdk=macosx*]" = (
+ x86_64,
+ i386,
+ );
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ CURRENT_PROJECT_VERSION = 198;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = "";
+ STRIP_INSTALLED_PRODUCT = NO;
+ VALID_ARCHS = "armv4t armv5 armv6 armv7 armv7s i386 ppc ppc64 ppc7400 ppc970 x86_64";
+ VERSIONING_SYSTEM = "apple-generic";
+ VERSION_INFO_BUILDER = "$(USER)";
+ };
+ name = DebugClang;
+ };
+ 4968B7AA16657FAE00741ABB /* DebugClang */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = "source/debugserver-entitlements.plist";
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "-";
+ "CODE_SIGN_IDENTITY[sdk=macosx*]" = lldb_codesign;
+ COPY_PHASE_STRIP = YES;
+ CURRENT_PROJECT_VERSION = 198;
+ FRAMEWORK_SEARCH_PATHS = $SDKROOT/System/Library/PrivateFrameworks;
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=iphoneos*]" = (
+ "$(SDKROOT)/System/Library/PrivateFrameworks",
+ "$(SDKROOT)/Developer/Library/PrivateFrameworks",
+ );
+ "FRAMEWORK_SEARCH_PATHS[arch=*][sdk=macosx*]" = "$(SDKROOT)/System/Library/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = LLDB_DEBUGSERVER_DEBUG;
+ GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+ INSTALL_PATH = /usr/bin;
+ LLDB_DEBUGSERVER = 1;
+ OTHER_CFLAGS = "-Wparentheses";
+ "OTHER_CFLAGS[arch=*][sdk=iphoneos*]" = (
+ "-Wparentheses",
+ "-DWITH_LOCKDOWN",
+ "-DWITH_SPRINGBOARD",
+ "-DUSE_ARM_DISASSEMBLER_FRAMEWORK",
+ "-DOS_OBJECT_USE_OBJC=0",
+ );
+ "OTHER_CPLUSPLUSFLAGS[arch=*][sdk=iphoneos*]" = "$(OTHER_CFLAGS)";
+ OTHER_LDFLAGS = (
+ "-sectcreate",
+ __TEXT,
+ __info_plist,
+ "$(PROJECT_DIR)/resources/lldb-debugserver-Info.plist",
+ );
+ "OTHER_LDFLAGS[arch=*][sdk=iphoneos*]" = (
+ "-framework",
+ SpringBoardServices,
+ "-framework",
+ ARMDisassembler,
+ "-llockdown",
+ );
+ OTHER_MIGFLAGS = "-I$(DERIVED_FILE_DIR)";
+ PRODUCT_NAME = debugserver;
+ "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
+ "PROVISIONING_PROFILE[sdk=macosx*]" = "";
+ SKIP_INSTALL = YES;
+ USER_HEADER_SEARCH_PATHS = "./source ../../source $(DERIVED_SOURCES_DIR)";
+ ZERO_LINK = NO;
+ };
+ name = DebugClang;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -718,6 +822,7 @@
isa = XCConfigurationList;
buildConfigurations = (
1DEB914F08733D8E0010E9CD /* Debug */,
+ 4968B7A916657FAE00741ABB /* DebugClang */,
1DEB915008733D8E0010E9CD /* Release */,
262419A11198A93E00067686 /* BuildAndIntegration */,
);
@@ -728,6 +833,7 @@
isa = XCConfigurationList;
buildConfigurations = (
26CE0596115C31C30022F371 /* Debug */,
+ 4968B7AA16657FAE00741ABB /* DebugClang */,
26CE0597115C31C30022F371 /* Release */,
262419A21198A93E00067686 /* BuildAndIntegration */,
);
Index: aze/lldb/tools/debugserver/source/com.apple.debugserver.posix.plist
===================================================================
--- aze.orig/lldb/tools/debugserver/source/com.apple.debugserver.posix.plist 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/com.apple.debugserver.posix.plist 2013-03-03 09:35:50.335457350 +0100
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>Label</key>
- <string>com.apple.debugserver</string>
+ <string>com.apple.debugserver.posix</string>
<key>UserName</key>
<string>mobile</string>
<key>ProgramArguments</key>
Index: aze/lldb/tools/debugserver/source/debugserver.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/debugserver.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/debugserver.cpp 2013-03-03 09:35:50.335457350 +0100
@@ -93,7 +93,7 @@
if (set_events & RNBContext::event_read_thread_exiting)
{
- RNBLogSTDERR ("error: packet read thread exited.");
+ RNBLogSTDERR ("error: packet read thread exited.\n");
return eRNBRunLoopModeExit;
}
@@ -108,10 +108,13 @@
if (type == RNBRemote::vattach || type == RNBRemote::vattachwait || type == RNBRemote::vattachorwait)
{
if (err == rnb_success)
+ {
+ RNBLogSTDOUT ("Attach succeeded, ready to debug.\n");
return eRNBRunLoopModeInferiorExecuting;
+ }
else
{
- RNBLogSTDERR ("error: attach failed.");
+ RNBLogSTDERR ("error: attach failed.\n");
return eRNBRunLoopModeExit;
}
}
@@ -127,7 +130,7 @@
}
else if (err == rnb_not_connected)
{
- RNBLogSTDERR ("error: connection lost.");
+ RNBLogSTDERR ("error: connection lost.\n");
return eRNBRunLoopModeExit;
}
else
@@ -498,8 +501,9 @@
if (!ctx.ProcessStateRunning())
{
- // Clear the stdio bits if we are not running so we don't send any async packets
+ // Clear some bits if we are not running so we don't send any async packets
event_mask &= ~RNBContext::event_proc_stdio_available;
+ event_mask &= ~RNBContext::event_proc_profile_data;
}
// We want to make sure we consume all process state changes and have
@@ -519,6 +523,11 @@
remote->FlushSTDIO();
}
+ if (set_events & RNBContext::event_proc_profile_data)
+ {
+ remote->SendAsyncProfileData();
+ }
+
if (set_events & RNBContext::event_read_packet_available)
{
// handleReceivedPacket will take care of resetting the
@@ -1322,6 +1331,7 @@
ctx.SetLaunchFlavor(launch_flavor);
bool ignore_existing = false;
+ RNBLogSTDOUT ("Waiting to attach to process %s...\n", waitfor_pid_name.c_str());
nub_process_t pid = DNBProcessAttachWait (waitfor_pid_name.c_str(), launch_flavor, ignore_existing, timeout_ptr, waitfor_interval, err_str, sizeof(err_str));
g_pid = pid;
@@ -1330,7 +1340,7 @@
ctx.LaunchStatus().SetError(-1, DNBError::Generic);
if (err_str[0])
ctx.LaunchStatus().SetErrorString(err_str);
- RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s", waitfor_pid_name.c_str(), err_str);
+ RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s\n", waitfor_pid_name.c_str(), err_str);
mode = eRNBRunLoopModeExit;
}
else
@@ -1361,6 +1371,7 @@
timeout_ptr = &attach_timeout_abstime;
}
+ RNBLogSTDOUT ("Attaching to process %s...\n", attach_pid_name.c_str());
nub_process_t pid = DNBProcessAttachByName (attach_pid_name.c_str(), timeout_ptr, err_str, sizeof(err_str));
g_pid = pid;
if (pid == INVALID_NUB_PROCESS)
@@ -1368,7 +1379,7 @@
ctx.LaunchStatus().SetError(-1, DNBError::Generic);
if (err_str[0])
ctx.LaunchStatus().SetErrorString(err_str);
- RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s", waitfor_pid_name.c_str(), err_str);
+ RNBLogSTDERR ("error: failed to attach to process named: \"%s\" %s\n", waitfor_pid_name.c_str(), err_str);
mode = eRNBRunLoopModeExit;
}
else
@@ -1380,7 +1391,7 @@
}
else
{
- RNBLogSTDERR ("error: asked to attach with empty name and invalid PID.");
+ RNBLogSTDERR ("error: asked to attach with empty name and invalid PID.\n");
mode = eRNBRunLoopModeExit;
}
@@ -1397,7 +1408,7 @@
mode = eRNBRunLoopModeExit;
}
if (mode != eRNBRunLoopModeExit)
- RNBLogSTDOUT ("Got a connection, waiting for debugger instructions for process %d.\n", attach_pid);
+ RNBLogSTDOUT ("Waiting for debugger instructions for process %d.\n", attach_pid);
}
break;
@@ -1423,7 +1434,7 @@
}
if (mode != eRNBRunLoopModeExit)
- RNBLogSTDOUT ("Got a connection, waiting for debugger instructions.\n");
+ RNBLogSTDOUT ("Got a connection, launched process %s.\n", argv_sub_zero);
}
else
{
@@ -1462,6 +1473,7 @@
remote->StopReadRemoteDataThread ();
remote->Context().SetProcessID(INVALID_NUB_PROCESS);
+ RNBLogSTDOUT ("Exiting.\n");
return 0;
}
Index: aze/lldb/tools/debugserver/source/DNBBreakpoint.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNBBreakpoint.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNBBreakpoint.cpp 2013-03-03 09:35:50.335457350 +0100
@@ -13,6 +13,7 @@
#include "DNBBreakpoint.h"
#include <algorithm>
+#include <inttypes.h>
#include "DNBLog.h"
@@ -77,7 +78,7 @@
{
if (IsBreakpoint())
{
- DNBLog ("DNBBreakpoint %u: tid = %4.4x addr = 0x%llx state = %s type = %s breakpoint hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
+ DNBLog ("DNBBreakpoint %u: tid = %8.8" PRIx64 " addr = 0x%llx state = %s type = %s breakpoint hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
m_breakID,
m_tid,
(uint64_t)m_addr,
@@ -91,7 +92,7 @@
}
else
{
- DNBLog ("DNBBreakpoint %u: tid = %4.4x addr = 0x%llx size = %llu state = %s type = %s watchpoint (%s%s) hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
+ DNBLog ("DNBBreakpoint %u: tid = %8.8" PRIx64 " addr = 0x%llx size = %llu state = %s type = %s watchpoint (%s%s) hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %p baton = %p",
m_breakID,
m_tid,
(uint64_t)m_addr,
Index: aze/lldb/tools/debugserver/source/DNB.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNB.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNB.cpp 2013-03-03 09:35:50.335457350 +0100
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "DNB.h"
+#include <inttypes.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -255,6 +256,7 @@
// We failed to get the task for our process ID which is bad.
// Kill our process otherwise it will be stopped at the entry
// point and get reparented to someone else and never go away.
+ DNBLog ("Could not get task port for process, sending SIGKILL and exiting.");
kill (SIGKILL, pid);
if (err_str && err_len > 0)
@@ -1217,6 +1219,28 @@
return -1;
}
+std::string
+DNBProcessGetProfileData (nub_process_t pid)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ return procSP->Task().GetProfileData();
+
+ return std::string("");
+}
+
+nub_bool_t
+DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ {
+ procSP->SetEnableAsyncProfiling(enable, interval_usec);
+ return true;
+ }
+
+ return false;
+}
//----------------------------------------------------------------------
// Formatted output that uses memory and registers from process and
@@ -1362,7 +1386,7 @@
}
else
{
- fprintf(file, "error: unable to read register '%s' for process %#.4x and thread %#.4x\n", register_name.c_str(), pid, tid);
+ fprintf(file, "error: unable to read register '%s' for process %#.4x and thread %#.8" PRIx64 "\n", register_name.c_str(), pid, tid);
return total_bytes_read;
}
}
@@ -2071,6 +2095,15 @@
return 0;
}
+nub_size_t
+DNBProcessGetAvailableProfileData (nub_process_t pid, char *buf, nub_size_t buf_size)
+{
+ MachProcessSP procSP;
+ if (GetProcessSP (pid, procSP))
+ return procSP->GetAsyncProfileData (buf, buf_size);
+ return 0;
+}
+
nub_size_t
DNBProcessGetStopCount (nub_process_t pid)
{
Index: aze/lldb/tools/debugserver/source/DNBDataRef.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNBDataRef.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNBDataRef.cpp 2013-03-03 09:35:50.335457350 +0100
@@ -195,105 +195,6 @@
assert(m_ptrSize != 0);
return GetMax64(offset_ptr, m_ptrSize);
}
-
-//----------------------------------------------------------------------
-// GetDwarfEHPtr
-//
-// Used for calls when the value type is specified by a DWARF EH Frame
-// pointer encoding.
-//----------------------------------------------------------------------
-/*
-uint64_t
-DNBDataRef::GetDwarfEHPtr(offset_t *offset_ptr, uint32_t encoding) const
-{
- if (encoding == DW_EH_PE_omit)
- return ULLONG_MAX; // Value isn't in the buffer...
-
- uint64_t baseAddress = 0;
- uint64_t addressValue = 0;
-
- BOOL signExtendValue = NO;
- // Decode the base part or adjust our offset
- switch (encoding & 0x70)
- {
- case DW_EH_PE_pcrel:
- // SetEHPtrBaseAddresses should be called prior to extracting these
- // so the base addresses are cached.
- assert(m_addrPCRelative != INVALID_NUB_ADDRESS);
- signExtendValue = YES;
- baseAddress = *offset_ptr + m_addrPCRelative;
- break;
-
- case DW_EH_PE_textrel:
- // SetEHPtrBaseAddresses should be called prior to extracting these
- // so the base addresses are cached.
- assert(m_addrTEXT != INVALID_NUB_ADDRESS);
- signExtendValue = YES;
- baseAddress = m_addrTEXT;
- break;
-
- case DW_EH_PE_datarel:
- // SetEHPtrBaseAddresses should be called prior to extracting these
- // so the base addresses are cached.
- assert(m_addrDATA != INVALID_NUB_ADDRESS);
- signExtendValue = YES;
- baseAddress = m_addrDATA;
- break;
-
- case DW_EH_PE_funcrel:
- signExtendValue = YES;
- break;
-
- case DW_EH_PE_aligned:
- // SetPointerSize should be called prior to extracting these so the
- // pointer size is cached
- assert(m_ptrSize != 0);
- if (m_ptrSize)
- {
- // Align to a address size boundary first
- uint32_t alignOffset = *offset_ptr % m_ptrSize;
- if (alignOffset)
- offset_ptr += m_ptrSize - alignOffset;
- }
- break;
-
- default:
- break;
- }
-
- // Decode the value part
- switch (encoding & DW_EH_PE_MASK_ENCODING)
- {
- case DW_EH_PE_absptr : addressValue = GetPointer(offset_ptr); break;
- case DW_EH_PE_uleb128 : addressValue = Get_ULEB128(offset_ptr); break;
- case DW_EH_PE_udata2 : addressValue = Get16(offset_ptr); break;
- case DW_EH_PE_udata4 : addressValue = Get32(offset_ptr); break;
- case DW_EH_PE_udata8 : addressValue = Get64(offset_ptr); break;
- case DW_EH_PE_sleb128 : addressValue = Get_SLEB128(offset_ptr); break;
- case DW_EH_PE_sdata2 : addressValue = (int16_t)Get16(offset_ptr); break;
- case DW_EH_PE_sdata4 : addressValue = (int32_t)Get32(offset_ptr); break;
- case DW_EH_PE_sdata8 : addressValue = (int64_t)Get64(offset_ptr); break;
- default:
- // Unhandled encoding type
- assert(encoding);
- break;
- }
-
- // Since we promote everything to 64 bit, we may need to sign extend
- if (signExtendValue && m_ptrSize < sizeof(baseAddress))
- {
- uint64_t sign_bit = 1ull << ((m_ptrSize * 8ull) - 1ull);
- if (sign_bit & addressValue)
- {
- uint64_t mask = ~sign_bit + 1;
- addressValue |= mask;
- }
- }
- return baseAddress + addressValue;
-}
-*/
-
-
//----------------------------------------------------------------------
// GetCStr
//----------------------------------------------------------------------
Index: aze/lldb/tools/debugserver/source/DNBDefs.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNBDefs.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNBDefs.h 2013-03-03 09:35:50.335457350 +0100
@@ -73,7 +73,7 @@
typedef uint32_t nub_watch_t;
typedef uint32_t nub_index_t;
typedef pid_t nub_process_t;
-typedef unsigned int nub_thread_t;
+typedef uint64_t nub_thread_t;
typedef uint32_t nub_event_t;
typedef uint32_t nub_bool_t;
@@ -134,11 +134,13 @@
eEventProcessStoppedStateChanged = 1 << 1, // The process has changed state to stopped
eEventSharedLibsStateChange = 1 << 2, // Shared libraries loaded/unloaded state has changed
eEventStdioAvailable = 1 << 3, // Something is available on stdout/stderr
- eEventProcessAsyncInterrupt = 1 << 4, // Gives the ability for any infinite wait calls to be interrupted
+ eEventProfileDataAvailable = 1 << 4, // Profile data ready for retrieval
+ eEventProcessAsyncInterrupt = 1 << 5, // Gives the ability for any infinite wait calls to be interrupted
kAllEventsMask = eEventProcessRunningStateChanged |
eEventProcessStoppedStateChanged |
eEventSharedLibsStateChange |
eEventStdioAvailable |
+ eEventProfileDataAvailable |
eEventProcessAsyncInterrupt
};
@@ -228,6 +230,8 @@
uint32_t reg_dwarf; // DWARF register number (INVALID_NUB_REGNUM when none)
uint32_t reg_generic; // Generic register number (INVALID_NUB_REGNUM when none)
uint32_t reg_gdb; // The GDB register number (INVALID_NUB_REGNUM when none)
+ uint32_t *pseudo_regs; // If this register is a part of another register, list the one or more registers
+ uint32_t *update_regs; // If modifying this register will invalidate other registers, list them here
};
struct DNBRegisterSetInfo
Index: aze/lldb/tools/debugserver/source/DNB.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNB.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNB.h 2013-03-03 09:35:50.335457350 +0100
@@ -17,10 +17,6 @@
#include "DNBDefs.h"
#include <mach/thread_info.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#define DNB_EXPORT __attribute__((visibility("default")))
typedef bool (*DNBShouldCancelCallback) (void *);
@@ -67,6 +63,8 @@
nub_addr_t DNBProcessMemoryAllocate (nub_process_t pid, nub_size_t size, uint32_t permissions) DNB_EXPORT;
nub_bool_t DNBProcessMemoryDeallocate (nub_process_t pid, nub_addr_t addr) DNB_EXPORT;
int DNBProcessMemoryRegionInfo (nub_process_t pid, nub_addr_t addr, DNBRegionInfo *region_info) DNB_EXPORT;
+std::string DNBProcessGetProfileData (nub_process_t pid) DNB_EXPORT;
+nub_bool_t DNBProcessSetEnableAsyncProfiling (nub_process_t pid, nub_bool_t enable, uint64_t interval_usec) DNB_EXPORT;
//----------------------------------------------------------------------
// Process status
@@ -88,6 +86,7 @@
nub_addr_t DNBProcessLookupAddress (nub_process_t pid, const char *name, const char *shlib) DNB_EXPORT;
nub_size_t DNBProcessGetAvailableSTDOUT (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
nub_size_t DNBProcessGetAvailableSTDERR (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
+nub_size_t DNBProcessGetAvailableProfileData (nub_process_t pid, char *buf, nub_size_t buf_size) DNB_EXPORT;
nub_size_t DNBProcessGetStopCount (nub_process_t pid) DNB_EXPORT;
uint32_t DNBProcessGetCPUType (nub_process_t pid) DNB_EXPORT;
@@ -157,8 +156,4 @@
const char * DNBStateAsString (nub_state_t state) DNB_EXPORT;
nub_bool_t DNBResolveExecutablePath (const char *path, char *resolved_path, size_t resolved_path_size) DNB_EXPORT;
-#ifdef __cplusplus
-}
-#endif
-
#endif
Index: aze/lldb/tools/debugserver/source/DNBLog.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNBLog.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNBLog.cpp 2013-03-03 09:35:50.335457350 +0100
@@ -84,6 +84,12 @@
g_log_baton = baton;
}
+DNBCallbackLog
+DNBLogGetLogCallback ()
+{
+ return g_log_callback;
+}
+
bool
DNBLogEnabled ()
{
Index: aze/lldb/tools/debugserver/source/DNBLog.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/DNBLog.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/DNBLog.h 2013-03-03 09:35:50.339457350 +0100
@@ -50,6 +50,7 @@
uint32_t DNBLogSetLogMask (uint32_t mask) DNB_EXPORT;
uint32_t DNBLogGetLogMask () DNB_EXPORT;
void DNBLogSetLogCallback (DNBCallbackLog callback, void *baton) DNB_EXPORT;
+DNBCallbackLog DNBLogGetLogCallback () DNB_EXPORT;
bool DNBLogEnabled () DNB_EXPORT;
bool DNBLogEnabledForAny (uint32_t mask) DNB_EXPORT;
int DNBLogGetDebug () DNB_EXPORT;
Index: aze/lldb/tools/debugserver/source/libdebugserver.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/tools/debugserver/source/libdebugserver.cpp 2013-03-03 09:35:50.339457350 +0100
@@ -0,0 +1,397 @@
+//===-- libdebugserver.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <getopt.h>
+#include <netinet/in.h>
+#include <sys/select.h>
+#include <sys/sysctl.h>
+
+#include "DNB.h"
+#include "DNBLog.h"
+#include "DNBTimer.h"
+#include "PseudoTerminal.h"
+#include "RNBContext.h"
+#include "RNBServices.h"
+#include "RNBSocket.h"
+#include "RNBRemote.h"
+#include "SysSignal.h"
+
+//----------------------------------------------------------------------
+// Run loop modes which determine which run loop function will be called
+//----------------------------------------------------------------------
+typedef enum
+{
+ eRNBRunLoopModeInvalid = 0,
+ eRNBRunLoopModeGetStartModeFromRemoteProtocol,
+ eRNBRunLoopModeInferiorExecuting,
+ eRNBRunLoopModeExit
+} RNBRunLoopMode;
+
+
+//----------------------------------------------------------------------
+// Global Variables
+//----------------------------------------------------------------------
+RNBRemoteSP g_remoteSP;
+int g_disable_aslr = 0;
+int g_isatty = 0;
+
+#define RNBLogSTDOUT(fmt, ...) do { if (g_isatty) { fprintf(stdout, fmt, ## __VA_ARGS__); } else { _DNBLog(0, fmt, ## __VA_ARGS__); } } while (0)
+#define RNBLogSTDERR(fmt, ...) do { if (g_isatty) { fprintf(stderr, fmt, ## __VA_ARGS__); } else { _DNBLog(0, fmt, ## __VA_ARGS__); } } while (0)
+
+
+//----------------------------------------------------------------------
+// Get our program path and arguments from the remote connection.
+// We will need to start up the remote connection without a PID, get the
+// arguments, wait for the new process to finish launching and hit its
+// entry point, and then return the run loop mode that should come next.
+//----------------------------------------------------------------------
+RNBRunLoopMode
+RNBRunLoopGetStartModeFromRemote (RNBRemoteSP &remoteSP)
+{
+ std::string packet;
+
+ if (remoteSP.get() != NULL)
+ {
+ RNBRemote* remote = remoteSP.get();
+ RNBContext& ctx = remote->Context();
+ uint32_t event_mask = RNBContext::event_read_packet_available;
+
+ // Spin waiting to get the A packet.
+ while (1)
+ {
+ DNBLogThreadedIf (LOG_RNB_MAX, "%s ctx.Events().WaitForSetEvents( 0x%08x ) ...",__FUNCTION__, event_mask);
+ nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
+ DNBLogThreadedIf (LOG_RNB_MAX, "%s ctx.Events().WaitForSetEvents( 0x%08x ) => 0x%08x", __FUNCTION__, event_mask, set_events);
+
+ if (set_events & RNBContext::event_read_packet_available)
+ {
+ rnb_err_t err = rnb_err;
+ RNBRemote::PacketEnum type;
+
+ err = remote->HandleReceivedPacket (&type);
+
+ // check if we tried to attach to a process
+ if (type == RNBRemote::vattach || type == RNBRemote::vattachwait)
+ {
+ if (err == rnb_success)
+ return eRNBRunLoopModeInferiorExecuting;
+ else
+ {
+ RNBLogSTDERR ("error: attach failed.");
+ return eRNBRunLoopModeExit;
+ }
+ }
+
+
+ if (err == rnb_success)
+ {
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s Got success...",__FUNCTION__);
+ continue;
+ }
+ else if (err == rnb_not_connected)
+ {
+ RNBLogSTDERR ("error: connection lost.");
+ return eRNBRunLoopModeExit;
+ }
+ else
+ {
+ // a catch all for any other gdb remote packets that failed
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s Error getting packet.",__FUNCTION__);
+ continue;
+ }
+
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
+ }
+ else
+ {
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s Connection closed before getting \"A\" packet.", __FUNCTION__);
+ return eRNBRunLoopModeExit;
+ }
+ }
+ }
+ return eRNBRunLoopModeExit;
+}
+
+
+//----------------------------------------------------------------------
+// Watch for signals:
+// SIGINT: so we can halt our inferior. (disabled for now)
+// SIGPIPE: in case our child process dies
+//----------------------------------------------------------------------
+nub_process_t g_pid;
+int g_sigpipe_received = 0;
+void
+signal_handler(int signo)
+{
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (%s)", __FUNCTION__, SysSignal::Name(signo));
+
+ switch (signo)
+ {
+ // case SIGINT:
+ // DNBProcessKill (g_pid, signo);
+ // break;
+
+ case SIGPIPE:
+ g_sigpipe_received = 1;
+ break;
+ }
+}
+
+// Return the new run loop mode based off of the current process state
+RNBRunLoopMode
+HandleProcessStateChange (RNBRemoteSP &remote, bool initialize)
+{
+ RNBContext& ctx = remote->Context();
+ nub_process_t pid = ctx.ProcessID();
+
+ if (pid == INVALID_NUB_PROCESS)
+ {
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "#### %s error: pid invalid, exiting...", __FUNCTION__);
+ return eRNBRunLoopModeExit;
+ }
+ nub_state_t pid_state = DNBProcessGetState (pid);
+
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state));
+
+ switch (pid_state)
+ {
+ case eStateInvalid:
+ case eStateUnloaded:
+ // Something bad happened
+ return eRNBRunLoopModeExit;
+ break;
+
+ case eStateAttaching:
+ case eStateLaunching:
+ return eRNBRunLoopModeInferiorExecuting;
+
+ case eStateSuspended:
+ case eStateCrashed:
+ case eStateStopped:
+ if (initialize == false)
+ {
+ // Compare the last stop count to our current notion of a stop count
+ // to make sure we don't notify more than once for a given stop.
+ nub_size_t prev_pid_stop_count = ctx.GetProcessStopCount();
+ bool pid_stop_count_changed = ctx.SetProcessStopCount(DNBProcessGetStopCount(pid));
+ if (pid_stop_count_changed)
+ {
+ remote->FlushSTDIO();
+
+ if (ctx.GetProcessStopCount() == 1)
+ {
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s pid_stop_count %u (old %u)) Notify??? no, first stop...", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state), ctx.GetProcessStopCount(), prev_pid_stop_count);
+ }
+ else
+ {
+
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s pid_stop_count %u (old %u)) Notify??? YES!!!", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state), ctx.GetProcessStopCount(), prev_pid_stop_count);
+ remote->NotifyThatProcessStopped ();
+ }
+ }
+ else
+ {
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "%s (&remote, initialize=%i) pid_state = %s pid_stop_count %u (old %u)) Notify??? skipping...", __FUNCTION__, (int)initialize, DNBStateAsString (pid_state), ctx.GetProcessStopCount(), prev_pid_stop_count);
+ }
+ }
+ return eRNBRunLoopModeInferiorExecuting;
+
+ case eStateStepping:
+ case eStateRunning:
+ return eRNBRunLoopModeInferiorExecuting;
+
+ case eStateExited:
+ remote->HandlePacket_last_signal(NULL);
+ return eRNBRunLoopModeExit;
+ case eStateDetached:
+ return eRNBRunLoopModeExit;
+
+ }
+
+ // Catch all...
+ return eRNBRunLoopModeExit;
+}
+// This function handles the case where our inferior program is stopped and
+// we are waiting for gdb remote protocol packets. When a packet occurs that
+// makes the inferior run, we need to leave this function with a new state
+// as the return code.
+RNBRunLoopMode
+RNBRunLoopInferiorExecuting (RNBRemoteSP &remote)
+{
+ DNBLogThreadedIf (LOG_RNB_MINIMAL, "#### %s", __FUNCTION__);
+ RNBContext& ctx = remote->Context();
+
+ // Init our mode and set 'is_running' based on the current process state
+ RNBRunLoopMode mode = HandleProcessStateChange (remote, true);
+
+ while (ctx.ProcessID() != INVALID_NUB_PROCESS)
+ {
+
+ std::string set_events_str;
+ uint32_t event_mask = ctx.NormalEventBits();
+
+ if (!ctx.ProcessStateRunning())
+ {
+ // Clear the stdio bits if we are not running so we don't send any async packets
+ event_mask &= ~RNBContext::event_proc_stdio_available;
+ }
+
+ // We want to make sure we consume all process state changes and have
+ // whomever is notifying us to wait for us to reset the event bit before
+ // continuing.
+ //ctx.Events().SetResetAckMask (RNBContext::event_proc_state_changed);
+
+ DNBLogThreadedIf (LOG_RNB_EVENTS, "%s ctx.Events().WaitForSetEvents(0x%08x) ...",__FUNCTION__, event_mask);
+ nub_event_t set_events = ctx.Events().WaitForSetEvents(event_mask);
+ DNBLogThreadedIf (LOG_RNB_EVENTS, "%s ctx.Events().WaitForSetEvents(0x%08x) => 0x%08x (%s)",__FUNCTION__, event_mask, set_events, ctx.EventsAsString(set_events, set_events_str));
+
+ if (set_events)
+ {
+ if ((set_events & RNBContext::event_proc_thread_exiting) ||
+ (set_events & RNBContext::event_proc_stdio_available))
+ {
+ remote->FlushSTDIO();
+ }
+
+ if (set_events & RNBContext::event_read_packet_available)
+ {
+ // handleReceivedPacket will take care of resetting the
+ // event_read_packet_available events when there are no more...
+ set_events ^= RNBContext::event_read_packet_available;
+
+ if (ctx.ProcessStateRunning())
+ {
+ if (remote->HandleAsyncPacket() == rnb_not_connected)
+ {
+ // TODO: connect again? Exit?
+ }
+ }
+ else
+ {
+ if (remote->HandleReceivedPacket() == rnb_not_connected)
+ {
+ // TODO: connect again? Exit?
+ }
+ }
+ }
+
+ if (set_events & RNBContext::event_proc_state_changed)
+ {
+ mode = HandleProcessStateChange (remote, false);
+ ctx.Events().ResetEvents(RNBContext::event_proc_state_changed);
+ set_events ^= RNBContext::event_proc_state_changed;
+ }
+
+ if (set_events & RNBContext::event_proc_thread_exiting)
+ {
+ mode = eRNBRunLoopModeExit;
+ }
+
+ if (set_events & RNBContext::event_read_thread_exiting)
+ {
+ // Out remote packet receiving thread exited, exit for now.
+ if (ctx.HasValidProcessID())
+ {
+ // TODO: We should add code that will leave the current process
+ // in its current state and listen for another connection...
+ if (ctx.ProcessStateRunning())
+ {
+ DNBProcessKill (ctx.ProcessID(), SIGINT);
+ }
+ }
+ mode = eRNBRunLoopModeExit;
+ }
+ }
+
+ // Reset all event bits that weren't reset for now...
+ if (set_events != 0)
+ ctx.Events().ResetEvents(set_events);
+
+ if (mode != eRNBRunLoopModeInferiorExecuting)
+ break;
+ }
+
+ return mode;
+}
+
+void
+ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args)
+{
+#if 0
+ vprintf(format, args);
+#endif
+}
+
+extern "C" int
+debug_server_main(int fd)
+{
+#if 1
+ g_isatty = 0;
+#else
+ g_isatty = ::isatty (STDIN_FILENO);
+
+ DNBLogSetDebug(1);
+ DNBLogSetVerbose(1);
+ DNBLogSetLogMask(-1);
+ DNBLogSetLogCallback(ASLLogCallback, NULL);
+#endif
+
+ signal (SIGPIPE, signal_handler);
+
+ g_remoteSP.reset (new RNBRemote);
+
+ RNBRemote *remote = g_remoteSP.get();
+ if (remote == NULL)
+ {
+ RNBLogSTDERR ("error: failed to create a remote connection class\n");
+ return -1;
+ }
+
+
+ RNBRunLoopMode mode = eRNBRunLoopModeGetStartModeFromRemoteProtocol;
+
+ while (mode != eRNBRunLoopModeExit)
+ {
+ switch (mode)
+ {
+ case eRNBRunLoopModeGetStartModeFromRemoteProtocol:
+ if (g_remoteSP->Comm().useFD(fd) == rnb_success) {
+ RNBLogSTDOUT("Starting remote data thread.\n");
+ g_remoteSP->StartReadRemoteDataThread();
+
+ RNBLogSTDOUT("Waiting for start mode from remote.\n");
+ mode = RNBRunLoopGetStartModeFromRemote(g_remoteSP);
+ }
+ else
+ {
+ mode = eRNBRunLoopModeExit;
+ }
+ break;
+
+ case eRNBRunLoopModeInferiorExecuting:
+ mode = RNBRunLoopInferiorExecuting(g_remoteSP);
+ break;
+
+ default:
+ mode = eRNBRunLoopModeExit;
+ break;
+
+ case eRNBRunLoopModeExit:
+ break;
+ }
+ }
+
+ g_remoteSP->StopReadRemoteDataThread ();
+ g_remoteSP->Context().SetProcessID(INVALID_NUB_PROCESS);
+
+ return 0;
+}
Index: aze/lldb/tools/debugserver/source/libdebugserver.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/tools/debugserver/source/libdebugserver.h 2013-03-03 09:35:50.339457350 +0100
@@ -0,0 +1,15 @@
+//===-- libdebugserver.h ----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef debugserver_libdebugserver_h
+#define debugserver_libdebugserver_h
+
+int debug_server_main(int fd);
+
+#endif
Index: aze/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp 2013-03-03 09:35:50.339457350 +0100
@@ -188,10 +188,10 @@
// Read the registers from our thread
mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
uint32_t *r = &m_state.context.gpr.__r[0];
DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count = %u) regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x",
- m_thread->ThreadID(),
+ m_thread->MachPortNumber(),
ARM_THREAD_STATE,
ARM_THREAD_STATE_COUNT,
kret,
@@ -227,12 +227,12 @@
// Read the registers from our thread
mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
if (DNBLogEnabledForAny (LOG_THREAD))
{
uint32_t *r = &m_state.context.vfp.__r[0];
DNBLogThreaded ("thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x (count => %u)",
- m_thread->ThreadID(),
+ m_thread->MachPortNumber(),
ARM_THREAD_STATE,
ARM_THREAD_STATE_COUNT,
kret,
@@ -260,7 +260,7 @@
// Read the registers from our thread
mach_msg_type_number_t count = ARM_EXCEPTION_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
m_state.SetError(set, Read, kret);
return kret;
}
@@ -287,7 +287,7 @@
// Read the registers from our thread
mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT;
- kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
+ kern_return_t kret = ::thread_get_state(m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
m_state.SetError(set, Read, kret);
return kret;
}
@@ -296,7 +296,7 @@
DNBArchMachARM::SetGPRState()
{
int set = e_regSetGPR;
- kern_return_t kret = ::thread_set_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state(m_thread->MachPortNumber(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -306,7 +306,7 @@
DNBArchMachARM::SetVFPState()
{
int set = e_regSetVFP;
- kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -316,7 +316,7 @@
DNBArchMachARM::SetEXCState()
{
int set = e_regSetEXC;
- kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -326,7 +326,7 @@
DNBArchMachARM::SetDBGState()
{
int set = e_regSetDBG;
- kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
+ kern_return_t kret = ::thread_set_state (m_thread->MachPortNumber(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
m_state.SetError(set, Write, kret); // Set the current write error for this register set
m_state.InvalidateRegisterSetState(set); // Invalidate the current register state in case registers are read back differently
return kret; // Return the error code
@@ -2450,6 +2450,8 @@
(write ? WCR_STORE : 0) | // Stop on write access?
WCR_ENABLE; // Enable this watchpoint;
+ DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() adding watchpoint on address 0x%llx with control register value 0x%x", (uint64_t) m_state.dbg.__wvr[i], (uint32_t) m_state.dbg.__wcr[i]);
+
kret = SetDBGState();
//DumpDBGState(m_state.dbg);
@@ -2841,13 +2843,28 @@
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
-#define DEFINE_GPR_NAME(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
+#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, gdb_##reg, NULL, NULL}
+#define DEFINE_GPR_NAME(reg, alt, gen, inval) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg, NULL, inval}
//#define FLOAT_FORMAT Float
#define FLOAT_FORMAT Hex
-#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
+#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, FLOAT_FORMAT, 4, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx, NULL, NULL}
//#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, Float, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, gdb_d##idx }
-#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
+#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, FLOAT_FORMAT, 8, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_d##idx, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
+
+// In case we are debugging to a debug target that the ability to
+// change into the protected modes with folded registers (ABT, IRQ,
+// FIQ, SYS, USR, etc..), we should invalidate r8-r14 if the CPSR
+// gets modified.
+
+uint32_t g_invalidate_cpsr[] = {
+ gpr_r8,
+ gpr_r9,
+ gpr_r10,
+ gpr_r11,
+ gpr_r12,
+ gpr_sp,
+ gpr_lr,
+ INVALID_NUB_REGNUM };
// General purpose registers
const DNBRegisterInfo
@@ -2866,10 +2883,10 @@
DEFINE_GPR_IDX (10, r10, NULL, INVALID_NUB_REGNUM ),
DEFINE_GPR_IDX (11, r11, NULL, INVALID_NUB_REGNUM ),
DEFINE_GPR_IDX (12, r12, NULL, INVALID_NUB_REGNUM ),
- DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP ),
- DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA ),
- DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC ),
- DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS )
+ DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP, NULL),
+ DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA, NULL),
+ DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC, NULL),
+ DEFINE_GPR_NAME (cpsr, "flags", GENERIC_REGNUM_FLAGS, g_invalidate_cpsr)
};
// Floating point registers
@@ -2940,7 +2957,7 @@
DEFINE_VFP_D_IDX (29),
DEFINE_VFP_D_IDX (30),
DEFINE_VFP_D_IDX (31),
- { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr }
+ { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, Hex, 4, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr, NULL, NULL }
};
// Exception registers
Index: aze/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp 2013-03-03 09:35:50.339457350 +0100
@@ -83,6 +83,26 @@
gpr_es = 13,
gpr_fs = 14,
gpr_gs = 15,
+ gpr_ax ,
+ gpr_bx ,
+ gpr_cx ,
+ gpr_dx ,
+ gpr_di ,
+ gpr_si ,
+ gpr_bp ,
+ gpr_sp ,
+ gpr_ah ,
+ gpr_bh ,
+ gpr_ch ,
+ gpr_dh ,
+ gpr_al ,
+ gpr_bl ,
+ gpr_cl ,
+ gpr_dl ,
+ gpr_dil,
+ gpr_sil,
+ gpr_bpl,
+ gpr_spl,
k_num_gpr_regs
};
@@ -314,7 +334,7 @@
m_state.SetError(e_regSetGPR, Read, 0);
#else
mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
+ m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
#endif
}
return m_state.GetError(e_regSetGPR, Read);
@@ -463,17 +483,17 @@
if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
- m_state.SetError (e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
+ m_state.SetError (e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, %u (%u passed in)) => 0x%8.8x",
- m_thread->ThreadID(), __i386_AVX_STATE, count, e_regSetWordSizeAVX,
+ m_thread->MachPortNumber(), __i386_AVX_STATE, count, e_regSetWordSizeAVX,
m_state.GetError(e_regSetFPU, Read));
}
else
{
mach_msg_type_number_t count = e_regSetWordSizeFPU;
- m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
+ m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, %u (%u passed in) => 0x%8.8x",
- m_thread->ThreadID(), __i386_FLOAT_STATE, count, e_regSetWordSizeFPU,
+ m_thread->MachPortNumber(), __i386_FLOAT_STATE, count, e_regSetWordSizeFPU,
m_state.GetError(e_regSetFPU, Read));
}
}
@@ -487,7 +507,7 @@
if (force || m_state.GetError(e_regSetEXC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
+ m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
}
return m_state.GetError(e_regSetEXC, Read);
}
@@ -495,7 +515,7 @@
kern_return_t
DNBArchImplI386::SetGPRState()
{
- m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
+ m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
return m_state.GetError(e_regSetGPR, Write);
}
@@ -510,9 +530,9 @@
else
{
if (CPUHasAVX() || FORCE_AVX_REGS)
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
else
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
return m_state.GetError(e_regSetFPU, Write);
}
}
@@ -520,7 +540,7 @@
kern_return_t
DNBArchImplI386::SetEXCState()
{
- m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
+ m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
return m_state.GetError(e_regSetEXC, Write);
}
@@ -530,7 +550,7 @@
if (force || m_state.GetError(e_regSetDBG, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeDBG;
- m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->ThreadID(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
+ m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->MachPortNumber(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
}
return m_state.GetError(e_regSetDBG, Read);
}
@@ -538,7 +558,7 @@
kern_return_t
DNBArchImplI386::SetDBGState()
{
- m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->ThreadID(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
+ m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->MachPortNumber(), __i386_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
return m_state.GetError(e_regSetDBG, Write);
}
@@ -821,7 +841,7 @@
bool
DNBArchImplI386::StartTransForHWP()
{
- if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back)
DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
m_2pc_dbg_checkpoint = m_state.context.dbg;
m_2pc_trans_state = Trans_Pending;
@@ -997,6 +1017,10 @@
// Register information defintions
//----------------------------------------------------------------------
+#define DEFINE_GPR_PSEUDO_16(reg16,reg32) { e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, GPR_OFFSET(reg32) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 }
+#define DEFINE_GPR_PSEUDO_8H(reg8,reg32) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg32)+1,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 }
+#define DEFINE_GPR_PSEUDO_8L(reg8,reg32) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg32) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg32, g_invalidate_##reg32 }
+
#define GPR_OFFSET(reg) (offsetof (DNBArchImplI386::GPR, __##reg))
#define FPU_OFFSET(reg) (offsetof (DNBArchImplI386::FPU, __fpu_##reg) + offsetof (DNBArchImplI386::Context, fpu.no_avx))
@@ -1022,110 +1046,148 @@
// the register state structures are defined correctly and have the correct
// sizes and offsets.
+uint32_t g_contained_eax[] = { gpr_eax, INVALID_NUB_REGNUM };
+uint32_t g_contained_ebx[] = { gpr_ebx, INVALID_NUB_REGNUM };
+uint32_t g_contained_ecx[] = { gpr_ecx, INVALID_NUB_REGNUM };
+uint32_t g_contained_edx[] = { gpr_edx, INVALID_NUB_REGNUM };
+uint32_t g_contained_edi[] = { gpr_edi, INVALID_NUB_REGNUM };
+uint32_t g_contained_esi[] = { gpr_esi, INVALID_NUB_REGNUM };
+uint32_t g_contained_ebp[] = { gpr_ebp, INVALID_NUB_REGNUM };
+uint32_t g_contained_esp[] = { gpr_esp, INVALID_NUB_REGNUM };
+
+uint32_t g_invalidate_eax[] = { gpr_eax , gpr_ax , gpr_ah , gpr_al, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_ebx[] = { gpr_ebx , gpr_bx , gpr_bh , gpr_bl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_ecx[] = { gpr_ecx , gpr_cx , gpr_ch , gpr_cl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_edx[] = { gpr_edx , gpr_dx , gpr_dh , gpr_dl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_edi[] = { gpr_edi , gpr_di , gpr_dil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_esi[] = { gpr_esi , gpr_si , gpr_sil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_ebp[] = { gpr_ebp , gpr_bp , gpr_bpl , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_esp[] = { gpr_esp , gpr_sp , gpr_spl , INVALID_NUB_REGNUM };
+
// General purpose registers for 64 bit
const DNBRegisterInfo
DNBArchImplI386::g_gpr_registers[] =
{
-{ e_regSetGPR, gpr_eax, "eax" , NULL , Uint, Hex, GPR_SIZE(eax), GPR_OFFSET(eax) , gcc_eax , dwarf_eax , -1U , gdb_eax },
-{ e_regSetGPR, gpr_ebx, "ebx" , NULL , Uint, Hex, GPR_SIZE(ebx), GPR_OFFSET(ebx) , gcc_ebx , dwarf_ebx , -1U , gdb_ebx },
-{ e_regSetGPR, gpr_ecx, "ecx" , NULL , Uint, Hex, GPR_SIZE(ecx), GPR_OFFSET(ecx) , gcc_ecx , dwarf_ecx , -1U , gdb_ecx },
-{ e_regSetGPR, gpr_edx, "edx" , NULL , Uint, Hex, GPR_SIZE(edx), GPR_OFFSET(edx) , gcc_edx , dwarf_edx , -1U , gdb_edx },
-{ e_regSetGPR, gpr_edi, "edi" , NULL , Uint, Hex, GPR_SIZE(edi), GPR_OFFSET(edi) , gcc_edi , dwarf_edi , -1U , gdb_edi },
-{ e_regSetGPR, gpr_esi, "esi" , NULL , Uint, Hex, GPR_SIZE(esi), GPR_OFFSET(esi) , gcc_esi , dwarf_esi , -1U , gdb_esi },
-{ e_regSetGPR, gpr_ebp, "ebp" , "fp" , Uint, Hex, GPR_SIZE(ebp), GPR_OFFSET(ebp) , gcc_ebp , dwarf_ebp , GENERIC_REGNUM_FP , gdb_ebp },
-{ e_regSetGPR, gpr_esp, "esp" , "sp" , Uint, Hex, GPR_SIZE(esp), GPR_OFFSET(esp) , gcc_esp , dwarf_esp , GENERIC_REGNUM_SP , gdb_esp },
-{ e_regSetGPR, gpr_ss, "ss" , NULL , Uint, Hex, GPR_SIZE(ss), GPR_OFFSET(ss) , -1U , -1U , -1U , gdb_ss },
-{ e_regSetGPR, gpr_eflags, "eflags", "flags" , Uint, Hex, GPR_SIZE(eflags), GPR_OFFSET(eflags) , gcc_eflags, dwarf_eflags , GENERIC_REGNUM_FLAGS , gdb_eflags},
-{ e_regSetGPR, gpr_eip, "eip" , "pc" , Uint, Hex, GPR_SIZE(eip), GPR_OFFSET(eip) , gcc_eip , dwarf_eip , GENERIC_REGNUM_PC , gdb_eip },
-{ e_regSetGPR, gpr_cs, "cs" , NULL , Uint, Hex, GPR_SIZE(cs), GPR_OFFSET(cs) , -1U , -1U , -1U , gdb_cs },
-{ e_regSetGPR, gpr_ds, "ds" , NULL , Uint, Hex, GPR_SIZE(ds), GPR_OFFSET(ds) , -1U , -1U , -1U , gdb_ds },
-{ e_regSetGPR, gpr_es, "es" , NULL , Uint, Hex, GPR_SIZE(es), GPR_OFFSET(es) , -1U , -1U , -1U , gdb_es },
-{ e_regSetGPR, gpr_fs, "fs" , NULL , Uint, Hex, GPR_SIZE(fs), GPR_OFFSET(fs) , -1U , -1U , -1U , gdb_fs },
-{ e_regSetGPR, gpr_gs, "gs" , NULL , Uint, Hex, GPR_SIZE(gs), GPR_OFFSET(gs) , -1U , -1U , -1U , gdb_gs }
+{ e_regSetGPR, gpr_eax, "eax" , NULL , Uint, Hex, GPR_SIZE(eax), GPR_OFFSET(eax) , gcc_eax , dwarf_eax , INVALID_NUB_REGNUM , gdb_eax , NULL, g_invalidate_eax },
+{ e_regSetGPR, gpr_ebx, "ebx" , NULL , Uint, Hex, GPR_SIZE(ebx), GPR_OFFSET(ebx) , gcc_ebx , dwarf_ebx , INVALID_NUB_REGNUM , gdb_ebx , NULL, g_invalidate_ebx },
+{ e_regSetGPR, gpr_ecx, "ecx" , NULL , Uint, Hex, GPR_SIZE(ecx), GPR_OFFSET(ecx) , gcc_ecx , dwarf_ecx , INVALID_NUB_REGNUM , gdb_ecx , NULL, g_invalidate_ecx },
+{ e_regSetGPR, gpr_edx, "edx" , NULL , Uint, Hex, GPR_SIZE(edx), GPR_OFFSET(edx) , gcc_edx , dwarf_edx , INVALID_NUB_REGNUM , gdb_edx , NULL, g_invalidate_edx },
+{ e_regSetGPR, gpr_edi, "edi" , NULL , Uint, Hex, GPR_SIZE(edi), GPR_OFFSET(edi) , gcc_edi , dwarf_edi , INVALID_NUB_REGNUM , gdb_edi , NULL, g_invalidate_edi },
+{ e_regSetGPR, gpr_esi, "esi" , NULL , Uint, Hex, GPR_SIZE(esi), GPR_OFFSET(esi) , gcc_esi , dwarf_esi , INVALID_NUB_REGNUM , gdb_esi , NULL, g_invalidate_esi },
+{ e_regSetGPR, gpr_ebp, "ebp" , "fp" , Uint, Hex, GPR_SIZE(ebp), GPR_OFFSET(ebp) , gcc_ebp , dwarf_ebp , GENERIC_REGNUM_FP , gdb_ebp , NULL, g_invalidate_ebp },
+{ e_regSetGPR, gpr_esp, "esp" , "sp" , Uint, Hex, GPR_SIZE(esp), GPR_OFFSET(esp) , gcc_esp , dwarf_esp , GENERIC_REGNUM_SP , gdb_esp , NULL, g_invalidate_esp },
+{ e_regSetGPR, gpr_ss, "ss" , NULL , Uint, Hex, GPR_SIZE(ss), GPR_OFFSET(ss) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_ss , NULL, NULL},
+{ e_regSetGPR, gpr_eflags, "eflags", "flags" , Uint, Hex, GPR_SIZE(eflags), GPR_OFFSET(eflags) , gcc_eflags , dwarf_eflags , GENERIC_REGNUM_FLAGS , gdb_eflags, NULL, NULL},
+{ e_regSetGPR, gpr_eip, "eip" , "pc" , Uint, Hex, GPR_SIZE(eip), GPR_OFFSET(eip) , gcc_eip , dwarf_eip , GENERIC_REGNUM_PC , gdb_eip , NULL, NULL},
+{ e_regSetGPR, gpr_cs, "cs" , NULL , Uint, Hex, GPR_SIZE(cs), GPR_OFFSET(cs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_cs , NULL, NULL},
+{ e_regSetGPR, gpr_ds, "ds" , NULL , Uint, Hex, GPR_SIZE(ds), GPR_OFFSET(ds) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_ds , NULL, NULL},
+{ e_regSetGPR, gpr_es, "es" , NULL , Uint, Hex, GPR_SIZE(es), GPR_OFFSET(es) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_es , NULL, NULL},
+{ e_regSetGPR, gpr_fs, "fs" , NULL , Uint, Hex, GPR_SIZE(fs), GPR_OFFSET(fs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_fs , NULL, NULL},
+{ e_regSetGPR, gpr_gs, "gs" , NULL , Uint, Hex, GPR_SIZE(gs), GPR_OFFSET(gs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM , gdb_gs , NULL, NULL},
+DEFINE_GPR_PSEUDO_16 (ax , eax),
+DEFINE_GPR_PSEUDO_16 (bx , ebx),
+DEFINE_GPR_PSEUDO_16 (cx , ecx),
+DEFINE_GPR_PSEUDO_16 (dx , edx),
+DEFINE_GPR_PSEUDO_16 (di , edi),
+DEFINE_GPR_PSEUDO_16 (si , esi),
+DEFINE_GPR_PSEUDO_16 (bp , ebp),
+DEFINE_GPR_PSEUDO_16 (sp , esp),
+DEFINE_GPR_PSEUDO_8H (ah , eax),
+DEFINE_GPR_PSEUDO_8H (bh , ebx),
+DEFINE_GPR_PSEUDO_8H (ch , ecx),
+DEFINE_GPR_PSEUDO_8H (dh , edx),
+DEFINE_GPR_PSEUDO_8L (al , eax),
+DEFINE_GPR_PSEUDO_8L (bl , ebx),
+DEFINE_GPR_PSEUDO_8L (cl , ecx),
+DEFINE_GPR_PSEUDO_8L (dl , edx),
+DEFINE_GPR_PSEUDO_8L (dil, edi),
+DEFINE_GPR_PSEUDO_8L (sil, esi),
+DEFINE_GPR_PSEUDO_8L (bpl, ebp),
+DEFINE_GPR_PSEUDO_8L (spl, esp)
};
const DNBRegisterInfo
DNBArchImplI386::g_fpu_registers_no_avx[] =
{
-{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
-
-{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), -1U, dwarf_stmm0, -1U, gdb_stmm0 },
-{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), -1U, dwarf_stmm1, -1U, gdb_stmm1 },
-{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), -1U, dwarf_stmm2, -1U, gdb_stmm2 },
-{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), -1U, dwarf_stmm3, -1U, gdb_stmm3 },
-{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), -1U, dwarf_stmm4, -1U, gdb_stmm4 },
-{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), -1U, dwarf_stmm5, -1U, gdb_stmm5 },
-{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), -1U, dwarf_stmm6, -1U, gdb_stmm6 },
-{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), -1U, dwarf_stmm7, -1U, gdb_stmm7 },
-
-{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), -1U, dwarf_xmm0, -1U, gdb_xmm0 },
-{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), -1U, dwarf_xmm1, -1U, gdb_xmm1 },
-{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), -1U, dwarf_xmm2, -1U, gdb_xmm2 },
-{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), -1U, dwarf_xmm3, -1U, gdb_xmm3 },
-{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), -1U, dwarf_xmm4, -1U, gdb_xmm4 },
-{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), -1U, dwarf_xmm5, -1U, gdb_xmm5 },
-{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), -1U, dwarf_xmm6, -1U, gdb_xmm6 },
-{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), -1U, dwarf_xmm7, -1U, gdb_xmm7 }
+{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+
+{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0, INVALID_NUB_REGNUM, gdb_stmm0, NULL, NULL },
+{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1, INVALID_NUB_REGNUM, gdb_stmm1, NULL, NULL },
+{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2, INVALID_NUB_REGNUM, gdb_stmm2, NULL, NULL },
+{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3, INVALID_NUB_REGNUM, gdb_stmm3, NULL, NULL },
+{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4, INVALID_NUB_REGNUM, gdb_stmm4, NULL, NULL },
+{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5, INVALID_NUB_REGNUM, gdb_stmm5, NULL, NULL },
+{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6, INVALID_NUB_REGNUM, gdb_stmm6, NULL, NULL },
+{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7, INVALID_NUB_REGNUM, gdb_stmm7, NULL, NULL },
+
+{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), FPU_OFFSET(xmm0), INVALID_NUB_REGNUM, dwarf_xmm0, INVALID_NUB_REGNUM, gdb_xmm0, NULL, NULL },
+{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), FPU_OFFSET(xmm1), INVALID_NUB_REGNUM, dwarf_xmm1, INVALID_NUB_REGNUM, gdb_xmm1, NULL, NULL },
+{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), FPU_OFFSET(xmm2), INVALID_NUB_REGNUM, dwarf_xmm2, INVALID_NUB_REGNUM, gdb_xmm2, NULL, NULL },
+{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), FPU_OFFSET(xmm3), INVALID_NUB_REGNUM, dwarf_xmm3, INVALID_NUB_REGNUM, gdb_xmm3, NULL, NULL },
+{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), FPU_OFFSET(xmm4), INVALID_NUB_REGNUM, dwarf_xmm4, INVALID_NUB_REGNUM, gdb_xmm4, NULL, NULL },
+{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), FPU_OFFSET(xmm5), INVALID_NUB_REGNUM, dwarf_xmm5, INVALID_NUB_REGNUM, gdb_xmm5, NULL, NULL },
+{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), FPU_OFFSET(xmm6), INVALID_NUB_REGNUM, dwarf_xmm6, INVALID_NUB_REGNUM, gdb_xmm6, NULL, NULL },
+{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), FPU_OFFSET(xmm7), INVALID_NUB_REGNUM, dwarf_xmm7, INVALID_NUB_REGNUM, gdb_xmm7, NULL, NULL }
};
const DNBRegisterInfo
DNBArchImplI386::g_fpu_registers_avx[] =
{
-{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
-{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
-
-{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), -1U, dwarf_stmm0, -1U, gdb_stmm0 },
-{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), -1U, dwarf_stmm1, -1U, gdb_stmm1 },
-{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), -1U, dwarf_stmm2, -1U, gdb_stmm2 },
-{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), -1U, dwarf_stmm3, -1U, gdb_stmm3 },
-{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), -1U, dwarf_stmm4, -1U, gdb_stmm4 },
-{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), -1U, dwarf_stmm5, -1U, gdb_stmm5 },
-{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), -1U, dwarf_stmm6, -1U, gdb_stmm6 },
-{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), -1U, dwarf_stmm7, -1U, gdb_stmm7 },
-
-{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), AVX_OFFSET(xmm0), -1U, dwarf_xmm0, -1U, gdb_xmm0 },
-{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), AVX_OFFSET(xmm1), -1U, dwarf_xmm1, -1U, gdb_xmm1 },
-{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), AVX_OFFSET(xmm2), -1U, dwarf_xmm2, -1U, gdb_xmm2 },
-{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), AVX_OFFSET(xmm3), -1U, dwarf_xmm3, -1U, gdb_xmm3 },
-{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), AVX_OFFSET(xmm4), -1U, dwarf_xmm4, -1U, gdb_xmm4 },
-{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), AVX_OFFSET(xmm5), -1U, dwarf_xmm5, -1U, gdb_xmm5 },
-{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), AVX_OFFSET(xmm6), -1U, dwarf_xmm6, -1U, gdb_xmm6 },
-{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), AVX_OFFSET(xmm7), -1U, dwarf_xmm7, -1U, gdb_xmm7 },
-
-{ e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), -1U, dwarf_ymm0, -1U, gdb_ymm0 },
-{ e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), -1U, dwarf_ymm1, -1U, gdb_ymm1 },
-{ e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), -1U, dwarf_ymm2, -1U, gdb_ymm2 },
-{ e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), -1U, dwarf_ymm3, -1U, gdb_ymm3 },
-{ e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), -1U, dwarf_ymm4, -1U, gdb_ymm4 },
-{ e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), -1U, dwarf_ymm5, -1U, gdb_ymm5 },
-{ e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), -1U, dwarf_ymm6, -1U, gdb_ymm6 },
-{ e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), -1U, dwarf_ymm7, -1U, gdb_ymm7 },
+{ e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+
+{ e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), INVALID_NUB_REGNUM, dwarf_stmm0, INVALID_NUB_REGNUM, gdb_stmm0, NULL, NULL },
+{ e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), INVALID_NUB_REGNUM, dwarf_stmm1, INVALID_NUB_REGNUM, gdb_stmm1, NULL, NULL },
+{ e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), INVALID_NUB_REGNUM, dwarf_stmm2, INVALID_NUB_REGNUM, gdb_stmm2, NULL, NULL },
+{ e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), INVALID_NUB_REGNUM, dwarf_stmm3, INVALID_NUB_REGNUM, gdb_stmm3, NULL, NULL },
+{ e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), INVALID_NUB_REGNUM, dwarf_stmm4, INVALID_NUB_REGNUM, gdb_stmm4, NULL, NULL },
+{ e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), INVALID_NUB_REGNUM, dwarf_stmm5, INVALID_NUB_REGNUM, gdb_stmm5, NULL, NULL },
+{ e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), INVALID_NUB_REGNUM, dwarf_stmm6, INVALID_NUB_REGNUM, gdb_stmm6, NULL, NULL },
+{ e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), INVALID_NUB_REGNUM, dwarf_stmm7, INVALID_NUB_REGNUM, gdb_stmm7, NULL, NULL },
+
+{ e_regSetFPU, fpu_xmm0, "xmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0), AVX_OFFSET(xmm0), INVALID_NUB_REGNUM, dwarf_xmm0, INVALID_NUB_REGNUM, gdb_xmm0, NULL, NULL },
+{ e_regSetFPU, fpu_xmm1, "xmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1), AVX_OFFSET(xmm1), INVALID_NUB_REGNUM, dwarf_xmm1, INVALID_NUB_REGNUM, gdb_xmm1, NULL, NULL },
+{ e_regSetFPU, fpu_xmm2, "xmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2), AVX_OFFSET(xmm2), INVALID_NUB_REGNUM, dwarf_xmm2, INVALID_NUB_REGNUM, gdb_xmm2, NULL, NULL },
+{ e_regSetFPU, fpu_xmm3, "xmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3), AVX_OFFSET(xmm3), INVALID_NUB_REGNUM, dwarf_xmm3, INVALID_NUB_REGNUM, gdb_xmm3, NULL, NULL },
+{ e_regSetFPU, fpu_xmm4, "xmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4), AVX_OFFSET(xmm4), INVALID_NUB_REGNUM, dwarf_xmm4, INVALID_NUB_REGNUM, gdb_xmm4, NULL, NULL },
+{ e_regSetFPU, fpu_xmm5, "xmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5), AVX_OFFSET(xmm5), INVALID_NUB_REGNUM, dwarf_xmm5, INVALID_NUB_REGNUM, gdb_xmm5, NULL, NULL },
+{ e_regSetFPU, fpu_xmm6, "xmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6), AVX_OFFSET(xmm6), INVALID_NUB_REGNUM, dwarf_xmm6, INVALID_NUB_REGNUM, gdb_xmm6, NULL, NULL },
+{ e_regSetFPU, fpu_xmm7, "xmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7), AVX_OFFSET(xmm7), INVALID_NUB_REGNUM, dwarf_xmm7, INVALID_NUB_REGNUM, gdb_xmm7, NULL, NULL },
+
+{ e_regSetFPU, fpu_ymm0, "ymm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0), AVX_OFFSET_YMM(0), INVALID_NUB_REGNUM, dwarf_ymm0, INVALID_NUB_REGNUM, gdb_ymm0, NULL, NULL },
+{ e_regSetFPU, fpu_ymm1, "ymm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1), AVX_OFFSET_YMM(1), INVALID_NUB_REGNUM, dwarf_ymm1, INVALID_NUB_REGNUM, gdb_ymm1, NULL, NULL },
+{ e_regSetFPU, fpu_ymm2, "ymm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2), AVX_OFFSET_YMM(2), INVALID_NUB_REGNUM, dwarf_ymm2, INVALID_NUB_REGNUM, gdb_ymm2, NULL, NULL },
+{ e_regSetFPU, fpu_ymm3, "ymm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3), AVX_OFFSET_YMM(3), INVALID_NUB_REGNUM, dwarf_ymm3, INVALID_NUB_REGNUM, gdb_ymm3, NULL, NULL },
+{ e_regSetFPU, fpu_ymm4, "ymm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4), AVX_OFFSET_YMM(4), INVALID_NUB_REGNUM, dwarf_ymm4, INVALID_NUB_REGNUM, gdb_ymm4, NULL, NULL },
+{ e_regSetFPU, fpu_ymm5, "ymm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5), AVX_OFFSET_YMM(5), INVALID_NUB_REGNUM, dwarf_ymm5, INVALID_NUB_REGNUM, gdb_ymm5, NULL, NULL },
+{ e_regSetFPU, fpu_ymm6, "ymm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6), AVX_OFFSET_YMM(6), INVALID_NUB_REGNUM, dwarf_ymm6, INVALID_NUB_REGNUM, gdb_ymm6, NULL, NULL },
+{ e_regSetFPU, fpu_ymm7, "ymm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7), AVX_OFFSET_YMM(7), INVALID_NUB_REGNUM, dwarf_ymm7, INVALID_NUB_REGNUM, gdb_ymm7, NULL, NULL }
};
const DNBRegisterInfo
DNBArchImplI386::g_exc_registers[] =
{
-{ e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U },
-{ e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U },
-{ e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U }
+{ e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL },
+{ e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, NULL, NULL }
};
// Number of registers in each register set
Index: aze/lldb/tools/debugserver/source/MacOSX/MachException.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachException.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachException.cpp 2013-03-03 09:35:50.339457350 +0100
@@ -384,7 +384,7 @@
if (state_pid != -1)
{
errno = 0;
- if (::ptrace (PT_THUPDATE, state_pid, (caddr_t)state.thread_port, soft_signal) != 0)
+ if (::ptrace (PT_THUPDATE, state_pid, (caddr_t)((uintptr_t)state.thread_port), soft_signal) != 0)
err.SetError(errno, DNBError::POSIX);
else
err.Clear();
@@ -480,6 +480,17 @@
EXC_MASK_RPC_ALERT | \
EXC_MASK_MACHINE)
+// Don't listen for EXC_RESOURCE, it should really get handled by the system handler.
+
+#ifndef EXC_RESOURCE
+#define EXC_RESOURCE 11
+#endif
+
+#ifndef EXC_MASK_RESOURCE
+#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE)
+#endif
+
+#define LLDB_EXC_MASK (EXC_MASK_ALL & ~EXC_MASK_RESOURCE)
kern_return_t
MachException::PortInfo::Save (task_t task)
@@ -490,7 +501,7 @@
// and back off to just what is supported on the current system
DNBError err;
- mask = EXC_MASK_ALL;
+ mask = LLDB_EXC_MASK;
count = (sizeof (ports) / sizeof (ports[0]));
err = ::task_get_exception_ports (task, mask, masks, &count, ports, behaviors, flavors);
Index: aze/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp 2013-03-03 09:35:50.339457350 +0100
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "DNB.h"
+#include <inttypes.h>
#include <mach/mach.h>
#include <signal.h>
#include <spawn.h>
@@ -83,6 +84,11 @@
m_stdio_mutex (PTHREAD_MUTEX_RECURSIVE),
m_stdout_data (),
m_thread_actions (),
+ m_profile_enabled (false),
+ m_profile_interval_usec (0),
+ m_profile_thread (0),
+ m_profile_data_mutex(PTHREAD_MUTEX_RECURSIVE),
+ m_profile_data (),
m_thread_list (),
m_exception_messages (),
m_exception_messages_mutex (PTHREAD_MUTEX_RECURSIVE),
@@ -151,14 +157,20 @@
return m_thread_list.ThreadIDAtIndex(thread_idx);
}
+nub_thread_t
+MachProcess::GetThreadIDForMachPortNumber (thread_t mach_port_number) const
+{
+ return m_thread_list.GetThreadIDByMachPortNumber (mach_port_number);
+}
+
nub_bool_t
MachProcess::SyncThreadState (nub_thread_t tid)
{
MachThreadSP thread_sp(m_thread_list.GetThreadByID(tid));
if (!thread_sp)
return false;
- kern_return_t kret = ::thread_abort_safely(thread_sp->ThreadID());
- DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", thread_sp->ThreadID(), kret, thread_sp->Process()->StopCount());
+ kern_return_t kret = ::thread_abort_safely(thread_sp->MachPortNumber());
+ DNBLogThreadedIf (LOG_THREAD, "thread = 0x%8.8" PRIx32 " calling thread_abort_safely (tid) => %u (GetGPRState() for stop_count = %u)", thread_sp->MachPortNumber(), kret, thread_sp->Process()->StopCount());
if (kret == KERN_SUCCESS)
return true;
@@ -286,6 +298,11 @@
PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
m_exception_messages.clear();
}
+ if (m_profile_thread)
+ {
+ pthread_join(m_profile_thread, NULL);
+ m_profile_thread = NULL;
+ }
}
@@ -297,6 +314,31 @@
return ::pthread_create (&m_stdio_thread, NULL, MachProcess::STDIOThread, this) == 0;
}
+void
+MachProcess::SetEnableAsyncProfiling(bool enable, uint64_t interval_usec)
+{
+ m_profile_enabled = enable;
+ m_profile_interval_usec = interval_usec;
+
+ if (m_profile_enabled && (m_profile_thread == NULL))
+ {
+ StartProfileThread();
+ }
+ else if (!m_profile_enabled && m_profile_thread)
+ {
+ pthread_join(m_profile_thread, NULL);
+ m_profile_thread = NULL;
+ }
+}
+
+bool
+MachProcess::StartProfileThread()
+{
+ DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( )", __FUNCTION__);
+ // Create the thread that profiles the inferior and reports back if enabled
+ return ::pthread_create (&m_profile_thread, NULL, MachProcess::ProfileThread, this) == 0;
+}
+
nub_addr_t
MachProcess::LookupSymbol(const char *name, const char *shlib)
@@ -334,6 +376,7 @@
nub_state_t state = DoSIGSTOP(true, false, NULL);
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() state = %s", DNBStateAsString(state));
errno = 0;
+ DNBLog ("Sending ptrace PT_KILL to terminate inferior process.");
::ptrace (PT_KILL, m_pid, 0, 0);
DNBError err;
err.SetErrorToErrno();
@@ -614,13 +657,18 @@
DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %u...", (uint32_t)std::distance(begin, pos));
int thread_reply_signal = 0;
- const DNBThreadResumeAction *action = m_thread_actions.GetActionForThread (pos->state.thread_port, false);
+ nub_thread_t tid = m_thread_list.GetThreadIDByMachPortNumber (pos->state.thread_port);
+ const DNBThreadResumeAction *action = NULL;
+ if (tid != INVALID_NUB_THREAD)
+ {
+ action = m_thread_actions.GetActionForThread (tid, false);
+ }
if (action)
{
thread_reply_signal = action->signal;
if (thread_reply_signal)
- m_thread_actions.SetSignalHandledForThread (pos->state.thread_port);
+ m_thread_actions.SetSignalHandledForThread (tid);
}
DNBError err (pos->Reply(this, thread_reply_signal));
@@ -1311,6 +1359,77 @@
return NULL;
}
+
+void
+MachProcess::SignalAsyncProfileData (const char *info)
+{
+ DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (%s) ...", __FUNCTION__, info);
+ PTHREAD_MUTEX_LOCKER (locker, m_profile_data_mutex);
+ m_profile_data.push_back(info);
+ m_events.SetEvents(eEventProfileDataAvailable);
+
+ // Wait for the event bit to reset if a reset ACK is requested
+ m_events.WaitForResetAck(eEventProfileDataAvailable);
+}
+
+
+size_t
+MachProcess::GetAsyncProfileData (char *buf, size_t buf_size)
+{
+ DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s (&%p[%llu]) ...", __FUNCTION__, buf, (uint64_t)buf_size);
+ PTHREAD_MUTEX_LOCKER (locker, m_profile_data_mutex);
+ if (m_profile_data.empty())
+ return 0;
+
+ size_t bytes_available = m_profile_data.front().size();
+ if (bytes_available > 0)
+ {
+ if (bytes_available > buf_size)
+ {
+ memcpy(buf, m_profile_data.front().data(), buf_size);
+ m_profile_data.front().erase(0, buf_size);
+ bytes_available = buf_size;
+ }
+ else
+ {
+ memcpy(buf, m_profile_data.front().data(), bytes_available);
+ m_profile_data.erase(m_profile_data.begin());
+ }
+ }
+ return bytes_available;
+}
+
+
+void *
+MachProcess::ProfileThread(void *arg)
+{
+ MachProcess *proc = (MachProcess*) arg;
+ DNBLogThreadedIf(LOG_PROCESS, "MachProcess::%s ( arg = %p ) thread starting...", __FUNCTION__, arg);
+
+ while (proc->IsProfilingEnabled())
+ {
+ nub_state_t state = proc->GetState();
+ if (state == eStateRunning)
+ {
+ std::string data = proc->Task().GetProfileData();
+ if (!data.empty())
+ {
+ proc->SignalAsyncProfileData(data.c_str());
+ }
+ }
+ else if ((state == eStateUnloaded) || (state == eStateDetached) || (state == eStateUnloaded))
+ {
+ // Done. Get out of this thread.
+ break;
+ }
+
+ // A simple way to set up the profile interval. We can also use select() or dispatch timer source if necessary.
+ usleep(proc->ProfileInterval());
+ }
+ return NULL;
+}
+
+
pid_t
MachProcess::AttachForDebug (pid_t pid, char *err_str, size_t err_len)
{
@@ -1589,6 +1708,7 @@
{
if (launch_err.AsString() == NULL)
launch_err.SetErrorString("unable to start the exception thread");
+ DNBLog ("Could not get inferior's Mach exception port, sending ptrace PT_KILL and exiting.");
::ptrace (PT_KILL, m_pid, 0, 0);
m_pid = INVALID_NUB_PROCESS;
return INVALID_NUB_PROCESS;
@@ -1719,7 +1839,7 @@
}
}
- // if no_stdio or std paths not supplied, then route to "/dev/null".
+ // if no_stdio or std paths not supplied, then route to "/dev/null".
if (no_stdio || stdin_path == NULL || stdin_path[0] == '\0')
stdin_path = "/dev/null";
if (no_stdio || stdout_path == NULL || stdout_path[0] == '\0')
@@ -1929,6 +2049,7 @@
{
if (launch_err.AsString() == NULL)
launch_err.SetErrorString("unable to start the exception thread");
+ DNBLog ("Could not get inferior's Mach exception port, sending ptrace PT_KILL and exiting.");
::ptrace (PT_KILL, m_pid, 0, 0);
m_pid = INVALID_NUB_PROCESS;
return INVALID_NUB_PROCESS;
Index: aze/lldb/tools/debugserver/source/MacOSX/MachProcess.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachProcess.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachProcess.h 2013-03-03 09:35:50.339457350 +0100
@@ -144,6 +144,17 @@
void ExceptionMessageBundleComplete ();
void SharedLibrariesUpdated ();
nub_size_t CopyImageInfos (struct DNBExecutableImageInfo **image_infos, bool only_changed);
+
+ //----------------------------------------------------------------------
+ // Profile functions
+ //----------------------------------------------------------------------
+ void SetEnableAsyncProfiling (bool enable, uint64_t internal_usec);
+ bool IsProfilingEnabled () { return m_profile_enabled; }
+ uint64_t ProfileInterval () { return m_profile_interval_usec; }
+ bool StartProfileThread ();
+ static void * ProfileThread (void *arg);
+ void SignalAsyncProfileData (const char *info);
+ size_t GetAsyncProfileData (char *buf, size_t buf_size);
//----------------------------------------------------------------------
// Accessors
@@ -171,6 +182,8 @@
void DumpThreadStoppedReason(nub_thread_t tid) const;
const char * GetThreadInfo (nub_thread_t tid) const;
+ nub_thread_t GetThreadIDForMachPortNumber (thread_t mach_port_number) const;
+
uint32_t GetCPUType ();
nub_state_t GetState ();
void SetState (nub_state_t state);
@@ -266,6 +279,13 @@
pthread_t m_stdio_thread; // Thread ID for the thread that watches for child process stdio
PThreadMutex m_stdio_mutex; // Multithreaded protection for stdio
std::string m_stdout_data;
+
+ bool m_profile_enabled; // A flag to indicate if profiling is enabled
+ uint64_t m_profile_interval_usec; // If enable, the profiling interval in microseconds
+ pthread_t m_profile_thread; // Thread ID for the thread that profiles the inferior
+ PThreadMutex m_profile_data_mutex; // Multithreaded protection for profile info data
+ std::vector<std::string> m_profile_data; // Profile data, must be protected by m_profile_data_mutex
+
DNBThreadResumeActions m_thread_actions; // The thread actions for the current MachProcess::Resume() call
MachException::Message::collection
m_exception_messages; // A collection of exception messages caught when listening to the exception port
Index: aze/lldb/tools/debugserver/source/MacOSX/MachTask.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachTask.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachTask.cpp 2013-03-03 09:35:50.343457350 +0100
@@ -21,8 +21,12 @@
#include <mach-o/dyld_images.h>
#include <mach/mach_vm.h>
+#import <sys/sysctl.h>
// C++ Includes
+#include <iomanip>
+#include <sstream>
+
// Other libraries and framework includes
// Project includes
#include "CFUtils.h"
@@ -52,7 +56,6 @@
m_exception_port (MACH_PORT_NULL)
{
memset(&m_exc_port_info, 0, sizeof(m_exc_port_info));
-
}
//----------------------------------------------------------------------
@@ -87,18 +90,18 @@
{
struct task_basic_info task_info;
task_t task = TaskPort();
- if (task == TASK_NULL)
- return KERN_INVALID_ARGUMENT;
+ if (task == TASK_NULL)
+ return KERN_INVALID_ARGUMENT;
DNBError err;
err = BasicInfo(task, &task_info);
if (err.Success())
{
- // task_resume isn't counted like task_suspend calls are, are, so if the
- // task is not suspended, don't try and resume it since it is already
- // running
- if (task_info.suspend_count > 0)
+ // task_resume isn't counted like task_suspend calls are, are, so if the
+ // task is not suspended, don't try and resume it since it is already
+ // running
+ if (task_info.suspend_count > 0)
{
err = ::task_resume (task);
if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
@@ -224,6 +227,183 @@
return ret;
}
+#define TIME_VALUE_TO_TIMEVAL(a, r) do { \
+(r)->tv_sec = (a)->seconds; \
+(r)->tv_usec = (a)->microseconds; \
+} while (0)
+
+// We should consider moving this into each MacThread.
+static void get_threads_profile_data(task_t task, nub_process_t pid, std::vector<uint64_t> &threads_id, std::vector<std::string> &threads_name, std::vector<uint64_t> &threads_used_usec)
+{
+ kern_return_t kr;
+ thread_act_array_t threads;
+ mach_msg_type_number_t tcnt;
+
+ kr = task_threads(task, &threads, &tcnt);
+ if (kr != KERN_SUCCESS)
+ return;
+
+ for (int i = 0; i < tcnt; i++) {
+ thread_identifier_info_data_t identifier_info;
+ mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
+ kr = ::thread_info(threads[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifier_info, &count);
+ if (kr != KERN_SUCCESS) continue;
+
+ thread_basic_info_data_t basic_info;
+ count = THREAD_BASIC_INFO_COUNT;
+ kr = ::thread_info(threads[i], THREAD_BASIC_INFO, (thread_info_t)&basic_info, &count);
+ if (kr != KERN_SUCCESS) continue;
+
+ if ((basic_info.flags & TH_FLAGS_IDLE) == 0) {
+ nub_thread_t tid = MachThread::GetGloballyUniqueThreadIDForMachPortID (threads[i]);
+
+ threads_id.push_back(tid);
+
+ if (identifier_info.thread_handle != 0) {
+ struct proc_threadinfo proc_threadinfo;
+ int len = ::proc_pidinfo(pid, PROC_PIDTHREADINFO, identifier_info.thread_handle, &proc_threadinfo, PROC_PIDTHREADINFO_SIZE);
+ if (len && proc_threadinfo.pth_name[0]) {
+ threads_name.push_back(proc_threadinfo.pth_name);
+ }
+ else {
+ threads_name.push_back("");
+ }
+ }
+ else {
+ threads_name.push_back("");
+ }
+ struct timeval tv;
+ struct timeval thread_tv;
+ TIME_VALUE_TO_TIMEVAL(&basic_info.user_time, &thread_tv);
+ TIME_VALUE_TO_TIMEVAL(&basic_info.system_time, &tv);
+ timeradd(&thread_tv, &tv, &thread_tv);
+ uint64_t used_usec = thread_tv.tv_sec * 1000000ULL + thread_tv.tv_usec;
+ threads_used_usec.push_back(used_usec);
+ }
+
+ kr = mach_port_deallocate(mach_task_self(), threads[i]);
+ }
+ kr = mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)threads, tcnt * sizeof(*threads));
+}
+
+#define RAW_HEXBASE std::setfill('0') << std::hex << std::right
+#define DECIMAL std::dec << std::setfill(' ')
+std::string
+MachTask::GetProfileData ()
+{
+ std::string result;
+
+ static int32_t numCPU = -1;
+ int32_t mib[] = {CTL_HW, HW_AVAILCPU};
+ size_t len = sizeof(numCPU);
+ if (numCPU == -1)
+ {
+ if (sysctl(mib, sizeof(mib) / sizeof(int32_t), &numCPU, &len, NULL, 0) != 0)
+ return result;
+ }
+
+ mach_port_t localHost = mach_host_self();
+ struct host_cpu_load_info host_info;
+ mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+ kern_return_t kr = host_statistics(localHost, HOST_CPU_LOAD_INFO, (host_info_t)&host_info, &count);
+ if (kr != KERN_SUCCESS)
+ return result;
+
+ task_t task = TaskPort();
+ if (task == TASK_NULL)
+ return result;
+
+ struct task_basic_info task_info;
+ DNBError err;
+ err = BasicInfo(task, &task_info);
+
+ if (!err.Success())
+ return result;
+
+ uint64_t elapsed_usec = 0;
+ uint64_t task_used_usec = 0;
+ std::vector<uint64_t> threads_id;
+ std::vector<std::string> threads_name;
+ std::vector<uint64_t> threads_used_usec;
+
+ // Get current used time.
+ struct timeval current_used_time;
+ struct timeval tv;
+ TIME_VALUE_TO_TIMEVAL(&task_info.user_time, &current_used_time);
+ TIME_VALUE_TO_TIMEVAL(&task_info.system_time, &tv);
+ timeradd(&current_used_time, &tv, &current_used_time);
+ task_used_usec = current_used_time.tv_sec * 1000000ULL + current_used_time.tv_usec;
+ get_threads_profile_data(task, m_process->ProcessID(), threads_id, threads_name, threads_used_usec);
+
+ struct timeval current_elapsed_time;
+ int res = gettimeofday(&current_elapsed_time, NULL);
+ if (res == 0)
+ {
+ elapsed_usec = current_elapsed_time.tv_sec * 1000000ULL + current_elapsed_time.tv_usec;
+ }
+
+ struct vm_statistics vm_stats;
+ uint64_t physical_memory;
+ mach_vm_size_t rprvt = 0;
+ mach_vm_size_t rsize = 0;
+ mach_vm_size_t vprvt = 0;
+ mach_vm_size_t vsize = 0;
+ mach_vm_size_t dirty_size = 0;
+ if (m_vm_memory.GetMemoryProfile(task, task_info, m_process->GetCPUType(), m_process->ProcessID(), vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size))
+ {
+ std::ostringstream profile_data_stream;
+
+ profile_data_stream << "num_cpu:" << numCPU << ';';
+ profile_data_stream << "host_user_ticks:" << host_info.cpu_ticks[CPU_STATE_USER] << ';';
+ profile_data_stream << "host_sys_ticks:" << host_info.cpu_ticks[CPU_STATE_SYSTEM] << ';';
+ profile_data_stream << "host_idle_ticks:" << host_info.cpu_ticks[CPU_STATE_IDLE] << ';';
+
+ profile_data_stream << "elapsed_usec:" << elapsed_usec << ';';
+ profile_data_stream << "task_used_usec:" << task_used_usec << ';';
+
+ int num_threads = threads_id.size();
+ for (int i=0; i<num_threads; i++) {
+ profile_data_stream << "thread_used_id:" << std::hex << threads_id[i] << std::dec << ';';
+ profile_data_stream << "thread_used_usec:" << threads_used_usec[i] << ';';
+
+ profile_data_stream << "thread_used_name:";
+ int len = threads_name[i].size();
+ if (len) {
+ const char *thread_name = threads_name[i].c_str();
+ // Make sure that thread name doesn't interfere with our delimiter.
+ profile_data_stream << RAW_HEXBASE << std::setw(2);
+ const uint8_t *ubuf8 = (const uint8_t *)(thread_name);
+ for (int j=0; j<len; j++)
+ {
+ profile_data_stream << (uint32_t)(ubuf8[j]);
+ }
+ // Reset back to DECIMAL.
+ profile_data_stream << DECIMAL;
+ }
+ profile_data_stream << ';';
+ }
+
+ profile_data_stream << "wired:" << vm_stats.wire_count * vm_page_size << ';';
+ profile_data_stream << "active:" << vm_stats.active_count * vm_page_size << ';';
+ profile_data_stream << "inactive:" << vm_stats.inactive_count * vm_page_size << ';';
+ uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
+ profile_data_stream << "used:" << total_used_count * vm_page_size << ';';
+ profile_data_stream << "free:" << vm_stats.free_count * vm_page_size << ';';
+ profile_data_stream << "total:" << physical_memory << ';';
+
+ profile_data_stream << "rprvt:" << rprvt << ';';
+ profile_data_stream << "rsize:" << rsize << ';';
+ profile_data_stream << "vprvt:" << vprvt << ';';
+ profile_data_stream << "vsize:" << vsize << ';';
+ profile_data_stream << "dirty:" << dirty_size << ';';
+ profile_data_stream << "--end--;";
+
+ result = profile_data_stream.str();
+ }
+
+ return result;
+}
+
//----------------------------------------------------------------------
// MachTask::TaskPortForProcessID
@@ -242,14 +422,14 @@
task_t
MachTask::TaskPortForProcessID (pid_t pid, DNBError &err, uint32_t num_retries, uint32_t usec_interval)
{
- if (pid != INVALID_NUB_PROCESS)
- {
- DNBError err;
- mach_port_t task_self = mach_task_self ();
- task_t task = TASK_NULL;
- for (uint32_t i=0; i<num_retries; i++)
- {
- err = ::task_for_pid ( task_self, pid, &task);
+ if (pid != INVALID_NUB_PROCESS)
+ {
+ DNBError err;
+ mach_port_t task_self = mach_task_self ();
+ task_t task = TASK_NULL;
+ for (uint32_t i=0; i<num_retries; i++)
+ {
+ err = ::task_for_pid ( task_self, pid, &task);
if (DNBLogCheckLogBit(LOG_TASK) || err.Fail())
{
@@ -266,14 +446,14 @@
err.LogThreaded(str);
}
- if (err.Success())
- return task;
+ if (err.Success())
+ return task;
- // Sleep a bit and try again
- ::usleep (usec_interval);
- }
- }
- return TASK_NULL;
+ // Sleep a bit and try again
+ ::usleep (usec_interval);
+ }
+ }
+ return TASK_NULL;
}
Index: aze/lldb/tools/debugserver/source/MacOSX/MachTask.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachTask.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachTask.h 2013-03-03 09:35:50.343457350 +0100
@@ -23,6 +23,7 @@
#include <sys/socket.h>
// C++ Includes
#include <map>
+#include <string>
// Other libraries and framework includes
// Project includes
#include "MachException.h"
@@ -65,6 +66,7 @@
nub_size_t ReadMemory (nub_addr_t addr, nub_size_t size, void *buf);
nub_size_t WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf);
int GetMemoryRegionInfo (nub_addr_t addr, DNBRegionInfo *region_info);
+ std::string GetProfileData ();
nub_addr_t AllocateMemory (nub_size_t size, uint32_t permissions);
nub_bool_t DeallocateMemory (nub_addr_t addr);
Index: aze/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachThread.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachThread.cpp 2013-03-03 09:35:50.343457350 +0100
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include <inttypes.h>
#include "MachThread.h"
#include "MachProcess.h"
#include "DNBLog.h"
@@ -23,9 +24,10 @@
return ++g_nextID;
}
-MachThread::MachThread (MachProcess *process, thread_t tid) :
+MachThread::MachThread (MachProcess *process, uint64_t unique_thread_id, thread_t mach_port_num) :
m_process (process),
- m_tid (tid),
+ m_unique_id (unique_thread_id),
+ m_mach_port_number (mach_port_num),
m_seq_id (GetSequenceID()),
m_state (eStateUnloaded),
m_state_mutex (PTHREAD_MUTEX_RECURSIVE),
@@ -34,12 +36,10 @@
m_stop_exception (),
m_arch_ap (DNBArchProtocol::Create (this)),
m_reg_sets (NULL),
- m_num_reg_sets (0)
-#ifdef THREAD_IDENTIFIER_INFO_COUNT
- , m_ident_info(),
+ m_num_reg_sets (0),
+ m_ident_info(),
m_proc_threadinfo(),
m_dispatch_queue_name()
-#endif
{
nub_size_t num_reg_sets = 0;
m_reg_sets = m_arch_ap->GetRegisterSetInfo (&num_reg_sets);
@@ -49,12 +49,12 @@
// muck with it and also so we get the suspend count correct in case it was
// already suspended
GetBasicInfo();
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::MachThread ( process = %p, tid = 0x%4.4x, seq_id = %u )", &m_process, m_tid, m_seq_id);
+ DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::MachThread ( process = %p, tid = 0x%8.8" PRIx64 ", seq_id = %u )", &m_process, m_unique_id, m_seq_id);
}
MachThread::~MachThread()
{
- DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::~MachThread() for tid = 0x%4.4x (%u)", m_tid, m_seq_id);
+ DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::~MachThread() for tid = 0x%8.8" PRIx64 " (%u)", m_unique_id, m_seq_id);
}
@@ -63,13 +63,13 @@
MachThread::Suspend()
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
- if (ThreadIDIsValid(m_tid))
+ if (MachPortNumberIsValid(m_mach_port_number))
{
- DNBError err(::thread_suspend (m_tid), DNBError::MachKernel);
+ DNBError err(::thread_suspend (m_mach_port_number), DNBError::MachKernel);
if (err.Success())
m_suspend_count++;
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
+ err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
}
}
@@ -77,7 +77,7 @@
MachThread::Resume(bool others_stopped)
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
- if (ThreadIDIsValid(m_tid))
+ if (MachPortNumberIsValid(m_mach_port_number))
{
SetSuspendCountBeforeResume(others_stopped);
}
@@ -88,7 +88,7 @@
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
DNBError err;
- if (ThreadIDIsValid(m_tid) == false)
+ if (MachPortNumberIsValid(m_mach_port_number) == false)
return false;
size_t times_to_resume;
@@ -113,9 +113,9 @@
{
while (times_to_resume > 0)
{
- err = ::thread_resume (m_tid);
+ err = ::thread_resume (m_mach_port_number);
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_resume (%4.4x)", m_tid);
+ err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
if (err.Success())
--times_to_resume;
else
@@ -135,16 +135,16 @@
{
DNBLogThreadedIf(LOG_THREAD | LOG_VERBOSE, "MachThread::%s ( )", __FUNCTION__);
DNBError err;
- if (ThreadIDIsValid(m_tid) == false)
+ if (MachPortNumberIsValid(m_mach_port_number) == false)
return false;
if (m_suspend_count > 0)
{
while (m_suspend_count > 0)
{
- err = ::thread_resume (m_tid);
+ err = ::thread_resume (m_mach_port_number);
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
- err.LogThreaded("::thread_resume (%4.4x)", m_tid);
+ err.LogThreaded("::thread_resume (%4.4" PRIx32 ")", m_mach_port_number);
if (err.Success())
--m_suspend_count;
else
@@ -161,12 +161,12 @@
{
while (m_suspend_count < 0)
{
- err = ::thread_suspend (m_tid);
+ err = ::thread_suspend (m_mach_port_number);
if (err.Success())
++m_suspend_count;
if (DNBLogCheckLogBit(LOG_THREAD) || err.Fail())
{
- err.LogThreaded("::thread_suspend (%4.4x)", m_tid);
+ err.LogThreaded("::thread_suspend (%4.4" PRIx32 ")", m_mach_port_number);
return false;
}
}
@@ -181,7 +181,7 @@
static char g_basic_info_string[1024];
struct thread_basic_info basicInfo;
- if (GetBasicInfo(m_tid, &basicInfo))
+ if (GetBasicInfo(m_mach_port_number, &basicInfo))
{
// char run_state_str[32];
@@ -197,8 +197,8 @@
// }
float user = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f;
float system = (float)basicInfo.user_time.seconds + (float)basicInfo.user_time.microseconds / 1000000.0f;
- snprintf(g_basic_info_string, sizeof(g_basic_info_string), "Thread 0x%4.4x: user=%f system=%f cpu=%d sleep_time=%d",
- InferiorThreadID(),
+ snprintf(g_basic_info_string, sizeof(g_basic_info_string), "Thread 0x%8.8" PRIx64 ": user=%f system=%f cpu=%d sleep_time=%d",
+ m_unique_id,
user,
system,
basicInfo.cpu_usage,
@@ -209,6 +209,7 @@
return NULL;
}
+// Finds the Mach port number for a given thread in the inferior process' port namespace.
thread_t
MachThread::InferiorThreadID() const
{
@@ -233,7 +234,7 @@
if (kret == KERN_SUCCESS)
{
::mach_port_deallocate (my_task, my_name);
- if (my_name == m_tid)
+ if (my_name == m_mach_port_number)
{
inferior_tid = names[i];
break;
@@ -271,7 +272,7 @@
struct thread_basic_info *
MachThread::GetBasicInfo ()
{
- if (MachThread::GetBasicInfo(m_tid, &m_basic_info))
+ if (MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info))
return &m_basic_info;
return NULL;
}
@@ -280,7 +281,7 @@
bool
MachThread::GetBasicInfo(thread_t thread, struct thread_basic_info *basicInfoPtr)
{
- if (ThreadIDIsValid(thread))
+ if (MachPortNumberIsValid(thread))
{
unsigned int info_count = THREAD_BASIC_INFO_COUNT;
kern_return_t err = ::thread_info (thread, THREAD_BASIC_INFO, (thread_info_t) basicInfoPtr, &info_count);
@@ -293,7 +294,13 @@
bool
-MachThread::ThreadIDIsValid(thread_t thread)
+MachThread::ThreadIDIsValid(uint64_t thread)
+{
+ return thread != 0;
+}
+
+bool
+MachThread::MachPortNumberIsValid(thread_t thread)
{
return thread != THREAD_NULL;
}
@@ -354,10 +361,10 @@
default: thread_run_state = "???"; break;
}
- DNBLogThreaded("[%3u] #%3u tid: 0x%4.4x, pc: 0x%16.16llx, sp: 0x%16.16llx, breakID: %3d, user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
+ DNBLogThreaded("[%3u] #%3u tid: 0x%8.8" PRIx64 ", pc: 0x%16.16" PRIx64 ", sp: 0x%16.16" PRIx64 ", breakID: %3d, user: %d.%6.6d, system: %d.%6.6d, cpu: %2d, policy: %2d, run_state: %2d (%s), flags: %2d, suspend_count: %2d (current %2d), sleep_time: %d",
index,
m_seq_id,
- m_tid,
+ m_unique_id,
GetPC(INVALID_NUB_ADDRESS),
GetSP(INVALID_NUB_ADDRESS),
m_break_id,
@@ -498,7 +505,7 @@
RestoreSuspendCountAfterStop();
// Update the basic information for a thread
- MachThread::GetBasicInfo(m_tid, &m_basic_info);
+ MachThread::GetBasicInfo(m_mach_port_number, &m_basic_info);
#if ENABLE_AUTO_STEPPING_OVER_BP
// See if we were at a breakpoint when we last resumed that we disabled,
@@ -588,7 +595,7 @@
{
PTHREAD_MUTEX_LOCKER (locker, m_state_mutex);
m_state = state;
- DNBLogThreadedIf(LOG_THREAD, "MachThread::SetState ( %s ) for tid = 0x%4.4x", DNBStateAsString(state), m_tid);
+ DNBLogThreadedIf(LOG_THREAD, "MachThread::SetState ( %s ) for tid = 0x%8.8" PRIx64 "", DNBStateAsString(state), m_unique_id);
}
uint32_t
@@ -736,13 +743,11 @@
bool
MachThread::GetIdentifierInfo ()
{
-#ifdef THREAD_IDENTIFIER_INFO_COUNT
// Don't try to get the thread info once and cache it for the life of the thread. It changes over time, for instance
// if the thread name changes, then the thread_handle also changes... So you have to refetch it every time.
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- kern_return_t kret = ::thread_info (ThreadID(), THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
+ kern_return_t kret = ::thread_info (m_mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
return kret == KERN_SUCCESS;
-#endif
return false;
}
@@ -761,3 +766,18 @@
return NULL;
}
+
+uint64_t
+MachThread::GetGloballyUniqueThreadIDForMachPortID (thread_t mach_port_id)
+{
+ kern_return_t kr;
+ thread_identifier_info_data_t tident;
+ mach_msg_type_number_t tident_count = THREAD_IDENTIFIER_INFO_COUNT;
+ kr = thread_info (mach_port_id, THREAD_IDENTIFIER_INFO,
+ (thread_info_t) &tident, &tident_count);
+ if (kr != KERN_SUCCESS)
+ {
+ return mach_port_id;
+ }
+ return tident.thread_id;
+}
Index: aze/lldb/tools/debugserver/source/MacOSX/MachThread.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachThread.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachThread.h 2013-03-03 09:35:50.343457350 +0100
@@ -36,7 +36,7 @@
{
public:
- MachThread (MachProcess *process, thread_t thread = 0);
+ MachThread (MachProcess *process, uint64_t unique_thread_id = 0, thread_t mach_port_number = 0);
~MachThread ();
MachProcess * Process() { return m_process; }
@@ -44,11 +44,13 @@
Process() const { return m_process; }
nub_process_t ProcessID() const;
void Dump(uint32_t index);
- thread_t ThreadID() const { return m_tid; }
+ uint64_t ThreadID() const { return m_unique_id; }
+ thread_t MachPortNumber() const { return m_mach_port_number; }
thread_t InferiorThreadID() const;
uint32_t SequenceID() const { return m_seq_id; }
- static bool ThreadIDIsValid(thread_t thread);
+ static bool ThreadIDIsValid(uint64_t thread); // The 64-bit system-wide unique thread identifier
+ static bool MachPortNumberIsValid(thread_t thread); // The mach port # for this thread in debugserver namespace
void Resume(bool others_stopped);
void Suspend();
bool SetSuspendCountBeforeResume(bool others_stopped);
@@ -106,6 +108,8 @@
return m_arch_ap.get();
}
+ static uint64_t GetGloballyUniqueThreadIDForMachPortID (thread_t mach_port_id);
+
protected:
static bool GetBasicInfo(thread_t threadID, struct thread_basic_info *basic_info);
@@ -116,7 +120,8 @@
// GetDispatchQueueName();
//
MachProcess * m_process; // The process that owns this thread
- thread_t m_tid; // The thread port for this thread
+ uint64_t m_unique_id; // The globally unique ID for this thread (nub_thread_t)
+ thread_t m_mach_port_number; // The mach port # for this thread in debugserver namesp.
uint32_t m_seq_id; // A Sequential ID that increments with each new thread
nub_state_t m_state; // The state of our process
PThreadMutex m_state_mutex; // Multithreaded protection for m_state
@@ -128,11 +133,9 @@
std::auto_ptr<DNBArchProtocol> m_arch_ap; // Arch specific information for register state and more
const DNBRegisterSetInfo * m_reg_sets; // Register set information for this thread
nub_size_t m_num_reg_sets;
-#ifdef THREAD_IDENTIFIER_INFO_COUNT
thread_identifier_info_data_t m_ident_info;
struct proc_threadinfo m_proc_threadinfo;
std::string m_dispatch_queue_name;
-#endif
private:
friend class MachThreadList;
Index: aze/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachThreadList.cpp 2013-03-03 09:35:50.343457350 +0100
@@ -13,6 +13,7 @@
#include "MachThreadList.h"
+#include <inttypes.h>
#include <sys/sysctl.h>
#include "DNBLog.h"
@@ -30,7 +31,7 @@
}
nub_state_t
-MachThreadList::GetState(thread_t tid)
+MachThreadList::GetState(nub_thread_t tid)
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -39,7 +40,7 @@
}
const char *
-MachThreadList::GetName (thread_t tid)
+MachThreadList::GetName (nub_thread_t tid)
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -48,7 +49,7 @@
}
nub_thread_t
-MachThreadList::SetCurrentThread(thread_t tid)
+MachThreadList::SetCurrentThread(nub_thread_t tid)
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -72,8 +73,10 @@
bool
MachThreadList::GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info)
{
+ thread_t mach_port_number = GetMachPortNumberByThreadID (tid);
+
mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
- return ::thread_info (tid, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
+ return ::thread_info (mach_port_number, THREAD_IDENTIFIER_INFO, (thread_info_t)ident_info, &count) == KERN_SUCCESS;
}
void
@@ -110,8 +113,57 @@
return thread_sp;
}
+MachThreadSP
+MachThreadList::GetThreadByMachPortNumber (thread_t mach_port_number) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->MachPortNumber() == mach_port_number)
+ {
+ thread_sp = m_threads[idx];
+ break;
+ }
+ }
+ return thread_sp;
+}
+
+nub_thread_t
+MachThreadList::GetThreadIDByMachPortNumber (thread_t mach_port_number) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->MachPortNumber() == mach_port_number)
+ {
+ return m_threads[idx]->ThreadID();
+ }
+ }
+ return INVALID_NUB_THREAD;
+}
+
+thread_t
+MachThreadList::GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const
+{
+ PTHREAD_MUTEX_LOCKER (locker, m_threads_mutex);
+ MachThreadSP thread_sp;
+ const size_t num_threads = m_threads.size();
+ for (size_t idx = 0; idx < num_threads; ++idx)
+ {
+ if (m_threads[idx]->ThreadID() == globally_unique_id)
+ {
+ return m_threads[idx]->MachPortNumber();
+ }
+ }
+ return 0;
+}
+
bool
-MachThreadList::GetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value ) const
+MachThreadList::GetRegisterValue (nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, DNBRegisterValue *reg_value ) const
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -121,7 +173,7 @@
}
bool
-MachThreadList::SetRegisterValue ( nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value ) const
+MachThreadList::SetRegisterValue (nub_thread_t tid, uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value ) const
{
MachThreadSP thread_sp (GetThreadByID (tid));
if (thread_sp)
@@ -177,7 +229,7 @@
bool
MachThreadList::NotifyException(MachException::Data& exc)
{
- MachThreadSP thread_sp (GetThreadByID (exc.thread_port));
+ MachThreadSP thread_sp (GetThreadByMachPortNumber (exc.thread_port));
if (thread_sp)
{
thread_sp->NotifyException(exc);
@@ -238,9 +290,10 @@
// (add them), and which ones are not around anymore (remove them).
for (idx = 0; idx < thread_list_count; ++idx)
{
- const thread_t tid = thread_list[idx];
+ const thread_t mach_port_num = thread_list[idx];
- MachThreadSP thread_sp (GetThreadByID (tid));
+ uint64_t unique_thread_id = MachThread::GetGloballyUniqueThreadIDForMachPortID (mach_port_num);
+ MachThreadSP thread_sp (GetThreadByID (unique_thread_id));
if (thread_sp)
{
// Keep the existing thread class
@@ -249,7 +302,7 @@
else
{
// We don't have this thread, lets add it.
- thread_sp.reset(new MachThread(process, tid));
+ thread_sp.reset(new MachThread(process, unique_thread_id, mach_port_num));
// Add the new thread regardless of its is user ready state...
// Make sure the thread is ready to be displayed and shown to users
@@ -382,7 +435,7 @@
{
for (uint32_t idx = 0; idx < num_new_threads; ++idx)
{
- DNBLogThreadedIf (LOG_THREAD, "MachThreadList::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%4.4x, thread-is-user-ready=%i)",
+ DNBLogThreadedIf (LOG_THREAD, "MachThreadList::ProcessWillResume (pid = %4.4x) stop-id=%u, resuming newly discovered thread: 0x%8.8" PRIx64 ", thread-is-user-ready=%i)",
process->ProcessID(),
process->StopCount(),
new_threads[idx]->ThreadID(),
Index: aze/lldb/tools/debugserver/source/MacOSX/MachThreadList.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachThreadList.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachThreadList.h 2013-03-03 09:35:50.343457350 +0100
@@ -35,9 +35,9 @@
uint32_t ProcessDidStop (MachProcess *process);
bool NotifyException (MachException::Data& exc);
bool ShouldStop (bool &step_more);
- const char * GetName (thread_t tid);
- nub_state_t GetState (thread_t tid);
- nub_thread_t SetCurrentThread (thread_t tid);
+ const char * GetName (nub_thread_t tid);
+ nub_state_t GetState (nub_thread_t tid);
+ nub_thread_t SetCurrentThread (nub_thread_t tid);
bool GetThreadStoppedReason (nub_thread_t tid, struct DNBThreadStopInfo *stop_info) const;
void DumpThreadStoppedReason (nub_thread_t tid) const;
bool GetIdentifierInfo (nub_thread_t tid, thread_identifier_info_data_t *ident_info);
@@ -56,6 +56,10 @@
MachThreadSP GetThreadByID (nub_thread_t tid) const;
+ MachThreadSP GetThreadByMachPortNumber (thread_t mach_port_number) const;
+ nub_thread_t GetThreadIDByMachPortNumber (thread_t mach_port_number) const;
+ thread_t GetMachPortNumberByThreadID (nub_thread_t globally_unique_id) const;
+
protected:
typedef std::vector<MachThreadSP> collection;
typedef collection::iterator iterator;
Index: aze/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp 2013-03-03 09:35:50.343457350 +0100
@@ -15,6 +15,8 @@
#include "MachVMRegion.h"
#include "DNBLog.h"
#include <mach/mach_vm.h>
+#include <mach/shared_region.h>
+#include <sys/sysctl.h>
MachVMMemory::MachVMMemory() :
m_page_size (kInvalidPageSize),
@@ -88,6 +90,332 @@
return true;
}
+// For integrated graphics chip, this makes the accounting info for 'wired' memory more like top.
+static uint64_t GetStolenPages()
+{
+ static uint64_t stolenPages = 0;
+ static bool calculated = false;
+ if (calculated) return stolenPages;
+
+ static int mib_reserved[CTL_MAXNAME];
+ static int mib_unusable[CTL_MAXNAME];
+ static int mib_other[CTL_MAXNAME];
+ static size_t mib_reserved_len = 0;
+ static size_t mib_unusable_len = 0;
+ static size_t mib_other_len = 0;
+ int r;
+
+ /* This can be used for testing: */
+ //tsamp->pages_stolen = (256 * 1024 * 1024ULL) / tsamp->pagesize;
+
+ if(0 == mib_reserved_len)
+ {
+ mib_reserved_len = CTL_MAXNAME;
+
+ r = sysctlnametomib("machdep.memmap.Reserved", mib_reserved,
+ &mib_reserved_len);
+
+ if(-1 == r)
+ {
+ mib_reserved_len = 0;
+ return 0;
+ }
+
+ mib_unusable_len = CTL_MAXNAME;
+
+ r = sysctlnametomib("machdep.memmap.Unusable", mib_unusable,
+ &mib_unusable_len);
+
+ if(-1 == r)
+ {
+ mib_reserved_len = 0;
+ return 0;
+ }
+
+
+ mib_other_len = CTL_MAXNAME;
+
+ r = sysctlnametomib("machdep.memmap.Other", mib_other,
+ &mib_other_len);
+
+ if(-1 == r)
+ {
+ mib_reserved_len = 0;
+ return 0;
+ }
+ }
+
+ if(mib_reserved_len > 0 && mib_unusable_len > 0 && mib_other_len > 0)
+ {
+ uint64_t reserved = 0, unusable = 0, other = 0;
+ size_t reserved_len;
+ size_t unusable_len;
+ size_t other_len;
+
+ reserved_len = sizeof(reserved);
+ unusable_len = sizeof(unusable);
+ other_len = sizeof(other);
+
+ /* These are all declared as QUAD/uint64_t sysctls in the kernel. */
+
+ if(-1 == sysctl(mib_reserved, mib_reserved_len, &reserved,
+ &reserved_len, NULL, 0))
+ {
+ return 0;
+ }
+
+ if(-1 == sysctl(mib_unusable, mib_unusable_len, &unusable,
+ &unusable_len, NULL, 0))
+ {
+ return 0;
+ }
+
+ if(-1 == sysctl(mib_other, mib_other_len, &other,
+ &other_len, NULL, 0))
+ {
+ return 0;
+ }
+
+ if(reserved_len == sizeof(reserved)
+ && unusable_len == sizeof(unusable)
+ && other_len == sizeof(other))
+ {
+ uint64_t stolen = reserved + unusable + other;
+ uint64_t mb128 = 128 * 1024 * 1024ULL;
+
+ if(stolen >= mb128)
+ {
+ stolen = (stolen & ~((128 * 1024 * 1024ULL) - 1)); // rounding down
+ stolenPages = stolen/vm_page_size;
+ }
+ }
+ }
+
+ calculated = true;
+ return stolenPages;
+}
+
+static uint64_t GetPhysicalMemory()
+{
+ // This doesn't change often at all. No need to poll each time.
+ static uint64_t physical_memory = 0;
+ static bool calculated = false;
+ if (calculated) return physical_memory;
+
+ int mib[2];
+ mib[0] = CTL_HW;
+ mib[1] = HW_MEMSIZE;
+ size_t len = sizeof(physical_memory);
+ sysctl(mib, 2, &physical_memory, &len, NULL, 0);
+ return physical_memory;
+}
+
+// rsize and dirty_size is not adjusted for dyld shared cache and multiple __LINKEDIT segment, as in vmmap. In practice, dirty_size doesn't differ much but rsize may. There is performance penalty for the adjustment. Right now, only use the dirty_size.
+static void GetRegionSizes(task_t task, mach_vm_size_t &rsize, mach_vm_size_t &dirty_size)
+{
+ mach_vm_address_t address = 0;
+ mach_vm_size_t size;
+ kern_return_t err = 0;
+ unsigned nestingDepth = 0;
+ mach_vm_size_t pages_resident = 0;
+ mach_vm_size_t pages_dirtied = 0;
+
+ while (1)
+ {
+ mach_msg_type_number_t count;
+ struct vm_region_submap_info_64 info;
+
+ count = VM_REGION_SUBMAP_INFO_COUNT_64;
+ err = mach_vm_region_recurse(task, &address, &size, &nestingDepth, (vm_region_info_t)&info, &count);
+ if (err == KERN_INVALID_ADDRESS)
+ {
+ // It seems like this is a good break too.
+ break;
+ }
+ else if (err)
+ {
+ mach_error("vm_region",err);
+ break; // reached last region
+ }
+
+ bool should_count = true;
+ if (info.is_submap)
+ { // is it a submap?
+ nestingDepth++;
+ should_count = false;
+ }
+ else
+ {
+ // Don't count malloc stack logging data in the TOTAL VM usage lines.
+ if (info.user_tag == VM_MEMORY_ANALYSIS_TOOL)
+ should_count = false;
+ // Don't count system shared library region not used by this process.
+ if (address >= SHARED_REGION_BASE && address < (SHARED_REGION_BASE + SHARED_REGION_SIZE))
+ should_count = false;
+
+ address = address+size;
+ }
+
+ if (should_count)
+ {
+ pages_resident += info.pages_resident;
+ pages_dirtied += info.pages_dirtied;
+ }
+ }
+
+ rsize = pages_resident * vm_page_size;
+ dirty_size = pages_dirtied * vm_page_size;
+}
+
+// Test whether the virtual address is within the architecture's shared region.
+static bool InSharedRegion(mach_vm_address_t addr, cpu_type_t type)
+{
+ mach_vm_address_t base = 0, size = 0;
+
+ switch(type) {
+ case CPU_TYPE_ARM:
+ base = SHARED_REGION_BASE_ARM;
+ size = SHARED_REGION_SIZE_ARM;
+ break;
+
+ case CPU_TYPE_X86_64:
+ base = SHARED_REGION_BASE_X86_64;
+ size = SHARED_REGION_SIZE_X86_64;
+ break;
+
+ case CPU_TYPE_I386:
+ base = SHARED_REGION_BASE_I386;
+ size = SHARED_REGION_SIZE_I386;
+ break;
+
+ default: {
+ // Log error abut unknown CPU type
+ break;
+ }
+ }
+
+
+ return(addr >= base && addr < (base + size));
+}
+
+static void GetMemorySizes(task_t task, cpu_type_t cputype, nub_process_t pid, mach_vm_size_t &rprvt, mach_vm_size_t &vprvt)
+{
+ // Collecting some other info cheaply but not reporting for now.
+ mach_vm_size_t empty = 0;
+ mach_vm_size_t fw_private = 0;
+
+ mach_vm_size_t aliased = 0;
+ mach_vm_size_t pagesize = vm_page_size;
+ bool global_shared_text_data_mapped = false;
+
+ for (mach_vm_address_t addr=0, size=0; ; addr += size)
+ {
+ vm_region_top_info_data_t info;
+ mach_msg_type_number_t count = VM_REGION_TOP_INFO_COUNT;
+ mach_port_t object_name;
+
+ kern_return_t kr = mach_vm_region(task, &addr, &size, VM_REGION_TOP_INFO, (vm_region_info_t)&info, &count, &object_name);
+ if (kr != KERN_SUCCESS) break;
+
+ if (InSharedRegion(addr, cputype))
+ {
+ // Private Shared
+ fw_private += info.private_pages_resident * pagesize;
+
+ // Check if this process has the globally shared text and data regions mapped in. If so, set global_shared_text_data_mapped to TRUE and avoid checking again.
+ if (global_shared_text_data_mapped == FALSE && info.share_mode == SM_EMPTY) {
+ vm_region_basic_info_data_64_t b_info;
+ mach_vm_address_t b_addr = addr;
+ mach_vm_size_t b_size = size;
+ count = VM_REGION_BASIC_INFO_COUNT_64;
+
+ kr = mach_vm_region(task, &b_addr, &b_size, VM_REGION_BASIC_INFO, (vm_region_info_t)&b_info, &count, &object_name);
+ if (kr != KERN_SUCCESS) break;
+
+ if (b_info.reserved) {
+ global_shared_text_data_mapped = TRUE;
+ }
+ }
+
+ // Short circuit the loop if this isn't a shared private region, since that's the only region type we care about within the current address range.
+ if (info.share_mode != SM_PRIVATE)
+ {
+ continue;
+ }
+ }
+
+ // Update counters according to the region type.
+ if (info.share_mode == SM_COW && info.ref_count == 1)
+ {
+ // Treat single reference SM_COW as SM_PRIVATE
+ info.share_mode = SM_PRIVATE;
+ }
+
+ switch (info.share_mode)
+ {
+ case SM_LARGE_PAGE:
+ // Treat SM_LARGE_PAGE the same as SM_PRIVATE
+ // since they are not shareable and are wired.
+ case SM_PRIVATE:
+ rprvt += info.private_pages_resident * pagesize;
+ rprvt += info.shared_pages_resident * pagesize;
+ vprvt += size;
+ break;
+
+ case SM_EMPTY:
+ empty += size;
+ break;
+
+ case SM_COW:
+ case SM_SHARED:
+ {
+ if (pid == 0)
+ {
+ // Treat kernel_task specially
+ if (info.share_mode == SM_COW)
+ {
+ rprvt += info.private_pages_resident * pagesize;
+ vprvt += size;
+ }
+ break;
+ }
+
+ if (info.share_mode == SM_COW)
+ {
+ rprvt += info.private_pages_resident * pagesize;
+ vprvt += info.private_pages_resident * pagesize;
+ }
+ break;
+ }
+ default:
+ // log that something is really bad.
+ break;
+ }
+ }
+
+ rprvt += aliased;
+}
+
+nub_bool_t
+MachVMMemory::GetMemoryProfile(task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size)
+{
+ static mach_port_t localHost = mach_host_self();
+ mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
+ host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vm_stats, &count);
+ vm_stats.wire_count += GetStolenPages();
+ physical_memory = GetPhysicalMemory();
+
+ // This uses vmmap strategy. We don't use the returned rsize for now. We prefer to match top's version since that's what we do for the rest of the metrics.
+ GetRegionSizes(task, rsize, dirty_size);
+
+ GetMemorySizes(task, cputype, pid, rprvt, vprvt);
+
+ rsize = ti.resident_size;
+ vsize = ti.virtual_size;
+
+ return true;
+}
+
nub_size_t
MachVMMemory::Read(task_t task, nub_addr_t address, void *data, nub_size_t data_count)
{
Index: aze/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h 2013-03-03 09:35:50.343457350 +0100
@@ -28,12 +28,13 @@
nub_size_t Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count);
nub_size_t PageSize();
nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info);
+ nub_bool_t GetMemoryProfile(task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size);
protected:
nub_size_t MaxBytesLeftInPage(nub_addr_t addr, nub_size_t count);
nub_size_t WriteRegion(task_t task, const nub_addr_t address, const void *data, const nub_size_t data_count);
- vm_size_t m_page_size;
+ vm_size_t m_page_size;
DNBError m_err;
};
Index: aze/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/ppc/DNBArchImpl.cpp 2013-03-03 09:35:50.343457350 +0100
@@ -78,7 +78,7 @@
if (force || m_state.GetError(e_regSetGPR, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetGPR, (thread_state_t)&m_state.gpr, &count));
+ m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetGPR, (thread_state_t)&m_state.gpr, &count));
}
return m_state.GetError(e_regSetGPR, Read);
}
@@ -89,7 +89,7 @@
if (force || m_state.GetError(e_regSetFPR, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeFPR;
- m_state.SetError(e_regSetFPR, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetFPR, (thread_state_t)&m_state.fpr, &count));
+ m_state.SetError(e_regSetFPR, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetFPR, (thread_state_t)&m_state.fpr, &count));
}
return m_state.GetError(e_regSetFPR, Read);
}
@@ -100,7 +100,7 @@
if (force || m_state.GetError(e_regSetEXC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetEXC, (thread_state_t)&m_state.exc, &count));
+ m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetEXC, (thread_state_t)&m_state.exc, &count));
}
return m_state.GetError(e_regSetEXC, Read);
}
@@ -111,7 +111,7 @@
if (force || m_state.GetError(e_regSetVEC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeVEC;
- m_state.SetError(e_regSetVEC, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetVEC, (thread_state_t)&m_state.vec, &count));
+ m_state.SetError(e_regSetVEC, Read, ::thread_get_state(m_thread->MachPortNumber(), e_regSetVEC, (thread_state_t)&m_state.vec, &count));
}
return m_state.GetError(e_regSetVEC, Read);
}
@@ -119,28 +119,28 @@
kern_return_t
DNBArchMachPPC::SetGPRState()
{
- m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetGPR, (thread_state_t)&m_state.gpr, e_regSetWordSizeGPR));
+ m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetGPR, (thread_state_t)&m_state.gpr, e_regSetWordSizeGPR));
return m_state.GetError(e_regSetGPR, Write);
}
kern_return_t
DNBArchMachPPC::SetFPRState()
{
- m_state.SetError(e_regSetFPR, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetFPR, (thread_state_t)&m_state.fpr, e_regSetWordSizeFPR));
+ m_state.SetError(e_regSetFPR, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetFPR, (thread_state_t)&m_state.fpr, e_regSetWordSizeFPR));
return m_state.GetError(e_regSetFPR, Write);
}
kern_return_t
DNBArchMachPPC::SetEXCState()
{
- m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetEXC, (thread_state_t)&m_state.exc, e_regSetWordSizeEXC));
+ m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetEXC, (thread_state_t)&m_state.exc, e_regSetWordSizeEXC));
return m_state.GetError(e_regSetEXC, Write);
}
kern_return_t
DNBArchMachPPC::SetVECState()
{
- m_state.SetError(e_regSetVEC, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetVEC, (thread_state_t)&m_state.vec, e_regSetWordSizeVEC));
+ m_state.SetError(e_regSetVEC, Write, ::thread_set_state(m_thread->MachPortNumber(), e_regSetVEC, (thread_state_t)&m_state.vec, e_regSetWordSizeVEC));
return m_state.GetError(e_regSetVEC, Write);
}
Index: aze/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp 2013-03-03 09:35:50.347457349 +0100
@@ -180,7 +180,7 @@
m_state.SetError(e_regSetGPR, Read, 0);
#else
mach_msg_type_number_t count = e_regSetWordSizeGPR;
- m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
+ m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
"\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
"\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
@@ -188,7 +188,7 @@
"\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
"\n\trip = %16.16llx"
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
- m_thread->ThreadID(), x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT,
+ m_thread->MachPortNumber(), x86_THREAD_STATE64, x86_THREAD_STATE64_COUNT,
m_state.GetError(e_regSetGPR, Read),
m_state.context.gpr.__rax,m_state.context.gpr.__rbx,m_state.context.gpr.__rcx,
m_state.context.gpr.__rdx,m_state.context.gpr.__rdi,m_state.context.gpr.__rsi,
@@ -220,7 +220,7 @@
// "\n\t cs = %16.16llx"
// "\n\t fs = %16.16llx"
// "\n\t gs = %16.16llx",
- // m_thread->ThreadID(),
+ // m_thread->MachPortNumber(),
// x86_THREAD_STATE64,
// x86_THREAD_STATE64_COUNT,
// m_state.GetError(e_regSetGPR, Read),
@@ -414,17 +414,17 @@
if (CPUHasAVX() || FORCE_AVX_REGS)
{
mach_msg_type_number_t count = e_regSetWordSizeAVX;
- m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
+ m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &avx, %u (%u passed in) carp) => 0x%8.8x",
- m_thread->ThreadID(), __x86_64_AVX_STATE, (uint32_t)count,
+ m_thread->MachPortNumber(), __x86_64_AVX_STATE, (uint32_t)count,
e_regSetWordSizeAVX, m_state.GetError(e_regSetFPU, Read));
}
else
{
mach_msg_type_number_t count = e_regSetWordSizeFPU;
- m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
+ m_state.SetError(e_regSetFPU, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, &count));
DNBLogThreadedIf (LOG_THREAD, "::thread_get_state (0x%4.4x, %u, &fpu, %u (%u passed in) => 0x%8.8x",
- m_thread->ThreadID(), __x86_64_FLOAT_STATE, (uint32_t)count,
+ m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, (uint32_t)count,
e_regSetWordSizeFPU, m_state.GetError(e_regSetFPU, Read));
}
}
@@ -438,7 +438,7 @@
if (force || m_state.GetError(e_regSetEXC, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeEXC;
- m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
+ m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count));
}
return m_state.GetError(e_regSetEXC, Read);
}
@@ -446,10 +446,10 @@
kern_return_t
DNBArchImplX86_64::SetGPRState()
{
- kern_return_t kret = ::thread_abort_safely(m_thread->ThreadID());
- DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->ThreadID(), kret, m_thread->Process()->StopCount());
+ kern_return_t kret = ::thread_abort_safely(m_thread->MachPortNumber());
+ DNBLogThreadedIf (LOG_THREAD, "thread = 0x%4.4x calling thread_abort_safely (tid) => %u (SetGPRState() for stop_count = %u)", m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount());
- m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
+ m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE, (thread_state_t)&m_state.context.gpr, e_regSetWordSizeGPR));
DNBLogThreadedIf (LOG_THREAD, "::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
"\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
"\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
@@ -457,7 +457,7 @@
"\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
"\n\trip = %16.16llx"
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
- m_thread->ThreadID(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR,
+ m_thread->MachPortNumber(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR,
m_state.GetError(e_regSetGPR, Write),
m_state.context.gpr.__rax,m_state.context.gpr.__rbx,m_state.context.gpr.__rcx,
m_state.context.gpr.__rdx,m_state.context.gpr.__rdi,m_state.context.gpr.__rsi,
@@ -481,12 +481,12 @@
{
if (CPUHasAVX() || FORCE_AVX_REGS)
{
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_AVX_STATE, (thread_state_t)&m_state.context.fpu.avx, e_regSetWordSizeAVX));
return m_state.GetError(e_regSetFPU, Write);
}
else
{
- m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
+ m_state.SetError(e_regSetFPU, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_FLOAT_STATE, (thread_state_t)&m_state.context.fpu.no_avx, e_regSetWordSizeFPU));
return m_state.GetError(e_regSetFPU, Write);
}
}
@@ -495,7 +495,7 @@
kern_return_t
DNBArchImplX86_64::SetEXCState()
{
- m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
+ m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, e_regSetWordSizeEXC));
return m_state.GetError(e_regSetEXC, Write);
}
@@ -505,7 +505,7 @@
if (force || m_state.GetError(e_regSetDBG, Read))
{
mach_msg_type_number_t count = e_regSetWordSizeDBG;
- m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->ThreadID(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
+ m_state.SetError(e_regSetDBG, Read, ::thread_get_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, &count));
}
return m_state.GetError(e_regSetDBG, Read);
}
@@ -513,7 +513,7 @@
kern_return_t
DNBArchImplX86_64::SetDBGState()
{
- m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->ThreadID(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
+ m_state.SetError(e_regSetDBG, Write, ::thread_set_state(m_thread->MachPortNumber(), __x86_64_DEBUG_STATE, (thread_state_t)&m_state.context.dbg, e_regSetWordSizeDBG));
return m_state.GetError(e_regSetDBG, Write);
}
@@ -795,7 +795,7 @@
bool
DNBArchImplX86_64::StartTransForHWP()
{
- if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ if (m_2pc_trans_state != Trans_Done && m_2pc_trans_state != Trans_Rolled_Back)
DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
m_2pc_dbg_checkpoint = m_state.context.dbg;
m_2pc_trans_state = Trans_Pending;
@@ -995,6 +995,58 @@
gpr_cs,
gpr_fs,
gpr_gs,
+ gpr_eax,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_r8d, // Low 32 bits or r8
+ gpr_r9d, // Low 32 bits or r9
+ gpr_r10d, // Low 32 bits or r10
+ gpr_r11d, // Low 32 bits or r11
+ gpr_r12d, // Low 32 bits or r12
+ gpr_r13d, // Low 32 bits or r13
+ gpr_r14d, // Low 32 bits or r14
+ gpr_r15d, // Low 32 bits or r15
+ gpr_ax ,
+ gpr_bx ,
+ gpr_cx ,
+ gpr_dx ,
+ gpr_di ,
+ gpr_si ,
+ gpr_bp ,
+ gpr_sp ,
+ gpr_r8w, // Low 16 bits or r8
+ gpr_r9w, // Low 16 bits or r9
+ gpr_r10w, // Low 16 bits or r10
+ gpr_r11w, // Low 16 bits or r11
+ gpr_r12w, // Low 16 bits or r12
+ gpr_r13w, // Low 16 bits or r13
+ gpr_r14w, // Low 16 bits or r14
+ gpr_r15w, // Low 16 bits or r15
+ gpr_ah ,
+ gpr_bh ,
+ gpr_ch ,
+ gpr_dh ,
+ gpr_al ,
+ gpr_bl ,
+ gpr_cl ,
+ gpr_dl ,
+ gpr_dil,
+ gpr_sil,
+ gpr_bpl,
+ gpr_spl,
+ gpr_r8l, // Low 8 bits or r8
+ gpr_r9l, // Low 8 bits or r9
+ gpr_r10l, // Low 8 bits or r10
+ gpr_r11l, // Low 8 bits or r11
+ gpr_r12l, // Low 8 bits or r12
+ gpr_r13l, // Low 8 bits or r13
+ gpr_r14l, // Low 8 bits or r14
+ gpr_r15l, // Low 8 bits or r15
k_num_gpr_regs
};
@@ -1230,12 +1282,53 @@
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
-#define DEFINE_GPR(reg) { e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, INVALID_NUB_REGNUM, gdb_##reg }
-#define DEFINE_GPR_ALT(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg }
-#define DEFINE_GPR_ALT2(reg, alt) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_##reg }
-#define DEFINE_GPR_ALT3(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, gdb_##reg }
+#define DEFINE_GPR(reg) { e_regSetGPR, gpr_##reg, #reg, NULL, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, INVALID_NUB_REGNUM, gdb_##reg, NULL, g_invalidate_##reg }
+#define DEFINE_GPR_ALT(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg, NULL, g_invalidate_##reg }
+#define DEFINE_GPR_ALT2(reg, alt) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_##reg, NULL, NULL }
+#define DEFINE_GPR_ALT3(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gen, gdb_##reg, NULL, NULL }
+#define DEFINE_GPR_ALT4(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, GPR_SIZE(reg), GPR_OFFSET(reg), gcc_dwarf_##reg, gcc_dwarf_##reg, gen, gdb_##reg, NULL, NULL }
+
+#define DEFINE_GPR_PSEUDO_32(reg32,reg64) { e_regSetGPR, gpr_##reg32, #reg32, NULL, Uint, Hex, 4, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_16(reg16,reg64) { e_regSetGPR, gpr_##reg16, #reg16, NULL, Uint, Hex, 2, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8H(reg8,reg64) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg64)+1,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8L(reg8,reg64) { e_regSetGPR, gpr_##reg8 , #reg8 , NULL, Uint, Hex, 1, GPR_OFFSET(reg64) ,INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, g_contained_##reg64, g_invalidate_##reg64 }
// General purpose registers for 64 bit
+
+uint32_t g_contained_rax[] = { gpr_rax, INVALID_NUB_REGNUM };
+uint32_t g_contained_rbx[] = { gpr_rbx, INVALID_NUB_REGNUM };
+uint32_t g_contained_rcx[] = { gpr_rcx, INVALID_NUB_REGNUM };
+uint32_t g_contained_rdx[] = { gpr_rdx, INVALID_NUB_REGNUM };
+uint32_t g_contained_rdi[] = { gpr_rdi, INVALID_NUB_REGNUM };
+uint32_t g_contained_rsi[] = { gpr_rsi, INVALID_NUB_REGNUM };
+uint32_t g_contained_rbp[] = { gpr_rbp, INVALID_NUB_REGNUM };
+uint32_t g_contained_rsp[] = { gpr_rsp, INVALID_NUB_REGNUM };
+uint32_t g_contained_r8[] = { gpr_r8 , INVALID_NUB_REGNUM };
+uint32_t g_contained_r9[] = { gpr_r9 , INVALID_NUB_REGNUM };
+uint32_t g_contained_r10[] = { gpr_r10, INVALID_NUB_REGNUM };
+uint32_t g_contained_r11[] = { gpr_r11, INVALID_NUB_REGNUM };
+uint32_t g_contained_r12[] = { gpr_r12, INVALID_NUB_REGNUM };
+uint32_t g_contained_r13[] = { gpr_r13, INVALID_NUB_REGNUM };
+uint32_t g_contained_r14[] = { gpr_r14, INVALID_NUB_REGNUM };
+uint32_t g_contained_r15[] = { gpr_r15, INVALID_NUB_REGNUM };
+
+uint32_t g_invalidate_rax[] = { gpr_rax, gpr_eax , gpr_ax , gpr_ah , gpr_al, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rbx[] = { gpr_rbx, gpr_ebx , gpr_bx , gpr_bh , gpr_bl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rcx[] = { gpr_rcx, gpr_ecx , gpr_cx , gpr_ch , gpr_cl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rdx[] = { gpr_rdx, gpr_edx , gpr_dx , gpr_dh , gpr_dl, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rdi[] = { gpr_rdi, gpr_edi , gpr_di , gpr_dil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rsi[] = { gpr_rsi, gpr_esi , gpr_si , gpr_sil , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rbp[] = { gpr_rbp, gpr_ebp , gpr_bp , gpr_bpl , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_rsp[] = { gpr_rsp, gpr_esp , gpr_sp , gpr_spl , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r8 [] = { gpr_r8 , gpr_r8d , gpr_r8w , gpr_r8l , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r9 [] = { gpr_r9 , gpr_r9d , gpr_r9w , gpr_r9l , INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r10[] = { gpr_r10, gpr_r10d, gpr_r10w, gpr_r10l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r11[] = { gpr_r11, gpr_r11d, gpr_r11w, gpr_r11l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r12[] = { gpr_r12, gpr_r12d, gpr_r12w, gpr_r12l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r13[] = { gpr_r13, gpr_r13d, gpr_r13w, gpr_r13l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r14[] = { gpr_r14, gpr_r14d, gpr_r14w, gpr_r14l, INVALID_NUB_REGNUM };
+uint32_t g_invalidate_r15[] = { gpr_r15, gpr_r15d, gpr_r15w, gpr_r15l, INVALID_NUB_REGNUM };
+
const DNBRegisterInfo
DNBArchImplX86_64::g_gpr_registers[] =
{
@@ -1255,111 +1348,163 @@
DEFINE_GPR (r13),
DEFINE_GPR (r14),
DEFINE_GPR (r15),
- DEFINE_GPR_ALT (rip , "pc", GENERIC_REGNUM_PC),
+ DEFINE_GPR_ALT4 (rip , "pc", GENERIC_REGNUM_PC),
DEFINE_GPR_ALT3 (rflags, "flags", GENERIC_REGNUM_FLAGS),
DEFINE_GPR_ALT2 (cs, NULL),
DEFINE_GPR_ALT2 (fs, NULL),
DEFINE_GPR_ALT2 (gs, NULL),
+ DEFINE_GPR_PSEUDO_32 (eax, rax),
+ DEFINE_GPR_PSEUDO_32 (ebx, rbx),
+ DEFINE_GPR_PSEUDO_32 (ecx, rcx),
+ DEFINE_GPR_PSEUDO_32 (edx, rdx),
+ DEFINE_GPR_PSEUDO_32 (edi, rdi),
+ DEFINE_GPR_PSEUDO_32 (esi, rsi),
+ DEFINE_GPR_PSEUDO_32 (ebp, rbp),
+ DEFINE_GPR_PSEUDO_32 (esp, rsp),
+ DEFINE_GPR_PSEUDO_32 (r8d, r8),
+ DEFINE_GPR_PSEUDO_32 (r9d, r9),
+ DEFINE_GPR_PSEUDO_32 (r10d, r10),
+ DEFINE_GPR_PSEUDO_32 (r11d, r11),
+ DEFINE_GPR_PSEUDO_32 (r12d, r12),
+ DEFINE_GPR_PSEUDO_32 (r13d, r13),
+ DEFINE_GPR_PSEUDO_32 (r14d, r14),
+ DEFINE_GPR_PSEUDO_32 (r15d, r15),
+ DEFINE_GPR_PSEUDO_16 (ax , rax),
+ DEFINE_GPR_PSEUDO_16 (bx , rbx),
+ DEFINE_GPR_PSEUDO_16 (cx , rcx),
+ DEFINE_GPR_PSEUDO_16 (dx , rdx),
+ DEFINE_GPR_PSEUDO_16 (di , rdi),
+ DEFINE_GPR_PSEUDO_16 (si , rsi),
+ DEFINE_GPR_PSEUDO_16 (bp , rbp),
+ DEFINE_GPR_PSEUDO_16 (sp , rsp),
+ DEFINE_GPR_PSEUDO_16 (r8w, r8),
+ DEFINE_GPR_PSEUDO_16 (r9w, r9),
+ DEFINE_GPR_PSEUDO_16 (r10w, r10),
+ DEFINE_GPR_PSEUDO_16 (r11w, r11),
+ DEFINE_GPR_PSEUDO_16 (r12w, r12),
+ DEFINE_GPR_PSEUDO_16 (r13w, r13),
+ DEFINE_GPR_PSEUDO_16 (r14w, r14),
+ DEFINE_GPR_PSEUDO_16 (r15w, r15),
+ DEFINE_GPR_PSEUDO_8H (ah , rax),
+ DEFINE_GPR_PSEUDO_8H (bh , rbx),
+ DEFINE_GPR_PSEUDO_8H (ch , rcx),
+ DEFINE_GPR_PSEUDO_8H (dh , rdx),
+ DEFINE_GPR_PSEUDO_8L (al , rax),
+ DEFINE_GPR_PSEUDO_8L (bl , rbx),
+ DEFINE_GPR_PSEUDO_8L (cl , rcx),
+ DEFINE_GPR_PSEUDO_8L (dl , rdx),
+ DEFINE_GPR_PSEUDO_8L (dil, rdi),
+ DEFINE_GPR_PSEUDO_8L (sil, rsi),
+ DEFINE_GPR_PSEUDO_8L (bpl, rbp),
+ DEFINE_GPR_PSEUDO_8L (spl, rsp),
+ DEFINE_GPR_PSEUDO_8L (r8l, r8),
+ DEFINE_GPR_PSEUDO_8L (r9l, r9),
+ DEFINE_GPR_PSEUDO_8L (r10l, r10),
+ DEFINE_GPR_PSEUDO_8L (r11l, r11),
+ DEFINE_GPR_PSEUDO_8L (r12l, r12),
+ DEFINE_GPR_PSEUDO_8L (r13l, r13),
+ DEFINE_GPR_PSEUDO_8L (r14l, r14),
+ DEFINE_GPR_PSEUDO_8L (r15l, r15)
};
// Floating point registers 64 bit
const DNBRegisterInfo
DNBArchImplX86_64::g_fpu_registers_no_avx[] =
{
- { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
+ { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , FPU_OFFSET(fcw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , FPU_OFFSET(fsw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , FPU_OFFSET(ftw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , FPU_OFFSET(fop) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , FPU_OFFSET(ip) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , FPU_OFFSET(cs) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , FPU_OFFSET(dp) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , FPU_OFFSET(ds) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , FPU_OFFSET(mxcsr) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , FPU_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U, NULL, NULL },
- { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0 },
- { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1 },
- { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2 },
- { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3 },
- { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4 },
- { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5 },
- { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6 },
- { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7 },
+ { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), FPU_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0, NULL, NULL },
+ { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), FPU_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1, NULL, NULL },
+ { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), FPU_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2, NULL, NULL },
+ { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), FPU_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3, NULL, NULL },
+ { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), FPU_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4, NULL, NULL },
+ { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), FPU_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5, NULL, NULL },
+ { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), FPU_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6, NULL, NULL },
+ { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), FPU_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7, NULL, NULL },
- { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , FPU_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 },
- { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , FPU_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 },
- { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , FPU_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 },
- { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , FPU_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 },
- { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , FPU_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 },
- { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , FPU_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 },
- { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , FPU_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 },
- { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , FPU_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 },
- { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , FPU_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 },
- { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , FPU_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 },
- { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , FPU_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10 },
- { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , FPU_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11 },
- { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , FPU_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12 },
- { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , FPU_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13 },
- { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , FPU_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14 },
- { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , FPU_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15 },
+ { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , FPU_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , FPU_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , FPU_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , FPU_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , FPU_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , FPU_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , FPU_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , FPU_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , FPU_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , FPU_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , FPU_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10, NULL, NULL },
+ { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , FPU_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11, NULL, NULL },
+ { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , FPU_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12, NULL, NULL },
+ { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , FPU_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13, NULL, NULL },
+ { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , FPU_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14, NULL, NULL },
+ { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , FPU_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15, NULL, NULL },
};
const DNBRegisterInfo
DNBArchImplX86_64::g_fpu_registers_avx[] =
{
- { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U },
- { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U },
+ { e_regSetFPU, fpu_fcw , "fctrl" , NULL, Uint, Hex, FPU_SIZE_UINT(fcw) , AVX_OFFSET(fcw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fsw , "fstat" , NULL, Uint, Hex, FPU_SIZE_UINT(fsw) , AVX_OFFSET(fsw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ftw , "ftag" , NULL, Uint, Hex, FPU_SIZE_UINT(ftw) , AVX_OFFSET(ftw) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_fop , "fop" , NULL, Uint, Hex, FPU_SIZE_UINT(fop) , AVX_OFFSET(fop) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ip , "fioff" , NULL, Uint, Hex, FPU_SIZE_UINT(ip) , AVX_OFFSET(ip) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_cs , "fiseg" , NULL, Uint, Hex, FPU_SIZE_UINT(cs) , AVX_OFFSET(cs) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_dp , "fooff" , NULL, Uint, Hex, FPU_SIZE_UINT(dp) , AVX_OFFSET(dp) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_ds , "foseg" , NULL, Uint, Hex, FPU_SIZE_UINT(ds) , AVX_OFFSET(ds) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsr , "mxcsr" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsr) , AVX_OFFSET(mxcsr) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetFPU, fpu_mxcsrmask, "mxcsrmask" , NULL, Uint, Hex, FPU_SIZE_UINT(mxcsrmask) , AVX_OFFSET(mxcsrmask) , -1U, -1U, -1U, -1U, NULL, NULL },
- { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0 },
- { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1 },
- { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2 },
- { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3 },
- { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4 },
- { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5 },
- { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6 },
- { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7 },
+ { e_regSetFPU, fpu_stmm0, "stmm0", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm0), AVX_OFFSET(stmm0), gcc_dwarf_stmm0, gcc_dwarf_stmm0, -1U, gdb_stmm0, NULL, NULL },
+ { e_regSetFPU, fpu_stmm1, "stmm1", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm1), AVX_OFFSET(stmm1), gcc_dwarf_stmm1, gcc_dwarf_stmm1, -1U, gdb_stmm1, NULL, NULL },
+ { e_regSetFPU, fpu_stmm2, "stmm2", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm2), AVX_OFFSET(stmm2), gcc_dwarf_stmm2, gcc_dwarf_stmm2, -1U, gdb_stmm2, NULL, NULL },
+ { e_regSetFPU, fpu_stmm3, "stmm3", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm3), AVX_OFFSET(stmm3), gcc_dwarf_stmm3, gcc_dwarf_stmm3, -1U, gdb_stmm3, NULL, NULL },
+ { e_regSetFPU, fpu_stmm4, "stmm4", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm4), AVX_OFFSET(stmm4), gcc_dwarf_stmm4, gcc_dwarf_stmm4, -1U, gdb_stmm4, NULL, NULL },
+ { e_regSetFPU, fpu_stmm5, "stmm5", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm5), AVX_OFFSET(stmm5), gcc_dwarf_stmm5, gcc_dwarf_stmm5, -1U, gdb_stmm5, NULL, NULL },
+ { e_regSetFPU, fpu_stmm6, "stmm6", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm6), AVX_OFFSET(stmm6), gcc_dwarf_stmm6, gcc_dwarf_stmm6, -1U, gdb_stmm6, NULL, NULL },
+ { e_regSetFPU, fpu_stmm7, "stmm7", NULL, Vector, VectorOfUInt8, FPU_SIZE_MMST(stmm7), AVX_OFFSET(stmm7), gcc_dwarf_stmm7, gcc_dwarf_stmm7, -1U, gdb_stmm7, NULL, NULL },
- { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , AVX_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 },
- { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , AVX_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 },
- { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , AVX_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 },
- { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , AVX_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 },
- { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , AVX_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 },
- { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , AVX_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 },
- { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , AVX_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 },
- { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , AVX_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 },
- { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , AVX_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 },
- { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , AVX_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 },
- { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , AVX_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10 },
- { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , AVX_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11 },
- { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , AVX_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12 },
- { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , AVX_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13 },
- { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , AVX_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14 },
- { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , AVX_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15 },
-
- { e_regSetFPU, fpu_ymm0 , "ymm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0) , AVX_OFFSET_YMM(0) , gcc_dwarf_ymm0 , gcc_dwarf_ymm0 , -1U, gdb_ymm0 },
- { e_regSetFPU, fpu_ymm1 , "ymm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1) , AVX_OFFSET_YMM(1) , gcc_dwarf_ymm1 , gcc_dwarf_ymm1 , -1U, gdb_ymm1 },
- { e_regSetFPU, fpu_ymm2 , "ymm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2) , AVX_OFFSET_YMM(2) , gcc_dwarf_ymm2 , gcc_dwarf_ymm2 , -1U, gdb_ymm2 },
- { e_regSetFPU, fpu_ymm3 , "ymm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3) , AVX_OFFSET_YMM(3) , gcc_dwarf_ymm3 , gcc_dwarf_ymm3 , -1U, gdb_ymm3 },
- { e_regSetFPU, fpu_ymm4 , "ymm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4) , AVX_OFFSET_YMM(4) , gcc_dwarf_ymm4 , gcc_dwarf_ymm4 , -1U, gdb_ymm4 },
- { e_regSetFPU, fpu_ymm5 , "ymm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5) , AVX_OFFSET_YMM(5) , gcc_dwarf_ymm5 , gcc_dwarf_ymm5 , -1U, gdb_ymm5 },
- { e_regSetFPU, fpu_ymm6 , "ymm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6) , AVX_OFFSET_YMM(6) , gcc_dwarf_ymm6 , gcc_dwarf_ymm6 , -1U, gdb_ymm6 },
- { e_regSetFPU, fpu_ymm7 , "ymm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7) , AVX_OFFSET_YMM(7) , gcc_dwarf_ymm7 , gcc_dwarf_ymm7 , -1U, gdb_ymm7 },
- { e_regSetFPU, fpu_ymm8 , "ymm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm8) , AVX_OFFSET_YMM(8) , gcc_dwarf_ymm8 , gcc_dwarf_ymm8 , -1U, gdb_ymm8 },
- { e_regSetFPU, fpu_ymm9 , "ymm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm9) , AVX_OFFSET_YMM(9) , gcc_dwarf_ymm9 , gcc_dwarf_ymm9 , -1U, gdb_ymm9 },
- { e_regSetFPU, fpu_ymm10, "ymm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm10) , AVX_OFFSET_YMM(10), gcc_dwarf_ymm10, gcc_dwarf_ymm10, -1U, gdb_ymm10 },
- { e_regSetFPU, fpu_ymm11, "ymm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm11) , AVX_OFFSET_YMM(11), gcc_dwarf_ymm11, gcc_dwarf_ymm11, -1U, gdb_ymm11 },
- { e_regSetFPU, fpu_ymm12, "ymm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm12) , AVX_OFFSET_YMM(12), gcc_dwarf_ymm12, gcc_dwarf_ymm12, -1U, gdb_ymm12 },
- { e_regSetFPU, fpu_ymm13, "ymm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm13) , AVX_OFFSET_YMM(13), gcc_dwarf_ymm13, gcc_dwarf_ymm13, -1U, gdb_ymm13 },
- { e_regSetFPU, fpu_ymm14, "ymm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm14) , AVX_OFFSET_YMM(14), gcc_dwarf_ymm14, gcc_dwarf_ymm14, -1U, gdb_ymm14 },
- { e_regSetFPU, fpu_ymm15, "ymm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm15) , AVX_OFFSET_YMM(15), gcc_dwarf_ymm15, gcc_dwarf_ymm15, -1U, gdb_ymm15 }
+ { e_regSetFPU, fpu_xmm0 , "xmm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm0) , AVX_OFFSET(xmm0) , gcc_dwarf_xmm0 , gcc_dwarf_xmm0 , -1U, gdb_xmm0 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm1 , "xmm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm1) , AVX_OFFSET(xmm1) , gcc_dwarf_xmm1 , gcc_dwarf_xmm1 , -1U, gdb_xmm1 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm2 , "xmm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm2) , AVX_OFFSET(xmm2) , gcc_dwarf_xmm2 , gcc_dwarf_xmm2 , -1U, gdb_xmm2 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm3 , "xmm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm3) , AVX_OFFSET(xmm3) , gcc_dwarf_xmm3 , gcc_dwarf_xmm3 , -1U, gdb_xmm3 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm4 , "xmm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm4) , AVX_OFFSET(xmm4) , gcc_dwarf_xmm4 , gcc_dwarf_xmm4 , -1U, gdb_xmm4 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm5 , "xmm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm5) , AVX_OFFSET(xmm5) , gcc_dwarf_xmm5 , gcc_dwarf_xmm5 , -1U, gdb_xmm5 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm6 , "xmm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm6) , AVX_OFFSET(xmm6) , gcc_dwarf_xmm6 , gcc_dwarf_xmm6 , -1U, gdb_xmm6 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm7 , "xmm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm7) , AVX_OFFSET(xmm7) , gcc_dwarf_xmm7 , gcc_dwarf_xmm7 , -1U, gdb_xmm7 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm8 , "xmm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm8) , AVX_OFFSET(xmm8) , gcc_dwarf_xmm8 , gcc_dwarf_xmm8 , -1U, gdb_xmm8 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm9 , "xmm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm9) , AVX_OFFSET(xmm9) , gcc_dwarf_xmm9 , gcc_dwarf_xmm9 , -1U, gdb_xmm9 , NULL, NULL },
+ { e_regSetFPU, fpu_xmm10, "xmm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm10) , AVX_OFFSET(xmm10), gcc_dwarf_xmm10, gcc_dwarf_xmm10, -1U, gdb_xmm10, NULL, NULL },
+ { e_regSetFPU, fpu_xmm11, "xmm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm11) , AVX_OFFSET(xmm11), gcc_dwarf_xmm11, gcc_dwarf_xmm11, -1U, gdb_xmm11, NULL, NULL },
+ { e_regSetFPU, fpu_xmm12, "xmm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm12) , AVX_OFFSET(xmm12), gcc_dwarf_xmm12, gcc_dwarf_xmm12, -1U, gdb_xmm12, NULL, NULL },
+ { e_regSetFPU, fpu_xmm13, "xmm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm13) , AVX_OFFSET(xmm13), gcc_dwarf_xmm13, gcc_dwarf_xmm13, -1U, gdb_xmm13, NULL, NULL },
+ { e_regSetFPU, fpu_xmm14, "xmm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm14) , AVX_OFFSET(xmm14), gcc_dwarf_xmm14, gcc_dwarf_xmm14, -1U, gdb_xmm14, NULL, NULL },
+ { e_regSetFPU, fpu_xmm15, "xmm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_XMM(xmm15) , AVX_OFFSET(xmm15), gcc_dwarf_xmm15, gcc_dwarf_xmm15, -1U, gdb_xmm15, NULL, NULL },
+
+ { e_regSetFPU, fpu_ymm0 , "ymm0" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm0) , AVX_OFFSET_YMM(0) , gcc_dwarf_ymm0 , gcc_dwarf_ymm0 , -1U, gdb_ymm0, NULL, NULL },
+ { e_regSetFPU, fpu_ymm1 , "ymm1" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm1) , AVX_OFFSET_YMM(1) , gcc_dwarf_ymm1 , gcc_dwarf_ymm1 , -1U, gdb_ymm1, NULL, NULL },
+ { e_regSetFPU, fpu_ymm2 , "ymm2" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm2) , AVX_OFFSET_YMM(2) , gcc_dwarf_ymm2 , gcc_dwarf_ymm2 , -1U, gdb_ymm2, NULL, NULL },
+ { e_regSetFPU, fpu_ymm3 , "ymm3" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm3) , AVX_OFFSET_YMM(3) , gcc_dwarf_ymm3 , gcc_dwarf_ymm3 , -1U, gdb_ymm3, NULL, NULL },
+ { e_regSetFPU, fpu_ymm4 , "ymm4" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm4) , AVX_OFFSET_YMM(4) , gcc_dwarf_ymm4 , gcc_dwarf_ymm4 , -1U, gdb_ymm4, NULL, NULL },
+ { e_regSetFPU, fpu_ymm5 , "ymm5" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm5) , AVX_OFFSET_YMM(5) , gcc_dwarf_ymm5 , gcc_dwarf_ymm5 , -1U, gdb_ymm5, NULL, NULL },
+ { e_regSetFPU, fpu_ymm6 , "ymm6" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm6) , AVX_OFFSET_YMM(6) , gcc_dwarf_ymm6 , gcc_dwarf_ymm6 , -1U, gdb_ymm6, NULL, NULL },
+ { e_regSetFPU, fpu_ymm7 , "ymm7" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm7) , AVX_OFFSET_YMM(7) , gcc_dwarf_ymm7 , gcc_dwarf_ymm7 , -1U, gdb_ymm7, NULL, NULL },
+ { e_regSetFPU, fpu_ymm8 , "ymm8" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm8) , AVX_OFFSET_YMM(8) , gcc_dwarf_ymm8 , gcc_dwarf_ymm8 , -1U, gdb_ymm8 , NULL, NULL },
+ { e_regSetFPU, fpu_ymm9 , "ymm9" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm9) , AVX_OFFSET_YMM(9) , gcc_dwarf_ymm9 , gcc_dwarf_ymm9 , -1U, gdb_ymm9 , NULL, NULL },
+ { e_regSetFPU, fpu_ymm10, "ymm10" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm10) , AVX_OFFSET_YMM(10), gcc_dwarf_ymm10, gcc_dwarf_ymm10, -1U, gdb_ymm10, NULL, NULL },
+ { e_regSetFPU, fpu_ymm11, "ymm11" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm11) , AVX_OFFSET_YMM(11), gcc_dwarf_ymm11, gcc_dwarf_ymm11, -1U, gdb_ymm11, NULL, NULL },
+ { e_regSetFPU, fpu_ymm12, "ymm12" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm12) , AVX_OFFSET_YMM(12), gcc_dwarf_ymm12, gcc_dwarf_ymm12, -1U, gdb_ymm12, NULL, NULL },
+ { e_regSetFPU, fpu_ymm13, "ymm13" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm13) , AVX_OFFSET_YMM(13), gcc_dwarf_ymm13, gcc_dwarf_ymm13, -1U, gdb_ymm13, NULL, NULL },
+ { e_regSetFPU, fpu_ymm14, "ymm14" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm14) , AVX_OFFSET_YMM(14), gcc_dwarf_ymm14, gcc_dwarf_ymm14, -1U, gdb_ymm14, NULL, NULL },
+ { e_regSetFPU, fpu_ymm15, "ymm15" , NULL, Vector, VectorOfUInt8, FPU_SIZE_YMM(ymm15) , AVX_OFFSET_YMM(15), gcc_dwarf_ymm15, gcc_dwarf_ymm15, -1U, gdb_ymm15, NULL, NULL }
};
// Exception registers
@@ -1367,9 +1512,9 @@
const DNBRegisterInfo
DNBArchImplX86_64::g_exc_registers[] =
{
- { e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U },
- { e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U },
- { e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U }
+ { e_regSetEXC, exc_trapno, "trapno" , NULL, Uint, Hex, EXC_SIZE (trapno) , EXC_OFFSET (trapno) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetEXC, exc_err, "err" , NULL, Uint, Hex, EXC_SIZE (err) , EXC_OFFSET (err) , -1U, -1U, -1U, -1U, NULL, NULL },
+ { e_regSetEXC, exc_faultvaddr, "faultvaddr", NULL, Uint, Hex, EXC_SIZE (faultvaddr), EXC_OFFSET (faultvaddr) , -1U, -1U, -1U, -1U, NULL, NULL }
};
// Number of registers in each register set
Index: aze/lldb/tools/debugserver/source/RNBContext.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/RNBContext.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/RNBContext.cpp 2013-03-03 09:35:50.347457349 +0100
@@ -148,9 +148,9 @@
bool done = false;
while (!done)
{
- DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable, true)...", __FUNCTION__);
- nub_event_t pid_status_event = DNBProcessWaitForEvents (pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable, true, NULL);
- DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable, true) => 0x%8.8x", __FUNCTION__, pid_status_event);
+ DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable | eEventProfileDataAvailable, true)...", __FUNCTION__);
+ nub_event_t pid_status_event = DNBProcessWaitForEvents (pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable | eEventProfileDataAvailable, true, NULL);
+ DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s calling DNBProcessWaitForEvent(pid, eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged | eEventStdioAvailable | eEventProfileDataAvailable, true) => 0x%8.8x", __FUNCTION__, pid_status_event);
if (pid_status_event == 0)
{
@@ -167,6 +167,13 @@
ctx.Events().WaitForResetAck(RNBContext::event_proc_stdio_available);
}
+ if (pid_status_event & eEventProfileDataAvailable)
+ {
+ DNBLogThreadedIf(LOG_RNB_PROC, "RNBContext::%s (pid=%4.4x) got profile data event....", __FUNCTION__, pid);
+ ctx.Events().SetEvents (RNBContext::event_proc_profile_data);
+ // Wait for the main thread to consume this notification if it requested we wait for it
+ ctx.Events().WaitForResetAck(RNBContext::event_proc_profile_data);
+ }
if (pid_status_event & (eEventProcessRunningStateChanged | eEventProcessStoppedStateChanged))
{
@@ -217,6 +224,8 @@
s += "proc_thread_exiting ";
if (events & event_proc_stdio_available)
s += "proc_stdio_available ";
+ if (events & event_proc_profile_data)
+ s += "proc_profile_data ";
if (events & event_read_packet_available)
s += "read_packet_available ";
if (events & event_read_thread_running)
Index: aze/lldb/tools/debugserver/source/RNBContext.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/RNBContext.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/RNBContext.h 2013-03-03 09:35:50.347457349 +0100
@@ -29,13 +29,15 @@
event_proc_thread_running = 0x02, // Sticky
event_proc_thread_exiting = 0x04,
event_proc_stdio_available = 0x08,
- event_read_packet_available = 0x10,
- event_read_thread_running = 0x20, // Sticky
- event_read_thread_exiting = 0x40,
+ event_proc_profile_data = 0x10,
+ event_read_packet_available = 0x20,
+ event_read_thread_running = 0x40, // Sticky
+ event_read_thread_exiting = 0x80,
normal_event_bits = event_proc_state_changed |
event_proc_thread_exiting |
event_proc_stdio_available |
+ event_proc_profile_data |
event_read_packet_available |
event_read_thread_exiting,
Index: aze/lldb/tools/debugserver/source/RNBRemote.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/RNBRemote.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/RNBRemote.cpp 2013-03-03 09:35:50.347457349 +0100
@@ -30,7 +30,6 @@
#include <iomanip>
#include <sstream>
-
#include <TargetConditionals.h> // for endianness predefines
//----------------------------------------------------------------------
@@ -155,9 +154,9 @@
t.push_back (Packet (remove_read_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z3", "Remove read watchpoint"));
t.push_back (Packet (insert_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "Z4", "Insert access watchpoint"));
t.push_back (Packet (remove_access_watch_bp, &RNBRemote::HandlePacket_z, NULL, "z4", "Remove access watchpoint"));
+ t.push_back (Packet (query_monitor, &RNBRemote::HandlePacket_qRcmd, NULL, "qRcmd", "Monitor command"));
t.push_back (Packet (query_current_thread_id, &RNBRemote::HandlePacket_qC, NULL, "qC", "Query current thread ID"));
t.push_back (Packet (query_get_pid, &RNBRemote::HandlePacket_qGetPid, NULL, "qGetPid", "Query process id"));
-// t.push_back (Packet (query_memory_crc, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qCRC:", "Compute CRC of memory region"));
t.push_back (Packet (query_thread_ids_first, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qfThreadInfo", "Get list of active threads (first req)"));
t.push_back (Packet (query_thread_ids_subsequent, &RNBRemote::HandlePacket_qThreadInfo, NULL, "qsThreadInfo", "Get list of active threads (subsequent req)"));
// APPLE LOCAL: qThreadStopInfo
@@ -173,6 +172,7 @@
t.push_back (Packet (query_vattachorwait_supported, &RNBRemote::HandlePacket_qVAttachOrWaitSupported,NULL, "qVAttachOrWaitSupported", "Replys with OK if the 'vAttachOrWait' packet is supported."));
t.push_back (Packet (query_sync_thread_state_supported, &RNBRemote::HandlePacket_qSyncThreadStateSupported,NULL, "qSyncThreadStateSupported", "Replys with OK if the 'QSyncThreadState:' packet is supported."));
t.push_back (Packet (query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
+ t.push_back (Packet (query_process_info, &RNBRemote::HandlePacket_qProcessInfo, NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
// t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups"));
t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
@@ -193,6 +193,8 @@
t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
t.push_back (Packet (memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL, "qMemoryRegionInfo", "Return size and attributes of a memory region that contains the given address"));
+ t.push_back (Packet (get_profile_data, &RNBRemote::HandlePacket_GetProfileData, NULL, "qGetProfileData", "Return profiling data of the current target."));
+ t.push_back (Packet (set_enable_profiling, &RNBRemote::HandlePacket_SetEnableAsyncProfiling, NULL, "QSetEnableAsyncProfiling", "Enable or disable the profiling of current target."));
t.push_back (Packet (watchpoint_support_info, &RNBRemote::HandlePacket_WatchpointSupportInfo, NULL, "qWatchpointSupportInfo", "Return the number of supported hardware watchpoints"));
}
@@ -226,6 +228,25 @@
}
}
+void
+RNBRemote::SendAsyncProfileData ()
+{
+ if (m_ctx.HasValidProcessID())
+ {
+ nub_process_t pid = m_ctx.ProcessID();
+ char buf[1024];
+ nub_size_t count;
+ do
+ {
+ count = DNBProcessGetAvailableProfileData(pid, buf, sizeof(buf));
+ if (count > 0)
+ {
+ SendAsyncProfileDataPacket (buf, count);
+ }
+ } while (count > 0);
+ }
+}
+
rnb_err_t
RNBRemote::SendHexEncodedBytePacket (const char *header, const void *buf, size_t buf_len, const char *footer)
{
@@ -262,6 +283,18 @@
return SendHexEncodedBytePacket("O", buf, buf_size, NULL);
}
+// This makes use of asynchronous bit 'A' in the gdb remote protocol.
+rnb_err_t
+RNBRemote::SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size)
+{
+ if (buf_size == 0)
+ return rnb_success;
+
+ std::string packet("A");
+ packet.append(buf, buf_size);
+ return SendPacket(packet);
+}
+
rnb_err_t
RNBRemote::SendPacket (const std::string &s)
{
@@ -1401,6 +1434,135 @@
return SendPacket ("");
}
+
+const char *k_space_delimiters = " \t";
+static void
+skip_spaces (std::string &line)
+{
+ if (!line.empty())
+ {
+ size_t space_pos = line.find_first_not_of (k_space_delimiters);
+ if (space_pos > 0)
+ line.erase(0, space_pos);
+ }
+}
+
+static std::string
+get_identifier (std::string &line)
+{
+ std::string word;
+ skip_spaces (line);
+ const size_t line_size = line.size();
+ size_t end_pos;
+ for (end_pos = 0; end_pos < line_size; ++end_pos)
+ {
+ if (end_pos == 0)
+ {
+ if (isalpha(line[end_pos]) || line[end_pos] == '_')
+ continue;
+ }
+ else if (isalnum(line[end_pos]) || line[end_pos] == '_')
+ continue;
+ break;
+ }
+ word.assign (line, 0, end_pos);
+ line.erase(0, end_pos);
+ return word;
+}
+
+static std::string
+get_operator (std::string &line)
+{
+ std::string op;
+ skip_spaces (line);
+ if (!line.empty())
+ {
+ if (line[0] == '=')
+ {
+ op = '=';
+ line.erase(0,1);
+ }
+ }
+ return op;
+}
+
+static std::string
+get_value (std::string &line)
+{
+ std::string value;
+ skip_spaces (line);
+ if (!line.empty())
+ {
+ value.swap(line);
+ }
+ return value;
+}
+
+
+extern void FileLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
+extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
+
+rnb_err_t
+RNBRemote::HandlePacket_qRcmd (const char *p)
+{
+ const char *c = p + strlen("qRcmd,");
+ std::string line;
+ while (c[0] && c[1])
+ {
+ char smallbuf[3] = { c[0], c[1], '\0' };
+ errno = 0;
+ int ch = strtoul (smallbuf, NULL, 16);
+ if (errno != 0 && ch == 0)
+ return HandlePacket_ILLFORMED (__FILE__, __LINE__, p, "non-hex char in payload of qRcmd packet");
+ line.push_back(ch);
+ c += 2;
+ }
+ if (*c == '\0')
+ {
+ std::string command = get_identifier(line);
+ if (command.compare("set") == 0)
+ {
+ std::string variable = get_identifier (line);
+ std::string op = get_operator (line);
+ std::string value = get_value (line);
+ if (variable.compare("logfile") == 0)
+ {
+ FILE *log_file = fopen(value.c_str(), "w");
+ if (log_file)
+ {
+ DNBLogSetLogCallback(FileLogCallback, log_file);
+ return SendPacket ("OK");
+ }
+ return SendPacket ("E71");
+ }
+ else if (variable.compare("logmask") == 0)
+ {
+ char *end;
+ errno = 0;
+ uint32_t logmask = strtoul (value.c_str(), &end, 0);
+ if (errno == 0 && end && *end == '\0')
+ {
+ DNBLogSetLogMask (logmask);
+ if (!DNBLogGetLogCallback())
+ DNBLogSetLogCallback(ASLLogCallback, NULL);
+ return SendPacket ("OK");
+ }
+ errno = 0;
+ logmask = strtoul (value.c_str(), &end, 16);
+ if (errno == 0 && end && *end == '\0')
+ {
+ DNBLogSetLogMask (logmask);
+ return SendPacket ("OK");
+ }
+ return SendPacket ("E72");
+ }
+ return SendPacket ("E70");
+ }
+ return SendPacket ("E69");
+ }
+ return SendPacket ("E73");
+}
+
rnb_err_t
RNBRemote::HandlePacket_qC (const char *p)
{
@@ -1518,6 +1680,30 @@
case GENERIC_REGNUM_ARG8: ostrm << "generic:arg8;"; break;
default: break;
}
+
+ if (reg_entry->nub_info.pseudo_regs && reg_entry->nub_info.pseudo_regs[0] != INVALID_NUB_REGNUM)
+ {
+ ostrm << "container-regs:";
+ for (unsigned i=0; reg_entry->nub_info.pseudo_regs[i] != INVALID_NUB_REGNUM; ++i)
+ {
+ if (i > 0)
+ ostrm << ',';
+ ostrm << RAW_HEXBASE << reg_entry->nub_info.pseudo_regs[i];
+ }
+ ostrm << ';';
+ }
+
+ if (reg_entry->nub_info.update_regs && reg_entry->nub_info.update_regs[0] != INVALID_NUB_REGNUM)
+ {
+ ostrm << "invalidate-regs:";
+ for (unsigned i=0; reg_entry->nub_info.update_regs[i] != INVALID_NUB_REGNUM; ++i)
+ {
+ if (i > 0)
+ ostrm << ',';
+ ostrm << RAW_HEXBASE << reg_entry->nub_info.update_regs[i];
+ }
+ ostrm << ';';
+ }
return SendPacket (ostrm.str ());
}
@@ -1548,6 +1734,16 @@
{
if (*p == '|')
p++;
+
+// to regenerate the LOG_ entries (not including the LOG_RNB entries)
+// $ for logname in `grep '^#define LOG_' DNBDefs.h | egrep -v 'LOG_HI|LOG_LO' | awk '{print $2}'`
+// do
+// echo " else if (strncmp (p, \"$logname\", sizeof (\"$logname\") - 1) == 0)"
+// echo " {"
+// echo " p += sizeof (\"$logname\") - 1;"
+// echo " bitmask |= $logname;"
+// echo " }"
+// done
if (strncmp (p, "LOG_VERBOSE", sizeof ("LOG_VERBOSE") - 1) == 0)
{
p += sizeof ("LOG_VERBOSE") - 1;
@@ -1588,26 +1784,48 @@
p += sizeof ("LOG_MEMORY_DATA_LONG") - 1;
bitmask |= LOG_MEMORY_DATA_LONG;
}
+ else if (strncmp (p, "LOG_MEMORY_PROTECTIONS", sizeof ("LOG_MEMORY_PROTECTIONS") - 1) == 0)
+ {
+ p += sizeof ("LOG_MEMORY_PROTECTIONS") - 1;
+ bitmask |= LOG_MEMORY_PROTECTIONS;
+ }
else if (strncmp (p, "LOG_BREAKPOINTS", sizeof ("LOG_BREAKPOINTS") - 1) == 0)
{
p += sizeof ("LOG_BREAKPOINTS") - 1;
bitmask |= LOG_BREAKPOINTS;
}
- else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
- {
- p += sizeof ("LOG_ALL") - 1;
- bitmask |= LOG_ALL;
- }
else if (strncmp (p, "LOG_EVENTS", sizeof ("LOG_EVENTS") - 1) == 0)
{
p += sizeof ("LOG_EVENTS") - 1;
bitmask |= LOG_EVENTS;
}
+ else if (strncmp (p, "LOG_WATCHPOINTS", sizeof ("LOG_WATCHPOINTS") - 1) == 0)
+ {
+ p += sizeof ("LOG_WATCHPOINTS") - 1;
+ bitmask |= LOG_WATCHPOINTS;
+ }
+ else if (strncmp (p, "LOG_STEP", sizeof ("LOG_STEP") - 1) == 0)
+ {
+ p += sizeof ("LOG_STEP") - 1;
+ bitmask |= LOG_STEP;
+ }
+ else if (strncmp (p, "LOG_TASK", sizeof ("LOG_TASK") - 1) == 0)
+ {
+ p += sizeof ("LOG_TASK") - 1;
+ bitmask |= LOG_TASK;
+ }
+ else if (strncmp (p, "LOG_ALL", sizeof ("LOG_ALL") - 1) == 0)
+ {
+ p += sizeof ("LOG_ALL") - 1;
+ bitmask |= LOG_ALL;
+ }
else if (strncmp (p, "LOG_DEFAULT", sizeof ("LOG_DEFAULT") - 1) == 0)
{
p += sizeof ("LOG_DEFAULT") - 1;
bitmask |= LOG_DEFAULT;
}
+// end of auto-generated entries
+
else if (strncmp (p, "LOG_NONE", sizeof ("LOG_NONE") - 1) == 0)
{
p += sizeof ("LOG_NONE") - 1;
@@ -3428,6 +3646,58 @@
}
rnb_err_t
+RNBRemote::HandlePacket_GetProfileData (const char *p)
+{
+ nub_process_t pid = m_ctx.ProcessID();
+ if (pid == INVALID_NUB_PROCESS)
+ return SendPacket ("OK");
+
+ std::string data = DNBProcessGetProfileData(pid);
+ if (!data.empty())
+ {
+ return SendPacket (data.c_str());
+ }
+ else
+ {
+ return SendPacket ("OK");
+ }
+}
+
+
+// QSetEnableAsyncProfiling;enable:[0|1]:interval_usec:XXXXXX;
+rnb_err_t
+RNBRemote::HandlePacket_SetEnableAsyncProfiling (const char *p)
+{
+ nub_process_t pid = m_ctx.ProcessID();
+ if (pid == INVALID_NUB_PROCESS)
+ return SendPacket ("");
+
+ StringExtractor packet(p += sizeof ("QSetEnableAsyncProfiling:") - 1);
+ bool enable = false;
+ uint64_t interval_usec = 0;
+ std::string name;
+ std::string value;
+ while (packet.GetNameColonValue(name, value))
+ {
+ if (name.compare ("enable") == 0)
+ {
+ enable = strtoul(value.c_str(), NULL, 10) > 0;
+ }
+ else if (name.compare ("interval_usec") == 0)
+ {
+ interval_usec = strtoul(value.c_str(), NULL, 10);
+ }
+ }
+
+ if (interval_usec == 0)
+ {
+ enable = 0;
+ }
+ DNBProcessSetEnableAsyncProfiling(pid, enable, interval_usec);
+ return SendPacket ("OK");
+}
+
+rnb_err_t
RNBRemote::HandlePacket_WatchpointSupportInfo (const char *p)
{
/* This packet simply returns the number of supported hardware watchpoints.
@@ -3692,3 +3962,108 @@
strm << "ptrsize:" << std::dec << sizeof(void *) << ';';
return SendPacket (strm.str());
}
+
+
+// Note that all numeric values returned by qProcessInfo are hex encoded,
+// including the pid and the cpu type.
+
+rnb_err_t
+RNBRemote::HandlePacket_qProcessInfo (const char *p)
+{
+ nub_process_t pid;
+ std::ostringstream rep;
+
+ // If we haven't run the process yet, return an error.
+ if (!m_ctx.HasValidProcessID())
+ return SendPacket ("E68");
+
+ pid = m_ctx.ProcessID();
+
+ rep << "pid:" << std::hex << pid << ";";
+
+ int procpid_mib[4];
+ procpid_mib[0] = CTL_KERN;
+ procpid_mib[1] = KERN_PROC;
+ procpid_mib[2] = KERN_PROC_PID;
+ procpid_mib[3] = pid;
+ struct kinfo_proc proc_kinfo;
+ size_t proc_kinfo_size = sizeof(struct kinfo_proc);
+
+ if (::sysctl (procpid_mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0)
+ {
+ if (proc_kinfo_size > 0)
+ {
+ rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";";
+ rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";";
+ rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";";
+ rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";";
+ if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
+ rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";";
+ }
+ }
+
+ int cputype_mib[CTL_MAXNAME]={0,};
+ size_t cputype_mib_len = CTL_MAXNAME;
+ cpu_type_t cputype = -1;
+ if (::sysctlnametomib("sysctl.proc_cputype", cputype_mib, &cputype_mib_len) == 0)
+ {
+ cputype_mib[cputype_mib_len] = pid;
+ cputype_mib_len++;
+ size_t len = sizeof(cputype);
+ if (::sysctl (cputype_mib, cputype_mib_len, &cputype, &len, 0, 0) == 0)
+ {
+ rep << "cputype:" << std::hex << cputype << ";";
+ }
+ }
+
+ uint32_t cpusubtype;
+ size_t cpusubtype_len = sizeof(cpusubtype);
+ if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
+ {
+ if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486)
+ {
+ cpusubtype = CPU_SUBTYPE_X86_64_ALL;
+ }
+
+ rep << "cpusubtype:" << std::hex << cpusubtype << ';';
+ }
+
+ // The OS in the triple should be "ios" or "macosx" which doesn't match our
+ // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
+ // this for now.
+ if (cputype == CPU_TYPE_ARM)
+ rep << "ostype:ios;";
+ else
+ rep << "ostype:macosx;";
+
+ rep << "vendor:apple;";
+
+#if defined (__LITTLE_ENDIAN__)
+ rep << "endian:little;";
+#elif defined (__BIG_ENDIAN__)
+ rep << "endian:big;";
+#elif defined (__PDP_ENDIAN__)
+ rep << "endian:pdp;";
+#endif
+
+#if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
+ nub_thread_t thread = DNBProcessGetCurrentThread (pid);
+ kern_return_t kr;
+ x86_thread_state_t gp_regs;
+ mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
+ kr = thread_get_state (thread, x86_THREAD_STATE,
+ (thread_state_t) &gp_regs, &gp_count);
+ if (kr == KERN_SUCCESS)
+ {
+ if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
+ rep << "ptrsize:8;";
+ else
+ rep << "ptrsize:4;";
+ }
+#elif defined (__arm__)
+ rep << "ptrsize:4;";
+#endif
+
+ return SendPacket (rep.str());
+}
+
Index: aze/lldb/tools/debugserver/source/RNBRemote.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/RNBRemote.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/RNBRemote.h 2013-03-03 09:35:50.347457349 +0100
@@ -79,9 +79,9 @@
insert_access_watch_bp, // 'Z4'
remove_access_watch_bp, // 'z4'
+ query_monitor, // 'qRcmd'
query_current_thread_id, // 'qC'
query_get_pid, // 'qGetPid'
- query_memory_crc, // 'qCRC:'
query_thread_ids_first, // 'qfThreadInfo'
query_thread_ids_subsequent, // 'qsThreadInfo'
query_thread_extra_info, // 'qThreadExtraInfo'
@@ -95,6 +95,7 @@
query_vattachorwait_supported, // 'qVAttachOrWaitSupported'
query_sync_thread_state_supported,// 'QSyncThreadState'
query_host_info, // 'qHostInfo'
+ query_process_info, // 'qProcessInfo'
pass_signals_to_inferior, // 'QPassSignals'
start_noack_mode, // 'QStartNoAckMode'
prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
@@ -112,6 +113,8 @@
set_list_threads_in_stop_reply, // 'QListThreadsInStopReply:'
sync_thread_state, // 'QSyncThreadState:'
memory_region_info, // 'qMemoryRegionInfo:'
+ get_profile_data, // 'qGetProfileData'
+ set_enable_profiling, // 'QSetEnableAsyncProfiling'
watchpoint_support_info, // 'qWatchpointSupportInfo:'
allocate_memory, // '_M'
deallocate_memory, // '_m'
@@ -163,6 +166,7 @@
rnb_err_t HandlePacket_A (const char *p);
rnb_err_t HandlePacket_H (const char *p);
rnb_err_t HandlePacket_qC (const char *p);
+ rnb_err_t HandlePacket_qRcmd (const char *p);
rnb_err_t HandlePacket_qGetPid (const char *p);
rnb_err_t HandlePacket_qLaunchSuccess (const char *p);
rnb_err_t HandlePacket_qRegisterInfo (const char *p);
@@ -174,6 +178,7 @@
rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
rnb_err_t HandlePacket_qHostInfo (const char *p);
+ rnb_err_t HandlePacket_qProcessInfo (const char *p);
rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
rnb_err_t HandlePacket_QSetLogging (const char *p);
@@ -210,6 +215,8 @@
rnb_err_t HandlePacket_AllocateMemory (const char *p);
rnb_err_t HandlePacket_DeallocateMemory (const char *p);
rnb_err_t HandlePacket_MemoryRegionInfo (const char *p);
+ rnb_err_t HandlePacket_GetProfileData(const char *p);
+ rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
rnb_err_t HandlePacket_WatchpointSupportInfo (const char *p);
rnb_err_t HandlePacket_stop_process (const char *p);
@@ -219,6 +226,8 @@
rnb_err_t SendSTDOUTPacket (char *buf, nub_size_t buf_size);
rnb_err_t SendSTDERRPacket (char *buf, nub_size_t buf_size);
void FlushSTDIO ();
+ void SendAsyncProfileData ();
+ rnb_err_t SendAsyncProfileDataPacket (char *buf, nub_size_t buf_size);
RNBContext& Context() { return m_ctx; }
RNBSocket& Comm() { return m_comm; }
Index: aze/lldb/tools/debugserver/source/RNBSocket.cpp
===================================================================
--- aze.orig/lldb/tools/debugserver/source/RNBSocket.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/RNBSocket.cpp 2013-03-03 09:35:50.347457349 +0100
@@ -188,15 +188,18 @@
DNBLog("Connecting to com.apple.%s service...", DEBUGSERVER_PROGRAM_NAME);
// Disconnect from any previous connections
Disconnect(false);
-
- SSLContextRef ssl_ctx;
- bzero(&ssl_ctx, sizeof(ssl_ctx));
- if (::lockdown_secure_checkin (&m_fd, &ssl_ctx, NULL, NULL) != kLDESuccess)
+ if (::secure_lockdown_checkin (&m_ld_conn, NULL, NULL) != kLDESuccess)
{
- DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_secure_checkin(&m_fd, NULL, NULL, NULL) failed");
+ DNBLogThreadedIf(LOG_RNB_COMM, "::secure_lockdown_checkin(&m_fd, NULL, NULL) failed");
m_fd = -1;
return rnb_not_connected;
}
+ m_fd = ::lockdown_get_socket (m_ld_conn);
+ if (m_fd == -1)
+ {
+ DNBLogThreadedIf(LOG_RNB_COMM, "::lockdown_get_socket() failed");
+ return rnb_not_connected;
+ }
m_fd_from_lockdown = true;
return rnb_success;
}
@@ -238,7 +241,14 @@
{
#ifdef WITH_LOCKDOWN
if (m_fd_from_lockdown)
+ {
m_fd_from_lockdown = false;
+ m_fd = -1;
+ if (lockdown_deactivate (m_ld_conn) == 0)
+ return rnb_success;
+ else
+ return rnb_err;
+ }
#endif
return ClosePort (m_fd, save_errno);
}
Index: aze/lldb/tools/debugserver/source/RNBSocket.h
===================================================================
--- aze.orig/lldb/tools/debugserver/source/RNBSocket.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/debugserver/source/RNBSocket.h 2013-03-03 09:35:50.347457349 +0100
@@ -20,6 +20,10 @@
#include <string>
#include "DNBTimer.h"
+#ifdef WITH_LOCKDOWN
+#include "lockdown.h"
+#endif
+
class RNBSocket
{
public:
@@ -29,6 +33,7 @@
m_fd (-1),
#ifdef WITH_LOCKDOWN
m_fd_from_lockdown (false),
+ m_ld_conn (),
#endif
m_timer (true) // Make a thread safe timer
{
@@ -67,6 +72,7 @@
#ifdef WITH_LOCKDOWN
bool m_fd_from_lockdown;
+ lockdown_connection m_ld_conn;
#endif
DNBTimer m_timer;
Index: aze/lldb/tools/driver/CMakeLists.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/tools/driver/CMakeLists.txt 2013-03-03 09:35:50.347457349 +0100
@@ -0,0 +1,16 @@
+set(LLVM_NO_RTTI 1)
+add_lldb_executable(lldb
+ Driver.cpp
+ #DriverEvents.cpp
+ #DriverOptions.cpp
+ #DriverPosix.cpp
+ IOChannel.cpp
+ )
+
+target_link_libraries(lldb liblldb)
+# TODO: why isn't this done by add_lldb_executable?
+#target_link_libraries(lldb ${LLDB_USED_LIBS})
+#llvm_config(lldb ${LLVM_LINK_COMPONENTS})
+
+install(TARGETS lldb
+ RUNTIME DESTINATION bin)
Index: aze/lldb/tools/driver/Driver.cpp
===================================================================
--- aze.orig/lldb/tools/driver/Driver.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/driver/Driver.cpp 2013-03-03 09:35:50.347457349 +0100
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <limits.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <string>
@@ -62,7 +63,7 @@
// then this option belongs to option set n.
bool required; // This option is required (in the current usage level)
const char * long_option; // Full name for this option.
- char short_option; // Single character for this option.
+ int short_option; // Single character for this option.
int option_has_arg; // no_argument, required_argument or optional_argument
uint32_t completion_type; // Cookie the option class can use to do define the argument completion.
lldb::CommandArgumentType argument_type; // Type of argument this option takes
@@ -104,6 +105,8 @@
"Tells the debugger to open source files using the host's \"external editor\" mechanism." },
{ LLDB_3_TO_5, false, "no-lldbinit" , 'x', no_argument , 0, eArgTypeNone,
"Do not automatically parse any '.lldbinit' files." },
+ { LLDB_OPT_SET_6, true , "python-path" , 'P', no_argument , 0, eArgTypeNone,
+ "Prints out the path to the lldb.py file for this version of lldb." },
{ 0, false, NULL , 0 , 0 , 0, eArgTypeNone, NULL }
};
@@ -117,7 +120,8 @@
m_editline_reader (),
m_io_channel_ap (),
m_option_data (),
- m_waiting_for_command (false)
+ m_waiting_for_command (false),
+ m_done(false)
{
// We want to be able to handle CTRL+D in the terminal to have it terminate
// certain input
@@ -386,6 +390,7 @@
m_source_command_files (),
m_debug_mode (false),
m_print_version (false),
+ m_print_python_path (false),
m_print_help (false),
m_wait_for(false),
m_process_name(),
@@ -408,6 +413,7 @@
m_debug_mode = false;
m_print_help = false;
m_print_version = false;
+ m_print_python_path = false;
m_use_external_editor = false;
m_wait_for = false;
m_process_name.erase();
@@ -577,7 +583,7 @@
if (long_options_index >= 0)
{
- const char short_option = (char) g_options[long_options_index].short_option;
+ const int short_option = g_options[long_options_index].short_option;
switch (short_option)
{
@@ -589,6 +595,10 @@
m_option_data.m_print_version = true;
break;
+ case 'P':
+ m_option_data.m_print_python_path = true;
+ break;
+
case 'c':
{
SBFileSpec file(optarg);
@@ -702,6 +712,24 @@
::fprintf (out_fh, "%s\n", m_debugger.GetVersionString());
exit = true;
}
+ else if (m_option_data.m_print_python_path)
+ {
+ SBFileSpec python_file_spec = SBHostOS::GetLLDBPythonPath();
+ if (python_file_spec.IsValid())
+ {
+ char python_path[PATH_MAX];
+ size_t num_chars = python_file_spec.GetPath(python_path, PATH_MAX);
+ if (num_chars < PATH_MAX)
+ {
+ ::fprintf (out_fh, "%s\n", python_path);
+ }
+ else
+ ::fprintf (out_fh, "<PATH TOO LONG>\n");
+ }
+ else
+ ::fprintf (out_fh, "<COULD NOT FIND PATH>\n");
+ exit = true;
+ }
else if (m_option_data.m_process_name.empty() && m_option_data.m_process_pid == LLDB_INVALID_PROCESS_ID)
{
// Any arguments that are left over after option parsing are for
@@ -795,7 +823,6 @@
StopReason thread_stop_reason = thread.GetStopReason();
switch (thread_stop_reason)
{
- default:
case eStopReasonInvalid:
case eStopReasonNone:
break;
@@ -805,6 +832,8 @@
case eStopReasonWatchpoint:
case eStopReasonSignal:
case eStopReasonException:
+ case eStopReasonExec:
+ case eStopReasonThreadExiting:
if (!other_thread.IsValid())
other_thread = thread;
break;
@@ -919,7 +948,7 @@
case eStateDetached:
{
char message[1024];
- int message_len = ::snprintf (message, sizeof(message), "Process %llu %s\n", process.GetProcessID(),
+ int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " %s\n", process.GetProcessID(),
m_debugger.StateAsCString (event_state));
m_io_channel_ap->OutWrite(message, message_len, ASYNC);
}
@@ -944,11 +973,32 @@
// Make sure the program hasn't been auto-restarted:
if (SBProcess::GetRestartedFromEvent (event))
{
+ size_t num_reasons = SBProcess::GetNumRestartedReasonsFromEvent(event);
+ if (num_reasons > 0)
+ {
// FIXME: Do we want to report this, or would that just be annoyingly chatty?
- char message[1024];
- int message_len = ::snprintf (message, sizeof(message), "Process %llu stopped and was programmatically restarted.\n",
+ if (num_reasons == 1)
+ {
+ char message[1024];
+ const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, 0);
+ int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted: %s\n",
+ process.GetProcessID(), reason ? reason : "<UNKNOWN REASON>");
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ }
+ else
+ {
+ char message[1024];
+ int message_len = ::snprintf (message, sizeof(message), "Process %" PRIu64 " stopped and restarted, reasons:\n",
process.GetProcessID());
- m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ for (size_t i = 0; i < num_reasons; i++)
+ {
+ const char *reason = SBProcess::GetRestartedReasonAtIndexFromEvent (event, i);
+ int message_len = ::snprintf(message, sizeof(message), "\t%s\n", reason ? reason : "<UNKNOWN REASON>");
+ m_io_channel_ap->OutWrite(message, message_len, ASYNC);
+ }
+ }
+ }
}
else
{
@@ -985,7 +1035,8 @@
// reprint the thread status for that thread.
using namespace lldb;
const uint32_t event_type = event.GetType();
- if (event_type == SBThread::eBroadcastBitStackChanged)
+ if (event_type == SBThread::eBroadcastBitStackChanged
+ || event_type == SBThread::eBroadcastBitThreadSelected)
{
SBThread thread = SBThread::GetThreadFromEvent (event);
if (thread.IsValid())
@@ -1301,7 +1352,8 @@
SBTarget::eBroadcastBitBreakpointChanged);
listener.StartListeningForEventClass(m_debugger,
SBThread::GetBroadcasterClassName(),
- SBThread::eBroadcastBitStackChanged);
+ SBThread::eBroadcastBitStackChanged |
+ SBThread::eBroadcastBitThreadSelected);
listener.StartListeningForEvents (*m_io_channel_ap,
IOChannel::eBroadcastBitHasUserInput |
IOChannel::eBroadcastBitUserInterrupt |
@@ -1331,6 +1383,7 @@
// Now we handle options we got from the command line
char command_string[PATH_MAX * 2];
const size_t num_source_command_files = GetNumSourceCommandFiles();
+ const bool dump_stream_only_if_no_immediate = true;
if (num_source_command_files > 0)
{
for (size_t i=0; i < num_source_command_files; ++i)
@@ -1343,6 +1396,19 @@
result.PutError (m_debugger.GetErrorFileHandle());
result.PutOutput (m_debugger.GetOutputFileHandle());
}
+
+ // if the command sourcing generated an error - dump the result object
+ if (result.Succeeded() == false)
+ {
+ const size_t output_size = result.GetOutputSize();
+ if (output_size > 0)
+ m_io_channel_ap->OutWrite (result.GetOutput(dump_stream_only_if_no_immediate), output_size, NO_ASYNC);
+ const size_t error_size = result.GetErrorSize();
+ if (error_size > 0)
+ m_io_channel_ap->OutWrite (result.GetError(dump_stream_only_if_no_immediate), error_size, NO_ASYNC);
+ }
+
+ result.Clear();
}
}
@@ -1423,7 +1489,7 @@
{
command_str.append("-p ");
char pid_buffer[32];
- ::snprintf (pid_buffer, sizeof(pid_buffer), "%llu", m_option_data.m_process_pid);
+ ::snprintf (pid_buffer, sizeof(pid_buffer), "%" PRIu64, m_option_data.m_process_pid);
command_str.append(pid_buffer);
}
else
@@ -1545,6 +1611,15 @@
}
}
+void
+Driver::ResizeWindow (unsigned short col)
+{
+ GetDebugger().SetTerminalWidth (col);
+ if (m_io_channel_ap.get() != NULL)
+ {
+ m_io_channel_ap->ElResize();
+ }
+}
void
sigwinch_handler (int signo)
@@ -1555,7 +1630,7 @@
{
if ((window_size.ws_col > 0) && g_driver != NULL)
{
- g_driver->GetDebugger().SetTerminalWidth (window_size.ws_col);
+ g_driver->ResizeWindow (window_size.ws_col);
}
}
}
@@ -1578,6 +1653,24 @@
exit (signo);
}
+void
+sigtstp_handler (int signo)
+{
+ g_driver->GetDebugger().SaveInputTerminalState();
+ signal (signo, SIG_DFL);
+ kill (getpid(), signo);
+ signal (signo, sigtstp_handler);
+}
+
+void
+sigcont_handler (int signo)
+{
+ g_driver->GetDebugger().RestoreInputTerminalState();
+ signal (signo, SIG_DFL);
+ kill (getpid(), signo);
+ signal (signo, sigcont_handler);
+}
+
int
main (int argc, char const *argv[], const char *envp[])
{
@@ -1588,6 +1681,8 @@
signal (SIGPIPE, SIG_IGN);
signal (SIGWINCH, sigwinch_handler);
signal (SIGINT, sigint_handler);
+ signal (SIGTSTP, sigtstp_handler);
+ signal (SIGCONT, sigcont_handler);
// Create a scope for driver so that the driver object will destroy itself
// before SBDebugger::Terminate() is called.
Index: aze/lldb/tools/driver/Driver.h
===================================================================
--- aze.orig/lldb/tools/driver/Driver.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/driver/Driver.h 2013-03-03 09:35:50.347457349 +0100
@@ -111,6 +111,7 @@
std::vector<std::string> m_source_command_files;
bool m_debug_mode;
bool m_print_version;
+ bool m_print_python_path;
bool m_print_help;
bool m_wait_for;
std::string m_process_name;
@@ -150,6 +151,9 @@
{
m_done = true;
}
+
+ void
+ ResizeWindow (unsigned short col);
private:
lldb::SBDebugger m_debugger;
Index: aze/lldb/tools/driver/IOChannel.cpp
===================================================================
--- aze.orig/lldb/tools/driver/IOChannel.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/driver/IOChannel.cpp 2013-03-03 09:35:50.347457349 +0100
@@ -90,6 +90,12 @@
}
}
+void
+IOChannel::ElResize()
+{
+ el_resize(m_edit_line);
+}
+
unsigned char
IOChannel::HandleCompletion (EditLine *e, int ch)
{
@@ -472,7 +478,7 @@
}
BroadcastEventByType (IOChannel::eBroadcastBitThreadDidExit);
m_driver = NULL;
- m_read_thread = NULL;
+ m_read_thread = 0;
}
bool
Index: aze/lldb/tools/driver/IOChannel.h
===================================================================
--- aze.orig/lldb/tools/driver/IOChannel.h 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/driver/IOChannel.h 2013-03-03 09:35:50.351457348 +0100
@@ -104,6 +104,9 @@
static unsigned char
ElCompletionFn (EditLine *e, int ch);
+
+ void
+ ElResize();
protected:
Index: aze/lldb/tools/driver/Makefile
===================================================================
--- aze.orig/lldb/tools/driver/Makefile 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/driver/Makefile 2013-03-03 09:35:50.351457348 +0100
@@ -10,6 +10,8 @@
TOOLNAME = lldb
+NO_PEDANTIC = 1
+
LLVMLibsOptions += -ledit -llldb -llldbUtility
include $(LLDB_LEVEL)/Makefile
Index: aze/lldb/tools/lldb-platform/lldb-platform.cpp
===================================================================
--- aze.orig/lldb/tools/lldb-platform/lldb-platform.cpp 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/tools/lldb-platform/lldb-platform.cpp 2013-03-03 09:35:50.351457348 +0100
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
// C Includes
#include <errno.h>
#include <getopt.h>
Index: aze/lldb/utils/vim-lldb/doc/lldb.txt
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/doc/lldb.txt 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,102 @@
+*lldb.txt* A plugin that enables debugging from your favourite editor
+
+Author: Daniel Malea <daniel.malea@intel.com>
+License: Same terms as Vim itself (see |license|)
+
+INTRODUCTION *lldb*
+
+Installing this plugin enables a set of commands in Vim to control the
+LLDB (http://lldb.llvm.org) debugger.
+
+COMMANDS *lldb-commands*
+
+The LLDB command interpreter is exposed to Vim's command mode using the
+':L' prefix. Tab-completion is available and will cycle through commands.
+Some commands have modified behaviour in Vim; for example, :Lbreakpoint
+with no arguments will set a breakpoint at the current cursor, rather than
+printing the standard help information for the LLDB command 'breakpoint'.
+
+ *lldb-windows*
+
+In addition to the standard commands available under the LLDB interpreter,
+there are also commands to display or hide informational debugger panes.
+
+Windows can be shown or hidden using the ':Lhide <name>' or ':Lshow <name>'
+commands.
+ *lldb-:Lhide*
+:Lhide [windowname] Hide informational debugger pane named 'windowname'.
+
+ *lldb-:Lshow*
+:Lshow [windowname] Show informational debugger pane named 'windowname'.
+
+Possible window name arguments to the Lhide and Lshow commands include:
+
+ * backtrace
+ * breakpoints
+ * disassembly
+ * locals
+ * registers
+ * threads
+ *lldb-:Ltarget*
+:Ltarget [[create] executable]
+ Create a target with the specified executable. If
+ run with a single argument, that argument is assumed
+ to be a path to the executable to be debugged.
+ Otherwise, all arguments are passed into LLDB's command
+ interpreter.
+
+ *lldb-:Lstart*
+:Lstart Create a process by executing the current target
+ and wait for LLDB to attach.
+
+ *lldb-:Lrun*
+:Lrun Create a process by executing the current target
+ without waiting for LLDB to attach.
+
+ *lldb-:Lcontinue*
+:Lcontinue Continue execution of the process until the next
+ breakpoint is hit or the process exits.
+
+ *lldb-:Lthread*
+:Lthread <args> Passes through to LLDB. See :Lhelp thread.
+
+ *lldb-:Lstep*
+:Lstep Step into the current function call.
+
+ *lldb-:Lstepin*
+:Lstepin Step into the current function call.
+
+ *lldb-:Lstepinst*
+:Lstepinst Step one instruction.
+
+ *lldb-:Lstepinstover*
+:Lstepinstover Step one instruction, but skip over jump or call
+ instructions.
+
+ *lldb-:Lnext*
+:Lnext Step to the next line.
+
+ *lldb-:Lfinish*
+:Lfinish Step out of the current function.
+
+ *lldb-:Lbreakpoint*
+:Lbreakpoint [args] When arguments are provided, the lldb breakpoint
+ command is invoked. If no arguments are provided,
+ a breakpoint at the location under the cursor.
+
+MAPPINGS *lldb-mappings*
+
+On Mac OS X (under MacVim) , the following key mappings are available:
+
+<Command-B> Insert a breakpoint at the line under cursor
+
+
+ABOUT *lldb-about*
+
+Grab the latest version of this plugin (and LLDB sources) with:
+ git clone http://llvm.org/git/lldb
+
+File any bugs at:
+ http://llvm.org/bugs/enter_bug.cgi?product=lldb
+
+ vim:tw=78:et:ft=help:norl:
Index: aze/lldb/utils/vim-lldb/plugin/lldb.vim
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/plugin/lldb.vim 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,136 @@
+
+" Vim script glue code for LLDB integration
+
+function! s:FindPythonScriptDir()
+ for dir in pathogen#split(&runtimepath)
+ let searchstr = "python-vim-lldb"
+ let candidates = pathogen#glob_directories(dir . "/" . searchstr)
+ if len(candidates) > 0
+ return candidates[0]
+ endif
+ endfor
+ return
+endfunction()
+
+function! s:InitLldbPlugin()
+ if has('python') == 0
+ call confirm('ERROR: This Vim installation does not have python support. lldb.vim will not work.')
+ return
+ endif
+
+ " Key-Bindings
+ " FIXME: choose sensible keybindings for:
+ " - process: start, interrupt, continue, continue-to-cursor
+ " - step: instruction, in, over, out
+ "
+ if has('gui_macvim')
+ " Apple-B toggles breakpoint on cursor
+ map <D-B> :Lbreakpoint<CR>
+ endif
+
+ "
+ " Setup the python interpreter path
+ "
+ let vim_lldb_pydir = s:FindPythonScriptDir()
+ execute 'python import sys; sys.path.append("' . vim_lldb_pydir . '")'
+
+ "
+ " Register :L<Command>
+ " The LLDB CommandInterpreter provides tab-completion in Vim's command mode.
+ " FIXME: this list of commands, at least partially should be auto-generated
+ "
+
+ " Window show/hide commands
+ command -complete=custom,s:CompleteWindow -nargs=1 Lhide python ctrl.doHide('<args>')
+ command -complete=custom,s:CompleteWindow -nargs=1 Lshow python ctrl.doShow('<args>')
+
+ " Launching convenience commands (no autocompletion)
+ command -nargs=* Lstart python ctrl.doLaunch(True, '<args>')
+ command -nargs=* Lrun python ctrl.doLaunch(False, '<args>')
+
+ " Regexp-commands: because vim's command mode does not support '_' or '-'
+ " characters in command names, we omit them when creating the :L<cmd>
+ " equivalents.
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpattach python ctrl.doCommand('_regexp-attach', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpbreak python ctrl.doCommand('_regexp-break', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpbt python ctrl.doCommand('_regexp-bt', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpdown python ctrl.doCommand('_regexp-down', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexptbreak python ctrl.doCommand('_regexp-tbreak', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpdisplay python ctrl.doCommand('_regexp-display', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpundisplay python ctrl.doCommand('_regexp-undisplay', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregexpup python ctrl.doCommand('_regexp-up', '<args>')
+
+ command -complete=custom,s:CompleteCommand -nargs=* Lapropos python ctrl.doCommand('apropos', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lbacktrace python ctrl.doCommand('bt', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lbreakpoint python ctrl.doBreakpoint('<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lcommand python ctrl.doCommand('command', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Ldisassemble python ctrl.doCommand('disassemble', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lexpression python ctrl.doCommand('expression', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lhelp python ctrl.doCommand('help', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Llog python ctrl.doCommand('log', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lplatform python ctrl.doCommand('platform','<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lplugin python ctrl.doCommand('plugin', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lprocess python ctrl.doProcess('<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lregister python ctrl.doCommand('register', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lscript python ctrl.doCommand('script', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lsettings python ctrl.doCommand('settings','<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lsource python ctrl.doCommand('source', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Ltype python ctrl.doCommand('type', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lversion python ctrl.doCommand('version', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lwatchpoint python ctrl.doCommand('watchpoint', '<args>')
+
+ " Convenience (shortcut) LLDB commands
+ command -complete=custom,s:CompleteCommand -nargs=* Lprint python ctrl.doCommand('print', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=* Lbt python ctrl.doCommand('bt', '<args>')
+
+ " Frame/Thread-Selection (commands that also do an Uupdate but do not
+ " generate events in LLDB)
+ command -complete=custom,s:CompleteCommand -nargs=* Lframe python ctrl.doSelect('frame', '<args>')
+ command -complete=custom,s:CompleteCommand -nargs=? Lup python ctrl.doCommand('up', '<args>', print_on_success=False, goto_file=True)
+ command -complete=custom,s:CompleteCommand -nargs=? Ldown python ctrl.doCommand('down', '<args>', print_on_success=False, goto_file=True)
+ command -complete=custom,s:CompleteCommand -nargs=* Lthread python ctrl.doSelect('thread', '<args>')
+
+ command -complete=custom,s:CompleteCommand -nargs=* Ltarget python ctrl.doTarget('<args>')
+
+ " Continue
+ command -complete=custom,s:CompleteCommand -nargs=* Lcontinue python ctrl.doContinue()
+
+ " Thread-Stepping (no autocompletion)
+ command -nargs=0 Lstepinst python ctrl.doStep(StepType.INSTRUCTION)
+ command -nargs=0 Lstepinstover python ctrl.doStep(StepType.INSTRUCTION_OVER)
+ command -nargs=0 Lstepin python ctrl.doStep(StepType.INTO)
+ command -nargs=0 Lstep python ctrl.doStep(StepType.INTO)
+ command -nargs=0 Lnext python ctrl.doStep(StepType.OVER)
+ command -nargs=0 Lfinish python ctrl.doStep(StepType.OUT)
+
+ " hack: service the LLDB event-queue when the cursor moves
+ " FIXME: some threaded solution would be better...but it
+ " would have to be designed carefully because Vim's APIs are non threadsafe;
+ " use of the vim module **MUST** be restricted to the main thread.
+ command -nargs=0 Lrefresh python ctrl.doRefresh()
+ autocmd CursorMoved * :Lrefresh
+ autocmd CursorHold * :Lrefresh
+ autocmd VimLeavePre * python ctrl.doExit()
+
+ execute 'pyfile ' . vim_lldb_pydir . '/plugin.py'
+endfunction()
+
+function! s:CompleteCommand(A, L, P)
+ python << EOF
+a = vim.eval("a:A")
+l = vim.eval("a:L")
+p = vim.eval("a:P")
+returnCompleteCommand(a, l, p)
+EOF
+endfunction()
+
+function! s:CompleteWindow(A, L, P)
+ python << EOF
+a = vim.eval("a:A")
+l = vim.eval("a:L")
+p = vim.eval("a:P")
+returnCompleteWindow(a, l, p)
+EOF
+endfunction()
+
+call s:InitLldbPlugin()
Index: aze/lldb/utils/vim-lldb/python-vim-lldb/import_lldb.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/python-vim-lldb/import_lldb.py 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,61 @@
+
+# Locate and load the lldb python module
+
+import os, sys
+
+def import_lldb():
+ """ Find and import the lldb modules. This function tries to find the lldb module by:
+ 1. Simply by doing "import lldb" in case the system python installation is aware of lldb. If that fails,
+ 2. Executes the lldb executable pointed to by the LLDB environment variable (or if unset, the first lldb
+ on PATH") with the -P flag to determine the PYTHONPATH to set. If the lldb executable returns a valid
+ path, it is added to sys.path and the import is attempted again. If that fails, 3. On Mac OS X the
+ default Xcode 4.5 installation path.
+ """
+
+ # Try simple 'import lldb', in case of a system-wide install or a pre-configured PYTHONPATH
+ try:
+ import lldb
+ return True
+ except ImportError:
+ pass
+
+ # Allow overriding default path to lldb executable with the LLDB environment variable
+ lldb_executable = 'lldb'
+ if 'LLDB' in os.environ and os.path.exists(os.environ['LLDB']):
+ lldb_executable = os.environ['LLDB']
+
+ # Try using builtin module location support ('lldb -P')
+ from subprocess import check_output, CalledProcessError
+ try:
+ with open(os.devnull, 'w') as fnull:
+ lldb_minus_p_path = check_output("%s -P" % lldb_executable, shell=True, stderr=fnull).strip()
+ if not os.path.exists(lldb_minus_p_path):
+ #lldb -P returned invalid path, probably too old
+ pass
+ else:
+ sys.path.append(lldb_minus_p_path)
+ import lldb
+ return True
+ except CalledProcessError:
+ # Cannot run 'lldb -P' to determine location of lldb python module
+ pass
+ except ImportError:
+ # Unable to import lldb module from path returned by `lldb -P`
+ pass
+
+ # On Mac OS X, use the try the default path to XCode lldb module
+ if "darwin" in sys.platform:
+ xcode_python_path = "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/Current/Resources/Python/"
+ sys.path.append(xcode_python_path)
+ try:
+ import lldb
+ return True
+ except ImportError:
+ # Unable to import lldb module from default Xcode python path
+ pass
+
+ return False
+
+if not import_lldb():
+ import vim
+ vim.command('redraw | echo "%s"' % " Error loading lldb module; vim-lldb will be disabled. Check LLDB installation or set LLDB environment variable.")
Index: aze/lldb/utils/vim-lldb/python-vim-lldb/lldb_controller.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/python-vim-lldb/lldb_controller.py 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,353 @@
+
+#
+# This file defines the layer that talks to lldb
+#
+
+import os, re, sys
+import lldb
+import vim
+from vim_ui import UI
+
+# =================================================
+# Convert some enum value to its string counterpart
+# =================================================
+
+# Shamelessly copy/pasted from lldbutil.py in the test suite
+def state_type_to_str(enum):
+ """Returns the stateType string given an enum."""
+ if enum == lldb.eStateInvalid:
+ return "invalid"
+ elif enum == lldb.eStateUnloaded:
+ return "unloaded"
+ elif enum == lldb.eStateConnected:
+ return "connected"
+ elif enum == lldb.eStateAttaching:
+ return "attaching"
+ elif enum == lldb.eStateLaunching:
+ return "launching"
+ elif enum == lldb.eStateStopped:
+ return "stopped"
+ elif enum == lldb.eStateRunning:
+ return "running"
+ elif enum == lldb.eStateStepping:
+ return "stepping"
+ elif enum == lldb.eStateCrashed:
+ return "crashed"
+ elif enum == lldb.eStateDetached:
+ return "detached"
+ elif enum == lldb.eStateExited:
+ return "exited"
+ elif enum == lldb.eStateSuspended:
+ return "suspended"
+ else:
+ raise Exception("Unknown StateType enum")
+
+class StepType:
+ INSTRUCTION = 1
+ INSTRUCTION_OVER = 2
+ INTO = 3
+ OVER = 4
+ OUT = 5
+
+class LLDBController(object):
+ """ Handles Vim and LLDB events such as commands and lldb events. """
+
+ # Timeouts (sec) for waiting on new events. Because vim is not multi-threaded, we are restricted to
+ # servicing LLDB events from the main UI thread. Usually, we only process events that are already
+ # sitting on the queue. But in some situations (when we are expecting an event as a result of some
+ # user interaction) we want to wait for it. The constants below set these wait period in which the
+ # Vim UI is "blocked". Lower numbers will make Vim more responsive, but LLDB will be delayed and higher
+ # numbers will mean that LLDB events are processed faster, but the Vim UI may appear less responsive at
+ # times.
+ eventDelayStep = 2
+ eventDelayLaunch = 1
+ eventDelayContinue = 1
+
+ def __init__(self):
+ """ Creates the LLDB SBDebugger object and initializes the UI class. """
+ self.target = None
+ self.process = None
+ self.load_dependent_modules = True
+
+ self.dbg = lldb.SBDebugger.Create()
+ self.commandInterpreter = self.dbg.GetCommandInterpreter()
+
+ self.ui = UI()
+
+ def completeCommand(self, a, l, p):
+ """ Returns a list of viable completions for command a with length l and cursor at p """
+
+ assert l[0] == 'L'
+ # Remove first 'L' character that all commands start with
+ l = l[1:]
+
+ # Adjust length as string has 1 less character
+ p = int(p) - 1
+
+ result = lldb.SBStringList()
+ num = self.commandInterpreter.HandleCompletion(l, p, 1, -1, result)
+
+ if num == -1:
+ # FIXME: insert completion character... what's a completion character?
+ pass
+ elif num == -2:
+ # FIXME: replace line with result.GetStringAtIndex(0)
+ pass
+
+ if result.GetSize() > 0:
+ results = filter(None, [result.GetStringAtIndex(x) for x in range(result.GetSize())])
+ return results
+ else:
+ return []
+
+ def doStep(self, stepType):
+ """ Perform a step command and block the UI for eventDelayStep seconds in order to process
+ events on lldb's event queue.
+ FIXME: if the step does not complete in eventDelayStep seconds, we relinquish control to
+ the main thread to avoid the appearance of a "hang". If this happens, the UI will
+ update whenever; usually when the user moves the cursor. This is somewhat annoying.
+ """
+ if not self.process:
+ sys.stderr.write("No process to step")
+ return
+
+ t = self.process.GetSelectedThread()
+ if stepType == StepType.INSTRUCTION:
+ t.StepInstruction(False)
+ if stepType == StepType.INSTRUCTION_OVER:
+ t.StepInstruction(True)
+ elif stepType == StepType.INTO:
+ t.StepInto()
+ elif stepType == StepType.OVER:
+ t.StepOver()
+ elif stepType == StepType.OUT:
+ t.StepOut()
+
+ self.processPendingEvents(self.eventDelayStep, True)
+
+ def doSelect(self, command, args):
+ """ Like doCommand, but suppress output when "select" is the first argument."""
+ a = args.split(' ')
+ return self.doCommand(command, args, "select" != a[0], True)
+
+ def doProcess(self, args):
+ """ Handle 'process' command. If 'launch' is requested, use doLaunch() instead
+ of the command interpreter to start the inferior process.
+ """
+ a = args.split(' ')
+ if len(args) == 0 or (len(a) > 0 and a[0] != 'launch'):
+ self.doCommand("process", args)
+ #self.ui.update(self.target, "", self)
+ else:
+ self.doLaunch('-s' not in args, "")
+
+ def doLaunch(self, stop_at_entry, args):
+ """ Handle process launch. """
+ error = lldb.SBError()
+
+ fs = self.target.GetExecutable()
+ exe = os.path.join(fs.GetDirectory(), fs.GetFilename())
+ if self.process is not None and self.process.IsValid():
+ pid = self.process.GetProcessID()
+ state = state_type_to_str(self.process.GetState())
+ self.process.Destroy()
+
+ launchInfo = lldb.SBLaunchInfo(args.split(' '))
+ self.process = self.target.Launch(launchInfo, error)
+ if not error.Success():
+ sys.stderr.write("Error during launch: " + str(error))
+ return
+
+ # launch succeeded, store pid and add some event listeners
+ self.pid = self.process.GetProcessID()
+ self.processListener = lldb.SBListener("process_event_listener")
+ self.process.GetBroadcaster().AddListener(self.processListener, lldb.SBProcess.eBroadcastBitStateChanged)
+
+ print "Launched %s %s (pid=%d)" % (exe, args, self.pid)
+
+ if not stop_at_entry:
+ self.doContinue()
+ else:
+ self.processPendingEvents(self.eventDelayLaunch)
+
+ def doTarget(self, args):
+ """ Pass target command to interpreter, except if argument is not one of the valid options, or
+ is create, in which case try to create a target with the argument as the executable. For example:
+ target list ==> handled by interpreter
+ target create blah ==> custom creation of target 'blah'
+ target blah ==> also creates target blah
+ """
+ target_args = [#"create",
+ "delete",
+ "list",
+ "modules",
+ "select",
+ "stop-hook",
+ "symbols",
+ "variable"]
+
+ a = args.split(' ')
+ if len(args) == 0 or (len(a) > 0 and a[0] in target_args):
+ self.doCommand("target", args)
+ return
+ elif len(a) > 1 and a[0] == "create":
+ exe = a[1]
+ elif len(a) == 1 and a[0] not in target_args:
+ exe = a[0]
+
+ err = lldb.SBError()
+ self.target = self.dbg.CreateTarget(exe, None, None, self.load_dependent_modules, err)
+ if not self.target:
+ sys.stderr.write("Error creating target %s. %s" % (str(exe), str(err)))
+ return
+
+ self.ui.activate()
+ self.ui.update(self.target, "created target %s" % str(exe), self)
+
+ def doContinue(self):
+ """ Handle 'contiue' command.
+ FIXME: switch to doCommand("continue", ...) to handle -i ignore-count param.
+ """
+ if not self.process or not self.process.IsValid():
+ sys.stderr.write("No process to continue")
+ return
+
+ self.process.Continue()
+ self.processPendingEvents(self.eventDelayContinue)
+
+ def doBreakpoint(self, args):
+ """ Handle breakpoint command with command interpreter, except if the user calls
+ "breakpoint" with no other args, in which case add a breakpoint at the line
+ under the cursor.
+ """
+ a = args.split(' ')
+ if len(args) == 0:
+ show_output = False
+
+ # User called us with no args, so toggle the bp under cursor
+ cw = vim.current.window
+ cb = vim.current.buffer
+ name = cb.name
+ line = cw.cursor[0]
+
+ # Since the UI is responsbile for placing signs at bp locations, we have to
+ # ask it if there already is one or more breakpoints at (file, line)...
+ if self.ui.haveBreakpoint(name, line):
+ bps = self.ui.getBreakpoints(name, line)
+ args = "delete %s" % " ".join([str(b.GetID()) for b in bps])
+ self.ui.deleteBreakpoints(name, line)
+ else:
+ args = "set -f %s -l %d" % (name, line)
+ else:
+ show_output = True
+
+ self.doCommand("breakpoint", args, show_output)
+ return
+
+ def doRefresh(self):
+ """ process pending events and update UI on request """
+ status = self.processPendingEvents()
+
+ def doShow(self, name):
+ """ handle :Lshow <name> """
+ if self.ui.showWindow(name):
+ self.ui.update(self.target, "", self)
+
+ def doHide(self, name):
+ """ handle :Lhide <name> """
+ if self.ui.hideWindow(name):
+ self.ui.update(self.target, "", self)
+
+ def doExit(self):
+ self.dbg.Terminate()
+ self.dbg = None
+
+ def getCommandResult(self, command, command_args):
+ """ Run cmd in the command interpreter and returns (success, output) """
+ result = lldb.SBCommandReturnObject()
+ cmd = "%s %s" % (command, command_args)
+
+ self.commandInterpreter.HandleCommand(cmd, result)
+ return (result.Succeeded(), result.GetOutput() if result.Succeeded() else result.GetError())
+
+ def doCommand(self, command, command_args, print_on_success = True, goto_file=False):
+ """ Run cmd in interpreter and print result (success or failure) on the vim status line. """
+ (success, output) = self.getCommandResult(command, command_args)
+ if success:
+ self.ui.update(self.target, "", self, goto_file)
+ if len(output) > 0 and print_on_success:
+ print output
+ else:
+ sys.stderr.write(output)
+
+ def getCommandOutput(self, command, command_args=""):
+ """ runs cmd in the command interpreter andreturns (status, result) """
+ result = lldb.SBCommandReturnObject()
+ cmd = "%s %s" % (command, command_args)
+ self.commandInterpreter.HandleCommand(cmd, result)
+ return (result.Succeeded(), result.GetOutput() if result.Succeeded() else result.GetError())
+
+ def processPendingEvents(self, wait_seconds=0, goto_file=True):
+ """ Handle any events that are queued from the inferior.
+ Blocks for at most wait_seconds, or if wait_seconds == 0,
+ process only events that are already queued.
+ """
+
+ status = None
+ num_events_handled = 0
+
+ if self.process is not None:
+ event = lldb.SBEvent()
+ old_state = self.process.GetState()
+ new_state = None
+ done = False
+ if old_state == lldb.eStateInvalid or old_state == lldb.eStateExited:
+ # Early-exit if we are in 'boring' states
+ pass
+ else:
+ while not done and self.processListener is not None:
+ if not self.processListener.PeekAtNextEvent(event):
+ if wait_seconds > 0:
+ # No events on the queue, but we are allowed to wait for wait_seconds
+ # for any events to show up.
+ self.processListener.WaitForEvent(wait_seconds, event)
+ new_state = lldb.SBProcess.GetStateFromEvent(event)
+
+ num_events_handled += 1
+
+ done = not self.processListener.PeekAtNextEvent(event)
+ else:
+ # An event is on the queue, process it here.
+ self.processListener.GetNextEvent(event)
+ new_state = lldb.SBProcess.GetStateFromEvent(event)
+
+ # If needed, perform any event-specific behaviour here
+ num_events_handled += 1
+
+ if num_events_handled == 0:
+ pass
+ else:
+ if old_state == new_state:
+ status = ""
+ self.ui.update(self.target, status, self, goto_file)
+
+
+def returnCompleteCommand(a, l, p):
+ """ Returns a "\n"-separated string with possible completion results
+ for command a with length l and cursor at p.
+ """
+ separator = "\n"
+ results = ctrl.completeCommand(a, l, p)
+ vim.command('return "%s%s"' % (separator.join(results), separator))
+
+def returnCompleteWindow(a, l, p):
+ """ Returns a "\n"-separated string with possible completion results
+ for commands that expect a window name parameter (like hide/show).
+ FIXME: connect to ctrl.ui instead of hardcoding the list here
+ """
+ separator = "\n"
+ results = ['breakpoints', 'backtrace', 'disassembly', 'locals', 'threads', 'registers']
+ vim.command('return "%s%s"' % (separator.join(results), separator))
+
+global ctrl
+ctrl = LLDBController()
Index: aze/lldb/utils/vim-lldb/python-vim-lldb/plugin.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/python-vim-lldb/plugin.py 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,14 @@
+
+# Try to import all dependencies, catch and handle the error gracefully if it fails.
+
+import import_lldb
+
+try:
+ import lldb
+ import vim
+except ImportError:
+ sys.stderr.write("Unable to load vim/lldb module. Check lldb is on the path is available (or LLDB is set) and that script is invoked inside Vim with :pyfile")
+ pass
+else:
+ # Everthing went well, so use import to start the plugin controller
+ from lldb_controller import *
Index: aze/lldb/utils/vim-lldb/python-vim-lldb/vim_panes.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/python-vim-lldb/vim_panes.py 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,618 @@
+#
+# This file contains implementations of the LLDB display panes in VIM
+#
+# The most generic way to define a new window is to inherit from VimPane
+# and to implement:
+# - get_content() - returns a string with the pane contents
+#
+# Optionally, to highlight text, implement:
+# - get_highlights() - returns a map
+#
+# And call:
+# - define_highlight(unique_name, colour)
+# at some point in the constructor.
+#
+#
+# If the pane shows some key-value data that is in the context of a
+# single frame, inherit from FrameKeyValuePane and implement:
+# - get_frame_content(self, SBFrame frame)
+#
+#
+# If the pane presents some information that can be retrieved with
+# a simple LLDB command while the subprocess is stopped, inherit
+# from StoppedCommandPane and call:
+# - self.setCommand(command, command_args)
+# at some point in the constructor.
+#
+# Optionally, you can implement:
+# - get_selected_line()
+# to highlight a selected line and place the cursor there.
+#
+#
+# FIXME: implement WatchlistPane to displayed watched expressions
+# FIXME: define interface for interactive panes, like catching enter
+# presses to change selected frame/thread...
+#
+
+import lldb
+import vim
+
+import sys
+
+# ==============================================================
+# Get the description of an lldb object or None if not available
+# ==============================================================
+
+# Shamelessly copy/pasted from lldbutil.py in the test suite
+def get_description(obj, option=None):
+ """Calls lldb_obj.GetDescription() and returns a string, or None.
+
+ For SBTarget, SBBreakpointLocation, and SBWatchpoint lldb objects, an extra
+ option can be passed in to describe the detailed level of description
+ desired:
+ o lldb.eDescriptionLevelBrief
+ o lldb.eDescriptionLevelFull
+ o lldb.eDescriptionLevelVerbose
+ """
+ method = getattr(obj, 'GetDescription')
+ if not method:
+ return None
+ tuple = (lldb.SBTarget, lldb.SBBreakpointLocation, lldb.SBWatchpoint)
+ if isinstance(obj, tuple):
+ if option is None:
+ option = lldb.eDescriptionLevelBrief
+
+ stream = lldb.SBStream()
+ if option is None:
+ success = method(stream)
+ else:
+ success = method(stream, option)
+ if not success:
+ return None
+ return stream.GetData()
+
+def get_selected_thread(target):
+ """ Returns a tuple with (thread, error) where thread == None if error occurs """
+ process = target.GetProcess()
+ if process is None or not process.IsValid():
+ return (None, VimPane.MSG_NO_PROCESS)
+
+ thread = process.GetSelectedThread()
+ if thread is None or not thread.IsValid():
+ return (None, VimPane.MSG_NO_THREADS)
+ return (thread, "")
+
+def get_selected_frame(target):
+ """ Returns a tuple with (frame, error) where frame == None if error occurs """
+ (thread, error) = get_selected_thread(target)
+ if thread is None:
+ return (None, error)
+
+ frame = thread.GetSelectedFrame()
+ if frame is None or not frame.IsValid():
+ return (None, VimPane.MSG_NO_FRAME)
+ return (frame, "")
+
+def _cmd(cmd):
+ vim.command("call confirm('%s')" % cmd)
+ vim.command(cmd)
+
+def move_cursor(line, col=0):
+ """ moves cursor to specified line and col """
+ cw = vim.current.window
+ if cw.cursor[0] != line:
+ vim.command("execute \"normal %dgg\"" % line)
+
+def winnr():
+ """ Returns currently selected window number """
+ return int(vim.eval("winnr()"))
+
+def bufwinnr(name):
+ """ Returns window number corresponding with buffer name """
+ return int(vim.eval("bufwinnr('%s')" % name))
+
+def goto_window(nr):
+ """ go to window number nr"""
+ if nr != winnr():
+ vim.command(str(nr) + ' wincmd w')
+
+def goto_next_window():
+ """ go to next window. """
+ vim.command('wincmd w')
+ return (winnr(), vim.current.buffer.name)
+
+def goto_previous_window():
+ """ go to previously selected window """
+ vim.command("execute \"normal \\<c-w>p\"")
+
+def have_gui():
+ """ Returns True if vim is in a gui (Gvim/MacVim), False otherwise. """
+ return int(vim.eval("has('gui_running')")) == 1
+
+class PaneLayout(object):
+ """ A container for a (vertical) group layout of VimPanes """
+
+ def __init__(self):
+ self.panes = {}
+
+ def havePane(self, name):
+ """ Returns true if name is a registered pane, False otherwise """
+ return name in self.panes
+
+ def prepare(self, panes = []):
+ """ Draw panes on screen. If empty list is provided, show all. """
+
+ # If we can't select a window contained in the layout, we are doing a first draw
+ first_draw = not self.selectWindow(True)
+ did_first_draw = False
+
+ # Prepare each registered pane
+ for name in self.panes:
+ if name in panes or len(panes) == 0:
+ if first_draw:
+ # First window in layout will be created with :vsp, and closed later
+ vim.command(":vsp")
+ first_draw = False
+ did_first_draw = True
+ self.panes[name].prepare()
+
+ if did_first_draw:
+ # Close the split window
+ vim.command(":q")
+
+ self.selectWindow(False)
+
+ def contains(self, bufferName = None):
+ """ Returns True if window with name bufferName is contained in the layout, False otherwise.
+ If bufferName is None, the currently selected window is checked.
+ """
+ if not bufferName:
+ bufferName = vim.current.buffer.name
+
+ for p in self.panes:
+ if bufferName is not None and bufferName.endswith(p):
+ return True
+ return False
+
+ def selectWindow(self, select_contained = True):
+ """ Selects a window contained in the layout (if select_contained = True) and returns True.
+ If select_contained = False, a window that is not contained is selected. Returns False
+ if no group windows can be selected.
+ """
+ if select_contained == self.contains():
+ # Simple case: we are already selected
+ return True
+
+ # Otherwise, switch to next window until we find a contained window, or reach the first window again.
+ first = winnr()
+ (curnum, curname) = goto_next_window()
+
+ while not select_contained == self.contains(curname) and curnum != first:
+ (curnum, curname) = goto_next_window()
+
+ return self.contains(curname) == select_contained
+
+ def hide(self, panes = []):
+ """ Hide panes specified. If empty list provided, hide all. """
+ for name in self.panes:
+ if name in panes or len(panes) == 0:
+ self.panes[name].destroy()
+
+ def registerForUpdates(self, p):
+ self.panes[p.name] = p
+
+ def update(self, target, controller):
+ for name in self.panes:
+ self.panes[name].update(target, controller)
+
+
+class VimPane(object):
+ """ A generic base class for a pane that displays stuff """
+ CHANGED_VALUE_HIGHLIGHT_NAME_GUI = 'ColorColumn'
+ CHANGED_VALUE_HIGHLIGHT_NAME_TERM = 'lldb_changed'
+ CHANGED_VALUE_HIGHLIGHT_COLOUR_TERM = 'darkred'
+
+ SELECTED_HIGHLIGHT_NAME_GUI = 'Cursor'
+ SELECTED_HIGHLIGHT_NAME_TERM = 'lldb_selected'
+ SELECTED_HIGHLIGHT_COLOUR_TERM = 'darkblue'
+
+ MSG_NO_TARGET = "Target does not exist."
+ MSG_NO_PROCESS = "Process does not exist."
+ MSG_NO_THREADS = "No valid threads."
+ MSG_NO_FRAME = "No valid frame."
+
+ # list of defined highlights, so we avoid re-defining them
+ highlightTypes = []
+
+ def __init__(self, owner, name, open_below=False, height=3):
+ self.owner = owner
+ self.name = name
+ self.buffer = None
+ self.maxHeight = 20
+ self.openBelow = open_below
+ self.height = height
+ self.owner.registerForUpdates(self)
+
+ def isPrepared(self):
+ """ check window is OK """
+ if self.buffer == None or len(dir(self.buffer)) == 0 or bufwinnr(self.name) == -1:
+ return False
+ return True
+
+ def prepare(self, method = 'new'):
+ """ check window is OK, if not then create """
+ if not self.isPrepared():
+ self.create(method)
+
+ def on_create(self):
+ pass
+
+ def destroy(self):
+ """ destroy window """
+ if self.buffer == None or len(dir(self.buffer)) == 0:
+ return
+ vim.command('bdelete ' + self.name)
+
+ def create(self, method):
+ """ create window """
+
+ if method != 'edit':
+ belowcmd = "below" if self.openBelow else ""
+ vim.command('silent %s %s %s' % (belowcmd, method, self.name))
+ else:
+ vim.command('silent %s %s' % (method, self.name))
+
+ self.window = vim.current.window
+
+ # Set LLDB pane options
+ vim.command("setlocal buftype=nofile") # Don't try to open a file
+ vim.command("setlocal noswapfile") # Don't use a swap file
+ vim.command("set nonumber") # Don't display line numbers
+ #vim.command("set nowrap") # Don't wrap text
+
+ # Save some parameters and reference to buffer
+ self.buffer = vim.current.buffer
+ self.width = int( vim.eval("winwidth(0)") )
+ self.height = int( vim.eval("winheight(0)") )
+
+ self.on_create()
+ goto_previous_window()
+
+ def update(self, target, controller):
+ """ updates buffer contents """
+ self.target = target
+ if not self.isPrepared():
+ # Window is hidden, or otherwise not ready for an update
+ return
+
+ original_cursor = self.window.cursor
+
+ # Select pane
+ goto_window(bufwinnr(self.name))
+
+ # Clean and update content, and apply any highlights.
+ self.clean()
+
+ if self.write(self.get_content(target, controller)):
+ self.apply_highlights()
+
+ cursor = self.get_selected_line()
+ if cursor is None:
+ # Place the cursor at its original position in the window
+ cursor_line = min(original_cursor[0], len(self.buffer))
+ cursor_col = min(original_cursor[1], len(self.buffer[cursor_line - 1]))
+ else:
+ # Place the cursor at the location requested by a VimPane implementation
+ cursor_line = min(cursor, len(self.buffer))
+ cursor_col = self.window.cursor[1]
+
+ self.window.cursor = (cursor_line, cursor_col)
+
+ goto_previous_window()
+
+ def get_selected_line(self):
+ """ Returns the line number to move the cursor to, or None to leave
+ it where the user last left it.
+ Subclasses implement this to define custom behaviour.
+ """
+ return None
+
+ def apply_highlights(self):
+ """ Highlights each set of lines in each highlight group """
+ highlights = self.get_highlights()
+ for highlightType in highlights:
+ lines = highlights[highlightType]
+ if len(lines) == 0:
+ continue
+
+ cmd = 'match %s /' % highlightType
+ lines = ['\%' + '%d' % line + 'l' for line in lines]
+ cmd += '\\|'.join(lines)
+ cmd += '/'
+ vim.command(cmd)
+
+ def define_highlight(self, name, colour):
+ """ Defines highlihght """
+ if name in VimPane.highlightTypes:
+ # highlight already defined
+ return
+
+ vim.command("highlight %s ctermbg=%s guibg=%s" % (name, colour, colour))
+ VimPane.highlightTypes.append(name)
+
+ def write(self, msg):
+ """ replace buffer with msg"""
+ self.prepare()
+
+ msg = str(msg.encode("utf-8", "replace")).split('\n')
+ try:
+ self.buffer.append(msg)
+ vim.command("execute \"normal ggdd\"")
+ except vim.error:
+ # cannot update window; happens when vim is exiting.
+ return False
+
+ move_cursor(1, 0)
+ return True
+
+ def clean(self):
+ """ clean all datas in buffer """
+ self.prepare()
+ vim.command(':%d')
+ #self.buffer[:] = None
+
+ def get_content(self, target, controller):
+ """ subclasses implement this to provide pane content """
+ assert(0 and "pane subclass must implement this")
+ pass
+
+ def get_highlights(self):
+ """ Subclasses implement this to provide pane highlights.
+ This function is expected to return a map of:
+ { highlight_name ==> [line_number, ...], ... }
+ """
+ return {}
+
+
+class FrameKeyValuePane(VimPane):
+ def __init__(self, owner, name, open_below):
+ """ Initialize parent, define member variables, choose which highlight
+ to use based on whether or not we have a gui (MacVim/Gvim).
+ """
+
+ VimPane.__init__(self, owner, name, open_below)
+
+ # Map-of-maps key/value history { frame --> { variable_name, variable_value } }
+ self.frameValues = {}
+
+ if have_gui():
+ self.changedHighlight = VimPane.CHANGED_VALUE_HIGHLIGHT_NAME_GUI
+ else:
+ self.changedHighlight = VimPane.CHANGED_VALUE_HIGHLIGHT_NAME_TERM
+ self.define_highlight(VimPane.CHANGED_VALUE_HIGHLIGHT_NAME_TERM,
+ VimPane.CHANGED_VALUE_HIGHLIGHT_COLOUR_TERM)
+
+ def format_pair(self, key, value, changed = False):
+ """ Formats a key/value pair. Appends a '*' if changed == True """
+ marker = '*' if changed else ' '
+ return "%s %s = %s\n" % (marker, key, value)
+
+ def get_content(self, target, controller):
+ """ Get content for a frame-aware pane. Also builds the list of lines that
+ need highlighting (i.e. changed values.)
+ """
+ if target is None or not target.IsValid():
+ return VimPane.MSG_NO_TARGET
+
+ self.changedLines = []
+
+ (frame, err) = get_selected_frame(target)
+ if frame is None:
+ return err
+
+ output = get_description(frame)
+ lineNum = 1
+
+ # Retrieve the last values displayed for this frame
+ frameId = get_description(frame.GetBlock())
+ if frameId in self.frameValues:
+ frameOldValues = self.frameValues[frameId]
+ else:
+ frameOldValues = {}
+
+ # Read the frame variables
+ vals = self.get_frame_content(frame)
+ for (key, value) in vals:
+ lineNum += 1
+ if len(frameOldValues) == 0 or (key in frameOldValues and frameOldValues[key] == value):
+ output += self.format_pair(key, value)
+ else:
+ output += self.format_pair(key, value, True)
+ self.changedLines.append(lineNum)
+
+ # Save values as oldValues
+ newValues = {}
+ for (key, value) in vals:
+ newValues[key] = value
+ self.frameValues[frameId] = newValues
+
+ return output
+
+ def get_highlights(self):
+ ret = {}
+ ret[self.changedHighlight] = self.changedLines
+ return ret
+
+class LocalsPane(FrameKeyValuePane):
+ """ Pane that displays local variables """
+ def __init__(self, owner, name = 'locals'):
+ FrameKeyValuePane.__init__(self, owner, name, open_below=True)
+
+ # FIXME: allow users to customize display of args/locals/statics/scope
+ self.arguments = True
+ self.show_locals = True
+ self.show_statics = True
+ self.show_in_scope_only = True
+
+ def format_variable(self, var):
+ """ Returns a Tuple of strings "(Type) Name", "Value" for SBValue var """
+ val = var.GetValue()
+ if val is None:
+ # If the value is too big, SBValue.GetValue() returns None; replace with ...
+ val = "..."
+
+ return ("(%s) %s" % (var.GetTypeName(), var.GetName()), "%s" % val)
+
+ def get_frame_content(self, frame):
+ """ Returns list of key-value pairs of local variables in frame """
+ vals = frame.GetVariables(self.arguments,
+ self.show_locals,
+ self.show_statics,
+ self.show_in_scope_only)
+ return [self.format_variable(x) for x in vals]
+
+class RegistersPane(FrameKeyValuePane):
+ """ Pane that displays the contents of registers """
+ def __init__(self, owner, name = 'registers'):
+ FrameKeyValuePane.__init__(self, owner, name, open_below=True)
+
+ def format_register(self, reg):
+ """ Returns a tuple of strings ("name", "value") for SBRegister reg. """
+ name = reg.GetName()
+ val = reg.GetValue()
+ if val is None:
+ val = "..."
+ return (name, val.strip())
+
+ def get_frame_content(self, frame):
+ """ Returns a list of key-value pairs ("name", "value") of registers in frame """
+
+ result = []
+ for register_sets in frame.GetRegisters():
+ # hack the register group name into the list of registers...
+ result.append((" = = %s =" % register_sets.GetName(), ""))
+
+ for reg in register_sets:
+ result.append(self.format_register(reg))
+ return result
+
+class CommandPane(VimPane):
+ """ Pane that displays the output of an LLDB command """
+ def __init__(self, owner, name, open_below, process_required=True):
+ VimPane.__init__(self, owner, name, open_below)
+ self.process_required = process_required
+
+ def setCommand(self, command, args = ""):
+ self.command = command
+ self.args = args
+
+ def get_content(self, target, controller):
+ output = ""
+ if not target:
+ output = VimPane.MSG_NO_TARGET
+ elif self.process_required and not target.GetProcess():
+ output = VimPane.MSG_NO_PROCESS
+ else:
+ (success, output) = controller.getCommandOutput(self.command, self.args)
+ return output
+
+class StoppedCommandPane(CommandPane):
+ """ Pane that displays the output of an LLDB command when the process is
+ stopped; otherwise displays process status. This class also implements
+ highlighting for a single line (to show a single-line selected entity.)
+ """
+ def __init__(self, owner, name, open_below):
+ """ Initialize parent and define highlight to use for selected line. """
+ CommandPane.__init__(self, owner, name, open_below)
+ if have_gui():
+ self.selectedHighlight = VimPane.SELECTED_HIGHLIGHT_NAME_GUI
+ else:
+ self.selectedHighlight = VimPane.SELECTED_HIGHLIGHT_NAME_TERM
+ self.define_highlight(VimPane.SELECTED_HIGHLIGHT_NAME_TERM,
+ VimPane.SELECTED_HIGHLIGHT_COLOUR_TERM)
+
+ def get_content(self, target, controller):
+ """ Returns the output of a command that relies on the process being stopped.
+ If the process is not in 'stopped' state, the process status is returned.
+ """
+ output = ""
+ if not target or not target.IsValid():
+ output = VimPane.MSG_NO_TARGET
+ elif not target.GetProcess() or not target.GetProcess().IsValid():
+ output = VimPane.MSG_NO_PROCESS
+ elif target.GetProcess().GetState() == lldb.eStateStopped:
+ (success, output) = controller.getCommandOutput(self.command, self.args)
+ else:
+ (success, output) = controller.getCommandOutput("process", "status")
+ return output
+
+ def get_highlights(self):
+ """ Highlight the line under the cursor. Users moving the cursor has
+ no effect on the selected line.
+ """
+ ret = {}
+ line = self.get_selected_line()
+ if line is not None:
+ ret[self.selectedHighlight] = [line]
+ return ret
+ return ret
+
+ def get_selected_line(self):
+ """ Subclasses implement this to control where the cursor (and selected highlight)
+ is placed.
+ """
+ return None
+
+class DisassemblyPane(CommandPane):
+ """ Pane that displays disassembly around PC """
+ def __init__(self, owner, name = 'disassembly'):
+ CommandPane.__init__(self, owner, name, open_below=True)
+
+ # FIXME: let users customize the number of instructions to disassemble
+ self.setCommand("disassemble", "-c %d -p" % self.maxHeight)
+
+class ThreadPane(StoppedCommandPane):
+ """ Pane that displays threads list """
+ def __init__(self, owner, name = 'threads'):
+ StoppedCommandPane.__init__(self, owner, name, open_below=False)
+ self.setCommand("thread", "list")
+
+# FIXME: the function below assumes threads are listed in sequential order,
+# which turns out to not be the case. Highlighting of selected thread
+# will be disabled until this can be fixed. LLDB prints a '*' anyways
+# beside the selected thread, so this is not too big of a problem.
+# def get_selected_line(self):
+# """ Place the cursor on the line with the selected entity.
+# Subclasses should override this to customize selection.
+# Formula: selected_line = selected_thread_id + 1
+# """
+# (thread, err) = get_selected_thread(self.target)
+# if thread is None:
+# return None
+# else:
+# return thread.GetIndexID() + 1
+
+class BacktracePane(StoppedCommandPane):
+ """ Pane that displays backtrace """
+ def __init__(self, owner, name = 'backtrace'):
+ StoppedCommandPane.__init__(self, owner, name, open_below=False)
+ self.setCommand("bt", "")
+
+
+ def get_selected_line(self):
+ """ Returns the line number in the buffer with the selected frame.
+ Formula: selected_line = selected_frame_id + 2
+ FIXME: the above formula hack does not work when the function return
+ value is printed in the bt window; the wrong line is highlighted.
+ """
+
+ (frame, err) = get_selected_frame(self.target)
+ if frame is None:
+ return None
+ else:
+ return frame.GetFrameID() + 2
+
+class BreakpointsPane(CommandPane):
+ def __init__(self, owner, name = 'breakpoints'):
+ super(BreakpointsPane, self).__init__(owner, name, open_below=False, process_required=False)
+ self.setCommand("breakpoint", "list")
Index: aze/lldb/utils/vim-lldb/python-vim-lldb/vim_signs.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/python-vim-lldb/vim_signs.py 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,73 @@
+
+# Classes responsible for drawing signs in the Vim user interface.
+
+import vim
+
+class VimSign(object):
+ SIGN_TEXT_BREAKPOINT_RESOLVED = "B>"
+ SIGN_TEXT_BREAKPOINT_UNRESOLVED = "b>"
+ SIGN_TEXT_PC = "->"
+ SIGN_HIGHLIGHT_COLOUR_PC = 'darkblue'
+
+ # unique sign id (for ':[sign/highlight] define)
+ sign_id = 1
+
+ # unique name id (for ':sign place')
+ name_id = 1
+
+ # Map of {(sign_text, highlight_colour) --> sign_name}
+ defined_signs = {}
+
+ def __init__(self, sign_text, buffer, line_number, highlight_colour=None):
+ """ Define the sign and highlight (if applicable) and show the sign. """
+
+ # Get the sign name, either by defining it, or looking it up in the map of defined signs
+ key = (sign_text, highlight_colour)
+ if not key in VimSign.defined_signs:
+ name = self.define(sign_text, highlight_colour)
+ else:
+ name = VimSign.defined_signs[key]
+
+ self.show(name, buffer.number, line_number)
+ pass
+
+ def define(self, sign_text, highlight_colour):
+ """ Defines sign and highlight (if highlight_colour is not None). """
+ sign_name = "sign%d" % VimSign.name_id
+ if highlight_colour is None:
+ vim.command("sign define %s text=%s" % (sign_name, sign_text))
+ else:
+ self.highlight_name = "highlight%d" % VimSign.name_id
+ vim.command("highlight %s ctermbg=%s guibg=%s" % (self.highlight_name,
+ highlight_colour,
+ highlight_colour))
+ vim.command("sign define %s text=%s linehl=%s texthl=%s" % (sign_name,
+ sign_text,
+ self.highlight_name,
+ self.highlight_name))
+ VimSign.defined_signs[(sign_text, highlight_colour)] = sign_name
+ VimSign.name_id += 1
+ return sign_name
+
+
+ def show(self, name, buffer_number, line_number):
+ self.id = VimSign.sign_id
+ VimSign.sign_id += 1
+ vim.command("sign place %d name=%s line=%d buffer=%s" % (self.id, name, line_number, buffer_number))
+ pass
+
+ def hide(self):
+ vim.command("sign unplace %d" % self.id)
+ pass
+
+class BreakpointSign(VimSign):
+ def __init__(self, buffer, line_number, is_resolved):
+ txt = VimSign.SIGN_TEXT_BREAKPOINT_RESOLVED if is_resolved else VimSign.SIGN_TEXT_BREAKPOINT_UNRESOLVED
+ super(BreakpointSign, self).__init__(txt, buffer, line_number)
+
+class PCSign(VimSign):
+ def __init__(self, buffer, line_number, is_selected_thread):
+ super(PCSign, self).__init__(VimSign.SIGN_TEXT_PC,
+ buffer,
+ line_number,
+ VimSign.SIGN_HIGHLIGHT_COLOUR_PC if is_selected_thread else None)
Index: aze/lldb/utils/vim-lldb/python-vim-lldb/vim_ui.py
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/python-vim-lldb/vim_ui.py 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,235 @@
+
+# LLDB UI state in the Vim user interface.
+
+import os, re, sys
+import lldb
+import vim
+from vim_panes import *
+from vim_signs import *
+
+def is_same_file(a, b):
+ """ returns true if paths a and b are the same file """
+ a = os.path.realpath(a)
+ b = os.path.realpath(b)
+ return a in b or b in a
+
+class UI:
+ def __init__(self):
+ """ Declare UI state variables """
+
+ # Default panes to display
+ self.defaultPanes = ['breakpoints', 'backtrace', 'locals', 'threads', 'registers', 'disassembly']
+
+ # map of tuples (filename, line) --> SBBreakpoint
+ self.markedBreakpoints = {}
+
+ # Currently shown signs
+ self.breakpointSigns = {}
+ self.pcSigns = []
+
+ # Container for panes
+ self.paneCol = PaneLayout()
+
+ # All possible LLDB panes
+ self.backtracePane = BacktracePane(self.paneCol)
+ self.threadPane = ThreadPane(self.paneCol)
+ self.disassemblyPane = DisassemblyPane(self.paneCol)
+ self.localsPane = LocalsPane(self.paneCol)
+ self.registersPane = RegistersPane(self.paneCol)
+ self.breakPane = BreakpointsPane(self.paneCol)
+
+ def activate(self):
+ """ Activate UI: display default set of panes """
+ self.paneCol.prepare(self.defaultPanes)
+
+ def get_user_buffers(self, filter_name=None):
+ """ Returns a list of buffers that are not a part of the LLDB UI. That is, they
+ are not contained in the PaneLayout object self.paneCol.
+ """
+ ret = []
+ for w in vim.windows:
+ b = w.buffer
+ if not self.paneCol.contains(b.name):
+ if filter_name is None or filter_name in b.name:
+ ret.append(b)
+ return ret
+
+ def update_pc(self, process, buffers, goto_file):
+ """ Place the PC sign on the PC location of each thread's selected frame """
+
+ def GetPCSourceLocation(thread):
+ """ Returns a tuple (thread_index, file, line, column) that represents where
+ the PC sign should be placed for a thread.
+ """
+
+ frame = thread.GetSelectedFrame()
+ frame_num = frame.GetFrameID()
+ le = frame.GetLineEntry()
+ while not le.IsValid() and frame_num < thread.GetNumFrames():
+ frame_num += 1
+ le = thread.GetFrameAtIndex(frame_num).GetLineEntry()
+
+ if le.IsValid():
+ path = os.path.join(le.GetFileSpec().GetDirectory(), le.GetFileSpec().GetFilename())
+ return (thread.GetIndexID(), path, le.GetLine(), le.GetColumn())
+ return None
+
+
+ # Clear all existing PC signs
+ del_list = []
+ for sign in self.pcSigns:
+ sign.hide()
+ del_list.append(sign)
+ for sign in del_list:
+ self.pcSigns.remove(sign)
+ del sign
+
+ # Select a user (non-lldb) window
+ if not self.paneCol.selectWindow(False):
+ # No user window found; avoid clobbering by splitting
+ vim.command(":vsp")
+
+ # Show a PC marker for each thread
+ for thread in process:
+ loc = GetPCSourceLocation(thread)
+ if not loc:
+ # no valid source locations for PCs. hide all existing PC markers
+ continue
+
+ buf = None
+ (tid, fname, line, col) = loc
+ buffers = self.get_user_buffers(fname)
+ is_selected = thread.GetIndexID() == process.GetSelectedThread().GetIndexID()
+ if len(buffers) == 1:
+ buf = buffers[0]
+ if buf != vim.current.buffer:
+ # Vim has an open buffer to the required file: select it
+ vim.command('execute ":%db"' % buf.number)
+ elif is_selected and vim.current.buffer.name not in fname and os.path.exists(fname) and goto_file:
+ # FIXME: If current buffer is modified, vim will complain when we try to switch away.
+ # Find a way to detect if the current buffer is modified, and...warn instead?
+ vim.command('execute ":e %s"' % fname)
+ buf = vim.current.buffer
+ elif len(buffers) > 1 and goto_file:
+ #FIXME: multiple open buffers match PC location
+ continue
+ else:
+ continue
+
+ self.pcSigns.append(PCSign(buf, line, is_selected))
+
+ if is_selected and goto_file:
+ # if the selected file has a PC marker, move the cursor there too
+ curname = vim.current.buffer.name
+ if curname is not None and is_same_file(curname, fname):
+ move_cursor(line, 0)
+ elif move_cursor:
+ print "FIXME: not sure where to move cursor because %s != %s " % (vim.current.buffer.name, fname)
+
+ def update_breakpoints(self, target, buffers):
+ """ Decorates buffer with signs corresponding to breakpoints in target. """
+
+ def GetBreakpointLocations(bp):
+ """ Returns a list of tuples (resolved, filename, line) where a breakpoint was resolved. """
+ if not bp.IsValid():
+ sys.stderr.write("breakpoint is invalid, no locations")
+ return []
+
+ ret = []
+ numLocs = bp.GetNumLocations()
+ for i in range(numLocs):
+ loc = bp.GetLocationAtIndex(i)
+ desc = get_description(loc, lldb.eDescriptionLevelFull)
+ match = re.search('at\ ([^:]+):([\d]+)', desc)
+ try:
+ lineNum = int(match.group(2).strip())
+ ret.append((loc.IsResolved(), match.group(1), lineNum))
+ except ValueError as e:
+ sys.stderr.write("unable to parse breakpoint location line number: '%s'" % match.group(2))
+ sys.stderr.write(str(e))
+
+ return ret
+
+
+ if target is None or not target.IsValid():
+ return
+
+ needed_bps = {}
+ for bp_index in range(target.GetNumBreakpoints()):
+ bp = target.GetBreakpointAtIndex(bp_index)
+ locations = GetBreakpointLocations(bp)
+ for (is_resolved, file, line) in GetBreakpointLocations(bp):
+ for buf in buffers:
+ if file in buf.name:
+ needed_bps[(buf, line, is_resolved)] = bp
+
+ # Hide any signs that correspond with disabled breakpoints
+ del_list = []
+ for (b, l, r) in self.breakpointSigns:
+ if (b, l, r) not in needed_bps:
+ self.breakpointSigns[(b, l, r)].hide()
+ del_list.append((b, l, r))
+ for d in del_list:
+ del self.breakpointSigns[d]
+
+ # Show any signs for new breakpoints
+ for (b, l, r) in needed_bps:
+ bp = needed_bps[(b, l, r)]
+ if self.haveBreakpoint(b.name, l):
+ self.markedBreakpoints[(b.name, l)].append(bp)
+ else:
+ self.markedBreakpoints[(b.name, l)] = [bp]
+
+ if (b, l, r) not in self.breakpointSigns:
+ s = BreakpointSign(b, l, r)
+ self.breakpointSigns[(b, l, r)] = s
+
+ def update(self, target, status, controller, goto_file=False):
+ """ Updates debugger info panels and breakpoint/pc marks and prints
+ status to the vim status line. If goto_file is True, the user's
+ cursor is moved to the source PC location in the selected frame.
+ """
+
+ self.paneCol.update(target, controller)
+ self.update_breakpoints(target, self.get_user_buffers())
+
+ if target is not None and target.IsValid():
+ process = target.GetProcess()
+ if process is not None and process.IsValid():
+ self.update_pc(process, self.get_user_buffers, goto_file)
+
+ if status is not None and len(status) > 0:
+ print status
+
+ def haveBreakpoint(self, file, line):
+ """ Returns True if we have a breakpoint at file:line, False otherwise """
+ return (file, line) in self.markedBreakpoints
+
+ def getBreakpoints(self, fname, line):
+ """ Returns the LLDB SBBreakpoint object at fname:line """
+ if self.haveBreakpoint(fname, line):
+ return self.markedBreakpoints[(fname, line)]
+ else:
+ return None
+
+ def deleteBreakpoints(self, name, line):
+ del self.markedBreakpoints[(name, line)]
+
+ def showWindow(self, name):
+ """ Shows (un-hides) window pane specified by name """
+ if not self.paneCol.havePane(name):
+ sys.stderr.write("unknown window: %s" % name)
+ return False
+ self.paneCol.prepare([name])
+ return True
+
+ def hideWindow(self, name):
+ """ Hides window pane specified by name """
+ if not self.paneCol.havePane(name):
+ sys.stderr.write("unknown window: %s" % name)
+ return False
+ self.paneCol.hide([name])
+ return True
+
+global ui
+ui = UI()
Index: aze/lldb/utils/vim-lldb/README
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/utils/vim-lldb/README 2013-03-03 09:35:50.351457348 +0100
@@ -0,0 +1,59 @@
+
+=================
+LLDB Vim Frontend
+=================
+
+Prerequisites
+-------------
+
+This plugin is known to work with the following flavours of Vim:
+
+ * Linux (tested on Ubuntu 12.04/12.10):
+ * vim/gvim (from vim-gnome package version 7.3)
+
+ * Mac OS X (tested on Mountain Lion)
+ * Vim command-line (7.3 from Xcode)
+ * MacVim 7.3
+
+To install the plugin, ensure you have
+ * a working version of lldb on your path, or the environment variable LLDB
+ pointing to the lldb binary you would like to use.
+ * a python-enabled vim (check with ":python print 2")
+
+
+Installation
+------------
+
+1) Install the Vim pathogen plugin (it keeps installed plugins organized):
+
+ https://github.com/tpope/vim-pathogen
+
+ Or, for the impatient:
+
+mkdir -p ~/.vim/autoload ~/.vim/bundle; \
+curl -Sso ~/.vim/autoload/pathogen.vim \
+ https://raw.github.com/tpope/vim-pathogen/master/autoload/pathogen.vim
+
+2) Symlink (or copy) ~/.vim/bundle/vim-lldb to this directory:
+
+ln -sf <lldb-dir>/utils/vim-lldb ~/.vim/bundle/vim-lldb
+
+3) Update your help-tags. Start vim, do:
+
+ :Helptags
+
+4) Have fun!
+
+
+Usage/Getting Help
+------------------
+All LLDB commands (with tab-completion) can be accessed in Vim's
+command mode. Try it out by typing:
+
+:L<tab>
+
+There are several sources of help available:
+
+:help lldb -- Documentation for this plugin
+:Lhelp -- LLDB's built-in help system (i.e lldb 'help' command)
+:Lscript help (lldb) -- Complete LLDB Python API reference
Index: aze/lldb/www/architecture.html
===================================================================
--- aze.orig/lldb/www/architecture.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/architecture.html 2013-03-03 09:35:50.351457348 +0100
@@ -36,6 +36,7 @@
<li><a href="#breakpoint">Breakpoint</a></li>
<li><a href="#commands">Commands</a></li>
<li><a href="#core">Core</a></li>
+ <li><a href="#dataformatters">DataFormatters</a></li>
<li><a href="#expression">Expression</a></li>
<li><a href="#host">Host</a></li>
<li><a href="#interpreter">Interpreter</a></li>
@@ -143,6 +144,23 @@
</div>
<div class="postfooter"></div>
</div>
+ <a name="dataformatters"></a>
+ <div class="post">
+ <h1 class ="postheader">DataFormatters</h1>
+ <div class="postcontent">
+
+ <p>A collection of classes that implement the data formatters subsystem.</p>
+ <p>The main entry point for interacting with the LLDB data formatters is the DataVisualization class. It provides
+ a relatively stable front-end interface to ask questions of the data formatters regardless of the internal implementation.</p>
+ <p>For people actively maintaining the data formatters subsystem itself, however, the FormatManager class is the relevant point of entry.
+ This class is subject to more frequent changes as the formatters evolve. Currently, it provides a thin caching layer on top of a list of categories
+ that each export a group of formatters.
+ </p>
+ <p>From an end-user perspective, the "type" LLDB command is the point of access to the data formatters. A large group of generally-useful formatters
+ is provided by default and loaded upon debugger startup.
+ </div>
+ <div class="postfooter"></div>
+ </div>
<a name="expression"></a>
<div class="post">
<h1 class ="postheader">Expression</h1>
Index: aze/lldb/www/build.html
===================================================================
--- aze.orig/lldb/www/build.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/build.html 2013-03-03 09:35:50.351457348 +0100
@@ -17,6 +17,16 @@
<!--#include virtual="sidebar.incl"-->
<div id="middle">
+ <h1 class ="postheader">Continuous Integraton</h1>
+ <div class="postcontent">
+ <p> The following LLVM buildbots build and test LLDB trunk:
+ <ul>
+ <li> <a href="http://lab.llvm.org:8011/builders/lldb-x86_64-debian-clang">LLDB Linux x86_64 build with Clang (automake)</a>
+ <li> <a href="http://lab.llvm.org:8011/builders/lldb-x86_64-linux">LLDB Linux x86_64 build with GCC 4.6 (automake)</a>
+ <li> <a href="http://lab.llvm.org:8011/builders/lldb-x86_64-darwin11">LLDB Mac OS X x86_64 build with Clang (XCode)</a>
+ </ul>
+ </div>
+ <div class="postfooter"></div>
<div class="post">
<h1 class ="postheader">Building LLDB on Mac OS X</h1>
<div class="postcontent">
@@ -53,6 +63,12 @@
<li><a href="http://llvm.org/docs/GettingStarted.html">LLVM</a></li>
<li><a href="http://clang.llvm.org/get_started.html">Clang</a></li>
</ul>
+ <p>Supported compilers for building LLDB on Linux include:</p>
+ <ul>
+ <li>Clang 3.2</li>
+ <li><a href="http://gcc.gnu.org">GCC</a> 4.6.2 (later versions should work as well)</li>
+ </ul>
+ <p>It is recommended to use libstdc++ 4.6 (or higher) to build LLDB on Linux, but using libc++ is also known to work.</p>
<p>In addition to any dependencies required by LLVM and Clang, LLDB needs a few
development packages that may also need to be installed depending on your
system. The current list of dependencies are:</p>
@@ -65,10 +81,6 @@
<code>&gt; yum install swig python-devel libedit-devel</code>
<p>On an Ubuntu system one might run:</p>
<code>&gt; sudo apt-get install swig python-dev libedit-dev </code>
- <p>If building using GCC instead of Clang, GCC 4.6.2 or newer is required.</p>
- <ul>
- <li><a href="http://gcc.gnu.org">GCC</a></li>
- </ul>
<h2 >Building LLDB</h2>
<p>We first need to checkout the source trees into the appropriate locations. Both
Clang and LLDB build as subprojects of LLVM. This means we will be checking out
@@ -105,25 +117,33 @@
<code>&gt; cd $llvm/..
<br>&gt; mkdir build
<br>&gt; cd build
- <br>&gt; $llvm/configure --enable-cxx11 --enable-libcpp
+ </code>
+ <p>If you are using clang:</p>
+ <code>
+ <br>&gt; $llvm/configure --enable-cxx11
<br>&gt; make </code>
+ <p>If you are using GCC 4.6+:</p>
+ <code>
+ <br>&gt; $llvm/configure
+ <br>&gt; make CXXFLAGS=-std=c++0x</code>
<p>Note that once both LLVM and Clang have been configured and built it is not
necessary to perform a top-level <tt>make</tt> to rebuild changes made only to LLDB.
- You can run <tt>make</tt> from the <tt>build/tools/lldb</tt> subdirectory as well. If your
- compiler doesn't support libc++, you may need to tweak or remove the last
- parameter to the configure script.</p>
+ You can run <tt>make</tt> from the <tt>build/tools/lldb</tt> subdirectory as well.</p>
+ <p> If you wish to build with libc++ instead of libstdc++ (the default), you should run configure with the
+ <tt>--enable-libcpp</tt> flag.</p>
+ <p> If you wish to build a release version of LLDB, run configure with the <tt>--enable-optimized</tt> flag.</p>
<h2>Additional Notes</h2>
- <p>LLDB has a Python scripting capability and supplies it&#8217;s own Python module,
- <tt>lldb</tt>, built alongside the <tt>lldb</tt> binary. Python needs to know where to
- look for this module when LLDB starts up. To tell python the location of LLDB, set
- <tt>PYTHONPATH</tt> environment variable.
- <p>In bash with a <tt>Debug+Asserts</tt> build (the default if configure is invoked
- like in the example on this page) one might run:</p>
- <code>&gt; export PYTHONPATH=$llvm/build/Debug+Asserts/lib/python2.7/site-packages</code>
- <p>If you used different configure flags, or have a different version of python,
- you may need to adjust the above to suit your needs. To test that the lldb python module
- is built correctly and is available to Python, run:</p>
+ <p>LLDB has a Python scripting capability and supplies its own Python module named <tt>lldb</tt>.
+ If a script is run inside the command line <tt>lldb</tt> application, the Python module
+ is made available automatically. However, if a script is to be run by a Python interpreter
+ outside the command line application, the <tt>PYTHONPATH</tt> environment variable can be used
+ to let the Python interpreter find the <tt>lldb</tt> module.
+ <p>The correct path can be obtained by invoking the command line <tt>lldb</tt> tool with the -P flag:</p>
+ <code>&gt; export PYTHONPATH=`$llvm/build/Debug+Asserts/bin/lldb -P`</code>
+ <p>If you used a different build directory or made a release build, you may need to adjust the
+ above to suit your needs. To test that the lldb Python module
+ is built correctly and is available to the default Python interpreter, run:</p>
<code>&gt; python -c 'import lldb'</code></p>
</div>
<div class="postfooter"></div>
Index: aze/lldb/www/index.html
===================================================================
--- aze.orig/lldb/www/index.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/index.html 2013-03-03 09:35:50.351457348 +0100
@@ -92,6 +92,8 @@
<li>Mac OS X desktop user space debugging for i386 and x86-64</li>
<li>iOS simulator debugging on i386</li>
<li>iOS device debugging on ARM</li>
+ <li>Linux local user-space debugging for i386 and x86-64</li>
+ <li>FreeBSD local user-space debugging for i386 and x86-64</li>
</ul>
</div>
<div class="postfooter"></div>
@@ -108,8 +110,8 @@
<li>svn co http://llvm.org/svn/llvm-project/lldb/trunk lldb</li>
</ul>
- <p>Note that LLDB currently only builds out of the box on Mac OS X with
- Xcode, but patches to improve portability are definitely welcome.</p>
+ <p>Note that LLDB generally builds from top-of-trunk on Mac OS X with
+ Xcode and on Linux (with clang and libstdc++/libc++). </p>
<p>Discussions about LLDB should go to the <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev">lldb-dev</a> mailing
list. Commit messages for the lldb SVN module are automatically sent to the
@@ -123,4 +125,4 @@
</div>
</div>
</body>
-</html>
\ No newline at end of file
+</html>
Index: aze/lldb/www/lldb-gdb.html
===================================================================
--- aze.orig/lldb/www/lldb-gdb.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/lldb-gdb.html 2013-03-03 09:35:50.351457348 +0100
@@ -98,6 +98,25 @@
</td>
</tr>
+ <tr><td class="header" colspan="2">Set environment variables for process before launching.</td></tr>
+ <td class="content">
+ <b>(gdb)</b> set env DEBUG 1<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> settings set target.env-vars DEBUG=1<br>
+ <b>(lldb)</b> set se target.env-vars DEBUG=1<br>
+ <b>(lldb)</b> env DEBUG=1<br>
+ </td>
+ </tr>
+
+ <tr><td class="header" colspan="2">Set environment variables for process and launch process in one command.</td></tr>
+ <td class="content">
+ </td>
+ <td class="content">
+ <b>(lldb)</b> process launch -v DEBUG=1<br>
+ </td>
+ </tr>
+
<tr><td class="header" colspan="2">Attach to a process with process ID 123.</td></tr>
<tr>
<td class="content">
@@ -223,6 +242,16 @@
</td>
</tr>
+ <tr><td class="header" colspan="2">Return immediately from the currently selected frame, with an optional return value.</td></tr>
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> return &lt;RETURN EXPRESSION&gt;<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> thread return &lt;RETURN EXPRESSION&gt;<br>
+ </td>
+ </tr>
+
<tr><td class="header" colspan="2">Backtrace and disassemble every time you stop.</td></tr>
<tr>
<td class="content">
@@ -318,11 +347,23 @@
<b>(gdb)</b> rbreak regular-expression<br>
</td>
<td class="content">
- <b>(lldb)</b> breakpoint set --regex regular-expression<br>
+ <b>(lldb)</b> breakpoint set --func-regex regular-expression<br>
<b>(lldb)</b> br s -r regular-expression<br>
</td>
</tr>
+ <tr><td class="header" colspan="2">Ensure that breakpoints by file and line work for #included .c/.cpp/.m files.</td></tr>
+
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> b foo.c:12<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> settings set target.inline-breakpoint-strategy always<br>
+ <b>(lldb)</b> br s -f foo.c -l 12<br>
+ </td>
+ </tr>
+
<tr><td class="header" colspan="2">Set a breakpoint by regular expression on source file contents.</td></tr>
<tr>
@@ -631,6 +672,28 @@
</td>
</tr>
+ <tr><td class="header" colspan="2">Calling a function so you can stop at a breakpoint in the function.</td></tr>
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> set unwindonsignal 0<br>
+ <b>(gdb)</b> p function_with_a_breakpoint()<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> expr -i 0 -- function_with_a_breakpoint()<br>
+ </td>
+ </tr>
+
+ <tr><td class="header" colspan="2">Calling a function that crashes, and stopping when the function crashes.</td></tr>
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> set unwindonsignal 0<br>
+ <b>(gdb)</b> p function_which_crashes()<br>
+ </td>
+ <td class="content">
+ <b>(lldb)</b> expr -u 0 -- function_which_crashes()<br>
+ </td>
+ </tr>
+
</table>
<p>
@@ -873,6 +936,44 @@
<b>(lldb)</b> me r -o /tmp/mem.bin -b 0x1000 0x1200<br>
</td>
</tr>
+ <tr><td class="header" colspan="2">Get information about a specific heap allocation (available on Mac OS X only).</td></tr>
+ <tr>
+ <td class="content">
+ <b>(gdb)</b> info malloc 0x10010d680
+ </td>
+ <td class="content">
+ <b>(lldb)</b> script import lldb.macosx.heap<br>
+ <b>(lldb)</b> process launch --environment MallocStackLogging=1 -- [ARGS]<br>
+ <b>(lldb)</b> malloc_info --stack-history 0x10010d680<br>
+ </td>
+ </tr>
+ <tr><td class="header" colspan="2">Get information about a specific heap allocation and cast the result to any dynamic type that can be deduced (available on Mac OS X only)</td></tr>
+ <tr>
+ <td class="content">
+ </td>
+ <td class="content">
+ <b>(lldb)</b> script import lldb.macosx.heap<br>
+ <b>(lldb)</b> malloc_info --type 0x10010d680<br>
+ </td>
+ </tr>
+ <tr><td class="header" colspan="2">Find all heap blocks that contain a pointer specified by an expression EXPR (available on Mac OS X only).</td></tr>
+ <tr>
+ <td class="content">
+ </td>
+ <td class="content">
+ <b>(lldb)</b> script import lldb.macosx.heap<br>
+ <b>(lldb)</b> ptr_refs EXPR <br>
+ </td>
+ </tr>
+ <tr><td class="header" colspan="2">Find all heap blocks that contain a C string anywhere in the block (available on Mac OS X only).</td></tr>
+ <tr>
+ <td class="content">
+ </td>
+ <td class="content">
+ <b>(lldb)</b> script import lldb.macosx.heap<br>
+ <b>(lldb)</b> cstr_refs CSTRING<br>
+ </td>
+ </tr>
<tr><td class="header" colspan="2">Disassemble the current function for the current frame.</td></tr>
<tr>
<td class="content">
Index: aze/lldb/www/python-reference.html
===================================================================
--- aze.orig/lldb/www/python-reference.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/python-reference.html 2013-03-03 09:35:50.355457348 +0100
@@ -96,11 +96,8 @@
<p>This drops you into the embedded python interpreter. When running under the <b>script</b> command,
lldb sets some convenience variables that give you quick access to the currently selected entities that characterize
the program and debugger state. In each case, if there is no currently selected entity of the appropriate
- type, the variable's <b>IsValid</b> method will return false.
- <p>Note also, these variables hold the values
- of the selected objects on entry to the embedded interpreter. They do not update as you use the LLDB
- API's to change, for example, the currently selected stack frame or thread.</p>
- These are all global variables contained in the <b>lldb</b> python namespace :</p>
+ type, the variable's <b>IsValid</b> method will return false. These variables are:</p>
+
<table class="stats" width="620" cellspacing="0">
<tr>
<td class="hed" width="20%">Variable</td>
@@ -160,7 +157,7 @@
Contains the currently selected thread.
The <b>lldb.SBThread</b> object manages the stack frames in that thread.
A thread is always selected in the command interpreter when a target stops.
- The <b>thread select &lt;thread-index&gt;</b> commmand can be used to change the
+ The <b>thread select &lt;thread-index&gt;</b> command can be used to change the
currently selected thread. So as long as you have a stopped process, there will be
some selected thread.
</td>
@@ -177,14 +174,25 @@
The <b>lldb.SBFrame</b> object manage the stack locals and the register set for
that stack.
A stack frame is always selected in the command interpreter when a target stops.
- The <b>frame select &lt;frame-index&gt;</b> commmand can be used to change the
+ The <b>frame select &lt;frame-index&gt;</b> command can be used to change the
currently selected frame. So as long as you have a stopped process, there will
be some selected frame.
</td>
</tr>
</table>
- <p>Once in the embedded interpreter, these objects can be used. To get started, note that almost
+ <p>While extremely convenient, these variables have a couple caveats that you should be aware of.
+ First of all, they hold the values
+ of the selected objects on entry to the embedded interpreter. They do not update as you use the LLDB
+ API's to change, for example, the currently selected stack frame or thread.
+ <p>Moreover, they are only defined and meaningful while in the interactive Python interpreter.
+ There is no guarantee on their value in any other situation, hence you should not use them when defining
+ Python formatters, breakpoint scripts and commands (or any other Python extension point that LLDB provides).
+ As a rationale for such behavior, consider that lldb can
+ run in a multithreaded environment, and another thread might call the "script" command, changing the value out
+ from under you.</p>
+
+ <p>To get started with these objects and LLDB scripting, please note that almost
all of the <b>lldb</b> Python objects are able to briefly describe themselves when you pass them
to the Python <b>print</b> function:
<code><pre><tt>(lldb) <b>script</b>
@@ -509,6 +517,11 @@
<code><pre><tt><font color=green>#!/usr/bin/python</font>
import lldb
+import os
+
+def disassemble_instructions(insts):
+ for i in insts:
+ print i
<font color=green># Set the path to the executable to debug</font>
exe = "./a.out"
@@ -542,30 +555,30 @@
state = process.GetState ()
print process
if state == lldb.eStateStopped:
- <font color=green># Get the first thread</font>
- thread = process.GetThreadAtIndex (0)
- if thread:
- <font color=green># Print some simple thread info</font>
- print thread
- <font color=green># Get the first frame</font>
- frame = thread.GetFrameAtIndex (0)
- if frame:
- <font color=green># Print some simple frame info</font>
- print frame
- function = frame.GetFunction()
- <font color=green># See if we have debug info (a function)</font>
- if function:
- <font color=green># We do have a function, print some info for the function</font>
- print function
- <font color=green># Now get all instructions for this function and print them</font>
- insts = function.GetInstructions(target)
- disassemble_instructions (insts)
- else:
- <font color=green># See if we have a symbol in the symbol table for where we stopped</font>
- symbol = frame.GetSymbol();
- if symbol:
- <font color=green># We do have a symbol, print some info for the symbol</font>
- print symbol
+ <font color=green># Get the first thread</font>
+ thread = process.GetThreadAtIndex (0)
+ if thread:
+ <font color=green># Print some simple thread info</font>
+ print thread
+ <font color=green># Get the first frame</font>
+ frame = thread.GetFrameAtIndex (0)
+ if frame:
+ <font color=green># Print some simple frame info</font>
+ print frame
+ function = frame.GetFunction()
+ <font color=green># See if we have debug info (a function)</font>
+ if function:
+ <font color=green># We do have a function, print some info for the function</font>
+ print function
+ <font color=green># Now get all instructions for this function and print them</font>
+ insts = function.GetInstructions(target)
+ disassemble_instructions (insts)
+ else:
+ <font color=green># See if we have a symbol in the symbol table for where we stopped</font>
+ symbol = frame.GetSymbol();
+ if symbol:
+ <font color=green># We do have a symbol, print some info for the symbol</font>
+ print symbol
</tt></pre></code>
</div>
<div class="postfooter"></div>
Index: aze/lldb/www/sidebar.incl
===================================================================
--- aze.orig/lldb/www/sidebar.incl 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/sidebar.incl 2013-03-03 09:35:50.355457348 +0100
@@ -17,9 +17,11 @@
<li><a href="tutorial.html">Tutorial</a></li>
<li><a href="lldb-gdb.html">GDB and LLDB command examples</a></li>
<li><a href="formats.html">Frame and Thread Formatting</a></li>
+ <li><a href="symbolication.html">Symbolication</a></li>
<li><a href="varformats.html">Variable Formatting</a></li>
<li><a href="python-reference.html">Python Reference</a></li>
<li><a href="scripting.html">Python Example</a></li>
+ <li><a href="symbols.html">Symbols on Mac OS X</a></li>
<li><a href="architecture.html">Architecture</a></li>
</ul>
</div>
Index: aze/lldb/www/status.html
===================================================================
--- aze.orig/lldb/www/status.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/status.html 2013-03-03 09:35:50.355457348 +0100
@@ -64,7 +64,7 @@
<li>module scoping
</ul>
</td>
- <td>OK except on C++ exception (catch/throw)</td>
+ <td>OK</td>
<td>OK</td>
</tr>
<tr>
Index: aze/lldb/www/symbolication.html
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/www/symbolication.html 2013-03-03 09:35:50.355457348 +0100
@@ -0,0 +1,363 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<link href="style.css" rel="stylesheet" type="text/css" />
+<title>Symbolicating with LLDB</title>
+</head>
+
+<body>
+ <div class="www_title">
+ The <strong>LLDB</strong> Debugger
+ </div>
+
+<div id="container">
+ <div id="content">
+
+ <!--#include virtual="sidebar.incl"-->
+
+ <div id="middle">
+ <div class="post">
+ <h1 class="postheader">Manual Symbolication with LLDB</h1>
+ <div class="postcontent">
+ <p>LLDB is separated into a shared library that contains the core of the debugger,
+ and a driver that implements debugging and a command interpreter. LLDB can be
+ used to symbolicate your crash logs and can often provide more information than
+ other symbolication programs:
+ </p>
+ <ul>
+ <li>Inlined functions</li>
+ <li>Variables that are in scope for an address, along with their locations</li>
+ </ul>
+ <p>The simplest form of symbolication is to load an executable:</p>
+<code><pre><tt><b>(lldb)</b> target create --no-dependents --arch x86_64 /tmp/a.out
+</tt></pre></code>
+ <p>We use the "--no-dependents" flag with the "target create" command so
+ that we don't load all of the dependent shared libraries from the current
+ system. When we symbolicate, we are often symbolicating a binary that
+ was running on another system, and even though the main executable might
+ reference shared libraries in "/usr/lib", we often don't want to load
+ the versions on the current computer.</p>
+ <p>Using the "image list" command will show us a list of all shared libraries
+ associated with the current target. As expected, we currently only have a single
+ binary:
+ </p>
+ <code><pre><tt><b>(lldb)</b> image list
+[ 0] 73431214-6B76-3489-9557-5075F03E36B4 0x0000000100000000 /tmp/a.out
+ /tmp/a.out.dSYM/Contents/Resources/DWARF/a.out
+</tt></pre></code>
+
+ <p>Now we can look up an address:</p>
+<code><pre><tt><b>(lldb)</b> image lookup --address 0x100000aa3
+ Address: a.out[0x0000000100000aa3] (a.out.__TEXT.__text + 131)
+ Summary: a.out`main + 67 at main.c:13
+</tt></pre></code>
+ <p>Since we haven't specified a slide or any load addresses for individual sections
+ in the binary, the address that we use here is a <b>file</b> address. A <b>file</b>
+ address refers to a virtual address as defined by each object file.
+ </p>
+ <p>If we didn't use the "--no-dependents" option with "target create", we would
+ have loaded all dependent shared libraries:<p>
+ <code><pre><tt><b>(lldb)</b> image list
+[ 0] 73431214-6B76-3489-9557-5075F03E36B4 0x0000000100000000 /tmp/a.out
+ /tmp/a.out.dSYM/Contents/Resources/DWARF/a.out
+[ 1] 8CBCF9B9-EBB7-365E-A3FF-2F3850763C6B 0x0000000000000000 /usr/lib/system/libsystem_c.dylib
+[ 2] 62AA0B84-188A-348B-8F9E-3E2DB08DB93C 0x0000000000000000 /usr/lib/system/libsystem_dnssd.dylib
+[ 3] C0535565-35D1-31A7-A744-63D9F10F12A4 0x0000000000000000 /usr/lib/system/libsystem_kernel.dylib
+...
+</tt></pre></code>
+
+
+ <p>Now if we do a lookup using a <b>file</b> address, this can result in multiple
+ matches since most shared libraries have a virtual address space that starts at zero:</p>
+<code><pre><tt><b>(lldb)</b> image lookup -a 0x1000
+ Address: a.out[0x0000000000001000] (a.out.__PAGEZERO + 4096)
+
+ Address: libsystem_c.dylib[0x0000000000001000] (libsystem_c.dylib.__TEXT.__text + 928)
+ Summary: libsystem_c.dylib`mcount + 9
+
+ Address: libsystem_dnssd.dylib[0x0000000000001000] (libsystem_dnssd.dylib.__TEXT.__text + 456)
+ Summary: libsystem_dnssd.dylib`ConvertHeaderBytes + 38
+
+ Address: libsystem_kernel.dylib[0x0000000000001000] (libsystem_kernel.dylib.__TEXT.__text + 1116)
+ Summary: libsystem_kernel.dylib`clock_get_time + 102
+...
+</tt></pre></code>
+ <p>To avoid getting multiple file address matches, you can specify the
+ <b>name</b> of the shared library to limit the search:</p>
+<code><pre><tt><b>(lldb)</b> image lookup -a 0x1000 <b>a.out</b>
+ Address: a.out[0x0000000000001000] (a.out.__PAGEZERO + 4096)
+</tt></pre></code>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Defining Load Addresses for Sections</h1>
+ <div class="postcontent">
+ <p>When symbolicating your crash logs, it can be tedious if you always have to
+ adjust your crashlog-addresses into file addresses. To avoid having to do any
+ conversion, you can set the load address for the sections of the modules in your target.
+ Once you set any section load address, lookups will switch to using
+ <b>load</b> addresses. You can slide all sections in the executable by the same amount,
+ or set the <b>load</b> address for individual sections. The
+ "target modules load --slide" command allows us to set the <b>load</b> address for
+ all sections.
+ <p>Below is an example of sliding all sections in <b>a.out</b> by adding 0x123000 to each section's <b>file</b> address:</p>
+<code><pre><tt><b>(lldb)</b> target create --no-dependents --arch x86_64 /tmp/a.out
+<b>(lldb)</b> target modules load --file a.out --slide 0x123000
+</tt></pre></code>
+ <p>It is often much easier to specify the actual load location of each section by name.
+ Crash logs on Mac OS X have a <b>Binary Images</b> section that specifies
+ that address of the __TEXT segment for each binary. Specifying a slide requires
+ requires that you first find the original (<b>file</b>) address for the __TEXT
+ segment, and subtract the two values.
+ If you specify the
+ address of the __TEXT segment with "target modules load <i>section</i> <i>address</i>", you don't need to do any calculations. To specify
+ the load addresses of sections we can specify one or more section name + address pairs
+ in the "target modules load" command:</p>
+<code><pre><tt><b>(lldb)</b> target create --no-dependents --arch x86_64 /tmp/a.out
+<b>(lldb)</b> target modules load --file a.out __TEXT 0x100123000
+</tt></pre></code>
+ <p>We specified that the <b>__TEXT</b> section is loaded at 0x100123000.
+ Now that we have defined where sections have been loaded in our target,
+ any lookups we do will now use <b>load</b> addresses so we don't have to
+ do any math on the addresses in the crashlog backtraces, we can just use the
+ raw addresses:</p>
+<code><pre><tt><b>(lldb)</b> image lookup --address 0x100123aa3
+ Address: a.out[0x0000000100000aa3] (a.out.__TEXT.__text + 131)
+ Summary: a.out`main + 67 at main.c:13
+</tt></pre></code>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Loading Multiple Executables</h1>
+ <div class="postcontent">
+ <p>You often have more than one executable involved when you need to symbolicate
+ a crash log. When this happens, you create a target for the main executable
+ or one of the shared libraries, then add more modules to the target using the
+ "target modules add" command.<p>
+ <p>Lets say we have a Darwin crash log that contains the following images:
+<code><pre><tt>Binary Images:
+ <font color=blue>0x100000000</font> - 0x100000ff7 &lt;A866975B-CA1E-3649-98D0-6C5FAA444ECF&gt; /tmp/a.out
+ <font color=green>0x7fff83f32000</font> - 0x7fff83ffefe7 &lt;8CBCF9B9-EBB7-365E-A3FF-2F3850763C6B&gt; /usr/lib/system/libsystem_c.dylib
+ <font color=red>0x7fff883db000</font> - 0x7fff883e3ff7 &lt;62AA0B84-188A-348B-8F9E-3E2DB08DB93C&gt; /usr/lib/system/libsystem_dnssd.dylib
+ <font color=purple>0x7fff8c0dc000</font> - 0x7fff8c0f7ff7 &lt;C0535565-35D1-31A7-A744-63D9F10F12A4&gt; /usr/lib/system/libsystem_kernel.dylib
+</tt></pre></code>
+
+ <p>First we create the target using the main executable and then add any extra shared libraries we want:</p>
+<code><pre><tt><b>(lldb)</b> target create --no-dependents --arch x86_64 /tmp/a.out
+<b>(lldb)</b> target modules add /usr/lib/system/libsystem_c.dylib
+<b>(lldb)</b> target modules add /usr/lib/system/libsystem_dnssd.dylib
+<b>(lldb)</b> target modules add /usr/lib/system/libsystem_kernel.dylib
+</tt></pre></code>
+ <p>If you have debug symbols in standalone files, such as dSYM files on Mac OS X, you can specify their paths using the <b>--symfile</b> option for the "target create" (recent LLDB releases only) and "target modules add" commands:</p>
+<code><pre><tt><b>(lldb)</b> target create --no-dependents --arch x86_64 /tmp/a.out <b>--symfile /tmp/a.out.dSYM</b>
+<b>(lldb)</b> target modules add /usr/lib/system/libsystem_c.dylib <b>--symfile /build/server/a/libsystem_c.dylib.dSYM</b>
+<b>(lldb)</b> target modules add /usr/lib/system/libsystem_dnssd.dylib <b>--symfile /build/server/b/libsystem_dnssd.dylib.dSYM</b>
+<b>(lldb)</b> target modules add /usr/lib/system/libsystem_kernel.dylib <b>--symfile /build/server/c/libsystem_kernel.dylib.dSYM</b>
+</tt></pre></code>
+ <p>Then we set the load addresses for each __TEXT section (note the colors of the load addresses above and below) using the first address from the Binary Images section for each image:</p>
+<code><pre><tt><b>(lldb)</b> target modules load --file a.out <font color=blue>0x100000000</font>
+<b>(lldb)</b> target modules load --file libsystem_c.dylib <font color=green>0x7fff83f32000</font>
+<b>(lldb)</b> target modules load --file libsystem_dnssd.dylib <font color=red>0x7fff883db000</font>
+<b>(lldb)</b> target modules load --file libsystem_kernel.dylib <font color=purple>0x7fff8c0dc000</font>
+</tt></pre></code>
+ <p>Now any stack backtraces that haven't been symbolicated can be symbolicated using "image lookup"
+ with the raw backtrace addresses.</p>
+ <p>Given the following raw backtrace:</p>
+<code><pre><tt>Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
+0 libsystem_kernel.dylib 0x00007fff8a1e6d46 __kill + 10
+1 libsystem_c.dylib 0x00007fff84597df0 abort + 177
+2 libsystem_c.dylib 0x00007fff84598e2a __assert_rtn + 146
+3 a.out 0x0000000100000f46 main + 70
+4 libdyld.dylib 0x00007fff8c4197e1 start + 1
+</tt></pre></code>
+ <p>We can now symbolicate the <b>load</b> addresses:<p>
+<code><pre><tt><b>(lldb)</b> image lookup -a 0x00007fff8a1e6d46
+<b>(lldb)</b> image lookup -a 0x00007fff84597df0
+<b>(lldb)</b> image lookup -a 0x00007fff84598e2a
+<b>(lldb)</b> image lookup -a 0x0000000100000f46
+</tt></pre></code>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Getting Variable Information</h1>
+ <div class="postcontent">
+ <p>If you add the --verbose flag to the "image lookup --address" command,
+ you can get verbose information which can often include the locations
+ of some of your local variables:
+<code><pre><tt>><b>(lldb)</b> image lookup --address 0x100123aa3 --verbose
+ Address: a.out[0x0000000100000aa3] (a.out.__TEXT.__text + 110)
+ Summary: a.out`main + 50 at main.c:13
+ Module: file = "/tmp/a.out", arch = "x86_64"
+ CompileUnit: id = {0x00000000}, file = "/tmp/main.c", language = "ISO C:1999"
+ Function: id = {0x0000004f}, name = "main", range = [0x0000000100000bc0-0x0000000100000dc9)
+ FuncType: id = {0x0000004f}, decl = main.c:9, clang_type = "int (int, const char **, const char **, const char **)"
+ Blocks: id = {0x0000004f}, range = [0x100000bc0-0x100000dc9)
+ id = {0x000000ae}, range = [0x100000bf2-0x100000dc4)
+ LineEntry: [0x0000000100000bf2-0x0000000100000bfa): /tmp/main.c:13:23
+ Symbol: id = {0x00000004}, range = [0x0000000100000bc0-0x0000000100000dc9), name="main"
+ Variable: id = {0x000000bf}, name = "path", type= "char [1024]", location = DW_OP_fbreg(-1072), decl = main.c:28
+ Variable: id = {0x00000072}, name = "argc", type= "int", <b>location = r13</b>, decl = main.c:8
+ Variable: id = {0x00000081}, name = "argv", type= "const char **", <b>location = r12</b>, decl = main.c:8
+ Variable: id = {0x00000090}, name = "envp", type= "const char **", <b>location = r15</b>, decl = main.c:8
+ Variable: id = {0x0000009f}, name = "aapl", type= "const char **", <b>location = rbx</b>, decl = main.c:8
+</tt></pre></code>
+ <p>The interesting part is the variables that are listed. The variables are
+ the parameters and local variables that are in scope for the address that
+ was specified. These variable entries have locations which are shown in bold
+ above. Crash logs often have register information for the first frame in each
+ stack, and being able to reconstruct one or more local variables can often
+ help you decipher more information from a crash log than you normally would be
+ able to. Note that this is really only useful for the first frame, and only if
+ your crash logs have register information for your threads.
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Using Python API to Symbolicate</h1>
+ <div class="postcontent">
+ <p>All of the commands above can be done through the python script bridge. The code below
+ will recreate the target and add the three shared libraries that we added in the darwin
+ crash log example above:
+<code><pre><tt>triple = "x86_64-apple-macosx"
+platform_name = None
+add_dependents = False
+target = lldb.debugger.CreateTarget("/tmp/a.out", triple, platform_name, add_dependents, lldb.SBError())
+if target:
+ <font color=green># Get the executable module</font>
+ module = target.GetModuleAtIndex(0)
+ target.SetSectionLoadAddress(module.FindSection("__TEXT"), 0x100000000)
+ module = target.AddModule ("/usr/lib/system/libsystem_c.dylib", triple, None, "/build/server/a/libsystem_c.dylib.dSYM")
+ target.SetSectionLoadAddress(module.FindSection("__TEXT"), 0x7fff83f32000)
+ module = target.AddModule ("/usr/lib/system/libsystem_dnssd.dylib", triple, None, "/build/server/b/libsystem_dnssd.dylib.dSYM")
+ target.SetSectionLoadAddress(module.FindSection("__TEXT"), 0x7fff883db000)
+ module = target.AddModule ("/usr/lib/system/libsystem_kernel.dylib", triple, None, "/build/server/c/libsystem_kernel.dylib.dSYM")
+ target.SetSectionLoadAddress(module.FindSection("__TEXT"), 0x7fff8c0dc000)
+
+ load_addr = 0x00007fff8a1e6d46
+ <font color=green># so_addr is a section offset address, or a lldb.SBAddress object</font>
+ so_addr = target.ResolveLoadAddress (load_addr)
+ <font color=green># Get a symbol context for the section offset address which includes
+ # a module, compile unit, function, block, line entry, and symbol</font>
+ sym_ctx = so_addr.GetSymbolContext (lldb.eSymbolContextEverything)
+ print sym_ctx
+
+</tt></pre></code>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Use Builtin Python module to Symbolicate</h1>
+ <div class="postcontent">
+ <p>LLDB includes a module in the <b>lldb</b> package named <b>lldb.utils.symbolication</b>.
+ This module contains a lot of symbolication functions that simplify the symbolication
+ process by allowing you to create objects that represent symbolication class objects such as:
+ <ul>
+ <li>lldb.utils.symbolication.Address</li>
+ <li>lldb.utils.symbolication.Section</li>
+ <li>lldb.utils.symbolication.Image</li>
+ <li>lldb.utils.symbolication.Symbolicator</li>
+ </ul>
+ <h2>lldb.utils.symbolication.Address</h2>
+ <p>This class represents an address that will be symbolicated. It will cache any information
+ that has been looked up: module, compile unit, function, block, line entry, symbol.
+ It does this by having a lldb.SBSymbolContext as a member variable.
+ </p>
+ <h2>lldb.utils.symbolication.Section</h2>
+ <p>This class represents a section that might get loaded in a <b>lldb.utils.symbolication.Image</b>.
+ It has helper functions that allow you to set it from text that might have been extracted from
+ a crash log file.
+ </p>
+ <h2>lldb.utils.symbolication.Image</h2>
+ <p>This class represents a module that might get loaded into the target we use for symbolication.
+ This class contains the executable path, optional symbol file path, the triple, and the list of sections that will need to be loaded
+ if we choose the ask the target to load this image. Many of these objects will never be loaded
+ into the target unless they are needed by symbolication. You often have a crash log that has
+ 100 to 200 different shared libraries loaded, but your crash log stack backtraces only use a few
+ of these shared libraries. Only the images that contain stack backtrace addresses need to be loaded
+ in the target in order to symbolicate.
+ </p>
+ <p>Subclasses of this class will want to override the <b>locate_module_and_debug_symbols</b> method:
+<code><pre><tt>class CustomImage(lldb.utils.symbolication.Image):
+ def locate_module_and_debug_symbols (self):
+ <font color=green># Locate the module and symbol given the info found in the crash log</font>
+</tt></pre></code>
+ <p>Overriding this function allows clients to find the correct executable module and symbol files as they might reside on a build server.<p>
+ <h2>lldb.utils.symbolication.Symbolicator</h2>
+ <p>This class coordinates the symbolication process by loading only the <b>lldb.utils.symbolication.Image</b>
+ instances that need to be loaded in order to symbolicate an supplied address.
+ </p>
+ <h2>lldb.macosx.crashlog</h2>
+ <p><b>lldb.macosx.crashlog</b> is a package that is distributed on Mac OS X builds that subclasses the above classes.
+ This module parses the information in the Darwin crash logs and creates symbolication objects that
+ represent the images, the sections and the thread frames for the backtraces. It then uses the functions
+ in the lldb.utils.symbolication to symbolicate the crash logs.</p>
+ <p>
+ This module installs a new "crashlog" command into the lldb command interpreter so that you can use
+ it to parse and symbolicate Mac OS X crash logs:</p>
+<code><pre><tt><b>(lldb)</b> script import lldb.macosx.crashlog
+"crashlog" and "save_crashlog" command installed, use the "--help" option for detailed help
+<b>(lldb)</b> crashlog /tmp/crash.log
+...
+</tt></pre></code>
+ <p>The command that is installed has built in help that shows the
+ options that can be used when symbolicating:
+<code><pre><tt><b>(lldb)</b> crashlog --help
+Usage: crashlog [options] <FILE> [FILE ...]
+
+Symbolicate one or more darwin crash log files to provide source file and line
+information, inlined stack frames back to the concrete functions, and
+disassemble the location of the crash for the first frame of the crashed
+thread. If this script is imported into the LLDB command interpreter, a
+"crashlog" command will be added to the interpreter for use at the LLDB
+command line. After a crash log has been parsed and symbolicated, a target
+will have been created that has all of the shared libraries loaded at the load
+addresses found in the crash log file. This allows you to explore the program
+as if it were stopped at the locations described in the crash log and
+functions can be disassembled and lookups can be performed using the
+addresses found in the crash log.
+
+Options:
+ -h, --help show this help message and exit
+ -v, --verbose display verbose debug info
+ -g, --debug display verbose debug logging
+ -a, --load-all load all executable images, not just the images found
+ in the crashed stack frames
+ --images show image list
+ --debug-delay=NSEC pause for NSEC seconds for debugger
+ -c, --crashed-only only symbolicate the crashed thread
+ -d DISASSEMBLE_DEPTH, --disasm-depth=DISASSEMBLE_DEPTH
+ set the depth in stack frames that should be
+ disassembled (default is 1)
+ -D, --disasm-all enabled disassembly of frames on all threads (not just
+ the crashed thread)
+ -B DISASSEMBLE_BEFORE, --disasm-before=DISASSEMBLE_BEFORE
+ the number of instructions to disassemble before the
+ frame PC
+ -A DISASSEMBLE_AFTER, --disasm-after=DISASSEMBLE_AFTER
+ the number of instructions to disassemble after the
+ frame PC
+ -C NLINES, --source-context=NLINES
+ show NLINES source lines of source context (default =
+ 4)
+ --source-frames=NFRAMES
+ show source for NFRAMES (default = 4)
+ --source-all show source for all threads, not just the crashed
+ thread
+ -i, --interactive parse all crash logs and enter interactive mode
+
+</tt></pre></code>
+ <p>The source for the "symbolication" and "crashlog" modules are available in SVN:</p>
+ <ul>
+ <li><a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/symbolication.py">symbolication.py</a></li>
+ <li><a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/python/crashlog.py">crashlog.py</a></li>
+ </ul>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+</div>
+</body>
+</html>
Index: aze/lldb/www/symbols.html
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ aze/lldb/www/symbols.html 2013-03-03 09:35:50.355457348 +0100
@@ -0,0 +1,345 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<link href="style.css" rel="stylesheet" type="text/css" />
+<title>Debug Sybmols on Mac OS X</title>
+</head>
+
+<body>
+ <div class="www_title">
+ The <strong>LLDB</strong> Debugger
+ </div>
+
+<div id="container">
+ <div id="content">
+
+ <!--#include virtual="sidebar.incl"-->
+
+ <div id="middle">
+ <div class="post">
+ <h1 class="postheader">Debug Symbols on MacOSX</h1>
+ <div class="postcontent">
+ <p>On MacOSX, debug symbols are often in stand alone bundles called <b>dSYM</b> files.
+ These are bundles that contain DWARF debug information and other resources related to
+ builds and debug info.</p>
+ <p>The DebugSymbols.framework framework helps locate dSYM files when given a UUID. It can
+ locate the symbols using a variety of methods:</p>
+ <ul>
+ <li>Spotlight</li>
+ <li>Explicit search paths</li>
+ <li>Implicit search paths</li>
+ <li>File mapped UUID paths</li>
+ <li>Running one or more shell scripts</li>
+ </ul>
+ <p>DebugSymbols.framework also has global defaults that can be modified to allow
+ all of the debug tools (lldb, gdb, sample, CoreSymbolication.framework) to easily
+ find important debug symbols. The domain for the DebugSymbols.framework defaults
+ is <b>com.apple.DebugSymbols</b>, and the defaults can be read, written or modified
+ using the <b>defaults</b> shell command:
+<code><pre><tt><b>% defaults read com.apple.DebugSymbols
+% defaults write com.apple.DebugSymbols KEY ...
+% defaults delete com.apple.DebugSymbols KEY</b>
+</tt></pre></code>
+
+ <p>The following is a list of the defaults key value
+ setting pairs that can be used to enhance symbol location:</p>
+ <table class="stats" width="620" cellspacing="0">
+ <tr>
+ <td class="hed" width="20%">Defaults Key</td>
+ <td class="hed" width="70%">Description</td>
+ </tr>
+
+ <tr>
+ <td class="content">
+ <b>DBGFileMappedPaths</b>
+ </td>
+ <td class="content">
+ This default can be specified as a single string, or an array of strings.
+ Each string represents a directory that contains file mapped UUID values
+ that point to dSYM files. See the "File Mapped UUID Directories" section
+ below for more details. Whenever DebugSymbols.framework is asked to lookup
+ a dSYM file, it will first look in any file mapped UUID directories
+ for a quick match.
+ </td>
+ </tr>
+ <td class="content" colspan="2">
+<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGFileMappedPaths -string /path/to/uuidmap1</b>
+<b>% defaults write com.apple.DebugSymbols DBGFileMappedPaths -array /path/to/uuidmap1
+ /path/to/uuidmap2</b>
+</tt></pre></code>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGShellCommands</b>
+ </td>
+ <td class="content">
+ This default can be specified as a single string, or an array of strings.
+ Specifies a shell script that will get run in order to find the dSYM.
+ The shell script will be run given a single UUID value as the shell
+ command arguments and the shell command is expected to return a property
+ list. See the property list format defined below.
+ </td>
+ </tr>
+ <td class="content" colspan="2">
+<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGShellCommands -string /path/to/script1</b>
+<b>% defaults write com.apple.DebugSymbols DBGShellCommands -array /path/to/script1
+ /path/to/script2</b>
+</tt></pre></code>
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGSpotlightPaths</b>
+ </td>
+ <td class="content">
+ Specifies the directories to limit spotlight searches to as a string or array of strings. When any
+ other defaults are supplied to <b>com.apple.DebugSymbols</b>, spotlight
+ searches will be disabled unless this default is set to an empty array:
+ </td>
+ </tr>
+ <td class="content" colspan="2">
+<code><pre><tt><font color="green"># Specify an empty array to keep Spotlight searches enabled in all locations</font>
+<b>% defaults write com.apple.DebugSymbols DBGSpotlightPaths -array</b>
+
+<font color="green"># Specify an array of paths to limit spotlight searches to certain directories</font>
+<b>% defaults write com.apple.DebugSymbols DBGSpotlightPaths -array /path/dir1 /path/dir2</b>
+</tt></pre></code>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Shell Script Property List Format</h1>
+ <div class="postcontent">
+<p>Shell scripts that are specified with the <b>DBGShellCommands</b> defaults key
+will be run in the order in which they are specified until a match is found.
+The shell script will be invoked with a single UUID string value like
+"23516BE4-29BE-350C-91C9-F36E7999F0F1". The shell script must respond with a
+property list being written to STDOUT.
+The property list returned must contain UUID string values as the root key values, with
+a dictionary for each UUID. The dictionaries can contain one or more of the following keys:
+
+ <table class="stats" width="620" cellspacing="0">
+ <tr>
+ <td class="hed" width="20%">Key</td>
+ <td class="hed" width="70%">Description</td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGArchitecture</b>
+ </td>
+ <td class="content">A textual architecture or target triple like "x86_64", "i386", or "x86_64-apple-macosx".
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGBuildSourcePath</b>
+ </td>
+ <td class="content">A path prefix that was used when building the dSYM file. The debug information will
+ contain paths with this prefix.
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGSourcePath</b>
+ </td>
+ <td class="content">A path prefix for where the sources exist after the build has completed. Often when
+ building projects, build machines will host the sources in a temporary directory while building, then
+ move the sources to another location for archiving. If the paths in the debug info don't match where
+ the sources are currently hosted, then specifying this path along with the <b>DBGBuildSourcePath</b>
+ will help the developer tools always show you sources when debugging or symbolicating.
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGDSYMPath</b>
+ </td>
+ <td class="content">A path to the dSYM mach-o file inside the dSYM bundle.
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGSymbolRichExecutable</b>
+ </td>
+ <td class="content">A path to the symbol rich executable. Binaries are often stripped after
+ being built and packaged into a release. If your build systems saves an unstripped executable
+ a path to this executable can be provided.
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <b>DBGError</b>
+ </td>
+ <td class="content">If a binary can not be located for the supplied UUID, a user readable error
+ can be returned.
+ </td>
+ </tr>
+ </table>
+
+<p>Below is a sample shell script output for a binary that contains two architectures:
+<code><pre><tt>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
+&lt;plist version="1.0"&gt;
+&lt;dict&gt;
+ &lt;key&gt;23516BE4-29BE-350C-91C9-F36E7999F0F1&lt;/key&gt;
+ &lt;dict&gt;
+ &lt;key&gt;DBGArchitecture&lt;/key&gt;
+ &lt;string&gt;i386&lt;/string&gt;
+ &lt;key&gt;DBGBuildSourcePath&lt;/key&gt;
+ &lt;string&gt;/path/to/build/sources&lt;/string&gt;
+ &lt;key&gt;DBGSourcePath&lt;/key&gt;
+ &lt;string&gt;/path/to/actual/sources&lt;/string&gt;
+ &lt;key&gt;DBGDSYMPath&lt;/key&gt;
+ &lt;string&gt;/path/to/foo.dSYM/Contents/Resources/DWARF/foo&lt;/string&gt;
+ &lt;key&gt;DBGSymbolRichExecutable&lt;/key&gt;
+ &lt;string&gt;/path/to/unstripped/exectuable&lt;/string&gt;
+ &lt;/dict&gt;
+ &lt;key&gt;A40597AA-5529-3337-8C09-D8A014EB1578&lt;/key&gt;
+ &lt;dict&gt;
+ &lt;key&gt;DBGArchitecture&lt;/key&gt;
+ &lt;string&gt;x86_64&lt;/string&gt;
+ &lt;key&gt;DBGBuildSourcePath&lt;/key&gt;
+ &lt;string&gt;/path/to/build/sources&lt;/string&gt;
+ &lt;key&gt;DBGSourcePath&lt;/key&gt;
+ &lt;string&gt;/path/to/actual/sources&lt;/string&gt;
+ &lt;key&gt;DBGDSYMPath&lt;/key&gt;
+ &lt;string&gt;/path/to/foo.dSYM/Contents/Resources/DWARF/foo&lt;/string&gt;
+ &lt;key&gt;DBGSymbolRichExecutable&lt;/key&gt;
+ &lt;string&gt;/path/to/unstripped/exectuable&lt;/string&gt;
+ &lt;/dict&gt;
+&lt;/dict&gt;
+&lt;/plist&gt;
+</tt></pre></code>
+
+<p>There is no timeout imposed on a shell script when is it asked to locate a dSYM file, so be careful to not make a shell
+script that has high latency or takes a long time to download unless this
+is really what you want. This can slow down debug sessions in LLDB and GDB, symbolication
+with CoreSymbolication or Report Crash, with no visible feedback to the user. You can
+quickly return a plist with a single <b>DBGError</b> key that indicates a timeout
+has been reached. You might also want to exec new processes to do the downloads so
+that if you return an error that indicates a timeout, your download can still proceed
+after your shell script has exited so subsequent debug sessions can use the cached files.
+It is also important to track when a current download is in progress in case you get multiple requests for the same UUID so
+that you don't end up downloading the same file simultaneously. Also you will want
+to verify the download was successful and then and only then place the file into the
+cache for tools that will cache files locally.
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">Embedding UUID property lists inside the dSYM bundles</h1>
+ <div class="postcontent">
+<p>Since dSYM files are bundles, you can also place UUID info plists files inside
+your dSYM bundles in the <b>Contents/Resources</b> directory. One of the main
+reasons to create the UUID plists inside the dSYM bundles
+is that it will help LLDB and other developer tools show you source. LLDB currently
+knows how to check for these plist files so it can automatically remap the source
+location information in the debug info.
+
+<p>If we take the two UUID values from the returns plist above, we can split
+them out and save then in the dSYM bundle:
+
+<code><pre><tt><b>% ls /path/to/foo.dSYM/Contents/Resources</b>
+23516BE4-29BE-350C-91C9-F36E7999F0F1.plist
+A40597AA-5529-3337-8C09-D8A014EB1578.plist
+
+<b>% cat /path/to/foo.dSYM/Contents/Resources/23516BE4-29BE-350C-91C9-F36E7999F0F1.plist</b>
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
+&lt;plist version="1.0"&gt;
+&lt;dict&gt;
+ &lt;key&gt;DBGArchitecture&lt;/key&gt;
+ &lt;string&gt;i386&lt;/string&gt;
+ &lt;key&gt;DBGBuildSourcePath&lt;/key&gt;
+ &lt;string&gt;/path/to/build/sources&lt;/string&gt;
+ &lt;key&gt;DBGSourcePath&lt;/key&gt;
+ &lt;string&gt;/path/to/actual/sources&lt;/string&gt;
+ &lt;key&gt;DBGDSYMPath&lt;/key&gt;
+ &lt;string&gt;/path/to/foo.dSYM/Contents/Resources/DWARF/foo&lt;/string&gt;
+ &lt;key&gt;DBGSymbolRichExecutable&lt;/key&gt;
+ &lt;string&gt;/path/to/unstripped/exectuable&lt;/string&gt;
+&lt;/dict&gt;
+&lt;/plist&gt;
+</tt></pre></code>
+
+<p>Note that the output is very close to what is needed by shell script output,
+so making the results of your shell script will be very easy to create by
+combining two plists into a single one where you take the UUID and use it a
+ string key, and the value is the contents of the plist.
+
+
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">File Mapped UUID Directories</h1>
+ <div class="postcontent">
+<p>File Mapped directories can be used for efficient dSYM file lookups for
+local or remote dSYM files. The UUID is broken up by splitting the first
+20 hex digits into 4 character chunks, and a directory is created for each
+chunk, and each subsequent directory is created inside the previous one.
+A symlink is then created whose name is the last 12 hex digits in the deepest
+directory. The symlinks value is a full path to the mach-o files inside the
+dSYM bundle which contains the DWARF. Whenever DebugSymbols.framework is asked
+to lookup a dSYM file, it will first look in any file mapped UUID directories
+for a quick match if the defaults are appropriately set.
+
+<p>For example, if we take the sample UUID plist inforamtion from above, we
+can create a File Mapped UUID directory cache in <b>~/Library/SymbolCache/dsyms/uuids</b>.
+We can easily see how things are laid out:
+
+<code><pre><tt><b>% find ~/Library/SymbolCache/dsyms/uuids -type l</b>
+~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1
+~/Library/SymbolCache/dsyms/uuids/A405/97AA/5529/3337/8C09/D8A014EB1578
+</tt></pre></code>
+
+<p>The last entries in these file mapped directories are symlinks to the actual dsym mach file in the dsym bundle:
+
+<code><pre><tt><b>% ls -lAF ~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1</b>
+~/Library/SymbolCache/dsyms/uuids/2351/6BE4/29BE/350C/91C9/F36E7999F0F1@ -> ../../../../../../dsyms/foo.dSYM/Contents/Resources/DWARF/foo
+</tt></pre></code>
+<p>Then you can also tell DebugSymbols to check this UUID file map cache using:
+
+<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGFileMappedPaths ~/Library/SymbolCache/dsyms/uuids</b>
+</tt></pre></code>
+
+
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ <div class="post">
+ <h1 class="postheader">dSYM Locating Shell Script Tips</h1>
+ <div class="postcontent">
+
+<p>One possible implementation of a dSYM finding shell script is to have the script
+download and cache files locally in a known location. Then create a UUID map
+for each UUID value that was found in a local UUID File Map cache so the next query for the dSYM
+file will be able to use the cached version. So the shell script is used to
+initially download and cache the file, and subsequent accesses will use the
+cache and avoid calling the shell script.
+
+<p>Then the defaults for DebugSymbols.framework will entail enabling your shell script,
+enabling the file mapped path setting so that already downloaded dSYMS fill quickly
+be found without needing to run the shell script every time, and also leaving spotlight enabled
+so that other normal dSYM files are still found:
+
+<code><pre><tt><b>% defaults write com.apple.DebugSymbols DBGShellCommands /path/to/shellscript
+% defaults write com.apple.DebugSymbols DBGFileMappedPaths ~/Library/SymbolCache/dsyms/uuids
+% defaults write com.apple.DebugSymbols DBGSpotlightPaths -array</b>
+</tt></pre></code>
+
+Hopefully this helps explain how DebugSymbols.framework can help any company
+implement a smart symbol finding and caching with minimal overhead.
+</p>
+ </div>
+ <div class="postfooter"></div>
+ </div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
\ No newline at end of file
Index: aze/lldb/www/tutorial.html
===================================================================
--- aze.orig/lldb/www/tutorial.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/tutorial.html 2013-03-03 09:35:50.355457348 +0100
@@ -93,6 +93,13 @@
<br>(lldb) breakpoint set -n foo
</code>
+ <p>You can use the --name option multiple times to make a breakpoint on a set of functions as well. This is convenient
+ since it allows you to set commmon conditions or commands without having to specify them multiple times:</p>
+
+ <code>
+ (lldb) breakpoint set --name foo --name bar
+ </code>
+
<p>Setting breakpoints by name is even more specialized in LLDB as you can specify
that you want to set a breakpoint at a function by method name. To set a breakpoint
on all C++ methods named <code>foo</code> you can enter either of:</p>
@@ -117,6 +124,8 @@
<br>(lldb) breakpoint set -s foo.dylib -n foo
</code>
+ <p>The <code>--shlib</code> option can also be repeated to specify several shared libraries.</p>
+
<p>Suggestions on more interesting primitives of this sort are also very welcome.</p>
<p>Just like gdb, the lldb command interpreter does a shortest unique
@@ -136,10 +145,12 @@
things like if you specify "<code>--shlib &lt;path&gt;</code>", and are completing on "<code>--file &lt;path&gt;</code>", we will only
list source files in the shared library specified by "<code>--shlib &lt;path&gt;</code>".</p>
- <p>The individual commands are pretty extensively documented, using
- the <code>help</code> command. And there is an <code>apropos</code> command that will
- search the help for a particular word and dump a summary help string
- for each matching command.</p>
+ <p>The individual commands are pretty extensively documented. You can
+ use the <code>help</code> command to get an overview of which commands are
+ available or to obtain details about specific commands. There is also an
+ <code>apropos</code> command that will search the help text for all commands
+ for a particular word and dump a summary help string for each matching
+ command.</p>
<p>Finally, there is a mechanism to construct aliases for commonly used
commands. So for instance if you get annoyed typing:</p>
Index: aze/lldb/www/varformats.html
===================================================================
--- aze.orig/lldb/www/varformats.html 2013-03-03 09:35:47.779457405 +0100
+++ aze/lldb/www/varformats.html 2013-03-03 09:35:50.355457348 +0100
@@ -16,8 +16,7 @@
<h1 class="postheader">Variable display</h1>
<div class="postcontent">
- <p>LLDB was recently modified to allow users to define custom
- formatting options for the variables display.</p>
+ <p>LLDB has a data formatters subsystem that allows users to define custom display options for their variables.</p>
<p>Usually, when you type <code>frame variable</code> or
run some <code>expression</code> LLDB will
@@ -1076,8 +1075,7 @@
} <br/>
</code> </p>
- <p>Currently, in LLDB <a href="http://llvm.org/svn/llvm-project/lldb/trunk/">top of tree</a>, synthetic children providers are enabled for
- <code>std::vector&lt;T&gt;</code>, <code>std::list&lt;T&gt;</code> and <code>std::map&lt;K,V&gt;</code> both in the version provided by <a href="http://gcc.gnu.org/libstdc++/">libstdcpp</a> and by <a href="http://libcxx.llvm.org/">libcxx</a>.</p>
+ <p>LLDB has synthetic children providers for basic STL classes, both in the version provided by <a href="http://gcc.gnu.org/libstdc++/">libstdcpp</a> and by <a href="http://libcxx.llvm.org/">libcxx</a>. and for basic Cocoa containers (NSArray and NSDictionary).</p>
<p>Synthetic children extend summary strings by enabling a new special variable: <code>${svar</code>.<br/>
This symbol tells LLDB to refer expression paths to the
@@ -1171,17 +1169,16 @@
<b>(lldb)</b> frame variable ns_string --dynamic-type no-run-target --show-types
</td>
</table>
- <code>(id, dynamic type: __NSCFString) ns_string = 0x00000001001183d0 @&quot;An NSString saying hello world&quot;<br/>
+ <code>(__NSCFString *) ns_string = 0x00000001001183d0 @&quot;An NSString saying hello world&quot;<br/>
</code>
<p>
Because LLDB uses a detection algorithm that does not need to invoke any functions
on the target process, <code>no-run-target</code> is enough for this to work.
As a final sidenote on this, LLDB is currently able to provide a summary string for <code>NSString</code>
that shows the content of the string, without requiring you to run code on the target
- process. This features requires you to enable the AppKit category (see below for details). The
- Python code for this formatter is at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/summaries/cocoa/CFString.py">
- CFString.py</a> (the script is well commented, but intricate and might not be obvious, lacking
- working experience with Cocoa and the LLDB API).
+ process. This features requires you to enable the AppKit category (see below for details).
+ The first implementation of this feature was a Python script (still available for reference at <a href="http://llvm.org/svn/llvm-project/lldb/trunk/examples/summaries/cocoa/CFString.py">CFString.py</a>).
+ However, this is out of sync with the current implementation of the NSString formatter (which is a C++ function compiled into the LLDB core).
</p>
</div>
</div>