From 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Wed, 6 Jan 2016 20:12:03 +0000 Subject: Vendor import of lldb trunk r256945: https://llvm.org/svn/llvm-project/lldb/trunk@256945 --- examples/functions/main.cpp | 364 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 examples/functions/main.cpp (limited to 'examples/functions/main.cpp') diff --git a/examples/functions/main.cpp b/examples/functions/main.cpp new file mode 100644 index 0000000000000..4381098e33050 --- /dev/null +++ b/examples/functions/main.cpp @@ -0,0 +1,364 @@ +//===-- 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 +#include +#include + +#if defined(__APPLE__) +#include +#else +#include "LLDB/SBBlock.h" +#include "LLDB/SBCompileUnit.h" +#include "LLDB/SBDebugger.h" +#include "LLDB/SBFunction.h" +#include "LLDB/SBModule.h" +#include "LLDB/SBStream.h" +#include "LLDB/SBSymbol.h" +#include "LLDB/SBTarget.h" +#include "LLDB/SBThread.h" +#include "LLDB/SBProcess.h" +#endif + +#include + +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=] [--platform=] [--verbose] [--help] [--canonical] --] [....]\n" + "\n" + "DESCRIPTION\n" + " Loads the executable pointed to by 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 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; +} + -- cgit v1.2.3