blob: 5d8cc344a6c2795842c94a72f7994afab62a858d [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));
Sean Callananf4527032016-02-12 23:55:13 +0000328
329 m_strip_underscore = (m_execution_engine_ap->getDataLayout().getGlobalPrefix() == '_');
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000330
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000331 if (!m_execution_engine_ap.get())
332 {
333 error.SetErrorToGenericError();
334 error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000335 return;
336 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000337
Greg Clayton23f8c952014-03-24 23:10:19 +0000338 // Make sure we see all sections, including ones that don't have relocations...
339 m_execution_engine_ap->setProcessAllSections(true);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000340
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000341 m_execution_engine_ap->DisableLazyCompilation();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000343 // We don't actually need the function pointer here, this just forces it to get resolved.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000344
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000345 void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000346
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000347 if (!error.Success())
348 {
349 // We got an error through our callback!
350 return;
351 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000352
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000353 if (!function)
354 {
355 error.SetErrorToGenericError();
356 error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
357 return;
358 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000359
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000360 if (!fun_ptr)
361 {
362 error.SetErrorToGenericError();
363 error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
364 return;
365 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000366
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000367 m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000368
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000369 CommitAllocations(process_sp);
370 ReportAllocations(*m_execution_engine_ap);
371 WriteData(process_sp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000372
Jim Ingham27e5fe82015-01-27 18:03:05 +0000373 if (m_failed_lookups.size())
374 {
375 StreamString ss;
376
377 ss.PutCString("Couldn't lookup symbols:\n");
378
379 bool emitNewLine = false;
380
381 for (const ConstString &failed_lookup : m_failed_lookups)
382 {
383 if (emitNewLine)
384 ss.PutCString("\n");
385 emitNewLine = true;
386 ss.PutCString(" ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000387 ss.PutCString(Mangled(failed_lookup).GetDemangledName(lldb::eLanguageTypeObjC_plus_plus).AsCString());
Jim Ingham27e5fe82015-01-27 18:03:05 +0000388 }
389
390 m_failed_lookups.clear();
391
392 error.SetErrorString(ss.GetData());
393
394 return;
395 }
396
397 m_function_load_addr = LLDB_INVALID_ADDRESS;
398 m_function_end_load_addr = LLDB_INVALID_ADDRESS;
399
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000400 for (JittedFunction &jitted_function : m_jitted_functions)
401 {
402 jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000403
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000404 if (!jitted_function.m_name.compare(m_name.AsCString()))
405 {
406 AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
407 m_function_end_load_addr = func_range.first + func_range.second;
408 m_function_load_addr = jitted_function.m_remote_addr;
409 }
410 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000411
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000412 if (log)
413 {
414 log->Printf("Code can be run in the target.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000415
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000416 StreamString disassembly_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000417
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000418 Error err = DisassembleFunction(disassembly_stream, process_sp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000419
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000420 if (!err.Success())
421 {
422 log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
423 }
424 else
425 {
426 log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
427 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000428
Sean Callanan4f2c1982014-01-21 00:54:48 +0000429 log->Printf("Sections: ");
430 for (AllocationRecord &record : m_records)
431 {
432 if (record.m_process_address != LLDB_INVALID_ADDRESS)
433 {
434 record.dump(log);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000435
Sean Callanan4f2c1982014-01-21 00:54:48 +0000436 DataBufferHeap my_buffer(record.m_size, 0);
437 Error err;
438 ReadMemory(my_buffer.GetBytes(), record.m_process_address, record.m_size, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000439
Sean Callanan4f2c1982014-01-21 00:54:48 +0000440 if (err.Success())
441 {
442 DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
443 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), record.m_process_address, 16, DataExtractor::TypeUInt8);
444 }
445 }
Sean Callanan44dbf112015-10-23 00:39:09 +0000446 else
447 {
448 record.dump(log);
449
450 DataExtractor my_extractor ((const void*)record.m_host_address, record.m_size, lldb::eByteOrderBig, 8);
451 my_extractor.PutToLog(log, 0, record.m_size, record.m_host_address, 16, DataExtractor::TypeUInt8);
452 }
Sean Callanan4f2c1982014-01-21 00:54:48 +0000453 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000454 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000455
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000456 func_addr = m_function_load_addr;
457 func_end = m_function_end_load_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000458
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000459 return;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000460}
461
462IRExecutionUnit::~IRExecutionUnit ()
463{
Sean Callanan14b1bae2013-04-16 23:25:35 +0000464 m_module_ap.reset();
465 m_execution_engine_ap.reset();
466 m_context_ap.reset();
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000467}
468
469IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
Todd Fialad5635cd2014-09-24 15:55:47 +0000470 m_default_mm_ap (new llvm::SectionMemoryManager()),
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000471 m_parent (parent)
472{
473}
474
Greg Clayton23f8c952014-03-24 23:10:19 +0000475IRExecutionUnit::MemoryManager::~MemoryManager ()
476{
477}
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000478
Greg Clayton23f8c952014-03-24 23:10:19 +0000479lldb::SectionType
480IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind)
481{
482 lldb::SectionType sect_type = lldb::eSectionTypeCode;
483 switch (alloc_kind)
484 {
485 case AllocationKind::Stub: sect_type = lldb::eSectionTypeCode; break;
486 case AllocationKind::Code: sect_type = lldb::eSectionTypeCode; break;
487 case AllocationKind::Data: sect_type = lldb::eSectionTypeData; break;
488 case AllocationKind::Global:sect_type = lldb::eSectionTypeData; break;
489 case AllocationKind::Bytes: sect_type = lldb::eSectionTypeOther; break;
490 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000491
Greg Clayton23f8c952014-03-24 23:10:19 +0000492 if (!name.empty())
493 {
494 if (name.equals("__text") || name.equals(".text"))
495 sect_type = lldb::eSectionTypeCode;
496 else if (name.equals("__data") || name.equals(".data"))
497 sect_type = lldb::eSectionTypeCode;
498 else if (name.startswith("__debug_") || name.startswith(".debug_"))
499 {
500 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
501 llvm::StringRef dwarf_name(name.substr(name_idx));
502 switch (dwarf_name[0])
503 {
504 case 'a':
505 if (dwarf_name.equals("abbrev"))
506 sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
507 else if (dwarf_name.equals("aranges"))
508 sect_type = lldb::eSectionTypeDWARFDebugAranges;
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000509 else if (dwarf_name.equals("addr"))
510 sect_type = lldb::eSectionTypeDWARFDebugAddr;
Greg Clayton23f8c952014-03-24 23:10:19 +0000511 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000512
Greg Clayton23f8c952014-03-24 23:10:19 +0000513 case 'f':
514 if (dwarf_name.equals("frame"))
515 sect_type = lldb::eSectionTypeDWARFDebugFrame;
516 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000517
Greg Clayton23f8c952014-03-24 23:10:19 +0000518 case 'i':
519 if (dwarf_name.equals("info"))
520 sect_type = lldb::eSectionTypeDWARFDebugInfo;
521 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000522
Greg Clayton23f8c952014-03-24 23:10:19 +0000523 case 'l':
524 if (dwarf_name.equals("line"))
525 sect_type = lldb::eSectionTypeDWARFDebugLine;
526 else if (dwarf_name.equals("loc"))
527 sect_type = lldb::eSectionTypeDWARFDebugLoc;
528 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000529
Greg Clayton23f8c952014-03-24 23:10:19 +0000530 case 'm':
531 if (dwarf_name.equals("macinfo"))
532 sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
533 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000534
Greg Clayton23f8c952014-03-24 23:10:19 +0000535 case 'p':
536 if (dwarf_name.equals("pubnames"))
537 sect_type = lldb::eSectionTypeDWARFDebugPubNames;
538 else if (dwarf_name.equals("pubtypes"))
539 sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
540 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000541
Greg Clayton23f8c952014-03-24 23:10:19 +0000542 case 's':
543 if (dwarf_name.equals("str"))
544 sect_type = lldb::eSectionTypeDWARFDebugStr;
Tamas Berghammerc178d4c2015-08-25 11:45:58 +0000545 else if (dwarf_name.equals("str_offsets"))
546 sect_type = lldb::eSectionTypeDWARFDebugStrOffsets;
Greg Clayton23f8c952014-03-24 23:10:19 +0000547 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000548
Greg Clayton23f8c952014-03-24 23:10:19 +0000549 case 'r':
550 if (dwarf_name.equals("ranges"))
551 sect_type = lldb::eSectionTypeDWARFDebugRanges;
552 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000553
Greg Clayton23f8c952014-03-24 23:10:19 +0000554 default:
555 break;
556 }
557 }
558 else if (name.startswith("__apple_") || name.startswith(".apple_"))
559 {
560#if 0
561 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
562 llvm::StringRef apple_name(name.substr(name_idx));
563 switch (apple_name[0])
564 {
565 case 'n':
566 if (apple_name.equals("names"))
567 sect_type = lldb::eSectionTypeDWARFAppleNames;
568 else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
569 sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
570 break;
571 case 't':
572 if (apple_name.equals("types"))
573 sect_type = lldb::eSectionTypeDWARFAppleTypes;
574 break;
575 case 'o':
576 if (apple_name.equals("objc"))
577 sect_type = lldb::eSectionTypeDWARFAppleObjC;
578 break;
579 default:
580 break;
581 }
582#else
583 sect_type = lldb::eSectionTypeInvalid;
584#endif
585 }
586 else if (name.equals("__objc_imageinfo"))
587 sect_type = lldb::eSectionTypeOther;
588 }
589 return sect_type;
590}
591
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000592uint8_t *
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000593IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
594 unsigned Alignment,
Filip Pizlobfcff682013-10-02 01:43:46 +0000595 unsigned SectionID,
596 llvm::StringRef SectionName)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000597{
Greg Clayton5160ce52013-03-27 23:08:40 +0000598 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000599
Filip Pizlobfcff682013-10-02 01:43:46 +0000600 uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID, SectionName);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000601
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000602 m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
Sean Callananec1c0b32013-04-09 01:13:08 +0000603 lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
Greg Clayton23f8c952014-03-24 23:10:19 +0000604 GetSectionTypeFromSectionName (SectionName, AllocationKind::Code),
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000605 Size,
606 Alignment,
Greg Clayton23f8c952014-03-24 23:10:19 +0000607 SectionID,
608 SectionName.str().c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000609
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000610 if (log)
611 {
612 log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
David Blaikie129b8392015-04-08 20:23:52 +0000613 (uint64_t)Size, Alignment, SectionID, (void *)return_value);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000614 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000615
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000616 return return_value;
617}
618
619uint8_t *
620IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
621 unsigned Alignment,
622 unsigned SectionID,
Filip Pizlobfcff682013-10-02 01:43:46 +0000623 llvm::StringRef SectionName,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000624 bool IsReadOnly)
625{
Greg Clayton5160ce52013-03-27 23:08:40 +0000626 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000627
Filip Pizlobfcff682013-10-02 01:43:46 +0000628 uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000629
Vince Harrond7e6a4f2015-05-13 00:25:54 +0000630 uint32_t permissions = lldb::ePermissionsReadable;
631 if (!IsReadOnly)
632 permissions |= lldb::ePermissionsWritable;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000633 m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
Vince Harrond7e6a4f2015-05-13 00:25:54 +0000634 permissions,
Greg Clayton23f8c952014-03-24 23:10:19 +0000635 GetSectionTypeFromSectionName (SectionName, AllocationKind::Data),
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000636 Size,
637 Alignment,
Greg Clayton23f8c952014-03-24 23:10:19 +0000638 SectionID,
639 SectionName.str().c_str()));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000640 if (log)
641 {
642 log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
David Blaikie129b8392015-04-08 20:23:52 +0000643 (uint64_t)Size, Alignment, SectionID, (void *)return_value);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000644 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000645
646 return return_value;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000647}
648
Sean Callananb2814802016-02-12 21:11:25 +0000649static ConstString
650FindBestAlternateMangledName(const ConstString &demangled,
651 const lldb::LanguageType &lang_type,
652 const SymbolContext &sym_ctx)
653{
654 CPlusPlusLanguage::MethodName cpp_name(demangled);
655 std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
656
657 if (!scope_qualified_name.size())
658 return ConstString();
659
660 if (!sym_ctx.module_sp)
661 return ConstString();
662
663 SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
664 if (!sym_vendor)
665 return ConstString();
666
667 lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
668 if (!sym_file)
669 return ConstString();
670
671 std::vector<ConstString> alternates;
672 sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
673
674 std::vector<ConstString> param_and_qual_matches;
675 std::vector<ConstString> param_matches;
676 for (size_t i = 0; i < alternates.size(); i++)
677 {
678 ConstString alternate_mangled_name = alternates[i];
679 Mangled mangled(alternate_mangled_name, true);
680 ConstString demangled = mangled.GetDemangledName(lang_type);
681
682 CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
683 if (!cpp_name.IsValid())
684 continue;
685
686 if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments())
687 {
688 if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
689 param_and_qual_matches.push_back(alternate_mangled_name);
690 else
691 param_matches.push_back(alternate_mangled_name);
692 }
693 }
694
695 if (param_and_qual_matches.size())
696 return param_and_qual_matches[0]; // It is assumed that there will be only one!
697 else if (param_matches.size())
698 return param_matches[0]; // Return one of them as a best match
699 else
700 return ConstString();
701}
702
Sean Callananf4527032016-02-12 23:55:13 +0000703struct IRExecutionUnit::SearchSpec
Sean Callananb2814802016-02-12 21:11:25 +0000704{
705 ConstString name;
706 uint32_t mask;
707
708 SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeAuto) :
709 name(n),
710 mask(m)
711 {
712 }
713};
714
Sean Callananf4527032016-02-12 23:55:13 +0000715void
716IRExecutionUnit::CollectCandidateCNames(std::vector<IRExecutionUnit::SearchSpec> &C_specs, const ConstString &name)
Sean Callananb2814802016-02-12 21:11:25 +0000717{
Sean Callananf4527032016-02-12 23:55:13 +0000718 if (m_strip_underscore && name.AsCString()[0] == '_')
719 C_specs.insert(C_specs.begin(), ConstString(&name.AsCString()[1]));
Sean Callananb2814802016-02-12 21:11:25 +0000720 C_specs.push_back(SearchSpec(name));
Sean Callananb2814802016-02-12 21:11:25 +0000721}
722
Sean Callananf4527032016-02-12 23:55:13 +0000723void
724IRExecutionUnit::CollectCandidateCPlusPlusNames(std::vector<IRExecutionUnit::SearchSpec> &CPP_specs, const std::vector<SearchSpec> &C_specs, const SymbolContext &sc)
Sean Callananb2814802016-02-12 21:11:25 +0000725{
726 for (const SearchSpec &C_spec : C_specs)
727 {
728 const ConstString &name = C_spec.name;
729
730 if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString()))
731 {
732 Mangled mangled(name, true);
733 ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
734
735 if (demangled)
736 {
737 ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lldb::eLanguageTypeC_plus_plus, sc);
738
739 if (best_alternate_mangled_name)
740 {
741 CPP_specs.push_back(best_alternate_mangled_name);
742 }
743
744 CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull));
745 }
746 }
747
748 // Maybe we're looking for a const symbol but the debug info told us it was const...
749 if (!strncmp(name.GetCString(), "_ZN", 3) &&
750 strncmp(name.GetCString(), "_ZNK", 4))
751 {
752 std::string fixed_scratch("_ZNK");
753 fixed_scratch.append(name.GetCString() + 3);
754 CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
755 }
756
757 // Maybe we're looking for a static symbol but we thought it was global...
758 if (!strncmp(name.GetCString(), "_Z", 2) &&
759 strncmp(name.GetCString(), "_ZL", 3))
760 {
761 std::string fixed_scratch("_ZL");
762 fixed_scratch.append(name.GetCString() + 2);
763 CPP_specs.push_back(ConstString(fixed_scratch.c_str()));
764 }
765
766 }
767}
768
Sean Callananf4527032016-02-12 23:55:13 +0000769lldb::addr_t
770IRExecutionUnit::FindInSymbols(const std::vector<IRExecutionUnit::SearchSpec> &specs, const lldb_private::SymbolContext &sc)
Sean Callananb2814802016-02-12 21:11:25 +0000771{
772 for (const SearchSpec &spec : specs)
773 {
774 SymbolContextList sc_list;
775
776 if (sc.module_sp)
777 {
778 sc.module_sp->FindFunctions(spec.name,
779 NULL,
780 spec.mask,
781 true, // include_symbols
782 false, // include_inlines
783 true, // append
784 sc_list);
785 }
786
787 if (sc_list.GetSize() == 0 && sc.target_sp)
788 {
789 sc.target_sp->GetImages().FindFunctions(spec.name,
790 spec.mask,
791 true, // include_symbols
792 false, // include_inlines
793 true, // append
794 sc_list);
795 }
796
797 if (sc_list.GetSize() == 0 && sc.target_sp)
798 {
799 sc.target_sp->GetImages().FindSymbolsWithNameAndType(spec.name, lldb::eSymbolTypeAny, sc_list);
800 }
801
802 lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
803
804 for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si)
805 {
806 bool is_external = false;
807
808 SymbolContext candidate_sc;
809
810 sc_list.GetContextAtIndex(si, candidate_sc);
811 if (candidate_sc.function)
812 {
813 is_external = true;
814 }
815 else if (sc.symbol)
816 {
817 if (sc.symbol->IsExternal())
818 {
819 is_external = true;
820 }
821 }
822
823 lldb::addr_t load_address = candidate_sc.symbol->ResolveCallableAddress(*sc.target_sp);
824
825 if (load_address == LLDB_INVALID_ADDRESS)
826 load_address = candidate_sc.symbol->GetAddress().GetLoadAddress(sc.target_sp.get());
827
828 if (load_address != LLDB_INVALID_ADDRESS)
829 {
830 if (is_external)
831 {
832 return load_address;
833 }
834 else
835 {
836 best_internal_load_address = load_address;
837 }
838 }
839 }
840 if (best_internal_load_address != LLDB_INVALID_ADDRESS)
841 {
842 return best_internal_load_address;
843 }
844 }
845
846 return LLDB_INVALID_ADDRESS;
847}
848
Sean Callananf4527032016-02-12 23:55:13 +0000849lldb::addr_t
850IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs, const lldb_private::SymbolContext &sc)
Sean Callananb2814802016-02-12 21:11:25 +0000851{
852 lldb::TargetSP target_sp = sc.target_sp;
853
854 if (!target_sp)
855 {
856 return LLDB_INVALID_ADDRESS;
857 }
858
859 lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();
860
861 if (!process_sp)
862 {
863 return LLDB_INVALID_ADDRESS;
864 }
865
866 ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
867
868 if (runtime)
869 {
870 for (const SearchSpec &spec : specs)
871 {
872 lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name);
873
874 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
875 return symbol_load_addr;
876 }
877 }
878
879 return LLDB_INVALID_ADDRESS;
880}
881
882lldb::addr_t
Sean Callananf4527032016-02-12 23:55:13 +0000883IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name)
Sean Callananb2814802016-02-12 21:11:25 +0000884{
885 std::vector<SearchSpec> candidate_C_names;
886 std::vector<SearchSpec> candidate_CPlusPlus_names;
887
888 CollectCandidateCNames(candidate_C_names, name);
889
Sean Callananf4527032016-02-12 23:55:13 +0000890 lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx);
Sean Callananb2814802016-02-12 21:11:25 +0000891 if (ret == LLDB_INVALID_ADDRESS)
Sean Callananf4527032016-02-12 23:55:13 +0000892 ret = FindInRuntimes(candidate_C_names, m_sym_ctx);
Sean Callananb2814802016-02-12 21:11:25 +0000893
894 if (ret == LLDB_INVALID_ADDRESS)
895 {
Sean Callananf4527032016-02-12 23:55:13 +0000896 CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names, m_sym_ctx);
897 ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx);
Sean Callananb2814802016-02-12 21:11:25 +0000898 }
899
900 return ret;
901}
902
Jim Ingham27e5fe82015-01-27 18:03:05 +0000903uint64_t
904IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
905{
906 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Greg Claytond6171a72015-07-02 16:43:49 +0000907
Sean Callananb2814802016-02-12 21:11:25 +0000908 ConstString name_cs(Name.c_str());
Jim Ingham27e5fe82015-01-27 18:03:05 +0000909
Sean Callananb2814802016-02-12 21:11:25 +0000910 lldb::addr_t ret = m_parent.FindSymbol(name_cs);
Jim Ingham27e5fe82015-01-27 18:03:05 +0000911
Sean Callananb2814802016-02-12 21:11:25 +0000912 if (ret == LLDB_INVALID_ADDRESS)
Jim Ingham27e5fe82015-01-27 18:03:05 +0000913 {
914 if (log)
915 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
Sean Callananb2814802016-02-12 21:11:25 +0000916 Name.c_str());
917
918 m_parent.ReportSymbolLookupError(name_cs);
Jim Ingham27e5fe82015-01-27 18:03:05 +0000919 return 0xbad0bad0;
920 }
Sean Callananb2814802016-02-12 21:11:25 +0000921 else
922 {
923 if (log)
924 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
925 Name.c_str(),
926 ret);
927 return ret;
928 }
Jim Ingham27e5fe82015-01-27 18:03:05 +0000929}
930
931void *
932IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name,
933 bool AbortOnFailure) {
934 assert (sizeof(void *) == 8);
935
936 return (void*)getSymbolAddress(Name);
937}
938
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000939lldb::addr_t
940IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
941{
Sean Callananffae9442013-06-27 01:42:47 +0000942 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
943
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000944 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000945 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000946 if (local_address >= record.m_host_address &&
947 local_address < record.m_host_address + record.m_size)
948 {
949 if (record.m_process_address == LLDB_INVALID_ADDRESS)
950 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000951
Sean Callananffae9442013-06-27 01:42:47 +0000952 lldb::addr_t ret = record.m_process_address + (local_address - record.m_host_address);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000953
Sean Callananffae9442013-06-27 01:42:47 +0000954 if (log)
955 {
956 log->Printf("IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
957 local_address,
Michael Sartain89c862f2013-08-07 19:05:15 +0000958 (uint64_t)record.m_host_address,
959 (uint64_t)record.m_host_address + (uint64_t)record.m_size,
Sean Callananffae9442013-06-27 01:42:47 +0000960 ret,
961 record.m_process_address,
962 record.m_process_address + record.m_size);
963 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000964
Sean Callananffae9442013-06-27 01:42:47 +0000965 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000966 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000967 }
968
969 return LLDB_INVALID_ADDRESS;
970}
971
972IRExecutionUnit::AddrRange
973IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
974{
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000975 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000976 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000977 if (local_address >= record.m_host_address &&
978 local_address < record.m_host_address + record.m_size)
979 {
980 if (record.m_process_address == LLDB_INVALID_ADDRESS)
981 return AddrRange(0, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000982
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000983 return AddrRange(record.m_process_address, record.m_size);
984 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000985 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000986
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000987 return AddrRange (0, 0);
988}
989
990bool
991IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
992{
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000993 bool ret = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000994
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000995 lldb_private::Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000996
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000997 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000998 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000999 if (record.m_process_address != LLDB_INVALID_ADDRESS)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001000 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001001
Greg Clayton23f8c952014-03-24 23:10:19 +00001002 switch (record.m_sect_type)
1003 {
1004 case lldb::eSectionTypeInvalid:
1005 case lldb::eSectionTypeDWARFDebugAbbrev:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001006 case lldb::eSectionTypeDWARFDebugAddr:
Greg Clayton23f8c952014-03-24 23:10:19 +00001007 case lldb::eSectionTypeDWARFDebugAranges:
1008 case lldb::eSectionTypeDWARFDebugFrame:
1009 case lldb::eSectionTypeDWARFDebugInfo:
1010 case lldb::eSectionTypeDWARFDebugLine:
1011 case lldb::eSectionTypeDWARFDebugLoc:
1012 case lldb::eSectionTypeDWARFDebugMacInfo:
1013 case lldb::eSectionTypeDWARFDebugPubNames:
1014 case lldb::eSectionTypeDWARFDebugPubTypes:
1015 case lldb::eSectionTypeDWARFDebugRanges:
1016 case lldb::eSectionTypeDWARFDebugStr:
Tamas Berghammerc178d4c2015-08-25 11:45:58 +00001017 case lldb::eSectionTypeDWARFDebugStrOffsets:
Greg Clayton23f8c952014-03-24 23:10:19 +00001018 case lldb::eSectionTypeDWARFAppleNames:
1019 case lldb::eSectionTypeDWARFAppleTypes:
1020 case lldb::eSectionTypeDWARFAppleNamespaces:
1021 case lldb::eSectionTypeDWARFAppleObjC:
1022 err.Clear();
1023 break;
1024 default:
Jim Ingham2c381412015-11-04 20:32:27 +00001025 const bool zero_memory = false;
Greg Clayton23f8c952014-03-24 23:10:19 +00001026 record.m_process_address = Malloc (record.m_size,
1027 record.m_alignment,
1028 record.m_permissions,
1029 eAllocationPolicyProcessOnly,
Jim Ingham2c381412015-11-04 20:32:27 +00001030 zero_memory,
Greg Clayton23f8c952014-03-24 23:10:19 +00001031 err);
1032 break;
1033 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001034
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001035 if (!err.Success())
1036 {
1037 ret = false;
1038 break;
1039 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001040 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001041
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001042 if (!ret)
1043 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001044 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001045 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001046 if (record.m_process_address != LLDB_INVALID_ADDRESS)
1047 {
1048 Free(record.m_process_address, err);
1049 record.m_process_address = LLDB_INVALID_ADDRESS;
1050 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001051 }
1052 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001053
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001054 return ret;
1055}
1056
1057void
1058IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
1059{
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001060 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001061 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001062 if (record.m_process_address == LLDB_INVALID_ADDRESS)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001063 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001064
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001065 if (record.m_section_id == eSectionIDInvalid)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001066 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001067
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001068 engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001069 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001070
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001071 // Trigger re-application of relocations.
1072 engine.finalizeObject();
1073}
1074
1075bool
1076IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
1077{
Greg Clayton23f8c952014-03-24 23:10:19 +00001078 bool wrote_something = false;
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001079 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001080 {
Greg Clayton23f8c952014-03-24 23:10:19 +00001081 if (record.m_process_address != LLDB_INVALID_ADDRESS)
1082 {
1083 lldb_private::Error err;
1084 WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
1085 if (err.Success())
1086 wrote_something = true;
1087 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001088 }
Greg Clayton23f8c952014-03-24 23:10:19 +00001089 return wrote_something;
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001090}
1091
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001092void
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001093IRExecutionUnit::AllocationRecord::dump (Log *log)
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001094{
1095 if (!log)
1096 return;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001097
Sean Callanan44dbf112015-10-23 00:39:09 +00001098 log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001099 (unsigned long long)m_host_address,
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001100 (unsigned long long)m_size,
Sean Callanan5a1af4e2013-04-05 02:22:57 +00001101 (unsigned long long)m_process_address,
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001102 (unsigned)m_alignment,
Sean Callanan44dbf112015-10-23 00:39:09 +00001103 (unsigned)m_section_id,
1104 m_name.c_str());
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001105}
Greg Clayton23f8c952014-03-24 23:10:19 +00001106
1107
1108lldb::ByteOrder
1109IRExecutionUnit::GetByteOrder () const
1110{
1111 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1112 return exe_ctx.GetByteOrder();
1113}
1114
1115uint32_t
1116IRExecutionUnit::GetAddressByteSize () const
1117{
1118 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1119 return exe_ctx.GetAddressByteSize();
1120}
1121
1122void
1123IRExecutionUnit::PopulateSymtab (lldb_private::ObjectFile *obj_file,
1124 lldb_private::Symtab &symtab)
1125{
1126 // No symbols yet...
1127}
1128
1129
1130void
1131IRExecutionUnit::PopulateSectionList (lldb_private::ObjectFile *obj_file,
1132 lldb_private::SectionList &section_list)
1133{
1134 for (AllocationRecord &record : m_records)
1135 {
1136 if (record.m_size > 0)
1137 {
1138 lldb::SectionSP section_sp (new lldb_private::Section (obj_file->GetModule(),
1139 obj_file,
1140 record.m_section_id,
1141 ConstString(record.m_name),
1142 record.m_sect_type,
1143 record.m_process_address,
1144 record.m_size,
1145 record.m_host_address, // file_offset (which is the host address for the data)
1146 record.m_size, // file_size
Greg Clayton48672af2014-06-24 22:22:43 +00001147 0,
Greg Clayton23f8c952014-03-24 23:10:19 +00001148 record.m_permissions)); // flags
1149 section_list.AddSection (section_sp);
1150 }
1151 }
1152}
1153
1154bool
1155IRExecutionUnit::GetArchitecture (lldb_private::ArchSpec &arch)
1156{
1157 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1158 Target *target = exe_ctx.GetTargetPtr();
1159 if (target)
1160 arch = target->GetArchitecture();
1161 else
1162 arch.Clear();
1163 return arch.IsValid();
1164}
1165
1166lldb::ModuleSP
1167IRExecutionUnit::GetJITModule ()
1168{
1169 ExecutionContext exe_ctx (GetBestExecutionContextScope());
1170 Target *target = exe_ctx.GetTargetPtr();
1171 if (target)
1172 {
1173 lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule (std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(shared_from_this()));
1174 if (jit_module_sp)
1175 {
1176 bool changed = false;
1177 jit_module_sp->SetLoadAddress(*target, 0, true, changed);
1178 }
1179 return jit_module_sp;
1180 }
1181 return lldb::ModuleSP();
1182}