12588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton//===-- main.cpp ------------------------------------------------*- C++ -*-===// 22588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 32588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// The LLVM Compiler Infrastructure 42588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 52588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// This file is distributed under the University of Illinois Open Source 62588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// License. See LICENSE.TXT for details. 72588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 82588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton//===----------------------------------------------------------------------===// 92588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 10d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton#include <getopt.h> 112588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton#include <stdint.h> 122588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton#include <stdlib.h> 132588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 14582466329a734d71285534df27a459b48408b6d4Greg Clayton#if defined(__APPLE__) 152588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton#include <LLDB/LLDB.h> 16582466329a734d71285534df27a459b48408b6d4Greg Clayton#else 17582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBBlock.h" 18582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBCompileUnit.h" 19582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBDebugger.h" 20582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBFunction.h" 21582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBModule.h" 22582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBStream.h" 23582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBSymbol.h" 24582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBTarget.h" 25582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBThread.h" 26582466329a734d71285534df27a459b48408b6d4Greg Clayton#include "LLDB/SBProcess.h" 27582466329a734d71285534df27a459b48408b6d4Greg Clayton#endif 282588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 29d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton#include <string> 30d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 312588f145be57d415ed8eb0cbe7344c279397713aGreg Claytonusing namespace lldb; 322588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 332588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton//---------------------------------------------------------------------- 342588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// This quick sample code shows how to create a debugger instance and 352588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// create an executable target without adding dependent shared 362588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// libraries. It will then set a regular expression breakpoint to get 372588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// breakpoint locations for all functions in the module, and use the 382588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// locations to extract the symbol context for each location. Then it 392588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// dumps all // information about the function: its name, file address 402588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// range, the return type (if any), and all argument types. 412588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 422588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// To build the program, type (while in this directory): 432588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 442588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// $ make 452588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 462588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// then to run this on MacOSX, specify the path to your LLDB.framework 472588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// library using the DYLD_FRAMEWORK_PATH option and run the executable 482588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// 492588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton// $ DYLD_FRAMEWORK_PATH=/Volumes/data/lldb/tot/build/Debug ./a.out executable_path1 [executable_path2 ...] 502588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton//---------------------------------------------------------------------- 512588f145be57d415ed8eb0cbe7344c279397713aGreg Claytonclass LLDBSentry 522588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton{ 532588f145be57d415ed8eb0cbe7344c279397713aGreg Claytonpublic: 542588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton LLDBSentry() { 552588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton // Initialize LLDB 562588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton SBDebugger::Initialize(); 572588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 582588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton ~LLDBSentry() { 592588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton // Terminate LLDB 602588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton SBDebugger::Terminate(); 612588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 622588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton}; 63d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 64d70d22810c721bdbccb7a6b5d891ec7344365425Greg Claytonstatic struct option g_long_options[] = 65d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton{ 66d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { "arch", required_argument, NULL, 'a' }, 67d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { "canonical", no_argument, NULL, 'c' }, 68d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { "extern", no_argument, NULL, 'x' }, 69d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { "help", no_argument, NULL, 'h' }, 70d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { "platform", required_argument, NULL, 'p' }, 71d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { "verbose", no_argument, NULL, 'v' }, 72d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { NULL, 0, NULL, 0 } 73d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton}; 74d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 75d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton#define PROGRAM_NAME "lldb-functions" 76d70d22810c721bdbccb7a6b5d891ec7344365425Greg Claytonvoid 77d70d22810c721bdbccb7a6b5d891ec7344365425Greg Claytonusage () 78d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton{ 79d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton puts ( 80d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "NAME\n" 81d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton " " PROGRAM_NAME " -- extract all function signatures from one or more binaries.\n" 82d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "\n" 83d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "SYNOPSIS\n" 84d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton " " PROGRAM_NAME " [[--arch=<ARCH>] [--platform=<PLATFORM>] [--verbose] [--help] [--canonical] --] <PATH> [<PATH>....]\n" 85d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "\n" 86d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "DESCRIPTION\n" 87d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton " Loads the executable pointed to by <PATH> and dumps complete signatures for all functions that have debug information.\n" 88d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "\n" 89d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton "EXAMPLE\n" 90d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton " " PROGRAM_NAME " --arch=x86_64 /usr/lib/dyld\n" 91d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton ); 92d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton exit(0); 93d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton} 942588f145be57d415ed8eb0cbe7344c279397713aGreg Claytonint 952588f145be57d415ed8eb0cbe7344c279397713aGreg Claytonmain (int argc, char const *argv[]) 962588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton{ 972588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton // Use a sentry object to properly initialize/terminate LLDB. 982588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton LLDBSentry sentry; 992588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 100d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBDebugger debugger (SBDebugger::Create()); 101d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 102d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton // Create a debugger instance so we can create a target 103d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (!debugger.IsValid()) 104d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton fprintf (stderr, "error: failed to create a debugger object\n"); 105d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 106d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton bool show_usage = false; 107d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton bool verbose = false; 108d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton bool canonical = false; 109d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton bool external_only = false; 110d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *arch = NULL; 111d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *platform = NULL; 112d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton std::string short_options("h?"); 113d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton for (const struct option *opt = g_long_options; opt->name; ++opt) 114d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 115d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (isprint(opt->val)) 116d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 117d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton short_options.append(1, (char)opt->val); 118d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton switch (opt->has_arg) 119d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 120d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case no_argument: 121d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 122d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case required_argument: 123d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton short_options.append(1, ':'); 124d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 125d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case optional_argument: 126d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton short_options.append(2, ':'); 127d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 128d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 129d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 130d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 131d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton#ifdef __GLIBC__ 132d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton optind = 0; 133d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton#else 134d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton optreset = 1; 135d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton optind = 1; 136d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton#endif 137d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton char ch; 138d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton while ((ch = getopt_long_only(argc, (char * const *)argv, short_options.c_str(), g_long_options, 0)) != -1) 139d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 140d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton switch (ch) 141d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 142d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 0: 143d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 144d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 145d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 'a': 146d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (arch != NULL) 147d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 148d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton fprintf (stderr, "error: the --arch option can only be specified once\n"); 149d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton exit(1); 150d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 151d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton arch = optarg; 152d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 153d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 154d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 'c': 155d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton canonical = true; 156d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 157d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 158d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 'x': 159d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton external_only = true; 160d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 161d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 162d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 'p': 163d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton platform = optarg; 164d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 165d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 166d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 'v': 167d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton verbose = true; 168d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 169d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 170d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case 'h': 171d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton case '?': 172d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton default: 173d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton show_usage = true; 174d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton break; 175d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 176d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 177d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton argc -= optind; 178d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton argv += optind; 1792588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 1802588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton const bool add_dependent_libs = false; 1812588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton SBError error; 182d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton for (int arg_idx = 0; arg_idx < argc; ++arg_idx) 1832588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 184d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton // The first argument is the file path we want to look something up in 1852588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton const char *exe_file_path = argv[arg_idx]; 1862588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 187d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton // Create a target using the executable. 188d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBTarget target = debugger.CreateTarget (exe_file_path, 189d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton arch, 190d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton platform, 191d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton add_dependent_libs, 192d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton error); 1932588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 194d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (error.Success()) 1952588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 196d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (target.IsValid()) 1972588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 198d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBFileSpec exe_file_spec (exe_file_path, true); 199d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBModule module (target.FindModule (exe_file_spec)); 200d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBFileSpecList comp_unit_list; 2012588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 202d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (module.IsValid()) 203d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 204d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton char command[1024]; 205d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton lldb::SBCommandReturnObject command_result; 206d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton snprintf (command, sizeof(command), "add-dsym --uuid %s", module.GetUUIDString()); 207d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton debugger.GetCommandInterpreter().HandleCommand (command, command_result); 208d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (!command_result.Succeeded()) 2092588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 210d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton fprintf (stderr, "error: couldn't locate debug symbols for '%s'\n", exe_file_path); 211d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton exit(1); 212d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 2132588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 214d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBFileSpecList module_list; 215d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton module_list.Append(exe_file_spec); 216d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBBreakpoint bp = target.BreakpointCreateByRegex (".", module_list, comp_unit_list); 217d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 218d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const size_t num_locations = bp.GetNumLocations(); 219d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton for (uint32_t bp_loc_idx=0; bp_loc_idx<num_locations; ++bp_loc_idx) 220d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 221d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBBreakpointLocation bp_loc = bp.GetLocationAtIndex(bp_loc_idx); 222d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBSymbolContext sc (bp_loc.GetAddress().GetSymbolContext(eSymbolContextEverything)); 223d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (sc.IsValid()) 2242588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 225d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (sc.GetBlock().GetContainingInlinedBlock().IsValid()) 226d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 227d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton // Skip inlined functions 228d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton continue; 229d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 230d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBFunction function (sc.GetFunction()); 231d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (function.IsValid()) 2322588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 233d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton addr_t lo_pc = function.GetStartAddress().GetFileAddress(); 234d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (lo_pc == LLDB_INVALID_ADDRESS) 2352588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 236d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton // Skip functions that don't have concrete instances in the binary 2372588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton continue; 2382588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 239d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton addr_t hi_pc = function.GetEndAddress().GetFileAddress(); 240d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *func_demangled_name = function.GetName(); 241d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *func_mangled_name = function.GetMangledName(); 242d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 243d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton bool dump = true; 244d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const bool is_objc_method = ((func_demangled_name[0] == '-') || (func_demangled_name[0] == '+')) && (func_demangled_name[1] == '['); 245d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (external_only) 246d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 247d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton // Dump all objective C methods, or external symbols 248d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton dump = is_objc_method; 249d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (!dump) 250d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton dump = sc.GetSymbol().IsExternal(); 251d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 252d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 253d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (dump) 2542588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 255d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (verbose) 2562588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 257d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("\n name: %s\n", func_demangled_name); 258d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (func_mangled_name) 259d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("mangled: %s\n", func_mangled_name); 260d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf (" range: [0x%16.16llx - 0x%16.16llx)\n type: ", lo_pc, hi_pc); 261d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 262d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 263d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 264d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("[0x%16.16llx - 0x%16.16llx) ", lo_pc, hi_pc); 2652588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 2662588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton SBType function_type = function.GetType(); 2672588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton SBType return_type = function_type.GetFunctionReturnType(); 268d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 269d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (canonical) 270d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton return_type = return_type.GetCanonicalType(); 271d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 272d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (func_mangled_name && 273d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton func_mangled_name[0] == '_' && 274d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton func_mangled_name[1] == 'Z') 2752588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 276d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("%s %s\n", return_type.GetName(), func_demangled_name); 2772588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 278d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 2792588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 280d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBTypeList function_args = function_type.GetFunctionArgumentTypes(); 281d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const size_t num_function_args = function_args.GetSize(); 2822588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 283d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (is_objc_method) 2842588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 285d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *class_name_start = func_demangled_name + 2; 286d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 287d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (num_function_args == 0) 288d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 289d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf("%c(%s)[%s\n", func_demangled_name[0], return_type.GetName(), class_name_start); 290d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 291d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 292d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 293d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *class_name_end = strchr(class_name_start,' '); 294d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const int class_name_len = class_name_end - class_name_start; 295d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("%c(%s)[%*.*s", func_demangled_name[0], return_type.GetName(), class_name_len, class_name_len, class_name_start); 296d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 297d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *selector_pos = class_name_end + 1; 298d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args; ++function_arg_idx) 299d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 300d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const char *selector_end = strchr(selector_pos, ':') + 1; 301d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton const int selector_len = selector_end - selector_pos; 302d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBType function_arg_type = function_args.GetTypeAtIndex(function_arg_idx); 303d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 304d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (canonical) 305d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton function_arg_type = function_arg_type.GetCanonicalType(); 306d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 307d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf (" %*.*s", selector_len, selector_len, selector_pos); 308d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (function_arg_type.IsValid()) 309d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 310d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("(%s)", function_arg_type.GetName()); 311d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 312d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 313d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 314d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("(?)"); 315d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 316d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton selector_pos = selector_end; 317d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 318d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("]\n"); 319d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 3202588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3212588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton else 3222588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton { 323d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("%s ", return_type.GetName()); 324d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (strchr (func_demangled_name, '(')) 325d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("(*)("); 326d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 327d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("%s(", func_demangled_name); 328d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 329d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args; ++function_arg_idx) 330d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 331d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton SBType function_arg_type = function_args.GetTypeAtIndex(function_arg_idx); 332d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 333d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (canonical) 334d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton function_arg_type = function_arg_type.GetCanonicalType(); 335d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton 336d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton if (function_arg_type.IsValid()) 337d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 338d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("%s%s", function_arg_idx > 0 ? ", " : "", function_arg_type.GetName()); 339d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 340d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 341d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 342d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf ("%s???", function_arg_idx > 0 ? ", " : ""); 343d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 344d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 345d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton printf (")\n"); 346d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 3472588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3482588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3492588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3502588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3512588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3522588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3532588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 354d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton } 355d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton else 356d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton { 357d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton fprintf (stderr, "error: %s\n", error.GetCString()); 358d70d22810c721bdbccb7a6b5d891ec7344365425Greg Clayton exit(1); 3592588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3602588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton } 3612588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 3622588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton return 0; 3632588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton} 3642588f145be57d415ed8eb0cbe7344c279397713aGreg Clayton 365