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