1 //===-- main.cpp ------------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
13 #if defined(__APPLE__)
14 #include <LLDB/LLDB.h>
16 #include "LLDB/SBBlock.h"
17 #include "LLDB/SBCompileUnit.h"
18 #include "LLDB/SBDebugger.h"
19 #include "LLDB/SBFunction.h"
20 #include "LLDB/SBModule.h"
21 #include "LLDB/SBProcess.h"
22 #include "LLDB/SBStream.h"
23 #include "LLDB/SBSymbol.h"
24 #include "LLDB/SBTarget.h"
25 #include "LLDB/SBThread.h"
32 // This quick sample code shows how to create a debugger instance and
33 // create an "i386" executable target. Then we can lookup the executable
34 // module and resolve a file address into a section offset address,
35 // and find all symbol context objects (if any) for that address:
36 // compile unit, function, deepest block, line table entry and the
39 // To build the program, type (while in this directory):
43 // then (for example):
45 // $ DYLD_FRAMEWORK_PATH=/Volumes/data/lldb/svn/ToT/build/Debug ./a.out
46 // executable_path file_address
51 SBDebugger::Initialize();
55 SBDebugger::Terminate();
59 static struct option g_long_options
[] = {
60 {"help", no_argument
, NULL
, 'h'},
61 {"verbose", no_argument
, NULL
, 'v'},
62 {"arch", required_argument
, NULL
, 'a'},
63 {"platform", required_argument
, NULL
, 'p'},
66 #define PROGRAM_NAME "lldb-lookup"
69 " " PROGRAM_NAME
" -- symbolicate addresses using lldb.\n"
72 " " PROGRAM_NAME
" [[--arch=<ARCH>] [--platform=<PLATFORM>] "
73 "[--verbose] [--help] --] <PATH> <ADDRESS> "
77 " Loads the executable pointed to by <PATH> and looks up and "
82 " " PROGRAM_NAME
" --arch=x86_64 -- /usr/lib/dyld 0x100000000\n");
85 int main(int argc
, char const *argv
[]) {
86 // Use a sentry object to properly initialize/terminate LLDB.
89 SBDebugger
debugger(SBDebugger::Create());
91 // Create a debugger instance so we can create a target
92 if (!debugger
.IsValid())
93 fprintf(stderr
, "error: failed to create a debugger object\n");
95 bool show_usage
= false;
97 const char *arch
= NULL
;
98 const char *platform
= NULL
;
99 std::string
short_options("h?");
100 for (const struct option
*opt
= g_long_options
; opt
->name
; ++opt
) {
101 if (isprint(opt
->val
)) {
102 short_options
.append(1, (char)opt
->val
);
103 switch (opt
->has_arg
) {
106 case required_argument
:
107 short_options
.append(1, ':');
109 case optional_argument
:
110 short_options
.append(2, ':');
122 while ((ch
= getopt_long_only(argc
, (char *const *)argv
,
123 short_options
.c_str(), g_long_options
, 0)) !=
132 "error: the --arch option can only be specified once\n");
156 if (show_usage
|| argc
< 2)
160 // The first argument is the file path we want to look something up in
161 const char *exe_file_path
= argv
[arg_idx
];
162 const char *addr_cstr
;
163 const bool add_dependent_libs
= false;
166 strm
.RedirectToFileHandle(stdout
, false);
168 while ((addr_cstr
= argv
[++arg_idx
]) != NULL
) {
169 // The second argument in the address that we want to lookup
170 lldb::addr_t file_addr
= strtoull(addr_cstr
, NULL
, 0);
172 // Create a target using the executable.
173 SBTarget target
= debugger
.CreateTarget(exe_file_path
, arch
, platform
,
174 add_dependent_libs
, error
);
175 if (!error
.Success()) {
176 fprintf(stderr
, "error: %s\n", error
.GetCString());
180 printf("%sLooking up 0x%llx in '%s':\n", (arg_idx
> 1) ? "\n" : "",
181 file_addr
, exe_file_path
);
183 if (target
.IsValid()) {
184 // Find the executable module so we can do a lookup inside it
185 SBFileSpec
exe_file_spec(exe_file_path
, true);
186 SBModule
module(target
.FindModule(exe_file_spec
));
188 // Take a file virtual address and resolve it to a section offset
189 // address that can be used to do a symbol lookup by address
190 SBAddress addr
= module
.ResolveFileAddress(file_addr
);
191 bool success
= addr
.IsValid() && addr
.GetSection().IsValid();
193 // We can resolve a section offset address in the module
194 // and only ask for what we need. You can logical or together
195 // bits from the SymbolContextItem enumeration found in
196 // lldb-enumeration.h to request only what you want. Here we
197 // are asking for everything.
199 // NOTE: the less you ask for, the less LLDB will parse as
200 // LLDB does partial parsing on just about everything.
201 SBSymbolContext
sc(module
.ResolveSymbolContextForAddress(
202 addr
, eSymbolContextEverything
));
204 strm
.Printf(" Address: %s + 0x%llx\n Summary: ",
205 addr
.GetSection().GetName(), addr
.GetOffset());
206 addr
.GetDescription(strm
);
209 sc
.GetDescription(strm
);
212 "error: 0x%llx does not resolve to a valid file address in '%s'\n",
213 file_addr
, exe_file_path
);