blob: e962f2eb745e52ecdff4df6e6db76eea8ae87487 [file] [log] [blame]
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001//===-- IRExecutionUnit.cpp -------------------------------------*- C++ -*-===//
Sean Callanan8dfb68e2013-03-19 00:10:07 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Sean Callanan8dfb68e2013-03-19 00:10:07 +000010#include "llvm/ExecutionEngine/ExecutionEngine.h"
Sean Callanan44bc6572013-03-27 03:09:55 +000011#include "llvm/IR/LLVMContext.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000012#include "llvm/IR/Module.h"
Sean Callanan44bc6572013-03-27 03:09:55 +000013#include "llvm/Support/SourceMgr.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000014#include "llvm/Support/raw_ostream.h"
15
Sean Callanan8dfb68e2013-03-19 00:10:07 +000016#include "lldb/Core/DataBufferHeap.h"
17#include "lldb/Core/DataExtractor.h"
Jason Molendaaff1b352014-10-10 23:07:36 +000018#include "lldb/Core/Debugger.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000019#include "lldb/Core/Disassembler.h"
20#include "lldb/Core/Log.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000021#include "lldb/Core/Module.h"
22#include "lldb/Core/Section.h"
Sean Callananb2814802016-02-12 21:11:25 +000023#include "lldb/Symbol/CompileUnit.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000024#include "lldb/Symbol/SymbolContext.h"
Sean Callananb2814802016-02-12 21:11:25 +000025#include "lldb/Symbol/SymbolVendor.h"
26#include "lldb/Symbol/SymbolFile.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000027#include "lldb/Expression/IRExecutionUnit.h"
28#include "lldb/Target/ExecutionContext.h"
29#include "lldb/Target/Target.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000030#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000031
Sean Callananb2814802016-02-12 21:11:25 +000032#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
33
Sean Callanan8dfb68e2013-03-19 00:10:07 +000034using namespace lldb_private;
35
Greg Clayton7b0992d2013-04-18 22:45:39 +000036IRExecutionUnit::IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap,
37 std::unique_ptr<llvm::Module> &module_ap,
Sean Callanan8dfb68e2013-03-19 00:10:07 +000038 ConstString &name,
Sean Callananb024d872013-04-15 17:12:47 +000039 const lldb::TargetSP &target_sp,
Sean Callananb2814802016-02-12 21:11:25 +000040 const SymbolContext &sym_ctx,
Sean Callanan8dfb68e2013-03-19 00:10:07 +000041 std::vector<std::string> &cpu_features) :
Sean Callananb024d872013-04-15 17:12:47 +000042 IRMemoryMap(target_sp),
Greg Claytone01e07b2013-04-18 18:10:51 +000043 m_context_ap(context_ap.release()),
44 m_module_ap(module_ap.release()),
Sean Callanan8dfb68e2013-03-19 00:10:07 +000045 m_module(m_module_ap.get()),
Sean Callanan2c047352013-03-19 23:03:21 +000046 m_cpu_features(cpu_features),
Sean Callanan8dfb68e2013-03-19 00:10:07 +000047 m_name(name),
Sean Callananb2814802016-02-12 21:11:25 +000048 m_sym_ctx(sym_ctx),
Sean Callanan8dfb68e2013-03-19 00:10:07 +000049 m_did_jit(false),
50 m_function_load_addr(LLDB_INVALID_ADDRESS),
51 m_function_end_load_addr(LLDB_INVALID_ADDRESS)
52{
Sean Callanan8dfb68e2013-03-19 00:10:07 +000053}
54
55lldb::addr_t
56IRExecutionUnit::WriteNow (const uint8_t *bytes,
57 size_t size,
58 Error &error)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000059{
Jim Ingham2c381412015-11-04 20:32:27 +000060 const bool zero_memory = false;
Sean Callanan5a1af4e2013-04-05 02:22:57 +000061 lldb::addr_t allocation_process_addr = Malloc (size,
62 8,
63 lldb::ePermissionsWritable | lldb::ePermissionsReadable,
64 eAllocationPolicyMirror,
Jim Ingham2c381412015-11-04 20:32:27 +000065 zero_memory,
Sean Callanan5a1af4e2013-04-05 02:22:57 +000066 error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000067
Sean Callanan5a1af4e2013-04-05 02:22:57 +000068 if (!error.Success())
69 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000070
Sean Callanan5a1af4e2013-04-05 02:22:57 +000071 WriteMemory(allocation_process_addr, bytes, size, error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000072
Sean Callanan5a1af4e2013-04-05 02:22:57 +000073 if (!error.Success())
74 {
75 Error err;
76 Free (allocation_process_addr, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000077
Sean Callanan5a1af4e2013-04-05 02:22:57 +000078 return LLDB_INVALID_ADDRESS;
79 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000080
Sean Callanan5a1af4e2013-04-05 02:22:57 +000081 if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
82 {
83 DataBufferHeap my_buffer(size, 0);
84 Error err;
85 ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000086
Sean Callanan5a1af4e2013-04-05 02:22:57 +000087 if (err.Success())
88 {
89 DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
Sean Callanan4f2c1982014-01-21 00:54:48 +000090 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), allocation_process_addr, 16, DataExtractor::TypeUInt8);
Sean Callanan5a1af4e2013-04-05 02:22:57 +000091 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +000092 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000093
Sean Callanan5a1af4e2013-04-05 02:22:57 +000094 return allocation_process_addr;
Sean Callanan8dfb68e2013-03-19 00:10:07 +000095}
96
97void
98IRExecutionUnit::FreeNow (lldb::addr_t allocation)
99{
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000100 if (allocation == LLDB_INVALID_ADDRESS)
101 return;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000102
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000103 Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000104
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000105 Free(allocation, err);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000106}
107
108Error
109IRExecutionUnit::DisassembleFunction (Stream &stream,
110 lldb::ProcessSP &process_wp)
111{
Greg Clayton5160ce52013-03-27 23:08:40 +0000112 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000113
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000114 ExecutionContext exe_ctx(process_wp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000115
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000116 Error ret;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000117
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000118 ret.Clear();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000119
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000120 lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
121 lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000122
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000123 for (JittedFunction &function : m_jitted_functions)
124 {
125 if (strstr(function.m_name.c_str(), m_name.AsCString()))
126 {
127 func_local_addr = function.m_local_addr;
128 func_remote_addr = function.m_remote_addr;
129 }
130 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000131
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000132 if (func_local_addr == LLDB_INVALID_ADDRESS)
133 {
134 ret.SetErrorToGenericError();
135 ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
136 return ret;
137 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000138
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000139 if (log)
140 log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000141
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000142 std::pair <lldb::addr_t, lldb::addr_t> func_range;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000143
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000144 func_range = GetRemoteRangeForLocal(func_local_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000145
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000146 if (func_range.first == 0 && func_range.second == 0)
147 {
148 ret.SetErrorToGenericError();
149 ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
150 return ret;
151 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000152
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000153 if (log)
154 log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000155
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000156 Target *target = exe_ctx.GetTargetPtr();
157 if (!target)
158 {
159 ret.SetErrorToGenericError();
160 ret.SetErrorString("Couldn't find the target");
161 return ret;
162 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000163
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000164 lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000165
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000166 Process *process = exe_ctx.GetProcessPtr();
167 Error err;
168 process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000169
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000170 if (!err.Success())
171 {
172 ret.SetErrorToGenericError();
173 ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
174 return ret;
175 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000176
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000177 ArchSpec arch(target->GetArchitecture());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000178
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000179 const char *plugin_name = NULL;
180 const char *flavor_string = NULL;
Jim Ingham56d40422013-07-31 02:19:15 +0000181 lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000182
Jim Ingham56d40422013-07-31 02:19:15 +0000183 if (!disassembler_sp)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000184 {
185 ret.SetErrorToGenericError();
186 ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
187 return ret;
188 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000189
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000190 if (!process)
191 {
192 ret.SetErrorToGenericError();
193 ret.SetErrorString("Couldn't find the process");
194 return ret;
195 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000196
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000197 DataExtractor extractor(buffer_sp,
198 process->GetByteOrder(),
199 target->GetArchitecture().GetAddressByteSize());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000200
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000201 if (log)
202 {
203 log->Printf("Function data has contents:");
Greg Clayton5160ce52013-03-27 23:08:40 +0000204 extractor.PutToLog (log,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000205 0,
206 extractor.GetByteSize(),
207 func_remote_addr,
208 16,
209 DataExtractor::TypeUInt8);
210 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000211
Jim Ingham56d40422013-07-31 02:19:15 +0000212 disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000213
Jim Ingham56d40422013-07-31 02:19:15 +0000214 InstructionList &instruction_list = disassembler_sp->GetInstructionList();
Greg Clayton554f68d2015-02-04 22:00:53 +0000215 instruction_list.Dump(&stream, true, true, &exe_ctx);
216
Jim Ingham56d40422013-07-31 02:19:15 +0000217 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
218 // I'll fix that but for now, just clear the list and it will go away nicely.
219 disassembler_sp->GetInstructionList().Clear();
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000220 return ret;
221}
222
Sean Callanan44bc6572013-03-27 03:09:55 +0000223static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Context, unsigned LocCookie)
224{
225 Error *err = static_cast<Error*>(Context);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000226
Sean Callanan44bc6572013-03-27 03:09:55 +0000227 if (err && err->Success())
228 {
229 err->SetErrorToGenericError();
230 err->SetErrorStringWithFormat("Inline assembly error: %s", diagnostic.getMessage().str().c_str());
231 }
232}
233
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000234void
Jim Ingham27e5fe82015-01-27 18:03:05 +0000235IRExecutionUnit::ReportSymbolLookupError(const ConstString &name)
236{
237 m_failed_lookups.push_back(name);
238}
239
240void
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000241IRExecutionUnit::GetRunnableInfo(Error &error,
242 lldb::addr_t &func_addr,
243 lldb::addr_t &func_end)
244{
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000245 lldb::ProcessSP process_sp(GetProcessWP().lock());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000246
Sean Callanan7c435a52014-02-06 22:25:20 +0000247 static Mutex s_runnable_info_mutex(Mutex::Type::eMutexTypeRecursive);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000248
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000249 func_addr = LLDB_INVALID_ADDRESS;
250 func_end = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000251
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000252 if (!process_sp)
253 {
254 error.SetErrorToGenericError();
255 error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
256 return;
257 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000258
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000259 if (m_did_jit)
260 {
261 func_addr = m_function_load_addr;
262 func_end = m_function_end_load_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000263
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000264 return;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000265 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000266
Sean Callanan7c435a52014-02-06 22:25:20 +0000267 Mutex::Locker runnable_info_mutex_locker(s_runnable_info_mutex);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000268
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000269 m_did_jit = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000270
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000271 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000272
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000273 std::string error_string;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000274
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000275 if (log)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000276 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000277 std::string s;
278 llvm::raw_string_ostream oss(s);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000279
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000280 m_module->print(oss, NULL);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000281
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000282 oss.flush();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000283
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000284 log->Printf ("Module being sent to JIT: \n%s", s.c_str());
285 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000286
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000287 llvm::Triple triple(m_module->getTargetTriple());
288 llvm::Function *function = m_module->getFunction (m_name.AsCString());
289 llvm::Reloc::Model relocModel;
290 llvm::CodeModel::Model codeModel;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000291
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000292 if (triple.isOSBinFormatELF())
293 {
294 relocModel = llvm::Reloc::Static;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000295 }
296 else
297 {
298 relocModel = llvm::Reloc::PIC_;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000299 }
Sean Callananb2814802016-02-12 21:11:25 +0000300
301 // This will be small for 32-bit and large for 64-bit.
302 codeModel = llvm::CodeModel::JITDefault;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000303
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000304 m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000305
Rafael Espindola7c03d952014-08-19 04:27:03 +0000306 llvm::EngineBuilder builder(std::move(m_module_ap));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000307
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000308 builder.setEngineKind(llvm::EngineKind::JIT)
309 .setErrorStr(&error_string)
310 .setRelocationModel(relocModel)
David Majnemerb313e462014-12-04 21:26:25 +0000311 .setMCJITMemoryManager(std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
David Majnemer8faf9372014-09-16 06:34:29 +0000312 .setCodeModel(codeModel)
Reid Kleckner54209532014-09-03 00:40:36 +0000313 .setOptLevel(llvm::CodeGenOpt::Less);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000314
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000315 llvm::StringRef mArch;
316 llvm::StringRef mCPU;
317 llvm::SmallVector<std::string, 0> mAttrs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000318
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000319 for (std::string &feature : m_cpu_features)
320 mAttrs.push_back(feature);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000321
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000322 llvm::TargetMachine *target_machine = builder.selectTarget(triple,
323 mArch,
324 mCPU,
325 mAttrs);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000326
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000327 m_execution_engine_ap.reset(builder.create(target_machine));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000328
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000329 if (!m_execution_engine_ap.get())
330 {
331 error.SetErrorToGenericError();
332 error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000333 return;
334 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000335
Greg Clayton23f8c952014-03-24 23:10:19 +0000336 // Make sure we see all sections, including ones that don't have relocations...
337 m_execution_engine_ap->setProcessAllSections(true);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000338
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000339 m_execution_engine_ap->DisableLazyCompilation();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000340
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000341 // We don't actually need the function pointer here, this just forces it to get resolved.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000343 void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000344
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000345 if (!error.Success())
346 {
347 // We got an error through our callback!
348 return;
349 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000350
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000351 if (!function)
352 {
353 error.SetErrorToGenericError();
354 error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
355 return;
356 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000357
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000358 if (!fun_ptr)
359 {
360 error.SetErrorToGenericError();
361 error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
362 return;
363 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000365 m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000366
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000367 CommitAllocations(process_sp);
368 ReportAllocations(*m_execution_engine_ap);
369 WriteData(process_sp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000370
Jim Ingham27e5fe82015-01-27 18:03:05 +0000371 if (m_failed_lookups.size())
372 {
373 StreamString ss;
374
375 ss.PutCString("Couldn't lookup symbols:\n");
376
377 bool emitNewLine = false;
378
379 for (const ConstString &failed_lookup : m_failed_lookups)
380 {
381 if (emitNewLine)
382 ss.PutCString("\n");
383 emitNewLine = true;
384 ss.PutCString(" ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000385 ss.PutCString(Mangled(failed_lookup).GetDemangledName(lldb::eLanguageTypeObjC_plus_plus).AsCString());
Jim Ingham27e5fe82015-01-27 18:03:05 +0000386 }
387
388 m_failed_lookups.clear();
389
390 error.SetErrorString(ss.GetData());
391
392 return;
393 }
394
395 m_function_load_addr = LLDB_INVALID_ADDRESS;
396 m_function_end_load_addr = LLDB_INVALID_ADDRESS;
397
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000398 for (JittedFunction &jitted_function : m_jitted_functions)
399 {
400 jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000401
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000402 if (!jitted_function.m_name.compare(m_name.AsCString()))
403 {
404 AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
405 m_function_end_load_addr = func_range.first + func_range.second;
406 m_function_load_addr = jitted_function.m_remote_addr;
407 }
408 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000409
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000410 if (log)
411 {
412 log->Printf("Code can be run in the target.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000413
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000414 StreamString disassembly_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000415
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000416 Error err = DisassembleFunction(disassembly_stream, process_sp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000417
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000418 if (!err.Success())
419 {
420 log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
421 }
422 else
423 {
424 log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
425 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000426
Sean Callanan4f2c1982014-01-21 00:54:48 +0000427 log->Printf("Sections: ");
428 for (AllocationRecord &record : m_records)
429 {
430 if (record.m_process_address != LLDB_INVALID_ADDRESS)
431 {
432 record.dump(log);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000433
Sean Callanan4f2c1982014-01-21 00:54:48 +0000434 DataBufferHeap my_buffer(record.m_size, 0);
435 Error err;
436 ReadMemory(my_buffer.GetBytes(), record.m_process_address, record.m_size, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000437
Sean Callanan4f2c1982014-01-21 00:54:48 +0000438 if (err.Success())
439 {
440 DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
441 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), record.m_process_address, 16, DataExtractor::TypeUInt8);
442 }
443 }
Sean Callanan44dbf112015-10-23 00:39:09 +0000444 else
445 {
446 record.dump(log);
447
448 DataExtractor my_extractor ((const void*)record.m_host_address, record.m_size, lldb::eByteOrderBig, 8);
449 my_extractor.PutToLog(log, 0, record.m_size, record.m_host_address, 16, DataExtractor::TypeUInt8);
450 }
Sean Callanan4f2c1982014-01-21 00:54:48 +0000451 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000452 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000453
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000454 func_addr = m_function_load_addr;
455 func_end = m_function_end_load_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000456
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000457 return;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000458}
459
460IRExecutionUnit::~IRExecutionUnit ()
461{
Sean Callanan14b1bae2013-04-16 23:25:35 +0000462 m_module_ap.reset();
463 m_execution_engine_ap.reset();
464 m_context_ap.reset();
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000465}
466
467IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
Todd Fialad5635cd2014-09-24 15:55:47 +0000468 m_default_mm_ap (new llvm::SectionMemoryManager()),
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000469 m_parent (parent)
470{
471}
472
Greg Clayton23f8c952014-03-24 23:10:19 +0000473IRExecutionUnit::MemoryManager::~MemoryManager ()
474{
475}
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000476
Greg Clayton23f8c952014-03-24 23:10:19 +0000477lldb::SectionType
478IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind)
479{
480 lldb::SectionType sect_type = lldb::eSectionTypeCode;
481 switch (alloc_kind)
482 {
483 case AllocationKind::Stub: sect_type = lldb::eSectionTypeCode; break;
484 case AllocationKind::Code: sect_type = lldb::eSectionTypeCode; break;
485 case AllocationKind::Data: sect_type = lldb::eSectionTypeData; break;
486 case AllocationKind::Global:sect_type = lldb::eSectionTypeData; break;
487 case AllocationKind::Bytes: sect_type = lldb::eSectionTypeOther; break;
488 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000489
Greg Clayton23f8c952014-03-24 23:10:19 +0000490 if (!name.empty())
491 {
492 if (name.equals("__text") || name.equals(".text"))
493 sect_type = lldb::eSectionTypeCode;
494 else if (name.equals("__data") || name.equals(".data"))
495 sect_type = lldb::eSectionTypeCode;
496 else if (name.startswith("__debug_") || name.startswith(".debug_"))
497 {
498 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
499 llvm::StringRef dwarf_name(name.substr(name_idx));
500 switch (dwarf_name[0])
501 {
502 case 'a':
503 if (dwarf_name.equals("abbrev"))
504 sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
505 else if (dwarf_name.equals("aranges"))
506 sect_type = lldb::eSectionTypeDWARFDebugAranges;
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000507 else if (dwarf_name.equals("addr"))
508 sect_type = lldb::eSectionTypeDWARFDebugAddr;
Greg Clayton23f8c952014-03-24 23:10:19 +0000509 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000510
Greg Clayton23f8c952014-03-24 23:10:19 +0000511 case 'f':
512 if (dwarf_name.equals("frame"))
513 sect_type = lldb::eSectionTypeDWARFDebugFrame;
514 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000515
Greg Clayton23f8c952014-03-24 23:10:19 +0000516 case 'i':
517 if (dwarf_name.equals("info"))
518 sect_type = lldb::eSectionTypeDWARFDebugInfo;
519 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000520
Greg Clayton23f8c952014-03-24 23:10:19 +0000521 case 'l':
522 if (dwarf_name.equals("line"))
523 sect_type = lldb::eSectionTypeDWARFDebugLine;
524 else if (dwarf_name.equals("loc"))
525 sect_type = lldb::eSectionTypeDWARFDebugLoc;
526 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000527
Greg Clayton23f8c952014-03-24 23:10:19 +0000528 case 'm':
529 if (dwarf_name.equals("macinfo"))
530 sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
531 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000532
Greg Clayton23f8c952014-03-24 23:10:19 +0000533 case 'p':
534 if (dwarf_name.equals("pubnames"))
535 sect_type = lldb::eSectionTypeDWARFDebugPubNames;
536 else if (dwarf_name.equals("pubtypes"))
537 sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
538 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000539
Greg Clayton23f8c952014-03-24 23:10:19 +0000540 case 's':
541 if (dwarf_name.equals("str"))
542 sect_type = lldb::eSectionTypeDWARFDebugStr;
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000543 else if (dwarf_name.equals("str_offsets"))
544 sect_type = lldb::eSectionTypeDWARFDebugStrOffsets;
Greg Clayton23f8c952014-03-24 23:10:19 +0000545 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000546
Greg Clayton23f8c952014-03-24 23:10:19 +0000547 case 'r':
548 if (dwarf_name.equals("ranges"))
549 sect_type = lldb::eSectionTypeDWARFDebugRanges;
550 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000551
Greg Clayton23f8c952014-03-24 23:10:19 +0000552 default:
553 break;
554 }
555 }
556 else if (name.startswith("__apple_") || name.startswith(".apple_"))
557 {
558#if 0
559 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
560 llvm::StringRef apple_name(name.substr(name_idx));
561 switch (apple_name[0])
562 {
563 case 'n':
564 if (apple_name.equals("names"))
565 sect_type = lldb::eSectionTypeDWARFAppleNames;
566 else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
567 sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
568 break;
569 case 't':
570 if (apple_name.equals("types"))
571 sect_type = lldb::eSectionTypeDWARFAppleTypes;
572 break;
573 case 'o':
574 if (apple_name.equals("objc"))
575 sect_type = lldb::eSectionTypeDWARFAppleObjC;
576 break;
577 default:
578 break;
579 }
580#else
581 sect_type = lldb::eSectionTypeInvalid;
582#endif
583 }
584 else if (name.equals("__objc_imageinfo"))
585 sect_type = lldb::eSectionTypeOther;
586 }
587 return sect_type;
588}
589
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000590uint8_t *
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000591IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
592 unsigned Alignment,
Filip Pizlobfcff682013-10-02 01:43:46 +0000593 unsigned SectionID,
594 llvm::StringRef SectionName)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000595{
Greg Clayton5160ce52013-03-27 23:08:40 +0000596 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000597
Filip Pizlobfcff682013-10-02 01:43:46 +0000598 uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID, SectionName);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000599
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000600 m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
Sean Callananec1c0b32013-04-09 01:13:08 +0000601 lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
Greg Clayton23f8c952014-03-24 23:10:19 +0000602 GetSectionTypeFromSectionName (SectionName, AllocationKind::Code),
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000603 Size,
604 Alignment,
Greg Clayton23f8c952014-03-24 23:10:19 +0000605 SectionID,
606 SectionName.str().c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000607
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000608 if (log)
609 {
610 log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
David Blaikie129b8392015-04-08 20:23:52 +0000611 (uint64_t)Size, Alignment, SectionID, (void *)return_value);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000612 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000613
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000614 return return_value;
615}
616
617uint8_t *
618IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
619 unsigned Alignment,
620 unsigned SectionID,
Filip Pizlobfcff682013-10-02 01:43:46 +0000621 llvm::StringRef SectionName,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000622 bool IsReadOnly)
623{
Greg Clayton5160ce52013-03-27 23:08:40 +0000624 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000625
Filip Pizlobfcff682013-10-02 01:43:46 +0000626 uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000627
Vince Harrond7e6a4f2015-05-13 00:25:54 +0000628 uint32_t permissions = lldb::ePermissionsReadable;
629 if (!IsReadOnly)
630 permissions |= lldb::ePermissionsWritable;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000631 m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
Vince Harrond7e6a4f2015-05-13 00:25:54 +0000632 permissions,
Greg Clayton23f8c952014-03-24 23:10:19 +0000633 GetSectionTypeFromSectionName (SectionName, AllocationKind::Data),
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000634 Size,
635 Alignment,
Greg Clayton23f8c952014-03-24 23:10:19 +0000636 SectionID,
637 SectionName.str().c_str()));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000638 if (log)
639 {
640 log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
David Blaikie129b8392015-04-08 20:23:52 +0000641 (uint64_t)Size, Alignment, SectionID, (void *)return_value);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000642 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000643
644 return return_value;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000645}
646
Sean Callananb2814802016-02-12 21:11:25 +0000647static void
648FindCodeSymbolInContext(const ConstString &name,
649 const SymbolContext &sym_ctx,
650 uint32_t name_type_mask,
651 SymbolContextList &sc_list)
652{
653 sc_list.Clear();
654 SymbolContextList temp_sc_list;
655 if (sym_ctx.module_sp)
656 sym_ctx.module_sp->FindFunctions(name,
657 NULL,
658 name_type_mask,
659 true, // include_symbols
660 false, // include_inlines
661 true, // append
662 temp_sc_list);
663 if (temp_sc_list.GetSize() == 0)
664 {
665 if (sym_ctx.target_sp)
666 sym_ctx.target_sp->GetImages().FindFunctions(name,
667 name_type_mask,
668 true, // include_symbols
669 false, // include_inlines
670 true, // append
671 temp_sc_list);
672 }
673
674 SymbolContextList internal_symbol_sc_list;
675 unsigned temp_sc_list_size = temp_sc_list.GetSize();
676 for (unsigned i = 0; i < temp_sc_list_size; i++)
677 {
678 SymbolContext sc;
679 temp_sc_list.GetContextAtIndex(i, sc);
680 if (sc.function)
681 {
682 sc_list.Append(sc);
683 }
684 else if (sc.symbol)
685 {
686 if (sc.symbol->IsExternal())
687 {
688 sc_list.Append(sc);
689 }
690 else
691 {
692 internal_symbol_sc_list.Append(sc);
693 }
694 }
695 }
696
697 // If we had internal symbols and we didn't find any external symbols or
698 // functions in debug info, then fallback to the internal symbols
699 if (sc_list.GetSize() == 0 && internal_symbol_sc_list.GetSize())
700 {
701 sc_list = internal_symbol_sc_list;
702 }
703}
704
705static ConstString
706FindBestAlternateMangledName(const ConstString &demangled,
707 const lldb::LanguageType &lang_type,
708 const SymbolContext &sym_ctx)
709{
710 CPlusPlusLanguage::MethodName cpp_name(demangled);
711 std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
712
713 if (!scope_qualified_name.size())
714 return ConstString();
715
716 if (!sym_ctx.module_sp)
717 return ConstString();
718
719 SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
720 if (!sym_vendor)
721 return ConstString();
722
723 lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
724 if (!sym_file)
725 return ConstString();
726
727 std::vector<ConstString> alternates;
728 sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
729
730 std::vector<ConstString> param_and_qual_matches;
731 std::vector<ConstString> param_matches;
732 for (size_t i = 0; i < alternates.size(); i++)
733 {
734 ConstString alternate_mangled_name = alternates[i];
735 Mangled mangled(alternate_mangled_name, true);
736 ConstString demangled = mangled.GetDemangledName(lang_type);
737
738 CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
739 if (!cpp_name.IsValid())
740 continue;
741
742 if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments())
743 {
744 if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
745 param_and_qual_matches.push_back(alternate_mangled_name);
746 else
747 param_matches.push_back(alternate_mangled_name);
748 }
749 }
750
751 if (param_and_qual_matches.size())
752 return param_and_qual_matches[0]; // It is assumed that there will be only one!
753 else if (param_matches.size())
754 return param_matches[0]; // Return one of them as a best match
755 else
756 return ConstString();
757}
758
759struct SearchSpec
760{
761 ConstString name;
762 uint32_t mask;
763
764 SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeAuto) :
765 name(n),
766 mask(m)
767 {
768 }
769};
770
771static void
772CollectCandidateCNames(std::vector<SearchSpec> &C_specs, const ConstString &name)
773{
774 C_specs.push_back(SearchSpec(name));
775 if (name.AsCString()[0] == '_')
776 C_specs.push_back(ConstString(&name.AsCString()[1]));
777}
778
779static void
780CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs, const std::vector<SearchSpec> &C_specs, const SymbolContext &sc)
781{
782 for (const SearchSpec &C_spec : C_specs)
783 {
784 const ConstString &name = C_spec.name;
785
786 if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString()))
787 {
788 Mangled mangled(name, true);
789 ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
790
791 if (demangled)
792 {
793 ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lldb::eLanguageTypeC_plus_plus, sc);
794
795 if (best_alternate_mangled_name)
796 {
797 CPP_specs.push_back(best_alternate_mangled_name);
798 }
799
800 CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull));
801 }
802 }
803
804 // Maybe we're looking for a const symbol but the debug info told us it was const...
805 if (!strncmp(name.GetCString(), "_ZN", 3) &&
806 strncmp(name.GetCString(), "_ZNK", 4))
807 {
808 std::string fixed_scratch("_ZNK");
809 fixed_scratch.append(name.GetCString() + 3);
810 CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
811 }
812
813 // Maybe we're looking for a static symbol but we thought it was global...
814 if (!strncmp(name.GetCString(), "_Z", 2) &&
815 strncmp(name.GetCString(), "_ZL", 3))
816 {
817 std::string fixed_scratch("_ZL");
818 fixed_scratch.append(name.GetCString() + 2);
819 CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
820 }
821
822 }
823}
824
825static lldb::addr_t
826FindInSymbols(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
827{
828 for (const SearchSpec &spec : specs)
829 {
830 SymbolContextList sc_list;
831
832 if (sc.module_sp)
833 {
834 sc.module_sp->FindFunctions(spec.name,
835 NULL,
836 spec.mask,
837 true, // include_symbols
838 false, // include_inlines
839 true, // append
840 sc_list);
841 }
842
843 if (sc_list.GetSize() == 0 && sc.target_sp)
844 {
845 sc.target_sp->GetImages().FindFunctions(spec.name,
846 spec.mask,
847 true, // include_symbols
848 false, // include_inlines
849 true, // append
850 sc_list);
851 }
852
853 if (sc_list.GetSize() == 0 && sc.target_sp)
854 {
855 sc.target_sp->GetImages().FindSymbolsWithNameAndType(spec.name, lldb::eSymbolTypeAny, sc_list);
856 }
857
858 lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
859
860 for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si)
861 {
862 bool is_external = false;
863
864 SymbolContext candidate_sc;
865
866 sc_list.GetContextAtIndex(si, candidate_sc);
867 if (candidate_sc.function)
868 {
869 is_external = true;
870 }
871 else if (sc.symbol)
872 {
873 if (sc.symbol->IsExternal())
874 {
875 is_external = true;
876 }
877 }
878
879 lldb::addr_t load_address = candidate_sc.symbol->ResolveCallableAddress(*sc.target_sp);
880
881 if (load_address == LLDB_INVALID_ADDRESS)
882 load_address = candidate_sc.symbol->GetAddress().GetLoadAddress(sc.target_sp.get());
883
884 if (load_address != LLDB_INVALID_ADDRESS)
885 {
886 if (is_external)
887 {
888 return load_address;
889 }
890 else
891 {
892 best_internal_load_address = load_address;
893 }
894 }
895 }
896 if (best_internal_load_address != LLDB_INVALID_ADDRESS)
897 {
898 return best_internal_load_address;
899 }
900 }
901
902 return LLDB_INVALID_ADDRESS;
903}
904
905static lldb::addr_t
906FindInRuntimes(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
907{
908 lldb::TargetSP target_sp = sc.target_sp;
909
910 if (!target_sp)
911 {
912 return LLDB_INVALID_ADDRESS;
913 }
914
915 lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();
916
917 if (!process_sp)
918 {
919 return LLDB_INVALID_ADDRESS;
920 }
921
922 ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
923
924 if (runtime)
925 {
926 for (const SearchSpec &spec : specs)
927 {
928 lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name);
929
930 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
931 return symbol_load_addr;
932 }
933 }
934
935 return LLDB_INVALID_ADDRESS;
936}
937
938lldb::addr_t
939IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name, const lldb_private::SymbolContext &sc)
940{
941 std::vector<SearchSpec> candidate_C_names;
942 std::vector<SearchSpec> candidate_CPlusPlus_names;
943
944 CollectCandidateCNames(candidate_C_names, name);
945
946 lldb::addr_t ret = FindInSymbols(candidate_C_names, sc);
947 if (ret == LLDB_INVALID_ADDRESS)
948 ret = FindInRuntimes(candidate_C_names, sc);
949
950 if (ret == LLDB_INVALID_ADDRESS)
951 {
952 CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, sc);
953 ret = FindInSymbols(candidate_CPlusPlus_names, sc);
954 }
955
956 return ret;
957}
958
Jim Ingham27e5fe82015-01-27 18:03:05 +0000959uint64_t
960IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
961{
962 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Greg Claytond6171a72015-07-02 16:43:49 +0000963
Sean Callananb2814802016-02-12 21:11:25 +0000964 ConstString name_cs(Name.c_str());
Jim Ingham27e5fe82015-01-27 18:03:05 +0000965
Sean Callananb2814802016-02-12 21:11:25 +0000966 lldb::addr_t ret = m_parent.FindSymbol(name_cs);
Jim Ingham27e5fe82015-01-27 18:03:05 +0000967
Sean Callananb2814802016-02-12 21:11:25 +0000968 if (ret == LLDB_INVALID_ADDRESS)
Jim Ingham27e5fe82015-01-27 18:03:05 +0000969 {
970 if (log)
971 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
Sean Callananb2814802016-02-12 21:11:25 +0000972 Name.c_str());
973
974 m_parent.ReportSymbolLookupError(name_cs);
Jim Ingham27e5fe82015-01-27 18:03:05 +0000975 return 0xbad0bad0;
976 }
Sean Callananb2814802016-02-12 21:11:25 +0000977 else
978 {
979 if (log)
980 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
981 Name.c_str(),
982 ret);
983 return ret;
984 }
Jim Ingham27e5fe82015-01-27 18:03:05 +0000985}
986
987void *
988IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name,
989 bool AbortOnFailure) {
990 assert (sizeof(void *) == 8);
991
992 return (void*)getSymbolAddress(Name);
993}
994
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000995lldb::addr_t
996IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
997{
Sean Callananffae9442013-06-27 01:42:47 +0000998 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
999
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001000 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001001 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001002 if (local_address >= record.m_host_address &&
1003 local_address < record.m_host_address + record.m_size)
1004 {
1005 if (record.m_process_address == LLDB_INVALID_ADDRESS)
1006 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001007
Sean Callananffae9442013-06-27 01:42:47 +00001008 lldb::addr_t ret = record.m_process_address + (local_address - record.m_host_address);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001009
Sean Callananffae9442013-06-27 01:42:47 +00001010 if (log)
1011 {
1012 log->Printf("IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
1013 local_address,
Michael Sartain89c862f2013-08-07 19:05:15 +00001014 (uint64_t)record.m_host_address,
1015 (uint64_t)record.m_host_address + (uint64_t)record.m_size,
Sean Callananffae9442013-06-27 01:42:47 +00001016 ret,
1017 record.m_process_address,
1018 record.m_process_address + record.m_size);
1019 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001020
Sean Callananffae9442013-06-27 01:42:47 +00001021 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001022 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001023 }
1024
1025 return LLDB_INVALID_ADDRESS;
1026}
1027
1028IRExecutionUnit::AddrRange
1029IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
1030{
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001031 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001032 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001033 if (local_address >= record.m_host_address &&
1034 local_address < record.m_host_address + record.m_size)
1035 {
1036 if (record.m_process_address == LLDB_INVALID_ADDRESS)
1037 return AddrRange(0, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001038
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001039 return AddrRange(record.m_process_address, record.m_size);
1040 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001041 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001042
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001043 return AddrRange (0, 0);
1044}
1045
1046bool
1047IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
1048{
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001049 bool ret = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001050
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001051 lldb_private::Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001052
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001053 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001054 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001055 if (record.m_process_address != LLDB_INVALID_ADDRESS)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001056 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001057
Greg Clayton23f8c952014-03-24 23:10:19 +00001058 switch (record.m_sect_type)
1059 {
1060 case lldb::eSectionTypeInvalid:
1061 case lldb::eSectionTypeDWARFDebugAbbrev:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001062 case lldb::eSectionTypeDWARFDebugAddr:
Greg Clayton23f8c952014-03-24 23:10:19 +00001063 case lldb::eSectionTypeDWARFDebugAranges:
1064 case lldb::eSectionTypeDWARFDebugFrame:
1065 case lldb::eSectionTypeDWARFDebugInfo:
1066 case lldb::eSectionTypeDWARFDebugLine:
1067 case lldb::eSectionTypeDWARFDebugLoc:
1068 case lldb::eSectionTypeDWARFDebugMacInfo:
1069 case lldb::eSectionTypeDWARFDebugPubNames:
1070 case lldb::eSectionTypeDWARFDebugPubTypes:
1071 case lldb::eSectionTypeDWARFDebugRanges:
1072 case lldb::eSectionTypeDWARFDebugStr:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001073 case lldb::eSectionTypeDWARFDebugStrOffsets:
Greg Clayton23f8c952014-03-24 23:10:19 +00001074 case lldb::eSectionTypeDWARFAppleNames:
1075 case lldb::eSectionTypeDWARFAppleTypes:
1076 case lldb::eSectionTypeDWARFAppleNamespaces:
1077 case lldb::eSectionTypeDWARFAppleObjC:
1078 err.Clear();
1079 break;
1080 default:
Jim Ingham2c381412015-11-04 20:32:27 +00001081 const bool zero_memory = false;
Greg Clayton23f8c952014-03-24 23:10:19 +00001082 record.m_process_address = Malloc (record.m_size,
1083 record.m_alignment,
1084 record.m_permissions,
1085 eAllocationPolicyProcessOnly,
Jim Ingham2c381412015-11-04 20:32:27 +00001086 zero_memory,
Greg Clayton23f8c952014-03-24 23:10:19 +00001087 err);
1088 break;
1089 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001090
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001091 if (!err.Success())
1092 {
1093 ret = false;
1094 break;
1095 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001096 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001097
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001098 if (!ret)
1099 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001100 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001101 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001102 if (record.m_process_address != LLDB_INVALID_ADDRESS)
1103 {
1104 Free(record.m_process_address, err);
1105 record.m_process_address = LLDB_INVALID_ADDRESS;
1106 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001107 }
1108 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001109
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001110 return ret;
1111}
1112
1113void
1114IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
1115{
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001116 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001117 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001118 if (record.m_process_address == LLDB_INVALID_ADDRESS)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001119 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001120
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001121 if (record.m_section_id == eSectionIDInvalid)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001122 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001123
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001124 engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001125 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001126
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001127 // Trigger re-application of relocations.
1128 engine.finalizeObject();
1129}
1130
1131bool
1132IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
1133{
Greg Clayton23f8c952014-03-24 23:10:19 +00001134 bool wrote_something = false;
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001135 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001136 {
Greg Clayton23f8c952014-03-24 23:10:19 +00001137 if (record.m_process_address != LLDB_INVALID_ADDRESS)
1138 {
1139 lldb_private::Error err;
1140 WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
1141 if (err.Success())
1142 wrote_something = true;
1143 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001144 }
Greg Clayton23f8c952014-03-24 23:10:19 +00001145 return wrote_something;
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001146}
1147
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001148void
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001149IRExecutionUnit::AllocationRecord::dump (Log *log)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001150{
1151 if (!log)
1152 return;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001153
Sean Callanan44dbf112015-10-23 00:39:09 +00001154 log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001155 (unsigned long long)m_host_address,
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001156 (unsigned long long)m_size,
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001157 (unsigned long long)m_process_address,
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001158 (unsigned)m_alignment,
Sean Callanan44dbf112015-10-23 00:39:09 +00001159 (unsigned)m_section_id,
1160 m_name.c_str());
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001161}
Greg Clayton23f8c952014-03-24 23:10:19 +00001162
1163
1164lldb::ByteOrder
1165IRExecutionUnit::GetByteOrder () const
1166{
1167 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1168 return exe_ctx.GetByteOrder();
1169}
1170
1171uint32_t
1172IRExecutionUnit::GetAddressByteSize () const
1173{
1174 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1175 return exe_ctx.GetAddressByteSize();
1176}
1177
1178void
1179IRExecutionUnit::PopulateSymtab (lldb_private::ObjectFile *obj_file,
1180 lldb_private::Symtab &symtab)
1181{
1182 // No symbols yet...
1183}
1184
1185
1186void
1187IRExecutionUnit::PopulateSectionList (lldb_private::ObjectFile *obj_file,
1188 lldb_private::SectionList &section_list)
1189{
1190 for (AllocationRecord &record : m_records)
1191 {
1192 if (record.m_size > 0)
1193 {
1194 lldb::SectionSP section_sp (new lldb_private::Section (obj_file->GetModule(),
1195 obj_file,
1196 record.m_section_id,
1197 ConstString(record.m_name),
1198 record.m_sect_type,
1199 record.m_process_address,
1200 record.m_size,
1201 record.m_host_address, // file_offset (which is the host address for the data)
1202 record.m_size, // file_size
Greg Clayton48672af2014-06-24 22:22:43 +00001203 0,
Greg Clayton23f8c952014-03-24 23:10:19 +00001204 record.m_permissions)); // flags
1205 section_list.AddSection (section_sp);
1206 }
1207 }
1208}
1209
1210bool
1211IRExecutionUnit::GetArchitecture (lldb_private::ArchSpec &arch)
1212{
1213 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1214 Target *target = exe_ctx.GetTargetPtr();
1215 if (target)
1216 arch = target->GetArchitecture();
1217 else
1218 arch.Clear();
1219 return arch.IsValid();
1220}
1221
1222lldb::ModuleSP
1223IRExecutionUnit::GetJITModule ()
1224{
1225 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1226 Target *target = exe_ctx.GetTargetPtr();
1227 if (target)
1228 {
1229 lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule (std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(shared_from_this()));
1230 if (jit_module_sp)
1231 {
1232 bool changed = false;
1233 jit_module_sp->SetLoadAddress(*target, 0, true, changed);
1234 }
1235 return jit_module_sp;
1236 }
1237 return lldb::ModuleSP();
1238}