blob: 9ca9e25907b67d699f64c54b3c8194ef6ab76a3a [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"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000014#include "lldb/Core/DataBufferHeap.h"
15#include "lldb/Core/DataExtractor.h"
Jason Molendaaff1b352014-10-10 23:07:36 +000016#include "lldb/Core/Debugger.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000017#include "lldb/Core/Disassembler.h"
18#include "lldb/Core/Log.h"
Greg Clayton23f8c952014-03-24 23:10:19 +000019#include "lldb/Core/Module.h"
20#include "lldb/Core/Section.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000021#include "lldb/Expression/IRExecutionUnit.h"
22#include "lldb/Target/ExecutionContext.h"
23#include "lldb/Target/Target.h"
24
25using namespace lldb_private;
26
Greg Clayton7b0992d2013-04-18 22:45:39 +000027IRExecutionUnit::IRExecutionUnit (std::unique_ptr<llvm::LLVMContext> &context_ap,
28 std::unique_ptr<llvm::Module> &module_ap,
Sean Callanan8dfb68e2013-03-19 00:10:07 +000029 ConstString &name,
Sean Callananb024d872013-04-15 17:12:47 +000030 const lldb::TargetSP &target_sp,
Sean Callanan8dfb68e2013-03-19 00:10:07 +000031 std::vector<std::string> &cpu_features) :
Sean Callananb024d872013-04-15 17:12:47 +000032 IRMemoryMap(target_sp),
Greg Claytone01e07b2013-04-18 18:10:51 +000033 m_context_ap(context_ap.release()),
34 m_module_ap(module_ap.release()),
Sean Callanan8dfb68e2013-03-19 00:10:07 +000035 m_module(m_module_ap.get()),
Sean Callanan2c047352013-03-19 23:03:21 +000036 m_cpu_features(cpu_features),
Sean Callanan8dfb68e2013-03-19 00:10:07 +000037 m_name(name),
38 m_did_jit(false),
39 m_function_load_addr(LLDB_INVALID_ADDRESS),
40 m_function_end_load_addr(LLDB_INVALID_ADDRESS)
41{
Sean Callanan8dfb68e2013-03-19 00:10:07 +000042}
43
44lldb::addr_t
45IRExecutionUnit::WriteNow (const uint8_t *bytes,
46 size_t size,
47 Error &error)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000048{
Sean Callanan5a1af4e2013-04-05 02:22:57 +000049 lldb::addr_t allocation_process_addr = Malloc (size,
50 8,
51 lldb::ePermissionsWritable | lldb::ePermissionsReadable,
52 eAllocationPolicyMirror,
53 error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000054
Sean Callanan5a1af4e2013-04-05 02:22:57 +000055 if (!error.Success())
56 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000057
Sean Callanan5a1af4e2013-04-05 02:22:57 +000058 WriteMemory(allocation_process_addr, bytes, size, error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000059
Sean Callanan5a1af4e2013-04-05 02:22:57 +000060 if (!error.Success())
61 {
62 Error err;
63 Free (allocation_process_addr, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000064
Sean Callanan5a1af4e2013-04-05 02:22:57 +000065 return LLDB_INVALID_ADDRESS;
66 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000067
Sean Callanan5a1af4e2013-04-05 02:22:57 +000068 if (Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
69 {
70 DataBufferHeap my_buffer(size, 0);
71 Error err;
72 ReadMemory(my_buffer.GetBytes(), allocation_process_addr, size, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000073
Sean Callanan5a1af4e2013-04-05 02:22:57 +000074 if (err.Success())
75 {
76 DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
Sean Callanan4f2c1982014-01-21 00:54:48 +000077 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), allocation_process_addr, 16, DataExtractor::TypeUInt8);
Sean Callanan5a1af4e2013-04-05 02:22:57 +000078 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +000079 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000080
Sean Callanan5a1af4e2013-04-05 02:22:57 +000081 return allocation_process_addr;
Sean Callanan8dfb68e2013-03-19 00:10:07 +000082}
83
84void
85IRExecutionUnit::FreeNow (lldb::addr_t allocation)
86{
Sean Callanan8dfb68e2013-03-19 00:10:07 +000087 if (allocation == LLDB_INVALID_ADDRESS)
88 return;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000089
Sean Callanan5a1af4e2013-04-05 02:22:57 +000090 Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000091
Sean Callanan5a1af4e2013-04-05 02:22:57 +000092 Free(allocation, err);
Sean Callanan8dfb68e2013-03-19 00:10:07 +000093}
94
95Error
96IRExecutionUnit::DisassembleFunction (Stream &stream,
97 lldb::ProcessSP &process_wp)
98{
Greg Clayton5160ce52013-03-27 23:08:40 +000099 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000100
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000101 ExecutionContext exe_ctx(process_wp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000102
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000103 Error ret;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000104
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000105 ret.Clear();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000106
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000107 lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
108 lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000109
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000110 for (JittedFunction &function : m_jitted_functions)
111 {
112 if (strstr(function.m_name.c_str(), m_name.AsCString()))
113 {
114 func_local_addr = function.m_local_addr;
115 func_remote_addr = function.m_remote_addr;
116 }
117 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000118
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000119 if (func_local_addr == LLDB_INVALID_ADDRESS)
120 {
121 ret.SetErrorToGenericError();
122 ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
123 return ret;
124 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000125
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000126 if (log)
127 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 +0000128
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000129 std::pair <lldb::addr_t, lldb::addr_t> func_range;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000130
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000131 func_range = GetRemoteRangeForLocal(func_local_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000132
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000133 if (func_range.first == 0 && func_range.second == 0)
134 {
135 ret.SetErrorToGenericError();
136 ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
137 return ret;
138 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000139
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000140 if (log)
141 log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000142
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000143 Target *target = exe_ctx.GetTargetPtr();
144 if (!target)
145 {
146 ret.SetErrorToGenericError();
147 ret.SetErrorString("Couldn't find the target");
148 return ret;
149 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000150
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000151 lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000152
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000153 Process *process = exe_ctx.GetProcessPtr();
154 Error err;
155 process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000156
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000157 if (!err.Success())
158 {
159 ret.SetErrorToGenericError();
160 ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
161 return ret;
162 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000163
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000164 ArchSpec arch(target->GetArchitecture());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000165
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000166 const char *plugin_name = NULL;
167 const char *flavor_string = NULL;
Jim Ingham56d40422013-07-31 02:19:15 +0000168 lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000169
Jim Ingham56d40422013-07-31 02:19:15 +0000170 if (!disassembler_sp)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000171 {
172 ret.SetErrorToGenericError();
173 ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
174 return ret;
175 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000176
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000177 if (!process)
178 {
179 ret.SetErrorToGenericError();
180 ret.SetErrorString("Couldn't find the process");
181 return ret;
182 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000183
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000184 DataExtractor extractor(buffer_sp,
185 process->GetByteOrder(),
186 target->GetArchitecture().GetAddressByteSize());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000187
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000188 if (log)
189 {
190 log->Printf("Function data has contents:");
Greg Clayton5160ce52013-03-27 23:08:40 +0000191 extractor.PutToLog (log,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000192 0,
193 extractor.GetByteSize(),
194 func_remote_addr,
195 16,
196 DataExtractor::TypeUInt8);
197 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000198
Jim Ingham56d40422013-07-31 02:19:15 +0000199 disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000200
Jim Ingham56d40422013-07-31 02:19:15 +0000201 InstructionList &instruction_list = disassembler_sp->GetInstructionList();
Greg Clayton554f68d2015-02-04 22:00:53 +0000202 instruction_list.Dump(&stream, true, true, &exe_ctx);
203
Jim Ingham56d40422013-07-31 02:19:15 +0000204 // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
205 // I'll fix that but for now, just clear the list and it will go away nicely.
206 disassembler_sp->GetInstructionList().Clear();
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000207 return ret;
208}
209
Sean Callanan44bc6572013-03-27 03:09:55 +0000210static void ReportInlineAsmError(const llvm::SMDiagnostic &diagnostic, void *Context, unsigned LocCookie)
211{
212 Error *err = static_cast<Error*>(Context);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000213
Sean Callanan44bc6572013-03-27 03:09:55 +0000214 if (err && err->Success())
215 {
216 err->SetErrorToGenericError();
217 err->SetErrorStringWithFormat("Inline assembly error: %s", diagnostic.getMessage().str().c_str());
218 }
219}
220
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000221void
Jim Ingham27e5fe82015-01-27 18:03:05 +0000222IRExecutionUnit::ReportSymbolLookupError(const ConstString &name)
223{
224 m_failed_lookups.push_back(name);
225}
226
227void
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000228IRExecutionUnit::GetRunnableInfo(Error &error,
229 lldb::addr_t &func_addr,
230 lldb::addr_t &func_end)
231{
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000232 lldb::ProcessSP process_sp(GetProcessWP().lock());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000233
Sean Callanan7c435a52014-02-06 22:25:20 +0000234 static Mutex s_runnable_info_mutex(Mutex::Type::eMutexTypeRecursive);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000235
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000236 func_addr = LLDB_INVALID_ADDRESS;
237 func_end = LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000238
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000239 if (!process_sp)
240 {
241 error.SetErrorToGenericError();
242 error.SetErrorString("Couldn't write the JIT compiled code into the process because the process is invalid");
243 return;
244 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000245
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000246 if (m_did_jit)
247 {
248 func_addr = m_function_load_addr;
249 func_end = m_function_end_load_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000250
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000251 return;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000252 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000253
Sean Callanan7c435a52014-02-06 22:25:20 +0000254 Mutex::Locker runnable_info_mutex_locker(s_runnable_info_mutex);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000255
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000256 m_did_jit = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000257
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000258 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000259
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000260 std::string error_string;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000261
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000262 if (log)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000263 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000264 std::string s;
265 llvm::raw_string_ostream oss(s);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000266
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000267 m_module->print(oss, NULL);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000268
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000269 oss.flush();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000270
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000271 log->Printf ("Module being sent to JIT: \n%s", s.c_str());
272 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000273
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000274 llvm::Triple triple(m_module->getTargetTriple());
275 llvm::Function *function = m_module->getFunction (m_name.AsCString());
276 llvm::Reloc::Model relocModel;
277 llvm::CodeModel::Model codeModel;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000278
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000279 if (triple.isOSBinFormatELF())
280 {
281 relocModel = llvm::Reloc::Static;
282 // This will be small for 32-bit and large for 64-bit.
283 codeModel = llvm::CodeModel::JITDefault;
284 }
285 else
286 {
287 relocModel = llvm::Reloc::PIC_;
288 codeModel = llvm::CodeModel::Small;
289 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000290
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000291 m_module_ap->getContext().setInlineAsmDiagnosticHandler(ReportInlineAsmError, &error);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000292
Rafael Espindola7c03d952014-08-19 04:27:03 +0000293 llvm::EngineBuilder builder(std::move(m_module_ap));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000294
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000295 builder.setEngineKind(llvm::EngineKind::JIT)
296 .setErrorStr(&error_string)
297 .setRelocationModel(relocModel)
David Majnemerb313e462014-12-04 21:26:25 +0000298 .setMCJITMemoryManager(std::unique_ptr<MemoryManager>(new MemoryManager(*this)))
David Majnemer8faf9372014-09-16 06:34:29 +0000299 .setCodeModel(codeModel)
Reid Kleckner54209532014-09-03 00:40:36 +0000300 .setOptLevel(llvm::CodeGenOpt::Less);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000301
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000302 llvm::StringRef mArch;
303 llvm::StringRef mCPU;
304 llvm::SmallVector<std::string, 0> mAttrs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000305
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000306 for (std::string &feature : m_cpu_features)
307 mAttrs.push_back(feature);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000308
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000309 llvm::TargetMachine *target_machine = builder.selectTarget(triple,
310 mArch,
311 mCPU,
312 mAttrs);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000313
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000314 m_execution_engine_ap.reset(builder.create(target_machine));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000315
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000316 if (!m_execution_engine_ap.get())
317 {
318 error.SetErrorToGenericError();
319 error.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000320 return;
321 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000322
Greg Clayton23f8c952014-03-24 23:10:19 +0000323 // Make sure we see all sections, including ones that don't have relocations...
324 m_execution_engine_ap->setProcessAllSections(true);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000326 m_execution_engine_ap->DisableLazyCompilation();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000327
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000328 // We don't actually need the function pointer here, this just forces it to get resolved.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000329
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000330 void *fun_ptr = m_execution_engine_ap->getPointerToFunction(function);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000331
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000332 if (!error.Success())
333 {
334 // We got an error through our callback!
335 return;
336 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000337
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000338 if (!function)
339 {
340 error.SetErrorToGenericError();
341 error.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", m_name.AsCString());
342 return;
343 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000344
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000345 if (!fun_ptr)
346 {
347 error.SetErrorToGenericError();
348 error.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", m_name.AsCString());
349 return;
350 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000351
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000352 m_jitted_functions.push_back (JittedFunction(m_name.AsCString(), (lldb::addr_t)fun_ptr));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000353
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000354 CommitAllocations(process_sp);
355 ReportAllocations(*m_execution_engine_ap);
356 WriteData(process_sp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000357
Jim Ingham27e5fe82015-01-27 18:03:05 +0000358 if (m_failed_lookups.size())
359 {
360 StreamString ss;
361
362 ss.PutCString("Couldn't lookup symbols:\n");
363
364 bool emitNewLine = false;
365
366 for (const ConstString &failed_lookup : m_failed_lookups)
367 {
368 if (emitNewLine)
369 ss.PutCString("\n");
370 emitNewLine = true;
371 ss.PutCString(" ");
372 ss.PutCString(Mangled(failed_lookup).GetDemangledName().AsCString());
373 }
374
375 m_failed_lookups.clear();
376
377 error.SetErrorString(ss.GetData());
378
379 return;
380 }
381
382 m_function_load_addr = LLDB_INVALID_ADDRESS;
383 m_function_end_load_addr = LLDB_INVALID_ADDRESS;
384
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000385 for (JittedFunction &jitted_function : m_jitted_functions)
386 {
387 jitted_function.m_remote_addr = GetRemoteAddressForLocal (jitted_function.m_local_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000388
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000389 if (!jitted_function.m_name.compare(m_name.AsCString()))
390 {
391 AddrRange func_range = GetRemoteRangeForLocal(jitted_function.m_local_addr);
392 m_function_end_load_addr = func_range.first + func_range.second;
393 m_function_load_addr = jitted_function.m_remote_addr;
394 }
395 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000396
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000397 if (log)
398 {
399 log->Printf("Code can be run in the target.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000400
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000401 StreamString disassembly_stream;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000402
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000403 Error err = DisassembleFunction(disassembly_stream, process_sp);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000404
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000405 if (!err.Success())
406 {
407 log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
408 }
409 else
410 {
411 log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
412 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000413
Sean Callanan4f2c1982014-01-21 00:54:48 +0000414 log->Printf("Sections: ");
415 for (AllocationRecord &record : m_records)
416 {
417 if (record.m_process_address != LLDB_INVALID_ADDRESS)
418 {
419 record.dump(log);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000420
Sean Callanan4f2c1982014-01-21 00:54:48 +0000421 DataBufferHeap my_buffer(record.m_size, 0);
422 Error err;
423 ReadMemory(my_buffer.GetBytes(), record.m_process_address, record.m_size, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000424
Sean Callanan4f2c1982014-01-21 00:54:48 +0000425 if (err.Success())
426 {
427 DataExtractor my_extractor(my_buffer.GetBytes(), my_buffer.GetByteSize(), lldb::eByteOrderBig, 8);
428 my_extractor.PutToLog(log, 0, my_buffer.GetByteSize(), record.m_process_address, 16, DataExtractor::TypeUInt8);
429 }
430 }
431 }
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000432 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000433
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000434 func_addr = m_function_load_addr;
435 func_end = m_function_end_load_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000436
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000437 return;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000438}
439
440IRExecutionUnit::~IRExecutionUnit ()
441{
Sean Callanan14b1bae2013-04-16 23:25:35 +0000442 m_module_ap.reset();
443 m_execution_engine_ap.reset();
444 m_context_ap.reset();
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000445}
446
447IRExecutionUnit::MemoryManager::MemoryManager (IRExecutionUnit &parent) :
Todd Fialad5635cd2014-09-24 15:55:47 +0000448 m_default_mm_ap (new llvm::SectionMemoryManager()),
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000449 m_parent (parent)
450{
451}
452
Greg Clayton23f8c952014-03-24 23:10:19 +0000453IRExecutionUnit::MemoryManager::~MemoryManager ()
454{
455}
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000456
Greg Clayton23f8c952014-03-24 23:10:19 +0000457lldb::SectionType
458IRExecutionUnit::GetSectionTypeFromSectionName (const llvm::StringRef &name, IRExecutionUnit::AllocationKind alloc_kind)
459{
460 lldb::SectionType sect_type = lldb::eSectionTypeCode;
461 switch (alloc_kind)
462 {
463 case AllocationKind::Stub: sect_type = lldb::eSectionTypeCode; break;
464 case AllocationKind::Code: sect_type = lldb::eSectionTypeCode; break;
465 case AllocationKind::Data: sect_type = lldb::eSectionTypeData; break;
466 case AllocationKind::Global:sect_type = lldb::eSectionTypeData; break;
467 case AllocationKind::Bytes: sect_type = lldb::eSectionTypeOther; break;
468 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000469
Greg Clayton23f8c952014-03-24 23:10:19 +0000470 if (!name.empty())
471 {
472 if (name.equals("__text") || name.equals(".text"))
473 sect_type = lldb::eSectionTypeCode;
474 else if (name.equals("__data") || name.equals(".data"))
475 sect_type = lldb::eSectionTypeCode;
476 else if (name.startswith("__debug_") || name.startswith(".debug_"))
477 {
478 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
479 llvm::StringRef dwarf_name(name.substr(name_idx));
480 switch (dwarf_name[0])
481 {
482 case 'a':
483 if (dwarf_name.equals("abbrev"))
484 sect_type = lldb::eSectionTypeDWARFDebugAbbrev;
485 else if (dwarf_name.equals("aranges"))
486 sect_type = lldb::eSectionTypeDWARFDebugAranges;
487 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000488
Greg Clayton23f8c952014-03-24 23:10:19 +0000489 case 'f':
490 if (dwarf_name.equals("frame"))
491 sect_type = lldb::eSectionTypeDWARFDebugFrame;
492 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000493
Greg Clayton23f8c952014-03-24 23:10:19 +0000494 case 'i':
495 if (dwarf_name.equals("info"))
496 sect_type = lldb::eSectionTypeDWARFDebugInfo;
497 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000498
Greg Clayton23f8c952014-03-24 23:10:19 +0000499 case 'l':
500 if (dwarf_name.equals("line"))
501 sect_type = lldb::eSectionTypeDWARFDebugLine;
502 else if (dwarf_name.equals("loc"))
503 sect_type = lldb::eSectionTypeDWARFDebugLoc;
504 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000505
Greg Clayton23f8c952014-03-24 23:10:19 +0000506 case 'm':
507 if (dwarf_name.equals("macinfo"))
508 sect_type = lldb::eSectionTypeDWARFDebugMacInfo;
509 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000510
Greg Clayton23f8c952014-03-24 23:10:19 +0000511 case 'p':
512 if (dwarf_name.equals("pubnames"))
513 sect_type = lldb::eSectionTypeDWARFDebugPubNames;
514 else if (dwarf_name.equals("pubtypes"))
515 sect_type = lldb::eSectionTypeDWARFDebugPubTypes;
516 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000517
Greg Clayton23f8c952014-03-24 23:10:19 +0000518 case 's':
519 if (dwarf_name.equals("str"))
520 sect_type = lldb::eSectionTypeDWARFDebugStr;
521 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000522
Greg Clayton23f8c952014-03-24 23:10:19 +0000523 case 'r':
524 if (dwarf_name.equals("ranges"))
525 sect_type = lldb::eSectionTypeDWARFDebugRanges;
526 break;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000527
Greg Clayton23f8c952014-03-24 23:10:19 +0000528 default:
529 break;
530 }
531 }
532 else if (name.startswith("__apple_") || name.startswith(".apple_"))
533 {
534#if 0
535 const uint32_t name_idx = name[0] == '_' ? 8 : 7;
536 llvm::StringRef apple_name(name.substr(name_idx));
537 switch (apple_name[0])
538 {
539 case 'n':
540 if (apple_name.equals("names"))
541 sect_type = lldb::eSectionTypeDWARFAppleNames;
542 else if (apple_name.equals("namespac") || apple_name.equals("namespaces"))
543 sect_type = lldb::eSectionTypeDWARFAppleNamespaces;
544 break;
545 case 't':
546 if (apple_name.equals("types"))
547 sect_type = lldb::eSectionTypeDWARFAppleTypes;
548 break;
549 case 'o':
550 if (apple_name.equals("objc"))
551 sect_type = lldb::eSectionTypeDWARFAppleObjC;
552 break;
553 default:
554 break;
555 }
556#else
557 sect_type = lldb::eSectionTypeInvalid;
558#endif
559 }
560 else if (name.equals("__objc_imageinfo"))
561 sect_type = lldb::eSectionTypeOther;
562 }
563 return sect_type;
564}
565
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000566uint8_t *
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000567IRExecutionUnit::MemoryManager::allocateCodeSection(uintptr_t Size,
568 unsigned Alignment,
Filip Pizlobfcff682013-10-02 01:43:46 +0000569 unsigned SectionID,
570 llvm::StringRef SectionName)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000571{
Greg Clayton5160ce52013-03-27 23:08:40 +0000572 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000573
Filip Pizlobfcff682013-10-02 01:43:46 +0000574 uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID, SectionName);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000575
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000576 m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
Sean Callananec1c0b32013-04-09 01:13:08 +0000577 lldb::ePermissionsReadable | lldb::ePermissionsExecutable,
Greg Clayton23f8c952014-03-24 23:10:19 +0000578 GetSectionTypeFromSectionName (SectionName, AllocationKind::Code),
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000579 Size,
580 Alignment,
Greg Clayton23f8c952014-03-24 23:10:19 +0000581 SectionID,
582 SectionName.str().c_str()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000583
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000584 if (log)
585 {
586 log->Printf("IRExecutionUnit::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
587 (uint64_t)Size, Alignment, SectionID, return_value);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000588 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000589
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000590 return return_value;
591}
592
593uint8_t *
594IRExecutionUnit::MemoryManager::allocateDataSection(uintptr_t Size,
595 unsigned Alignment,
596 unsigned SectionID,
Filip Pizlobfcff682013-10-02 01:43:46 +0000597 llvm::StringRef SectionName,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000598 bool IsReadOnly)
599{
Greg Clayton5160ce52013-03-27 23:08:40 +0000600 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000601
Filip Pizlobfcff682013-10-02 01:43:46 +0000602 uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000603
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000604 m_parent.m_records.push_back(AllocationRecord((uintptr_t)return_value,
Greg Clayton23f8c952014-03-24 23:10:19 +0000605 lldb::ePermissionsReadable | (IsReadOnly ? 0 : lldb::ePermissionsWritable),
606 GetSectionTypeFromSectionName (SectionName, AllocationKind::Data),
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000607 Size,
608 Alignment,
Greg Clayton23f8c952014-03-24 23:10:19 +0000609 SectionID,
610 SectionName.str().c_str()));
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000611 if (log)
612 {
613 log->Printf("IRExecutionUnit::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
614 (uint64_t)Size, Alignment, SectionID, return_value);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000615 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000616
617 return return_value;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000618}
619
Jim Ingham27e5fe82015-01-27 18:03:05 +0000620uint64_t
621IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
622{
623 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
624
625 SymbolContextList sc_list;
626
627 ExecutionContextScope *exe_scope = m_parent.GetBestExecutionContextScope();
628
629 lldb::TargetSP target_sp = exe_scope->CalculateTarget();
630
631 const char *name = Name.c_str();
632
633 ConstString bare_name_cs(name);
634 ConstString name_cs;
635
636 if (name[0] == '_')
637 name_cs = ConstString(name + 1);
638
639 if (!target_sp)
640 {
641 if (log)
642 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <no target>",
643 Name.c_str());
644
645 m_parent.ReportSymbolLookupError(name_cs);
646
647 return 0xbad0bad0;
648 }
649
650 uint32_t num_matches = 0;
651 lldb::ProcessSP process_sp = exe_scope->CalculateProcess();
652
653 if (!name_cs.IsEmpty())
654 {
655 target_sp->GetImages().FindSymbolsWithNameAndType(name_cs, lldb::eSymbolTypeAny, sc_list);
656 num_matches = sc_list.GetSize();
657 }
658
659 if (!num_matches)
660 {
661 target_sp->GetImages().FindSymbolsWithNameAndType(bare_name_cs, lldb::eSymbolTypeAny, sc_list);
662 num_matches = sc_list.GetSize();
663 }
664
665 lldb::addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
666
667 for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
668 {
669 SymbolContext sym_ctx;
670 sc_list.GetContextAtIndex(i, sym_ctx);
671
672 if (sym_ctx.symbol->GetType() == lldb::eSymbolTypeUndefined)
673 continue;
674
675 const Address *sym_address = &sym_ctx.symbol->GetAddress();
676
677 if (!sym_address || !sym_address->IsValid())
678 continue;
679
680 symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp);
681
682 if (symbol_load_addr == LLDB_INVALID_ADDRESS)
683 {
684 symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get());
685 }
686 }
687
688 if (symbol_load_addr == LLDB_INVALID_ADDRESS && process_sp && name_cs)
689 {
690 // Try the Objective-C language runtime.
691
692 ObjCLanguageRuntime *runtime = process_sp->GetObjCLanguageRuntime();
693
694 if (runtime)
695 symbol_load_addr = runtime->LookupRuntimeSymbol(name_cs);
696 }
697
698 if (symbol_load_addr == LLDB_INVALID_ADDRESS)
699 {
700 if (log)
701 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = <not found>",
702 name);
703
704 m_parent.ReportSymbolLookupError(bare_name_cs);
705
706 return 0xbad0bad0;
707 }
708
709 if (log)
710 log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64,
711 name,
712 symbol_load_addr);
713
714 if (symbol_load_addr == 0)
715 return 0xbad00add;
716
717 return symbol_load_addr;
718}
719
720void *
721IRExecutionUnit::MemoryManager::getPointerToNamedFunction(const std::string &Name,
722 bool AbortOnFailure) {
723 assert (sizeof(void *) == 8);
724
725 return (void*)getSymbolAddress(Name);
726}
727
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000728lldb::addr_t
729IRExecutionUnit::GetRemoteAddressForLocal (lldb::addr_t local_address)
730{
Sean Callananffae9442013-06-27 01:42:47 +0000731 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
732
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000733 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000734 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000735 if (local_address >= record.m_host_address &&
736 local_address < record.m_host_address + record.m_size)
737 {
738 if (record.m_process_address == LLDB_INVALID_ADDRESS)
739 return LLDB_INVALID_ADDRESS;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000740
Sean Callananffae9442013-06-27 01:42:47 +0000741 lldb::addr_t ret = record.m_process_address + (local_address - record.m_host_address);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000742
Sean Callananffae9442013-06-27 01:42:47 +0000743 if (log)
744 {
745 log->Printf("IRExecutionUnit::GetRemoteAddressForLocal() found 0x%" PRIx64 " in [0x%" PRIx64 "..0x%" PRIx64 "], and returned 0x%" PRIx64 " from [0x%" PRIx64 "..0x%" PRIx64 "].",
746 local_address,
Michael Sartain89c862f2013-08-07 19:05:15 +0000747 (uint64_t)record.m_host_address,
748 (uint64_t)record.m_host_address + (uint64_t)record.m_size,
Sean Callananffae9442013-06-27 01:42:47 +0000749 ret,
750 record.m_process_address,
751 record.m_process_address + record.m_size);
752 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000753
Sean Callananffae9442013-06-27 01:42:47 +0000754 return ret;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000755 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000756 }
757
758 return LLDB_INVALID_ADDRESS;
759}
760
761IRExecutionUnit::AddrRange
762IRExecutionUnit::GetRemoteRangeForLocal (lldb::addr_t local_address)
763{
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000764 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000765 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000766 if (local_address >= record.m_host_address &&
767 local_address < record.m_host_address + record.m_size)
768 {
769 if (record.m_process_address == LLDB_INVALID_ADDRESS)
770 return AddrRange(0, 0);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000771
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000772 return AddrRange(record.m_process_address, record.m_size);
773 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000774 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000775
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000776 return AddrRange (0, 0);
777}
778
779bool
780IRExecutionUnit::CommitAllocations (lldb::ProcessSP &process_sp)
781{
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000782 bool ret = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000783
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000784 lldb_private::Error err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000785
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000786 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000787 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000788 if (record.m_process_address != LLDB_INVALID_ADDRESS)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000789 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000790
Greg Clayton23f8c952014-03-24 23:10:19 +0000791 switch (record.m_sect_type)
792 {
793 case lldb::eSectionTypeInvalid:
794 case lldb::eSectionTypeDWARFDebugAbbrev:
795 case lldb::eSectionTypeDWARFDebugAranges:
796 case lldb::eSectionTypeDWARFDebugFrame:
797 case lldb::eSectionTypeDWARFDebugInfo:
798 case lldb::eSectionTypeDWARFDebugLine:
799 case lldb::eSectionTypeDWARFDebugLoc:
800 case lldb::eSectionTypeDWARFDebugMacInfo:
801 case lldb::eSectionTypeDWARFDebugPubNames:
802 case lldb::eSectionTypeDWARFDebugPubTypes:
803 case lldb::eSectionTypeDWARFDebugRanges:
804 case lldb::eSectionTypeDWARFDebugStr:
805 case lldb::eSectionTypeDWARFAppleNames:
806 case lldb::eSectionTypeDWARFAppleTypes:
807 case lldb::eSectionTypeDWARFAppleNamespaces:
808 case lldb::eSectionTypeDWARFAppleObjC:
809 err.Clear();
810 break;
811 default:
812 record.m_process_address = Malloc (record.m_size,
813 record.m_alignment,
814 record.m_permissions,
815 eAllocationPolicyProcessOnly,
816 err);
817 break;
818 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000819
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000820 if (!err.Success())
821 {
822 ret = false;
823 break;
824 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000825 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000826
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000827 if (!ret)
828 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000829 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000830 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000831 if (record.m_process_address != LLDB_INVALID_ADDRESS)
832 {
833 Free(record.m_process_address, err);
834 record.m_process_address = LLDB_INVALID_ADDRESS;
835 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000836 }
837 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000838
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000839 return ret;
840}
841
842void
843IRExecutionUnit::ReportAllocations (llvm::ExecutionEngine &engine)
844{
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000845 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000846 {
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000847 if (record.m_process_address == LLDB_INVALID_ADDRESS)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000848 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000849
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000850 if (record.m_section_id == eSectionIDInvalid)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000851 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000852
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000853 engine.mapSectionAddress((void*)record.m_host_address, record.m_process_address);
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000854 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000855
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000856 // Trigger re-application of relocations.
857 engine.finalizeObject();
858}
859
860bool
861IRExecutionUnit::WriteData (lldb::ProcessSP &process_sp)
862{
Greg Clayton23f8c952014-03-24 23:10:19 +0000863 bool wrote_something = false;
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000864 for (AllocationRecord &record : m_records)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000865 {
Greg Clayton23f8c952014-03-24 23:10:19 +0000866 if (record.m_process_address != LLDB_INVALID_ADDRESS)
867 {
868 lldb_private::Error err;
869 WriteMemory (record.m_process_address, (uint8_t*)record.m_host_address, record.m_size, err);
870 if (err.Success())
871 wrote_something = true;
872 }
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000873 }
Greg Clayton23f8c952014-03-24 23:10:19 +0000874 return wrote_something;
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000875}
876
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000877void
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000878IRExecutionUnit::AllocationRecord::dump (Log *log)
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000879{
880 if (!log)
881 return;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000882
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000883 log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000884 (unsigned long long)m_host_address,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000885 (unsigned long long)m_size,
Sean Callanan5a1af4e2013-04-05 02:22:57 +0000886 (unsigned long long)m_process_address,
Sean Callanan8dfb68e2013-03-19 00:10:07 +0000887 (unsigned)m_alignment,
888 (unsigned)m_section_id);
889}
Greg Clayton23f8c952014-03-24 23:10:19 +0000890
891
892lldb::ByteOrder
893IRExecutionUnit::GetByteOrder () const
894{
895 ExecutionContext exe_ctx (GetBestExecutionContextScope());
896 return exe_ctx.GetByteOrder();
897}
898
899uint32_t
900IRExecutionUnit::GetAddressByteSize () const
901{
902 ExecutionContext exe_ctx (GetBestExecutionContextScope());
903 return exe_ctx.GetAddressByteSize();
904}
905
906void
907IRExecutionUnit::PopulateSymtab (lldb_private::ObjectFile *obj_file,
908 lldb_private::Symtab &symtab)
909{
910 // No symbols yet...
911}
912
913
914void
915IRExecutionUnit::PopulateSectionList (lldb_private::ObjectFile *obj_file,
916 lldb_private::SectionList &section_list)
917{
918 for (AllocationRecord &record : m_records)
919 {
920 if (record.m_size > 0)
921 {
922 lldb::SectionSP section_sp (new lldb_private::Section (obj_file->GetModule(),
923 obj_file,
924 record.m_section_id,
925 ConstString(record.m_name),
926 record.m_sect_type,
927 record.m_process_address,
928 record.m_size,
929 record.m_host_address, // file_offset (which is the host address for the data)
930 record.m_size, // file_size
Greg Clayton48672af2014-06-24 22:22:43 +0000931 0,
Greg Clayton23f8c952014-03-24 23:10:19 +0000932 record.m_permissions)); // flags
933 section_list.AddSection (section_sp);
934 }
935 }
936}
937
938bool
939IRExecutionUnit::GetArchitecture (lldb_private::ArchSpec &arch)
940{
941 ExecutionContext exe_ctx (GetBestExecutionContextScope());
942 Target *target = exe_ctx.GetTargetPtr();
943 if (target)
944 arch = target->GetArchitecture();
945 else
946 arch.Clear();
947 return arch.IsValid();
948}
949
950lldb::ModuleSP
951IRExecutionUnit::GetJITModule ()
952{
953 ExecutionContext exe_ctx (GetBestExecutionContextScope());
954 Target *target = exe_ctx.GetTargetPtr();
955 if (target)
956 {
957 lldb::ModuleSP jit_module_sp = lldb_private::Module::CreateJITModule (std::static_pointer_cast<lldb_private::ObjectFileJITDelegate>(shared_from_this()));
958 if (jit_module_sp)
959 {
960 bool changed = false;
961 jit_module_sp->SetLoadAddress(*target, 0, true, changed);
962 }
963 return jit_module_sp;
964 }
965 return lldb::ModuleSP();
966}