Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,5 @@
# So that ~/binutils.py takes precedence.
script sys.path[:0] = [os.path.expanduser('~')]
script import binutils
command script add -f binutils.itob itob
command script add -f binutils.utob utob

View File

@@ -0,0 +1,36 @@
Files in this directory:
o .lldbinit:
An example lldb init file that imports the binutils.py module and adds the
following commands: 'itob' and 'utob'.
o binutils.py:
Python module which provides implementation for the 'itob' and 'utob' commands.
o README:
The file you are reading now.
================================================================================
The following terminal output shows an interaction with lldb using the .lldbinit
and the binutils.py files which are located in my HOME directory. The lldb init
file imports the utils Python module and adds the 'itob' and 'utob' commands.
$ /Volumes/data/lldb/svn/trunk/build/Debug/lldb
(lldb) help itob
Convert the integer to print its two's complement representation.
args[0] (mandatory) is the integer to be converted
args[1] (mandatory) is the bit width of the two's complement representation
args[2] (optional) if specified, turns on verbose printing
Syntax: itob
(lldb) itob -5 4
[1, 0, 1, 1]
(lldb) itob -5 32 v
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
(lldb) utob 0xABCD 32 v
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1]
(lldb)

View File

@@ -0,0 +1,125 @@
"Collection of tools for displaying bit representation of numbers."""
import StringIO
def binary(n, width=None):
"""
Return a list of (0|1)'s for the binary representation of n where n >= 0.
If you specify a width, it must be > 0, otherwise it is ignored. The list
could be padded with 0 bits if width is specified.
"""
l = []
if width and width <= 0:
width = None
while n > 0:
l.append(1 if n & 1 else 0)
n = n >> 1
if width:
for i in range(width - len(l)):
l.append(0)
l.reverse()
return l
def twos_complement(n, width):
"""
Return a list of (0|1)'s for the binary representation of a width-bit two's
complement numeral system of an integer n which may be negative.
"""
val = 2**(width - 1)
if n >= 0:
if n > (val - 1):
return None
# It is safe to represent n with width-bits.
return binary(n, width)
if n < 0:
if abs(n) > val:
return None
# It is safe to represent n (a negative int) with width-bits.
return binary(val * 2 - abs(n))
# print binary(0xABCD)
# [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1]
# print binary(0x1F, 8)
# [0, 0, 0, 1, 1, 1, 1, 1]
# print twos_complement(-5, 4)
# [1, 0, 1, 1]
# print twos_complement(7, 4)
# [0, 1, 1, 1]
# print binary(7)
# [1, 1, 1]
# print twos_complement(-5, 64)
# [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
def positions(width):
"""Helper function returning a list describing the bit positions.
Bit positions greater than 99 are truncated to 2 digits, for example,
100 -> 00 and 127 -> 27."""
return ['{0:2}'.format(i)[-2:] for i in reversed(range(width))]
def utob(debugger, command_line, result, dict):
"""Convert the unsigned integer to print its binary representation.
args[0] (mandatory) is the unsigned integer to be converted
args[1] (optional) is the bit width of the binary representation
args[2] (optional) if specified, turns on verbose printing"""
args = command_line.split()
try:
n = int(args[0], 0)
width = None
if len(args) > 1:
width = int(args[1], 0)
if width < 0:
width = 0
except:
print utob.__doc__
return
if len(args) > 2:
verbose = True
else:
verbose = False
bits = binary(n, width)
if not bits:
print "insufficient width value: %d" % width
return
if verbose and width > 0:
pos = positions(width)
print ' ' + ' '.join(pos)
print ' %s' % str(bits)
def itob(debugger, command_line, result, dict):
"""Convert the integer to print its two's complement representation.
args[0] (mandatory) is the integer to be converted
args[1] (mandatory) is the bit width of the two's complement representation
args[2] (optional) if specified, turns on verbose printing"""
args = command_line.split()
try:
n = int(args[0], 0)
width = int(args[1], 0)
if width < 0:
width = 0
except:
print itob.__doc__
return
if len(args) > 2:
verbose = True
else:
verbose = False
bits = twos_complement(n, width)
if not bits:
print "insufficient width value: %d" % width
return
if verbose and width > 0:
pos = positions(width)
print ' ' + ' '.join(pos)
print ' %s' % str(bits)

View File

@@ -0,0 +1,40 @@
Files in this directory:
o importcmd.py:
Python module which provides implementation for the 'import' command.
o README:
The file you are reading now.
================================================================================
The import command defined by importcmd.py can be used in LLDB to load a Python
module given its full pathname.
The command works by extending Python's sys.path lookup to include the path to
the module to be imported when required, and then going through the language
ordinary 'import' mechanism. In this respect, modules imported from LLDB command
line should not be distinguishable from those imported using the script interpreter.
The following terminal output shows an interaction with lldb using this new command.
Enrico-Granatas-MacBook-Pro:Debug enricogranata$ ./lldb
(lldb) script import importcmd
(lldb) command script add import -f importcmd.pyimport_cmd
(lldb) import ../demo.py
(lldb) script demo.test_function('hello world')
I am a Python function that says hello world
(lldb) quit
Enrico-Granatas-MacBook-Pro:Debug enricogranata$
Of course, the commands to import the importcmd.py module and to define the import
command, can be included in the .lldbinit file to make this feature available at
debugger startup
WARNING: The import command defined by importcmd.py is now obsolete
In TOT LLDB, you can say:
(lldb) command script import ../demo.py
(lldb) script demo.test_function('hello world')
I am a Python function that says hello world
(lldb) quit
using the native "command script import" command, which offers a superset of what the import command provided by importcmd.py does

View File

@@ -0,0 +1,38 @@
import sys
import os
import lldb
def check_has_dir_in_path(dirname):
return sys.path.__contains__(dirname)
def ensure_has_dir_in_path(dirname):
dirname = os.path.abspath(dirname)
if not (check_has_dir_in_path(dirname)):
sys.path.append(dirname)
def do_import(debugger, modname):
if (len(modname) > 4 and modname[-4:] == '.pyc'):
modname = modname[:-4]
if (len(modname) > 3 and modname[-3:] == '.py'):
modname = modname[:-3]
debugger.HandleCommand("script import " + modname)
def pyimport_cmd(debugger, args, result, dict):
"""Import a Python module given its full path"""
print 'WARNING: obsolete feature - use native command "command script import"'
if args == "":
return "no module path given"
if not (os.sep in args):
modname = args
ensure_has_dir_in_path('.')
else:
endofdir = args.rfind(os.sep)
modname = args[endofdir + 1:]
args = args[0:endofdir]
ensure_has_dir_in_path(args)
do_import(debugger, modname)
return None

View File

@@ -0,0 +1,7 @@
script import os, sys
# So that ~/utils.py takes precedence.
script sys.path[:0] = [os.path.expanduser('~')]
script import utils
command alias pwd script print os.getcwd()
command script add -f utils.chdir cd
command script add -f utils.system system

View File

@@ -0,0 +1,41 @@
Files in this directory:
o .lldbinit:
An example lldb init file that imports the utils.py module and adds the
following commands: 'pwd', 'cd', and 'system'.
o utils.py:
Python module which provides implementation for the 'cd' and 'system' commands.
o README:
The file you are reading now.
================================================================================
The following terminal output shows an interaction with lldb using the .lldbinit
and the utils.py files which are located in my HOME directory. The lldb init
file imports the utils Python module and adds the 'pwd', 'cd', and 'system'
commands.
Johnnys-MacBook-Pro:multiple_threads johnny$ pwd
/Volumes/data/lldb/svn/trunk/test/functionalities/watchpoint/multiple_threads
Johnnys-MacBook-Pro:multiple_threads johnny$ lldb
(lldb) pwd
/Volumes/data/lldb/svn/trunk/test/functionalities/watchpoint/multiple_threads
(lldb) cd ..
Current working directory: /Volumes/data/lldb/svn/trunk/test/functionalities/watchpoint
(lldb) help system
Execute the command (a string) in a subshell.
Syntax: system
(lldb) system ls -l
total 0
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 hello_watchlocation
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 hello_watchpoint
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 multiple_threads
drwxr-xr-x 7 johnny admin 238 Oct 11 17:24 watchpoint_commands
retcode: 0
(lldb)

View File

@@ -0,0 +1,58 @@
"""Utility for changing directories and execution of commands in a subshell."""
import os
import shlex
import subprocess
# Store the previous working directory for the 'cd -' command.
class Holder:
"""Holds the _prev_dir_ class attribute for chdir() function."""
_prev_dir_ = None
@classmethod
def prev_dir(cls):
return cls._prev_dir_
@classmethod
def swap(cls, dir):
cls._prev_dir_ = dir
def chdir(debugger, args, result, dict):
"""Change the working directory, or cd to ${HOME}.
You can also issue 'cd -' to change to the previous working directory."""
new_dir = args.strip()
if not new_dir:
new_dir = os.path.expanduser('~')
elif new_dir == '-':
if not Holder.prev_dir():
# Bad directory, not changing.
print "bad directory, not changing"
return
else:
new_dir = Holder.prev_dir()
Holder.swap(os.getcwd())
os.chdir(new_dir)
print "Current working directory: %s" % os.getcwd()
def system(debugger, command_line, result, dict):
"""Execute the command (a string) in a subshell."""
args = shlex.split(command_line)
process = subprocess.Popen(
args,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
output, error = process.communicate()
retcode = process.poll()
if output and error:
print "stdout=>\n", output
print "stderr=>\n", error
elif output:
print output
elif error:
print error
print "retcode:", retcode

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
#----------------------------------------------------------------------
# Fill in the source files to build
#----------------------------------------------------------------------
# Uncomment line below for debugging shell commands
# SHELL = /bin/sh -x
#----------------------------------------------------------------------
# Change any build/tool options needed
#----------------------------------------------------------------------
ARCH ?= x86_64
CFLAGS ?=-arch $(ARCH) -gdwarf-2 -O0
CXX ?= $(shell xcrun -find clang++)
EXE ?= libheap.dylib
DSYM ?= $(EXE).dSYM
#----------------------------------------------------------------------
# Compile the executable from all the objects (default rule) with no
# dsym file.
#----------------------------------------------------------------------
$(EXE) : heap_find.cpp
$(CXX) $(CFLAGS) -install_name "@executable_path/libheap.dylib" -dynamiclib -lobjc heap_find.cpp -o "$(EXE)"
#----------------------------------------------------------------------
# Include all of the makefiles for each source file so we don't have
# to manually track all of the prerequisites for each source file.
#----------------------------------------------------------------------
.PHONY: clean
all: $(EXE)
clean:
rm -rf "$(EXE)" "$(DSYM)"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
LEVEL = ../../test/make
CXX_SOURCES := main.cpp
EXE := lldb-functions
USE_LIBCPP := 1
MY_OS = $(shell uname -s)
ifeq "$(MY_OS)" "Darwin"
LLDB_BUILD_DIR ?= /Applications/Xcode.app/Contents/SharedFrameworks
LD_EXTRAS ?= -framework LLDB -Wl,-rpath,"$(LLDB_BUILD_DIR)"
FRAMEWORK_INCLUDES=-F"$(LLDB_BUILD_DIR)"
else
LD_EXTRAS ?= $(LLDB_BUILD_DIR)/_lldb.so
endif
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,346 @@
//===-- 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 <getopt.h>
#include <stdint.h>
#include <stdlib.h>
#if defined(__APPLE__)
#include <LLDB/LLDB.h>
#else
#include "LLDB/SBBlock.h"
#include "LLDB/SBCompileUnit.h"
#include "LLDB/SBDebugger.h"
#include "LLDB/SBFunction.h"
#include "LLDB/SBModule.h"
#include "LLDB/SBProcess.h"
#include "LLDB/SBStream.h"
#include "LLDB/SBSymbol.h"
#include "LLDB/SBTarget.h"
#include "LLDB/SBThread.h"
#endif
#include <string>
using namespace lldb;
//----------------------------------------------------------------------
// This quick sample code shows how to create a debugger instance and
// create an executable target without adding dependent shared
// libraries. It will then set a regular expression breakpoint to get
// breakpoint locations for all functions in the module, and use the
// locations to extract the symbol context for each location. Then it
// dumps all // information about the function: its name, file address
// range, the return type (if any), and all argument types.
//
// To build the program, type (while in this directory):
//
// $ make
//
// then to run this on MacOSX, specify the path to your LLDB.framework
// library using the DYLD_FRAMEWORK_PATH option and run the executable
//
// $ DYLD_FRAMEWORK_PATH=/Volumes/data/lldb/tot/build/Debug ./a.out
// executable_path1 [executable_path2 ...]
//----------------------------------------------------------------------
class LLDBSentry {
public:
LLDBSentry() {
// Initialize LLDB
SBDebugger::Initialize();
}
~LLDBSentry() {
// Terminate LLDB
SBDebugger::Terminate();
}
};
static struct option g_long_options[] = {
{"arch", required_argument, NULL, 'a'},
{"canonical", no_argument, NULL, 'c'},
{"extern", no_argument, NULL, 'x'},
{"help", no_argument, NULL, 'h'},
{"platform", required_argument, NULL, 'p'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}};
#define PROGRAM_NAME "lldb-functions"
void usage() {
puts("NAME\n"
" " PROGRAM_NAME
" -- extract all function signatures from one or more binaries.\n"
"\n"
"SYNOPSIS\n"
" " PROGRAM_NAME " [[--arch=<ARCH>] [--platform=<PLATFORM>] "
"[--verbose] [--help] [--canonical] --] <PATH> "
"[<PATH>....]\n"
"\n"
"DESCRIPTION\n"
" Loads the executable pointed to by <PATH> and dumps complete "
"signatures for all functions that have debug information.\n"
"\n"
"EXAMPLE\n"
" " PROGRAM_NAME " --arch=x86_64 /usr/lib/dyld\n");
exit(0);
}
int main(int argc, char const *argv[]) {
// Use a sentry object to properly initialize/terminate LLDB.
LLDBSentry sentry;
SBDebugger debugger(SBDebugger::Create());
// Create a debugger instance so we can create a target
if (!debugger.IsValid())
fprintf(stderr, "error: failed to create a debugger object\n");
bool show_usage = false;
bool verbose = false;
bool canonical = false;
bool external_only = false;
const char *arch = NULL;
const char *platform = NULL;
std::string short_options("h?");
for (const struct option *opt = g_long_options; opt->name; ++opt) {
if (isprint(opt->val)) {
short_options.append(1, (char)opt->val);
switch (opt->has_arg) {
case no_argument:
break;
case required_argument:
short_options.append(1, ':');
break;
case optional_argument:
short_options.append(2, ':');
break;
}
}
}
#ifdef __GLIBC__
optind = 0;
#else
optreset = 1;
optind = 1;
#endif
char ch;
while ((ch = getopt_long_only(argc, (char *const *)argv,
short_options.c_str(), g_long_options, 0)) !=
-1) {
switch (ch) {
case 0:
break;
case 'a':
if (arch != NULL) {
fprintf(stderr,
"error: the --arch option can only be specified once\n");
exit(1);
}
arch = optarg;
break;
case 'c':
canonical = true;
break;
case 'x':
external_only = true;
break;
case 'p':
platform = optarg;
break;
case 'v':
verbose = true;
break;
case 'h':
case '?':
default:
show_usage = true;
break;
}
}
argc -= optind;
argv += optind;
const bool add_dependent_libs = false;
SBError error;
for (int arg_idx = 0; arg_idx < argc; ++arg_idx) {
// The first argument is the file path we want to look something up in
const char *exe_file_path = argv[arg_idx];
// Create a target using the executable.
SBTarget target = debugger.CreateTarget(exe_file_path, arch, platform,
add_dependent_libs, error);
if (error.Success()) {
if (target.IsValid()) {
SBFileSpec exe_file_spec(exe_file_path, true);
SBModule module(target.FindModule(exe_file_spec));
SBFileSpecList comp_unit_list;
if (module.IsValid()) {
char command[1024];
lldb::SBCommandReturnObject command_result;
snprintf(command, sizeof(command), "add-dsym --uuid %s",
module.GetUUIDString());
debugger.GetCommandInterpreter().HandleCommand(command,
command_result);
if (!command_result.Succeeded()) {
fprintf(stderr, "error: couldn't locate debug symbols for '%s'\n",
exe_file_path);
exit(1);
}
SBFileSpecList module_list;
module_list.Append(exe_file_spec);
SBBreakpoint bp =
target.BreakpointCreateByRegex(".", module_list, comp_unit_list);
const size_t num_locations = bp.GetNumLocations();
for (uint32_t bp_loc_idx = 0; bp_loc_idx < num_locations;
++bp_loc_idx) {
SBBreakpointLocation bp_loc = bp.GetLocationAtIndex(bp_loc_idx);
SBSymbolContext sc(
bp_loc.GetAddress().GetSymbolContext(eSymbolContextEverything));
if (sc.IsValid()) {
if (sc.GetBlock().GetContainingInlinedBlock().IsValid()) {
// Skip inlined functions
continue;
}
SBFunction function(sc.GetFunction());
if (function.IsValid()) {
addr_t lo_pc = function.GetStartAddress().GetFileAddress();
if (lo_pc == LLDB_INVALID_ADDRESS) {
// Skip functions that don't have concrete instances in the
// binary
continue;
}
addr_t hi_pc = function.GetEndAddress().GetFileAddress();
const char *func_demangled_name = function.GetName();
const char *func_mangled_name = function.GetMangledName();
bool dump = true;
const bool is_objc_method = ((func_demangled_name[0] == '-') ||
(func_demangled_name[0] == '+')) &&
(func_demangled_name[1] == '[');
if (external_only) {
// Dump all objective C methods, or external symbols
dump = is_objc_method;
if (!dump)
dump = sc.GetSymbol().IsExternal();
}
if (dump) {
if (verbose) {
printf("\n name: %s\n", func_demangled_name);
if (func_mangled_name)
printf("mangled: %s\n", func_mangled_name);
printf(" range: [0x%16.16llx - 0x%16.16llx)\n type: ",
lo_pc, hi_pc);
} else {
printf("[0x%16.16llx - 0x%16.16llx) ", lo_pc, hi_pc);
}
SBType function_type = function.GetType();
SBType return_type = function_type.GetFunctionReturnType();
if (canonical)
return_type = return_type.GetCanonicalType();
if (func_mangled_name && func_mangled_name[0] == '_' &&
func_mangled_name[1] == 'Z') {
printf("%s %s\n", return_type.GetName(),
func_demangled_name);
} else {
SBTypeList function_args =
function_type.GetFunctionArgumentTypes();
const size_t num_function_args = function_args.GetSize();
if (is_objc_method) {
const char *class_name_start = func_demangled_name + 2;
if (num_function_args == 0) {
printf("%c(%s)[%s\n", func_demangled_name[0],
return_type.GetName(), class_name_start);
} else {
const char *class_name_end =
strchr(class_name_start, ' ');
const int class_name_len =
class_name_end - class_name_start;
printf("%c(%s)[%*.*s", func_demangled_name[0],
return_type.GetName(), class_name_len,
class_name_len, class_name_start);
const char *selector_pos = class_name_end + 1;
for (uint32_t function_arg_idx = 0;
function_arg_idx < num_function_args;
++function_arg_idx) {
const char *selector_end =
strchr(selector_pos, ':') + 1;
const int selector_len = selector_end - selector_pos;
SBType function_arg_type =
function_args.GetTypeAtIndex(function_arg_idx);
if (canonical)
function_arg_type =
function_arg_type.GetCanonicalType();
printf(" %*.*s", selector_len, selector_len,
selector_pos);
if (function_arg_type.IsValid()) {
printf("(%s)", function_arg_type.GetName());
} else {
printf("(?)");
}
selector_pos = selector_end;
}
printf("]\n");
}
} else {
printf("%s ", return_type.GetName());
if (strchr(func_demangled_name, '('))
printf("(*)(");
else
printf("%s(", func_demangled_name);
for (uint32_t function_arg_idx = 0;
function_arg_idx < num_function_args;
++function_arg_idx) {
SBType function_arg_type =
function_args.GetTypeAtIndex(function_arg_idx);
if (canonical)
function_arg_type =
function_arg_type.GetCanonicalType();
if (function_arg_type.IsValid()) {
printf("%s%s", function_arg_idx > 0 ? ", " : "",
function_arg_type.GetName());
} else {
printf("%s???", function_arg_idx > 0 ? ", " : "");
}
}
printf(")\n");
}
}
}
}
}
}
}
}
} else {
fprintf(stderr, "error: %s\n", error.GetCString());
exit(1);
}
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
LEVEL = ../../../../test/make
DYLIB_NAME := FDInterposing
DYLIB_ONLY := YES
DYLIB_CXX_SOURCES := FDInterposing.cpp
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,17 @@
LEVEL = ../../test/make
CXX_SOURCES := main.cpp
EXE := lldb-lookup
USE_LIBCPP := 1
MY_OS = $(shell uname -s)
ifeq "$(MY_OS)" "Darwin"
LLDB_BUILD_DIR ?= /Applications/Xcode.app/Contents/SharedFrameworks
LD_EXTRAS ?= -framework LLDB -Wl,-rpath,"$(LLDB_BUILD_DIR)"
FRAMEWORK_INCLUDES=-F"$(LLDB_BUILD_DIR)"
else
LD_EXTRAS ?= $(LLDB_BUILD_DIR)/_lldb.so
endif
include $(LEVEL)/Makefile.rules

View File

@@ -0,0 +1,222 @@
//===-- 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 <getopt.h>
#include <stdint.h>
#include <stdlib.h>
#if defined(__APPLE__)
#include <LLDB/LLDB.h>
#else
#include "LLDB/SBBlock.h"
#include "LLDB/SBCompileUnit.h"
#include "LLDB/SBDebugger.h"
#include "LLDB/SBFunction.h"
#include "LLDB/SBModule.h"
#include "LLDB/SBProcess.h"
#include "LLDB/SBStream.h"
#include "LLDB/SBSymbol.h"
#include "LLDB/SBTarget.h"
#include "LLDB/SBThread.h"
#endif
#include <string>
using namespace lldb;
//----------------------------------------------------------------------
// This quick sample code shows how to create a debugger instance and
// create an "i386" executable target. Then we can lookup the executable
// module and resolve a file address into a section offset address,
// and find all symbol context objects (if any) for that address:
// compile unit, function, deepest block, line table entry and the
// symbol.
//
// To build the program, type (while in this directory):
//
// $ make
//
// then (for example):
//
// $ DYLD_FRAMEWORK_PATH=/Volumes/data/lldb/svn/ToT/build/Debug ./a.out
// executable_path file_address
//----------------------------------------------------------------------
class LLDBSentry {
public:
LLDBSentry() {
// Initialize LLDB
SBDebugger::Initialize();
}
~LLDBSentry() {
// Terminate LLDB
SBDebugger::Terminate();
}
};
static struct option g_long_options[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{"arch", required_argument, NULL, 'a'},
{"platform", required_argument, NULL, 'p'},
{NULL, 0, NULL, 0}};
#define PROGRAM_NAME "lldb-lookup"
void usage() {
puts("NAME\n"
" " PROGRAM_NAME " -- symbolicate addresses using lldb.\n"
"\n"
"SYNOPSIS\n"
" " PROGRAM_NAME " [[--arch=<ARCH>] [--platform=<PLATFORM>] "
"[--verbose] [--help] --] <PATH> <ADDRESS> "
"[<ADDRESS>....]\n"
"\n"
"DESCRIPTION\n"
" Loads the executable pointed to by <PATH> and looks up and "
"<ADDRESS>\n"
" arguments\n"
"\n"
"EXAMPLE\n"
" " PROGRAM_NAME " --arch=x86_64 -- /usr/lib/dyld 0x100000000\n");
exit(0);
}
int main(int argc, char const *argv[]) {
// Use a sentry object to properly initialize/terminate LLDB.
LLDBSentry sentry;
SBDebugger debugger(SBDebugger::Create());
// Create a debugger instance so we can create a target
if (!debugger.IsValid())
fprintf(stderr, "error: failed to create a debugger object\n");
bool show_usage = false;
bool verbose = false;
const char *arch = NULL;
const char *platform = NULL;
std::string short_options("h?");
for (const struct option *opt = g_long_options; opt->name; ++opt) {
if (isprint(opt->val)) {
short_options.append(1, (char)opt->val);
switch (opt->has_arg) {
case no_argument:
break;
case required_argument:
short_options.append(1, ':');
break;
case optional_argument:
short_options.append(2, ':');
break;
}
}
}
#ifdef __GLIBC__
optind = 0;
#else
optreset = 1;
optind = 1;
#endif
char ch;
while ((ch = getopt_long_only(argc, (char *const *)argv,
short_options.c_str(), g_long_options, 0)) !=
-1) {
switch (ch) {
case 0:
break;
case 'a':
if (arch != NULL) {
fprintf(stderr,
"error: the --arch option can only be specified once\n");
exit(1);
}
arch = optarg;
break;
case 'p':
platform = optarg;
break;
case 'v':
verbose = true;
break;
case 'h':
case '?':
default:
show_usage = true;
break;
}
}
argc -= optind;
argv += optind;
if (show_usage || argc < 2)
usage();
int arg_idx = 0;
// The first argument is the file path we want to look something up in
const char *exe_file_path = argv[arg_idx];
const char *addr_cstr;
const bool add_dependent_libs = false;
SBError error;
SBStream strm;
strm.RedirectToFileHandle(stdout, false);
while ((addr_cstr = argv[++arg_idx]) != NULL) {
// The second argument in the address that we want to lookup
lldb::addr_t file_addr = strtoull(addr_cstr, NULL, 0);
// Create a target using the executable.
SBTarget target = debugger.CreateTarget(exe_file_path, arch, platform,
add_dependent_libs, error);
if (!error.Success()) {
fprintf(stderr, "error: %s\n", error.GetCString());
exit(1);
}
printf("%sLooking up 0x%llx in '%s':\n", (arg_idx > 1) ? "\n" : "",
file_addr, exe_file_path);
if (target.IsValid()) {
// Find the executable module so we can do a lookup inside it
SBFileSpec exe_file_spec(exe_file_path, true);
SBModule module(target.FindModule(exe_file_spec));
// Take a file virtual address and resolve it to a section offset
// address that can be used to do a symbol lookup by address
SBAddress addr = module.ResolveFileAddress(file_addr);
bool success = addr.IsValid() && addr.GetSection().IsValid();
if (success) {
// We can resolve a section offset address in the module
// and only ask for what we need. You can logical or together
// bits from the SymbolContextItem enumeration found in
// lldb-enumeration.h to request only what you want. Here we
// are asking for everything.
//
// NOTE: the less you ask for, the less LLDB will parse as
// LLDB does partial parsing on just about everything.
SBSymbolContext sc(module.ResolveSymbolContextForAddress(
addr, eSymbolContextEverything));
strm.Printf(" Address: %s + 0x%llx\n Summary: ",
addr.GetSection().GetName(), addr.GetOffset());
addr.GetDescription(strm);
strm.Printf("\n");
if (verbose)
sc.GetDescription(strm);
} else {
printf(
"error: 0x%llx does not resolve to a valid file address in '%s'\n",
file_addr, exe_file_path);
}
}
}
return 0;
}

View File

@@ -0,0 +1,47 @@
//===-- fooplugin.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/*
An example plugin for LLDB that provides a new foo command with a child
subcommand
Compile this into a dylib foo.dylib and load by placing in appropriate locations
on disk or
by typing plugin load foo.dylib at the LLDB command line
*/
#include <LLDB/SBCommandInterpreter.h>
#include <LLDB/SBCommandReturnObject.h>
#include <LLDB/SBDebugger.h>
namespace lldb {
bool PluginInitialize(lldb::SBDebugger debugger);
}
class ChildCommand : public lldb::SBCommandPluginInterface {
public:
virtual bool DoExecute(lldb::SBDebugger debugger, char **command,
lldb::SBCommandReturnObject &result) {
if (command) {
const char *arg = *command;
while (arg) {
result.Printf("%s\n", arg);
arg = *(++command);
}
return true;
}
return false;
}
};
bool lldb::PluginInitialize(lldb::SBDebugger debugger) {
lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
lldb::SBCommand foo = interpreter.AddMultiwordCommand("foo", NULL);
foo.AddCommand("child", new ChildCommand(), "a child of foo");
return true;
}

View File

@@ -0,0 +1,122 @@
#!/usr/bin/python
#----------------------------------------------------------------------
# Be sure to add the python path that points to the LLDB shared library.
#
# # To use this in the embedded python interpreter using "lldb" just
# import it with the full path using the "command script import"
# command
# (lldb) command script import /path/to/cmdtemplate.py
#----------------------------------------------------------------------
import lldb
import commands
import optparse
import shlex
class FrameStatCommand:
def create_options(self):
usage = "usage: %prog [options]"
description = '''This command is meant to be an example of how to make an LLDB command that
does something useful, follows best practices, and exploits the SB API.
Specifically, this command computes the aggregate and average size of the variables in the current frame
and allows you to tweak exactly which variables are to be accounted in the computation.
'''
# Pass add_help_option = False, since this keeps the command in line with lldb commands,
# and we wire up "help command" to work by providing the long & short help methods below.
self.parser = optparse.OptionParser(
description = description,
prog = 'framestats',
usage = usage,
add_help_option = False)
self.parser.add_option(
'-i',
'--in-scope',
action = 'store_true',
dest = 'inscope',
help = 'in_scope_only = True',
default = True)
self.parser.add_option(
'-a',
'--arguments',
action = 'store_true',
dest = 'arguments',
help = 'arguments = True',
default = True)
self.parser.add_option(
'-l',
'--locals',
action = 'store_true',
dest = 'locals',
help = 'locals = True',
default = True)
self.parser.add_option(
'-s',
'--statics',
action = 'store_true',
dest = 'statics',
help = 'statics = True',
default = True)
def get_short_help(self):
return "Example command for use in debugging"
def get_long_help(self):
return self.help_string
def __init__(self, debugger, unused):
self.create_options()
self.help_string = self.parser.format_help()
def __call__(self, debugger, command, exe_ctx, result):
# Use the Shell Lexer to properly parse up command options just like a
# shell would
command_args = shlex.split(command)
try:
(options, args) = self.parser.parse_args(command_args)
except:
# if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
# (courtesy of OptParse dealing with argument errors by throwing SystemExit)
result.SetError("option parsing failed")
return
# Always get program state from the SBExecutionContext passed in as exe_ctx
frame = exe_ctx.GetFrame()
if not frame.IsValid():
result.SetError("invalid frame")
return
variables_list = frame.GetVariables(
options.arguments,
options.locals,
options.statics,
options.inscope)
variables_count = variables_list.GetSize()
if variables_count == 0:
print >> result, "no variables here"
return
total_size = 0
for i in range(0, variables_count):
variable = variables_list.GetValueAtIndex(i)
variable_type = variable.GetType()
total_size = total_size + variable_type.GetByteSize()
average_size = float(total_size) / variables_count
print >>result, "Your frame has %d variables. Their total size is %d bytes. The average size is %f bytes" % (
variables_count, total_size, average_size)
# not returning anything is akin to returning success
def __lldb_init_module(debugger, dict):
# This initializer is being run from LLDB in the embedded command interpreter
# Add any commands contained in this module to LLDB
debugger.HandleCommand(
'command script add -c cmdtemplate.FrameStatCommand framestats')
print 'The "framestats" command has been installed, type "help framestats" for detailed help.'

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More