blob: 8bc66f7bb6d57703054a7f4433dc9aa364d9027c [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 Callanan5deb06e2016-09-26 20:18:51 +000011#include "llvm/ExecutionEngine/ObjectCache.h"
Sean Callananbd4dc692016-03-21 22:23:38 +000012#include "llvm/IR/Constants.h"
Sean Callanan44bc6572013-03-27 03:09:55 +000013#include "llvm/IR/LLVMContext.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000014#include "llvm/IR/Module.h"
Sean Callanan44bc6572013-03-27 03:09:55 +000015#include "llvm/Support/SourceMgr.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000016#include "llvm/Support/raw_ostream.h"
17
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"
Greg Clayton23f8c952014-03-24 23:10:19 +000020#include "lldb/Core/Module.h"
21#include "lldb/Core/Section.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000022#include "lldb/Expression/IRExecutionUnit.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/SymbolFile.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000026#include "lldb/Symbol/SymbolVendor.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000027#include "lldb/Target/ExecutionContext.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000028#include "lldb/Target/ObjCLanguageRuntime.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000029#include "lldb/Target/Target.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000030#include "lldb/Utility/DataBufferHeap.h"
31#include "lldb/Utility/DataExtractor.h"
Sean Callananbd4dc692016-03-21 22:23:38 +000032#include "lldb/Utility/LLDBAssert.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000033#include "lldb/Utility/Log.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000034
Sean Callananb2814802016-02-12 21:11:25 +000035#include "lldb/../../source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
36
Sean Callanan8dfb68e2013-03-19 00:10:07 +000037using namespace lldb_private;
38
Kate Stoneb9c1b512016-09-06 20:57:50 +000039IRExecutionUnit::IRExecutionUnit(std::unique_ptr<llvm::LLVMContext> &context_ap,
40 std::unique_ptr<llvm::Module> &module_ap,
41 ConstString &name,
42 const lldb::TargetSP &target_sp,
43 const SymbolContext &sym_ctx,
44 std::vector<std::string> &cpu_features)
45 : IRMemoryMap(target_sp), m_context_ap(context_ap.release()),
46 m_module_ap(module_ap.release()), m_module(m_module_ap.get()),
47 m_cpu_features(cpu_features), m_name(name), m_sym_ctx(sym_ctx),
48 m_did_jit(false), m_function_load_addr(LLDB_INVALID_ADDRESS),
49 m_function_end_load_addr(LLDB_INVALID_ADDRESS),
50 m_reported_allocations(false) {}
Sean Callanan8dfb68e2013-03-19 00:10:07 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052lldb::addr_t IRExecutionUnit::WriteNow(const uint8_t *bytes, size_t size,
Zachary Turner97206d52017-05-12 04:51:55 +000053 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 const bool zero_memory = false;
55 lldb::addr_t allocation_process_addr =
56 Malloc(size, 8, lldb::ePermissionsWritable | lldb::ePermissionsReadable,
57 eAllocationPolicyMirror, zero_memory, error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 if (!error.Success())
60 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062 WriteMemory(allocation_process_addr, bytes, size, error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064 if (!error.Success()) {
Zachary Turner97206d52017-05-12 04:51:55 +000065 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 Free(allocation_process_addr, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000067
Kate Stoneb9c1b512016-09-06 20:57:50 +000068 return LLDB_INVALID_ADDRESS;
69 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 if (Log *log =
72 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)) {
73 DataBufferHeap my_buffer(size, 0);
Zachary Turner97206d52017-05-12 04:51:55 +000074 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 if (err.Success()) {
78 DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(),
79 lldb::eByteOrderBig, 8);
80 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(),
81 allocation_process_addr, 16,
Sean Callanan8dfb68e2013-03-19 00:10:07 +000082 DataExtractor::TypeUInt8);
83 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000084 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086 return allocation_process_addr;
87}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089void IRExecutionUnit::FreeNow(lldb::addr_t allocation) {
90 if (allocation == LLDB_INVALID_ADDRESS)
91 return;
92
Zachary Turner97206d52017-05-12 04:51:55 +000093 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +000094
95 Free(allocation, err);
96}
97
Zachary Turner97206d52017-05-12 04:51:55 +000098Status IRExecutionUnit::DisassembleFunction(Stream &stream,
99 lldb::ProcessSP &process_wp) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000100 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
101
102 ExecutionContext exe_ctx(process_wp);
103
Zachary Turner97206d52017-05-12 04:51:55 +0000104 Status ret;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105
106 ret.Clear();
107
108 lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
109 lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
110
111 for (JittedFunction &function : m_jitted_functions) {
112 if (function.m_name == m_name) {
113 func_local_addr = function.m_local_addr;
114 func_remote_addr = function.m_remote_addr;
115 }
116 }
117
118 if (func_local_addr == LLDB_INVALID_ADDRESS) {
119 ret.SetErrorToGenericError();
120 ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly",
121 m_name.AsCString());
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000122 return ret;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 }
124
125 if (log)
126 log->Printf("Found function, has local address 0x%" PRIx64
127 " and remote address 0x%" PRIx64,
128 (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
129
130 std::pair<lldb::addr_t, lldb::addr_t> func_range;
131
132 func_range = GetRemoteRangeForLocal(func_local_addr);
133
134 if (func_range.first == 0 && func_range.second == 0) {
135 ret.SetErrorToGenericError();
136 ret.SetErrorStringWithFormat("Couldn't find code range for function %s",
137 m_name.AsCString());
138 return ret;
139 }
140
141 if (log)
142 log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]",
143 func_range.first, func_range.second);
144
145 Target *target = exe_ctx.GetTargetPtr();
146 if (!target) {
147 ret.SetErrorToGenericError();
148 ret.SetErrorString("Couldn't find the target");
149 return ret;
150 }
151
152 lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
153
154 Process *process = exe_ctx.GetProcessPtr();
Zachary Turner97206d52017-05-12 04:51:55 +0000155 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156 process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(),
157 buffer_sp->GetByteSize(), err);
158
159 if (!err.Success()) {
160 ret.SetErrorToGenericError();
161 ret.SetErrorStringWithFormat("Couldn't read from process: %s",
162 err.AsCString("unknown error"));
163 return ret;
164 }
165
166 ArchSpec arch(target->GetArchitecture());
167
168 const char *plugin_name = NULL;
169 const char *flavor_string = NULL;
170 lldb::DisassemblerSP disassembler_sp =
171 Disassembler::FindPlugin(arch, flavor_string, plugin_name);
172
173 if (!disassembler_sp) {
174 ret.SetErrorToGenericError();
175 ret.SetErrorStringWithFormat(
176 "Unable to find disassembler plug-in for %s architecture.",
177 arch.GetArchitectureName());
178 return ret;
179 }
180
181 if (!process) {
182 ret.SetErrorToGenericError();
183 ret.SetErrorString("Couldn't find the process");
184 return ret;
185 }
186
187 DataExtractor extractor(buffer_sp, process->GetByteOrder(),
188 target->GetArchitecture().GetAddressByteSize());
189
190 if (log) {
191 log->Printf("Function data has contents:");
192 extractor.PutToLog(log, 0, extractor.GetByteSize(), func_remote_addr, 16,
193 DataExtractor::TypeUInt8);
194 }
195
196 disassembler_sp->DecodeInstructions(Address(func_remote_addr), extractor, 0,
197 UINT32_MAX, false, false);
198
199 InstructionList &instruction_list = disassembler_sp->GetInstructionList();
200 instruction_list.Dump(&stream, true, true, &exe_ctx);
201 return ret;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000202}
203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic,
205 void *Context, unsigned LocCookie) {
Zachary Turner97206d52017-05-12 04:51:55 +0000206 Status *err = static_cast<Status *>(Context);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208 if (err && err->Success()) {
209 err->SetErrorToGenericError();
210 err->SetErrorStringWithFormat("Inline assembly error: %s",
211 diagnostic.getMessage().str().c_str());
212 }
Sean Callanan44bc6572013-03-27 03:09:55 +0000213}
214
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215void IRExecutionUnit::ReportSymbolLookupError(const ConstString &name) {
216 m_failed_lookups.push_back(name);
Jim Ingham27e5fe82015-01-27 18:03:05 +0000217}
218
Zachary Turner97206d52017-05-12 04:51:55 +0000219void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 lldb::addr_t &func_end) {
221 lldb::ProcessSP process_sp(GetProcessWP().lock());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000222
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223 static std::recursive_mutex s_runnable_info_mutex;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000224
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 func_addr = LLDB_INVALID_ADDRESS;
226 func_end = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000227
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 if (!process_sp) {
229 error.SetErrorToGenericError();
230 error.SetErrorString("Couldn't write the JIT compiled code into the "
231 "process because the process is invalid");
232 return;
233 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000234
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235 if (m_did_jit) {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000236 func_addr = m_function_load_addr;
237 func_end = m_function_end_load_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000238
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000239 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240 };
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000241
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 std::lock_guard<std::recursive_mutex> guard(s_runnable_info_mutex);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000243
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244 m_did_jit = true;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000245
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000247
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 std::string error_string;
249
250 if (log) {
251 std::string s;
252 llvm::raw_string_ostream oss(s);
253
254 m_module->print(oss, NULL);
255
256 oss.flush();
257
258 log->Printf("Module being sent to JIT: \n%s", s.c_str());
259 }
260
261 llvm::Triple triple(m_module->getTargetTriple());
262 llvm::Reloc::Model relocModel;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263
264 if (triple.isOSBinFormatELF()) {
265 relocModel = llvm::Reloc::Static;
266 } else {
267 relocModel = llvm::Reloc::PIC_;
268 }
269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270 m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError,
271 &error);
272
273 llvm::EngineBuilder builder(std::move(m_module_ap));
274
275 builder.setEngineKind(llvm::EngineKind::JIT)
276 .setErrorStr(&error_string)
277 .setRelocationModel(relocModel)
278 .setMCJITMemoryManager(
279 std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 .setOptLevel(llvm::CodeGenOpt::Less)
281 .setUseOrcMCJITReplacement(true);
282
283 llvm::StringRef mArch;
284 llvm::StringRef mCPU;
285 llvm::SmallVector<std::string, 0> mAttrs;
286
287 for (std::string &feature : m_cpu_features)
288 mAttrs.push_back(feature);
289
290 llvm::TargetMachine *target_machine =
291 builder.selectTarget(triple, mArch, mCPU, mAttrs);
292
293 m_execution_engine_ap.reset(builder.create(target_machine));
294
295 m_strip_underscore =
296 (m_execution_engine_ap->getDataLayout().getGlobalPrefix() == '_');
297
298 if (!m_execution_engine_ap.get()) {
299 error.SetErrorToGenericError();
300 error.SetErrorStringWithFormat("Couldn't JIT the function: %s",
301 error_string.c_str());
302 return;
303 }
304
Sean Callanan5deb06e2016-09-26 20:18:51 +0000305 class ObjectDumper : public llvm::ObjectCache {
306 public:
307 void notifyObjectCompiled(const llvm::Module *module,
308 llvm::MemoryBufferRef object) override {
309 int fd = 0;
310 llvm::SmallVector<char, 256> result_path;
311 std::string object_name_model =
312 "jit-object-" + module->getModuleIdentifier() + "-%%%.o";
313 (void)llvm::sys::fs::createUniqueFile(object_name_model, fd, result_path);
314 llvm::raw_fd_ostream fds(fd, true);
315 fds.write(object.getBufferStart(), object.getBufferSize());
316 }
317
318 std::unique_ptr<llvm::MemoryBuffer>
319 getObject(const llvm::Module *module) override {
320 // Return nothing - we're just abusing the object-cache mechanism to dump
321 // objects.
322 return nullptr;
323 }
324 };
325
326 if (process_sp->GetTarget().GetEnableSaveObjects()) {
327 m_object_cache_ap = llvm::make_unique<ObjectDumper>();
328 m_execution_engine_ap->setObjectCache(m_object_cache_ap.get());
329 }
330
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331 // Make sure we see all sections, including ones that don't have
332 // relocations...
333 m_execution_engine_ap->setProcessAllSections(true);
334
335 m_execution_engine_ap->DisableLazyCompilation();
336
337 for (llvm::Function &function : *m_module) {
338 if (function.isDeclaration() || function.hasPrivateLinkage())
339 continue;
340
341 const bool external =
342 function.hasExternalLinkage() || function.hasLinkOnceODRLinkage();
343
344 void *fun_ptr = m_execution_engine_ap->getPointerToFunction(&function);
345
346 if (!error.Success()) {
347 // We got an error through our callback!
348 return;
Greg Clayton23f8c952014-03-24 23:10:19 +0000349 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 if (!fun_ptr) {
352 error.SetErrorToGenericError();
353 error.SetErrorStringWithFormat(
354 "'%s' was in the JITted module but wasn't lowered",
355 function.getName().str().c_str());
356 return;
357 }
358 m_jitted_functions.push_back(JittedFunction(
359 function.getName().str().c_str(), external, (lldb::addr_t)fun_ptr));
360 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000361
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362 CommitAllocations(process_sp);
363 ReportAllocations(*m_execution_engine_ap);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365 // We have to do this after calling ReportAllocations because for the MCJIT,
366 // getGlobalValueAddress
367 // will cause the JIT to perform all relocations. That can only be done once,
368 // and has to happen
369 // after we do the remapping from local -> remote.
370 // That means we don't know the local address of the Variables, but we don't
371 // need that for anything,
372 // so that's okay.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000373
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374 std::function<void(llvm::GlobalValue &)> RegisterOneValue = [this](
375 llvm::GlobalValue &val) {
376 if (val.hasExternalLinkage() && !val.isDeclaration()) {
377 uint64_t var_ptr_addr =
378 m_execution_engine_ap->getGlobalValueAddress(val.getName().str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000379
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380 lldb::addr_t remote_addr = GetRemoteAddressForLocal(var_ptr_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 // This is a really unfortunae API that sometimes returns local addresses
383 // and sometimes returns remote addresses, based on whether
384 // the variable was relocated during ReportAllocations or not.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000385
Kate Stoneb9c1b512016-09-06 20:57:50 +0000386 if (remote_addr == LLDB_INVALID_ADDRESS) {
387 remote_addr = var_ptr_addr;
388 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000389
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 if (var_ptr_addr != 0)
391 m_jitted_global_variables.push_back(JittedGlobalVariable(
392 val.getName().str().c_str(), LLDB_INVALID_ADDRESS, remote_addr));
393 }
394 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000395
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396 for (llvm::GlobalVariable &global_var : m_module->getGlobalList()) {
397 RegisterOneValue(global_var);
398 }
399
400 for (llvm::GlobalAlias &global_alias : m_module->getAliasList()) {
401 RegisterOneValue(global_alias);
402 }
403
404 WriteData(process_sp);
405
406 if (m_failed_lookups.size()) {
407 StreamString ss;
408
409 ss.PutCString("Couldn't lookup symbols:\n");
410
411 bool emitNewLine = false;
412
413 for (const ConstString &failed_lookup : m_failed_lookups) {
414 if (emitNewLine)
415 ss.PutCString("\n");
416 emitNewLine = true;
417 ss.PutCString(" ");
418 ss.PutCString(Mangled(failed_lookup)
419 .GetDemangledName(lldb::eLanguageTypeObjC_plus_plus)
420 .AsCString());
421 }
422
423 m_failed_lookups.clear();
424
Zachary Turnerc1564272016-11-16 21:15:24 +0000425 error.SetErrorString(ss.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426
427 return;
428 }
429
430 m_function_load_addr = LLDB_INVALID_ADDRESS;
431 m_function_end_load_addr = LLDB_INVALID_ADDRESS;
432
433 for (JittedFunction &jitted_function : m_jitted_functions) {
434 jitted_function.m_remote_addr =
435 GetRemoteAddressForLocal(jitted_function.m_local_addr);
436
437 if (!m_name.IsEmpty() && jitted_function.m_name == m_name) {
438 AddrRange func_range =
439 GetRemoteRangeForLocal(jitted_function.m_local_addr);
440 m_function_end_load_addr = func_range.first + func_range.second;
441 m_function_load_addr = jitted_function.m_remote_addr;
442 }
443 }
444
445 if (log) {
446 log->Printf("Code can be run in the target.");
447
448 StreamString disassembly_stream;
449
Zachary Turner97206d52017-05-12 04:51:55 +0000450 Status err = DisassembleFunction(disassembly_stream, process_sp);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451
452 if (!err.Success()) {
453 log->Printf("Couldn't disassemble function : %s",
454 err.AsCString("unknown error"));
455 } else {
456 log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
457 }
458
459 log->Printf("Sections: ");
460 for (AllocationRecord &record : m_records) {
461 if (record.m_process_address != LLDB_INVALID_ADDRESS) {
462 record.dump(log);
463
464 DataBufferHeap my_buffer(record.m_size, 0);
Zachary Turner97206d52017-05-12 04:51:55 +0000465 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000466 ReadMemory(my_buffer.GetBytes(), record.m_process_address,
467 record.m_size, err);
468
469 if (err.Success()) {
470 DataExtractor my_extractor(my_buffer.GetBytes(),
471 my_buffer.GetByteSize(),
472 lldb::eByteOrderBig, 8);
473 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(),
474 record.m_process_address, 16,
475 DataExtractor::TypeUInt8);
Greg Clayton23f8c952014-03-24 23:10:19 +0000476 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477 } else {
478 record.dump(log);
479
480 DataExtractor my_extractor((const void *)record.m_host_address,
481 record.m_size, lldb::eByteOrderBig, 8);
482 my_extractor.PutToLog(log, 0, record.m_size, record.m_host_address, 16,
483 DataExtractor::TypeUInt8);
484 }
485 }
486 }
487
488 func_addr = m_function_load_addr;
489 func_end = m_function_end_load_addr;
490
491 return;
492}
493
494IRExecutionUnit::~IRExecutionUnit() {
495 m_module_ap.reset();
496 m_execution_engine_ap.reset();
497 m_context_ap.reset();
498}
499
500IRExecutionUnit::MemoryManager::MemoryManager(IRExecutionUnit &parent)
501 : m_default_mm_ap(new llvm::SectionMemoryManager()), m_parent(parent) {}
502
503IRExecutionUnit::MemoryManager::~MemoryManager() {}
504
505lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName(
506 const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind) {
507 lldb::SectionType sect_type = lldb::eSectionTypeCode;
508 switch (alloc_kind) {
509 case AllocationKind::Stub:
510 sect_type = lldb::eSectionTypeCode;
511 break;
512 case AllocationKind::Code:
513 sect_type = lldb::eSectionTypeCode;
514 break;
515 case AllocationKind::Data:
516 sect_type = lldb::eSectionTypeData;
517 break;
518 case AllocationKind::Global:
519 sect_type = lldb::eSectionTypeData;
520 break;
521 case AllocationKind::Bytes:
522 sect_type = lldb::eSectionTypeOther;
523 break;
524 }
525
526 if (!name.empty()) {
527 if (name.equals("__text") || name.equals(".text"))
528 sect_type = lldb::eSectionTypeCode;
529 else if (name.equals("__data") || name.equals(".data"))
530 sect_type = lldb::eSectionTypeCode;
531 else if (name.startswith("__debug_") || name.startswith(".debug_")) {
532 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
533 llvm::StringRef dwarf_name(name.substr(name_idx));
534 switch (dwarf_name[0]) {
535 case 'a':
536 if (dwarf_name.equals("abbrev"))
537 sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
538 else if (dwarf_name.equals("aranges"))
539 sect_type = lldb::eSectionTypeDWARFDebugAranges;
540 else if (dwarf_name.equals("addr"))
541 sect_type = lldb::eSectionTypeDWARFDebugAddr;
542 break;
543
544 case 'f':
545 if (dwarf_name.equals("frame"))
546 sect_type = lldb::eSectionTypeDWARFDebugFrame;
547 break;
548
549 case 'i':
550 if (dwarf_name.equals("info"))
551 sect_type = lldb::eSectionTypeDWARFDebugInfo;
552 break;
553
554 case 'l':
555 if (dwarf_name.equals("line"))
556 sect_type = lldb::eSectionTypeDWARFDebugLine;
557 else if (dwarf_name.equals("loc"))
558 sect_type = lldb::eSectionTypeDWARFDebugLoc;
559 break;
560
561 case 'm':
562 if (dwarf_name.equals("macinfo"))
563 sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
564 break;
565
566 case 'p':
567 if (dwarf_name.equals("pubnames"))
568 sect_type = lldb::eSectionTypeDWARFDebugPubNames;
569 else if (dwarf_name.equals("pubtypes"))
570 sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
571 break;
572
573 case 's':
574 if (dwarf_name.equals("str"))
575 sect_type = lldb::eSectionTypeDWARFDebugStr;
576 else if (dwarf_name.equals("str_offsets"))
577 sect_type = lldb::eSectionTypeDWARFDebugStrOffsets;
578 break;
579
580 case 'r':
581 if (dwarf_name.equals("ranges"))
582 sect_type = lldb::eSectionTypeDWARFDebugRanges;
583 break;
584
585 default:
586 break;
587 }
588 } else if (name.startswith("__apple_") || name.startswith(".apple_")) {
Greg Clayton23f8c952014-03-24 23:10:19 +0000589#if 0
590 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
591 llvm::StringRef apple_name(name.substr(name_idx));
592 switch (apple_name[0])
593 {
594 case 'n':
595 if (apple_name.equals("names"))
596 sect_type = lldb::eSectionTypeDWARFAppleNames;
597 else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
598 sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
599 break;
600 case 't':
601 if (apple_name.equals("types"))
602 sect_type = lldb::eSectionTypeDWARFAppleTypes;
603 break;
604 case 'o':
605 if (apple_name.equals("objc"))
606 sect_type = lldb::eSectionTypeDWARFAppleObjC;
607 break;
608 default:
609 break;
610 }
611#else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000612 sect_type = lldb::eSectionTypeInvalid;
Greg Clayton23f8c952014-03-24 23:10:19 +0000613#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000614 } else if (name.equals("__objc_imageinfo"))
615 sect_type = lldb::eSectionTypeOther;
616 }
617 return sect_type;
Greg Clayton23f8c952014-03-24 23:10:19 +0000618}
619
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620uint8_t *IRExecutionUnit::MemoryManager::allocateCodeSection(
621 uintptr_t Size, unsigned Alignment, unsigned SectionID,
622 llvm::StringRef SectionName) {
623 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000624
Kate Stoneb9c1b512016-09-06 20:57:50 +0000625 uint8_t *return_value = m_default_mm_ap->allocateCodeSection(
626 Size, Alignment, SectionID, SectionName);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628 m_parent.m_records.push_back(AllocationRecord(
629 (uintptr_t)return_value,
630 lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
631 GetSectionTypeFromSectionName(SectionName, AllocationKind::Code), Size,
632 Alignment, SectionID, SectionName.str().c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000633
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634 if (log) {
635 log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64
636 ", Alignment=%u, SectionID=%u) = %p",
637 (uint64_t)Size, Alignment, SectionID, (void *)return_value);
638 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000639
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 if (m_parent.m_reported_allocations) {
Zachary Turner97206d52017-05-12 04:51:55 +0000641 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642 lldb::ProcessSP process_sp =
643 m_parent.GetBestExecutionContextScope()->CalculateProcess();
644
645 m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
646 }
647
648 return return_value;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000649}
650
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651uint8_t *IRExecutionUnit::MemoryManager::allocateDataSection(
652 uintptr_t Size, unsigned Alignment, unsigned SectionID,
653 llvm::StringRef SectionName, bool IsReadOnly) {
654 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000655
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 uint8_t *return_value = m_default_mm_ap->allocateDataSection(
657 Size, Alignment, SectionID, SectionName, IsReadOnly);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000658
Kate Stoneb9c1b512016-09-06 20:57:50 +0000659 uint32_t permissions = lldb::ePermissionsReadable;
660 if (!IsReadOnly)
661 permissions |= lldb::ePermissionsWritable;
662 m_parent.m_records.push_back(AllocationRecord(
663 (uintptr_t)return_value, permissions,
664 GetSectionTypeFromSectionName(SectionName, AllocationKind::Data), Size,
665 Alignment, SectionID, SectionName.str().c_str()));
666 if (log) {
667 log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64
668 ", Alignment=%u, SectionID=%u) = %p",
669 (uint64_t)Size, Alignment, SectionID, (void *)return_value);
670 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000671
Kate Stoneb9c1b512016-09-06 20:57:50 +0000672 if (m_parent.m_reported_allocations) {
Zachary Turner97206d52017-05-12 04:51:55 +0000673 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 lldb::ProcessSP process_sp =
675 m_parent.GetBestExecutionContextScope()->CalculateProcess();
676
677 m_parent.CommitOneAllocation(process_sp, err, m_parent.m_records.back());
678 }
679
680 return return_value;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000681}
682
Sean Callananb2814802016-02-12 21:11:25 +0000683static ConstString
684FindBestAlternateMangledName(const ConstString &demangled,
685 const lldb::LanguageType &lang_type,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000686 const SymbolContext &sym_ctx) {
687 CPlusPlusLanguage::MethodName cpp_name(demangled);
688 std::string scope_qualified_name = cpp_name.GetScopeQualifiedName();
Sean Callananb2814802016-02-12 21:11:25 +0000689
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 if (!scope_qualified_name.size())
691 return ConstString();
Sean Callananb2814802016-02-12 21:11:25 +0000692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693 if (!sym_ctx.module_sp)
694 return ConstString();
Sean Callananb2814802016-02-12 21:11:25 +0000695
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor();
697 if (!sym_vendor)
698 return ConstString();
Sean Callananb2814802016-02-12 21:11:25 +0000699
Kate Stoneb9c1b512016-09-06 20:57:50 +0000700 lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile();
701 if (!sym_file)
702 return ConstString();
Sean Callananb2814802016-02-12 21:11:25 +0000703
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704 std::vector<ConstString> alternates;
705 sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates);
Sean Callananb2814802016-02-12 21:11:25 +0000706
Kate Stoneb9c1b512016-09-06 20:57:50 +0000707 std::vector<ConstString> param_and_qual_matches;
708 std::vector<ConstString> param_matches;
709 for (size_t i = 0; i < alternates.size(); i++) {
710 ConstString alternate_mangled_name = alternates[i];
711 Mangled mangled(alternate_mangled_name, true);
712 ConstString demangled = mangled.GetDemangledName(lang_type);
Sean Callananb2814802016-02-12 21:11:25 +0000713
Kate Stoneb9c1b512016-09-06 20:57:50 +0000714 CPlusPlusLanguage::MethodName alternate_cpp_name(demangled);
715 if (!cpp_name.IsValid())
716 continue;
Sean Callananb2814802016-02-12 21:11:25 +0000717
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718 if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) {
719 if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers())
720 param_and_qual_matches.push_back(alternate_mangled_name);
721 else
722 param_matches.push_back(alternate_mangled_name);
Sean Callananb2814802016-02-12 21:11:25 +0000723 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000724 }
Sean Callananb2814802016-02-12 21:11:25 +0000725
Kate Stoneb9c1b512016-09-06 20:57:50 +0000726 if (param_and_qual_matches.size())
727 return param_and_qual_matches[0]; // It is assumed that there will be only
728 // one!
729 else if (param_matches.size())
730 return param_matches[0]; // Return one of them as a best match
731 else
732 return ConstString();
Sean Callananb2814802016-02-12 21:11:25 +0000733}
734
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735struct IRExecutionUnit::SearchSpec {
736 ConstString name;
737 uint32_t mask;
Sean Callananb2814802016-02-12 21:11:25 +0000738
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeFull)
740 : name(n), mask(m) {}
Sean Callananb2814802016-02-12 21:11:25 +0000741};
742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743void IRExecutionUnit::CollectCandidateCNames(
744 std::vector<IRExecutionUnit::SearchSpec> &C_specs,
745 const ConstString &name) {
746 if (m_strip_underscore && name.AsCString()[0] == '_')
747 C_specs.insert(C_specs.begin(), ConstString(&name.AsCString()[1]));
748 C_specs.push_back(SearchSpec(name));
Sean Callananb2814802016-02-12 21:11:25 +0000749}
750
Kate Stoneb9c1b512016-09-06 20:57:50 +0000751void IRExecutionUnit::CollectCandidateCPlusPlusNames(
752 std::vector<IRExecutionUnit::SearchSpec> &CPP_specs,
753 const std::vector<SearchSpec> &C_specs, const SymbolContext &sc) {
754 for (const SearchSpec &C_spec : C_specs) {
755 const ConstString &name = C_spec.name;
Sean Callananb2814802016-02-12 21:11:25 +0000756
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757 if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
758 Mangled mangled(name, true);
759 ConstString demangled =
760 mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
Chaoren Lin74a1fc62016-02-24 03:15:21 +0000761
Kate Stoneb9c1b512016-09-06 20:57:50 +0000762 if (demangled) {
763 ConstString best_alternate_mangled_name = FindBestAlternateMangledName(
764 demangled, lldb::eLanguageTypeC_plus_plus, sc);
Chaoren Lin74a1fc62016-02-24 03:15:21 +0000765
Kate Stoneb9c1b512016-09-06 20:57:50 +0000766 if (best_alternate_mangled_name) {
767 CPP_specs.push_back(best_alternate_mangled_name);
Sean Callananb2814802016-02-12 21:11:25 +0000768 }
Chaoren Lin74a1fc62016-02-24 03:15:21 +0000769
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 CPP_specs.push_back(SearchSpec(demangled, lldb::eFunctionNameTypeFull));
771 }
Sean Callananb2814802016-02-12 21:11:25 +0000772 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773
Luke Drummondf5bb1d62016-12-19 17:22:44 +0000774 std::set<ConstString> alternates;
775 CPlusPlusLanguage::FindAlternateFunctionManglings(name, alternates);
776 CPP_specs.insert(CPP_specs.end(), alternates.begin(), alternates.end());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 }
Sean Callananb2814802016-02-12 21:11:25 +0000778}
779
Kate Stoneb9c1b512016-09-06 20:57:50 +0000780void IRExecutionUnit::CollectFallbackNames(
781 std::vector<SearchSpec> &fallback_specs,
782 const std::vector<SearchSpec> &C_specs) {
783 // As a last-ditch fallback, try the base name for C++ names. It's terrible,
784 // but the DWARF doesn't always encode "extern C" correctly.
785
786 for (const SearchSpec &C_spec : C_specs) {
787 const ConstString &name = C_spec.name;
788
789 if (CPlusPlusLanguage::IsCPPMangledName(name.GetCString())) {
790 Mangled mangled_name(name);
791 ConstString demangled_name =
792 mangled_name.GetDemangledName(lldb::eLanguageTypeC_plus_plus);
793 if (!demangled_name.IsEmpty()) {
794 const char *demangled_cstr = demangled_name.AsCString();
795 const char *lparen_loc = strchr(demangled_cstr, '(');
796 if (lparen_loc) {
797 llvm::StringRef base_name(demangled_cstr,
798 lparen_loc - demangled_cstr);
799 fallback_specs.push_back(ConstString(base_name));
Sean Callanan34ab28a2016-06-02 17:59:47 +0000800 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000801 }
Sean Callanan34ab28a2016-06-02 17:59:47 +0000802 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000803 }
Sean Callanan34ab28a2016-06-02 17:59:47 +0000804}
805
Kate Stoneb9c1b512016-09-06 20:57:50 +0000806lldb::addr_t IRExecutionUnit::FindInSymbols(
807 const std::vector<IRExecutionUnit::SearchSpec> &specs,
808 const lldb_private::SymbolContext &sc) {
809 Target *target = sc.target_sp.get();
Sean Callanan34ab28a2016-06-02 17:59:47 +0000810
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 if (!target) {
812 // we shouldn't be doing any symbol lookup at all without a target
813 return LLDB_INVALID_ADDRESS;
814 }
Sean Callananfed0e7582016-02-23 23:09:06 +0000815
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 for (const SearchSpec &spec : specs) {
817 SymbolContextList sc_list;
Sean Callananfed0e7582016-02-23 23:09:06 +0000818
Kate Stoneb9c1b512016-09-06 20:57:50 +0000819 lldb::addr_t best_internal_load_address = LLDB_INVALID_ADDRESS;
Sean Callananfed0e7582016-02-23 23:09:06 +0000820
Kate Stoneb9c1b512016-09-06 20:57:50 +0000821 std::function<bool(lldb::addr_t &, SymbolContextList &,
822 const lldb_private::SymbolContext &)>
823 get_external_load_address = [&best_internal_load_address, target](
824 lldb::addr_t &load_address, SymbolContextList &sc_list,
825 const lldb_private::SymbolContext &sc) -> lldb::addr_t {
826 load_address = LLDB_INVALID_ADDRESS;
Sean Callananfed0e7582016-02-23 23:09:06 +0000827
Kate Stoneb9c1b512016-09-06 20:57:50 +0000828 for (size_t si = 0, se = sc_list.GetSize(); si < se; ++si) {
829 SymbolContext candidate_sc;
830
831 sc_list.GetContextAtIndex(si, candidate_sc);
832
833 const bool is_external =
834 (candidate_sc.function) ||
835 (candidate_sc.symbol && candidate_sc.symbol->IsExternal());
836 if (candidate_sc.symbol) {
837 load_address = candidate_sc.symbol->ResolveCallableAddress(*target);
838
839 if (load_address == LLDB_INVALID_ADDRESS) {
840 if (target->GetProcessSP())
841 load_address =
842 candidate_sc.symbol->GetAddress().GetLoadAddress(target);
843 else
844 load_address = candidate_sc.symbol->GetAddress().GetFileAddress();
845 }
846 }
847
848 if (load_address == LLDB_INVALID_ADDRESS && candidate_sc.function) {
849 if (target->GetProcessSP())
850 load_address = candidate_sc.function->GetAddressRange()
851 .GetBaseAddress()
852 .GetLoadAddress(target);
853 else
854 load_address = candidate_sc.function->GetAddressRange()
855 .GetBaseAddress()
856 .GetFileAddress();
857 }
858
859 if (load_address != LLDB_INVALID_ADDRESS) {
860 if (is_external) {
861 return true;
862 } else if (best_internal_load_address == LLDB_INVALID_ADDRESS) {
863 best_internal_load_address = load_address;
Sean Callananfed0e7582016-02-23 23:09:06 +0000864 load_address = LLDB_INVALID_ADDRESS;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 }
866 }
867 }
Sean Callananfed0e7582016-02-23 23:09:06 +0000868
Kate Stoneb9c1b512016-09-06 20:57:50 +0000869 return false;
870 };
Sean Callananfed0e7582016-02-23 23:09:06 +0000871
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 if (sc.module_sp) {
873 sc.module_sp->FindFunctions(spec.name, NULL, spec.mask,
874 true, // include_symbols
875 false, // include_inlines
876 true, // append
877 sc_list);
878 }
Sean Callananfed0e7582016-02-23 23:09:06 +0000879
Kate Stoneb9c1b512016-09-06 20:57:50 +0000880 lldb::addr_t load_address = LLDB_INVALID_ADDRESS;
Ted Woodwardeee554d2016-03-09 22:05:17 +0000881
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 if (get_external_load_address(load_address, sc_list, sc)) {
883 return load_address;
884 } else {
885 sc_list.Clear();
886 }
887
888 if (sc_list.GetSize() == 0 && sc.target_sp) {
889 sc.target_sp->GetImages().FindFunctions(spec.name, spec.mask,
890 true, // include_symbols
891 false, // include_inlines
892 true, // append
893 sc_list);
894 }
895
896 if (get_external_load_address(load_address, sc_list, sc)) {
897 return load_address;
898 } else {
899 sc_list.Clear();
900 }
901
902 if (sc_list.GetSize() == 0 && sc.target_sp) {
903 sc.target_sp->GetImages().FindSymbolsWithNameAndType(
904 spec.name, lldb::eSymbolTypeAny, sc_list);
905 }
906
907 if (get_external_load_address(load_address, sc_list, sc)) {
908 return load_address;
909 }
910 // if there are any searches we try after this, add an sc_list.Clear() in an
911 // "else" clause here
912
913 if (best_internal_load_address != LLDB_INVALID_ADDRESS) {
914 return best_internal_load_address;
915 }
916 }
917
918 return LLDB_INVALID_ADDRESS;
919}
920
921lldb::addr_t
922IRExecutionUnit::FindInRuntimes(const std::vector<SearchSpec> &specs,
923 const lldb_private::SymbolContext &sc) {
924 lldb::TargetSP target_sp = sc.target_sp;
925
926 if (!target_sp) {
927 return LLDB_INVALID_ADDRESS;
928 }
929
930 lldb::ProcessSP process_sp = sc.target_sp->GetProcessSP();
931
932 if (!process_sp) {
933 return LLDB_INVALID_ADDRESS;
934 }
935
936 ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
937
938 if (runtime) {
939 for (const SearchSpec &spec : specs) {
940 lldb::addr_t symbol_load_addr = runtime->LookupRuntimeSymbol(spec.name);
941
942 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
943 return symbol_load_addr;
944 }
945 }
946
947 return LLDB_INVALID_ADDRESS;
948}
949
950lldb::addr_t IRExecutionUnit::FindInUserDefinedSymbols(
951 const std::vector<SearchSpec> &specs,
952 const lldb_private::SymbolContext &sc) {
953 lldb::TargetSP target_sp = sc.target_sp;
954
955 for (const SearchSpec &spec : specs) {
956 lldb::addr_t symbol_load_addr = target_sp->GetPersistentSymbol(spec.name);
957
958 if (symbol_load_addr != LLDB_INVALID_ADDRESS)
959 return symbol_load_addr;
960 }
961
962 return LLDB_INVALID_ADDRESS;
963}
964
965lldb::addr_t
966IRExecutionUnit::FindSymbol(const lldb_private::ConstString &name) {
967 std::vector<SearchSpec> candidate_C_names;
968 std::vector<SearchSpec> candidate_CPlusPlus_names;
969
970 CollectCandidateCNames(candidate_C_names, name);
971
972 lldb::addr_t ret = FindInSymbols(candidate_C_names, m_sym_ctx);
973 if (ret == LLDB_INVALID_ADDRESS)
974 ret = FindInRuntimes(candidate_C_names, m_sym_ctx);
975
976 if (ret == LLDB_INVALID_ADDRESS)
977 ret = FindInUserDefinedSymbols(candidate_C_names, m_sym_ctx);
978
979 if (ret == LLDB_INVALID_ADDRESS) {
980 CollectCandidateCPlusPlusNames(candidate_CPlusPlus_names, candidate_C_names,
981 m_sym_ctx);
982 ret = FindInSymbols(candidate_CPlusPlus_names, m_sym_ctx);
983 }
984
985 if (ret == LLDB_INVALID_ADDRESS) {
986 std::vector<SearchSpec> candidate_fallback_names;
987
988 CollectFallbackNames(candidate_fallback_names, candidate_C_names);
989 ret = FindInSymbols(candidate_fallback_names, m_sym_ctx);
990 }
991
992 return ret;
993}
994
995void IRExecutionUnit::GetStaticInitializers(
996 std::vector<lldb::addr_t> &static_initializers) {
997 if (llvm::GlobalVariable *global_ctors =
998 m_module->getNamedGlobal("llvm.global_ctors")) {
999 if (llvm::ConstantArray *ctor_array = llvm::dyn_cast<llvm::ConstantArray>(
1000 global_ctors->getInitializer())) {
1001 for (llvm::Use &ctor_use : ctor_array->operands()) {
1002 if (llvm::ConstantStruct *ctor_struct =
1003 llvm::dyn_cast<llvm::ConstantStruct>(ctor_use)) {
1004 lldbassert(ctor_struct->getNumOperands() ==
1005 3); // this is standardized
1006 if (llvm::Function *ctor_function =
1007 llvm::dyn_cast<llvm::Function>(ctor_struct->getOperand(1))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 ConstString ctor_function_name_cs(ctor_function->getName().str());
1009
1010 for (JittedFunction &jitted_function : m_jitted_functions) {
1011 if (ctor_function_name_cs == jitted_function.m_name) {
1012 if (jitted_function.m_remote_addr != LLDB_INVALID_ADDRESS) {
1013 static_initializers.push_back(jitted_function.m_remote_addr);
Ted Woodwardeee554d2016-03-09 22:05:17 +00001014 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 break;
1016 }
Sean Callananfed0e7582016-02-23 23:09:06 +00001017 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 }
Sean Callananb2814802016-02-12 21:11:25 +00001019 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020 }
Sean Callananb2814802016-02-12 21:11:25 +00001021 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 }
Sean Callananbd4dc692016-03-21 22:23:38 +00001023}
1024
Jim Ingham27e5fe82015-01-27 18:03:05 +00001025uint64_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001026IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) {
1027 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Greg Claytond6171a72015-07-02 16:43:49 +00001028
Kate Stoneb9c1b512016-09-06 20:57:50 +00001029 ConstString name_cs(Name.c_str());
Chaoren Lin74a1fc62016-02-24 03:15:21 +00001030
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 lldb::addr_t ret = m_parent.FindSymbol(name_cs);
Chaoren Lin74a1fc62016-02-24 03:15:21 +00001032
Kate Stoneb9c1b512016-09-06 20:57:50 +00001033 if (ret == LLDB_INVALID_ADDRESS) {
1034 if (log)
1035 log->Printf(
1036 "IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
1037 Name.c_str());
Sean Callananb2814802016-02-12 21:11:25 +00001038
Kate Stoneb9c1b512016-09-06 20:57:50 +00001039 m_parent.ReportSymbolLookupError(name_cs);
1040 return 0xbad0bad0;
1041 } else {
1042 if (log)
1043 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
1044 Name.c_str(), ret);
1045 return ret;
1046 }
Jim Ingham27e5fe82015-01-27 18:03:05 +00001047}
1048
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049void *IRExecutionUnit::MemoryManager::getPointerToNamedFunction(
1050 const std::string &Name, bool AbortOnFailure) {
1051 assert(sizeof(void *) == 8);
Chaoren Lin74a1fc62016-02-24 03:15:21 +00001052
Kate Stoneb9c1b512016-09-06 20:57:50 +00001053 return (void *)getSymbolAddress(Name);
Jim Ingham27e5fe82015-01-27 18:03:05 +00001054}
1055
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001056lldb::addr_t
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057IRExecutionUnit::GetRemoteAddressForLocal(lldb::addr_t local_address) {
1058 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callananffae9442013-06-27 01:42:47 +00001059
Kate Stoneb9c1b512016-09-06 20:57:50 +00001060 for (AllocationRecord &record : m_records) {
1061 if (local_address >= record.m_host_address &&
1062 local_address < record.m_host_address + record.m_size) {
1063 if (record.m_process_address == LLDB_INVALID_ADDRESS)
1064 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001065
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066 lldb::addr_t ret =
1067 record.m_process_address + (local_address - record.m_host_address);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001068
Kate Stoneb9c1b512016-09-06 20:57:50 +00001069 if (log) {
1070 log->Printf(
1071 "IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64
1072 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64
1073 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
1074 local_address, (uint64_t)record.m_host_address,
1075 (uint64_t)record.m_host_address + (uint64_t)record.m_size, ret,
1076 record.m_process_address, record.m_process_address + record.m_size);
1077 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001078
Kate Stoneb9c1b512016-09-06 20:57:50 +00001079 return ret;
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001080 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001082
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 return LLDB_INVALID_ADDRESS;
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001084}
1085
1086IRExecutionUnit::AddrRange
Kate Stoneb9c1b512016-09-06 20:57:50 +00001087IRExecutionUnit::GetRemoteRangeForLocal(lldb::addr_t local_address) {
1088 for (AllocationRecord &record : m_records) {
1089 if (local_address >= record.m_host_address &&
1090 local_address < record.m_host_address + record.m_size) {
1091 if (record.m_process_address == LLDB_INVALID_ADDRESS)
1092 return AddrRange(0, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001093
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 return AddrRange(record.m_process_address, record.m_size);
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001095 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001097
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098 return AddrRange(0, 0);
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001099}
1100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101bool IRExecutionUnit::CommitOneAllocation(lldb::ProcessSP &process_sp,
Zachary Turner97206d52017-05-12 04:51:55 +00001102 Status &error,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001103 AllocationRecord &record) {
1104 if (record.m_process_address != LLDB_INVALID_ADDRESS) {
1105 return true;
1106 }
1107
1108 switch (record.m_sect_type) {
1109 case lldb::eSectionTypeInvalid:
1110 case lldb::eSectionTypeDWARFDebugAbbrev:
1111 case lldb::eSectionTypeDWARFDebugAddr:
1112 case lldb::eSectionTypeDWARFDebugAranges:
Tamas Berghammer963ce482017-08-25 13:56:14 +00001113 case lldb::eSectionTypeDWARFDebugCuIndex:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114 case lldb::eSectionTypeDWARFDebugFrame:
1115 case lldb::eSectionTypeDWARFDebugInfo:
1116 case lldb::eSectionTypeDWARFDebugLine:
1117 case lldb::eSectionTypeDWARFDebugLoc:
1118 case lldb::eSectionTypeDWARFDebugMacInfo:
1119 case lldb::eSectionTypeDWARFDebugPubNames:
1120 case lldb::eSectionTypeDWARFDebugPubTypes:
1121 case lldb::eSectionTypeDWARFDebugRanges:
1122 case lldb::eSectionTypeDWARFDebugStr:
1123 case lldb::eSectionTypeDWARFDebugStrOffsets:
1124 case lldb::eSectionTypeDWARFAppleNames:
1125 case lldb::eSectionTypeDWARFAppleTypes:
1126 case lldb::eSectionTypeDWARFAppleNamespaces:
1127 case lldb::eSectionTypeDWARFAppleObjC:
1128 error.Clear();
1129 break;
1130 default:
1131 const bool zero_memory = false;
1132 record.m_process_address =
1133 Malloc(record.m_size, record.m_alignment, record.m_permissions,
1134 eAllocationPolicyProcessOnly, zero_memory, error);
1135 break;
1136 }
1137
1138 return error.Success();
1139}
1140
1141bool IRExecutionUnit::CommitAllocations(lldb::ProcessSP &process_sp) {
1142 bool ret = true;
1143
Zachary Turner97206d52017-05-12 04:51:55 +00001144 lldb_private::Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145
1146 for (AllocationRecord &record : m_records) {
1147 ret = CommitOneAllocation(process_sp, err, record);
1148
1149 if (!ret) {
1150 break;
Sean Callananbd4dc692016-03-21 22:23:38 +00001151 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 }
1153
1154 if (!ret) {
1155 for (AllocationRecord &record : m_records) {
1156 if (record.m_process_address != LLDB_INVALID_ADDRESS) {
1157 Free(record.m_process_address, err);
1158 record.m_process_address = LLDB_INVALID_ADDRESS;
1159 }
Sean Callananbd4dc692016-03-21 22:23:38 +00001160 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001161 }
1162
1163 return ret;
Sean Callananbd4dc692016-03-21 22:23:38 +00001164}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001165
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166void IRExecutionUnit::ReportAllocations(llvm::ExecutionEngine &engine) {
1167 m_reported_allocations = true;
Sean Callananbd4dc692016-03-21 22:23:38 +00001168
Kate Stoneb9c1b512016-09-06 20:57:50 +00001169 for (AllocationRecord &record : m_records) {
1170 if (record.m_process_address == LLDB_INVALID_ADDRESS)
1171 continue;
Sean Callananbd4dc692016-03-21 22:23:38 +00001172
Kate Stoneb9c1b512016-09-06 20:57:50 +00001173 if (record.m_section_id == eSectionIDInvalid)
1174 continue;
1175
1176 engine.mapSectionAddress((void *)record.m_host_address,
1177 record.m_process_address);
1178 }
1179
1180 // Trigger re-application of relocations.
1181 engine.finalizeObject();
1182}
1183
1184bool IRExecutionUnit::WriteData(lldb::ProcessSP &process_sp) {
1185 bool wrote_something = false;
1186 for (AllocationRecord &record : m_records) {
1187 if (record.m_process_address != LLDB_INVALID_ADDRESS) {
Zachary Turner97206d52017-05-12 04:51:55 +00001188 lldb_private::Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189 WriteMemory(record.m_process_address, (uint8_t *)record.m_host_address,
1190 record.m_size, err);
1191 if (err.Success())
1192 wrote_something = true;
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001193 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001194 }
1195 return wrote_something;
1196}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001197
Kate Stoneb9c1b512016-09-06 20:57:50 +00001198void IRExecutionUnit::AllocationRecord::dump(Log *log) {
1199 if (!log)
1200 return;
1201
1202 log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d, name %s)",
1203 (unsigned long long)m_host_address, (unsigned long long)m_size,
1204 (unsigned long long)m_process_address, (unsigned)m_alignment,
1205 (unsigned)m_section_id, m_name.c_str());
1206}
1207
1208lldb::ByteOrder IRExecutionUnit::GetByteOrder() const {
1209 ExecutionContext exe_ctx(GetBestExecutionContextScope());
1210 return exe_ctx.GetByteOrder();
1211}
1212
1213uint32_t IRExecutionUnit::GetAddressByteSize() const {
1214 ExecutionContext exe_ctx(GetBestExecutionContextScope());
1215 return exe_ctx.GetAddressByteSize();
1216}
1217
1218void IRExecutionUnit::PopulateSymtab(lldb_private::ObjectFile *obj_file,
1219 lldb_private::Symtab &symtab) {
1220 // No symbols yet...
1221}
1222
1223void IRExecutionUnit::PopulateSectionList(
1224 lldb_private::ObjectFile *obj_file,
1225 lldb_private::SectionList &section_list) {
1226 for (AllocationRecord &record : m_records) {
1227 if (record.m_size > 0) {
1228 lldb::SectionSP section_sp(new lldb_private::Section(
1229 obj_file->GetModule(), obj_file, record.m_section_id,
1230 ConstString(record.m_name), record.m_sect_type,
1231 record.m_process_address, record.m_size,
1232 record.m_host_address, // file_offset (which is the host address for
1233 // the data)
1234 record.m_size, // file_size
1235 0,
1236 record.m_permissions)); // flags
1237 section_list.AddSection(section_sp);
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001238 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001239 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001240}
1241
Kate Stoneb9c1b512016-09-06 20:57:50 +00001242bool IRExecutionUnit::GetArchitecture(lldb_private::ArchSpec &arch) {
1243 ExecutionContext exe_ctx(GetBestExecutionContextScope());
1244 Target *target = exe_ctx.GetTargetPtr();
1245 if (target)
1246 arch = target->GetArchitecture();
1247 else
1248 arch.Clear();
1249 return arch.IsValid();
1250}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001251
Kate Stoneb9c1b512016-09-06 20:57:50 +00001252lldb::ModuleSP IRExecutionUnit::GetJITModule() {
1253 ExecutionContext exe_ctx(GetBestExecutionContextScope());
1254 Target *target = exe_ctx.GetTargetPtr();
1255 if (target) {
1256 lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule(
1257 std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(
1258 shared_from_this()));
1259 if (jit_module_sp) {
1260 bool changed = false;
1261 jit_module_sp->SetLoadAddress(*target, 0, true, changed);
Sean Callanan8dfb68e2013-03-19 00:10:07 +00001262 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001263 return jit_module_sp;
1264 }
1265 return lldb::ModuleSP();
Greg Clayton23f8c952014-03-24 23:10:19 +00001266}