]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Core/EmulateInstruction.cpp
Vendor import of lldb release_39 branch r276489:
[FreeBSD/FreeBSD.git] / source / Core / EmulateInstruction.cpp
1 //===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
2 //
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
10 #include "lldb/Core/EmulateInstruction.h"
11
12 // C Includes
13 // C++ Includes
14 #include <cstring>
15
16 // Other libraries and framework includes
17 // Project includes
18 #include "lldb/Core/Address.h"
19 #include "lldb/Core/DataExtractor.h"
20 #include "lldb/Core/Error.h"
21 #include "lldb/Core/PluginManager.h"
22 #include "lldb/Core/RegisterValue.h"
23 #include "lldb/Core/StreamFile.h"
24 #include "lldb/Core/StreamString.h"
25 #include "lldb/Host/Endian.h"
26 #include "lldb/Symbol/UnwindPlan.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Target/Target.h"
30 #include "lldb/Target/Thread.h"
31
32 using namespace lldb;
33 using namespace lldb_private;
34
35 EmulateInstruction*
36 EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
37 {
38     EmulateInstructionCreateInstance create_callback = nullptr;
39     if (plugin_name)
40     {
41         ConstString const_plugin_name (plugin_name);
42         create_callback  = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
43         if (create_callback)
44         {
45                 EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
46             if (emulate_insn_ptr)
47                 return emulate_insn_ptr;
48         }
49     }
50     else
51     {
52         for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != nullptr; ++idx)
53         {
54             EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
55             if (emulate_insn_ptr)
56                 return emulate_insn_ptr;
57         }
58     }
59     return nullptr;
60 }
61
62 EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
63     m_arch(arch),
64     m_baton(nullptr),
65     m_read_mem_callback(&ReadMemoryDefault),
66     m_write_mem_callback(&WriteMemoryDefault),
67     m_read_reg_callback(&ReadRegisterDefault),
68     m_write_reg_callback(&WriteRegisterDefault),
69     m_addr(LLDB_INVALID_ADDRESS)
70 {
71     ::memset (&m_opcode, 0, sizeof (m_opcode));
72 }
73
74 bool
75 EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
76 {
77     if (m_read_reg_callback != nullptr)
78         return m_read_reg_callback (this, m_baton, reg_info, reg_value);
79     return false;
80 }
81
82 bool
83 EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value)
84 {
85     RegisterInfo reg_info;
86     if (GetRegisterInfo(reg_kind, reg_num, reg_info))
87         return ReadRegister (&reg_info, reg_value);
88     return false;
89 }
90
91 uint64_t
92 EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
93                                           uint32_t reg_num,
94                                           uint64_t fail_value, 
95                                           bool *success_ptr)
96 {
97     RegisterValue reg_value;
98     if (ReadRegister (reg_kind, reg_num, reg_value))
99         return reg_value.GetAsUInt64(fail_value, success_ptr);
100     if (success_ptr)
101         *success_ptr = false;
102     return fail_value;
103 }
104
105 uint64_t
106 EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
107                                           uint64_t fail_value, 
108                                           bool *success_ptr)
109 {
110     RegisterValue reg_value;
111     if (ReadRegister (reg_info, reg_value))
112         return reg_value.GetAsUInt64(fail_value, success_ptr);
113     if (success_ptr)
114         *success_ptr = false;
115     return fail_value;
116 }
117
118 bool
119 EmulateInstruction::WriteRegister (const Context &context, 
120                                    const RegisterInfo *reg_info, 
121                                    const RegisterValue& reg_value)
122 {
123     if (m_write_reg_callback != nullptr)
124         return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
125     return false;
126 }
127
128 bool
129 EmulateInstruction::WriteRegister (const Context &context, 
130                                    lldb::RegisterKind reg_kind,
131                                    uint32_t reg_num, 
132                                    const RegisterValue& reg_value)
133 {
134     RegisterInfo reg_info;
135     if (GetRegisterInfo(reg_kind, reg_num, reg_info))
136         return WriteRegister (context, &reg_info, reg_value);
137     return false;
138 }
139
140 bool
141 EmulateInstruction::WriteRegisterUnsigned (const Context &context,
142                                            lldb::RegisterKind reg_kind,
143                                            uint32_t reg_num,
144                                            uint64_t uint_value)
145 {
146     RegisterInfo reg_info;
147     if (GetRegisterInfo(reg_kind, reg_num, reg_info))
148     {
149         RegisterValue reg_value;
150         if (reg_value.SetUInt(uint_value, reg_info.byte_size))
151             return WriteRegister (context, &reg_info, reg_value);
152     }
153     return false;
154 }
155
156 bool
157 EmulateInstruction::WriteRegisterUnsigned (const Context &context,
158                                            const RegisterInfo *reg_info,
159                                            uint64_t uint_value)
160 {
161     if (reg_info != nullptr)
162     {
163         RegisterValue reg_value;
164         if (reg_value.SetUInt(uint_value, reg_info->byte_size))
165                 return WriteRegister (context, reg_info, reg_value);
166     }
167     return false;
168 }
169
170 size_t
171 EmulateInstruction::ReadMemory (const Context &context, 
172                                 lldb::addr_t addr, 
173                                 void *dst,
174                                 size_t dst_len)
175 {
176     if (m_read_mem_callback != nullptr)
177         return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
178     return false;
179 }
180
181 uint64_t
182 EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
183 {
184     uint64_t uval64 = 0;
185     bool success = false;
186     if (byte_size <= 8)
187     {
188         uint8_t buf[sizeof(uint64_t)];
189         size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
190         if (bytes_read == byte_size)
191         {
192             lldb::offset_t offset = 0;
193             DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
194             uval64 = data.GetMaxU64 (&offset, byte_size);
195             success = true;
196         }
197     }
198
199     if (success_ptr)
200         *success_ptr = success;
201
202     if (!success)
203         uval64 = fail_value;
204     return uval64;
205 }
206
207 bool
208 EmulateInstruction::WriteMemoryUnsigned (const Context &context, 
209                                          lldb::addr_t addr, 
210                                          uint64_t uval,
211                                          size_t uval_byte_size)
212 {
213     StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
214     strm.PutMaxHex64 (uval, uval_byte_size);
215     
216     size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
217     return (bytes_written == uval_byte_size);
218 }
219
220 bool
221 EmulateInstruction::WriteMemory (const Context &context, 
222                                  lldb::addr_t addr, 
223                                  const void *src,
224                                  size_t src_len)
225 {
226     if (m_write_mem_callback != nullptr)
227         return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
228     return false;
229 }
230
231 void
232 EmulateInstruction::SetBaton (void *baton)
233 {
234     m_baton = baton;
235 }
236
237 void
238 EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
239                                   WriteMemoryCallback write_mem_callback,
240                                   ReadRegisterCallback read_reg_callback,
241                                   WriteRegisterCallback write_reg_callback)
242 {
243     m_read_mem_callback = read_mem_callback;
244     m_write_mem_callback = write_mem_callback;
245     m_read_reg_callback = read_reg_callback;
246     m_write_reg_callback = write_reg_callback;
247 }
248
249 void
250 EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
251 {
252     m_read_mem_callback = read_mem_callback;
253 }
254
255 void
256 EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
257 {
258     m_write_mem_callback = write_mem_callback;
259 }
260
261 void
262 EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
263 {
264     m_read_reg_callback = read_reg_callback;
265 }
266
267 void
268 EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
269 {
270     m_write_reg_callback = write_reg_callback;
271 }
272
273 //
274 //  Read & Write Memory and Registers callback functions.
275 //
276
277 size_t 
278 EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
279                                      void *baton,
280                                      const Context &context, 
281                                      lldb::addr_t addr, 
282                                      void *dst,
283                                      size_t dst_len)
284 {
285     if (baton == nullptr || dst == nullptr || dst_len == 0)
286         return 0;
287
288     StackFrame *frame = (StackFrame *) baton;
289
290     ProcessSP process_sp (frame->CalculateProcess());
291     if (process_sp)
292     {
293         Error error;
294         return process_sp->ReadMemory (addr, dst, dst_len, error);
295     }
296     return 0;
297 }
298
299 size_t 
300 EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
301                                       void *baton,
302                                       const Context &context, 
303                                       lldb::addr_t addr, 
304                                       const void *src,
305                                       size_t src_len)
306 {
307     if (baton == nullptr || src == nullptr || src_len == 0)
308         return 0;
309     
310     StackFrame *frame = (StackFrame *) baton;
311
312     ProcessSP process_sp (frame->CalculateProcess());
313     if (process_sp)
314     {
315         Error error;
316         return process_sp->WriteMemory (addr, src, src_len, error);
317     }
318     
319     return 0;
320 }
321
322 bool   
323 EmulateInstruction::ReadRegisterFrame  (EmulateInstruction *instruction,
324                                         void *baton,
325                                         const RegisterInfo *reg_info,
326                                         RegisterValue &reg_value)
327 {
328     if (baton == nullptr)
329         return false;
330         
331     StackFrame *frame = (StackFrame *) baton;
332     return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
333 }
334
335 bool   
336 EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
337                                         void *baton,
338                                         const Context &context, 
339                                         const RegisterInfo *reg_info,
340                                         const RegisterValue &reg_value)
341 {
342     if (baton == nullptr)
343         return false;
344         
345     StackFrame *frame = (StackFrame *) baton;
346     return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
347 }
348
349 size_t 
350 EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
351                                        void *baton,
352                                        const Context &context, 
353                                        lldb::addr_t addr, 
354                                        void *dst,
355                                        size_t length)
356 {
357     StreamFile strm (stdout, false);
358     strm.Printf ("    Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
359     context.Dump (strm, instruction);    
360     strm.EOL();
361     *((uint64_t *) dst) = 0xdeadbeef;
362     return length;
363 }
364
365 size_t 
366 EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
367                                         void *baton,
368                                         const Context &context, 
369                                         lldb::addr_t addr, 
370                                         const void *dst,
371                                         size_t length)
372 {
373     StreamFile strm (stdout, false);
374     strm.Printf ("    Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
375     context.Dump (strm, instruction);    
376     strm.EOL();
377     return length;
378 }
379
380 bool   
381 EmulateInstruction::ReadRegisterDefault  (EmulateInstruction *instruction,
382                                           void *baton,
383                                           const RegisterInfo *reg_info,
384                                           RegisterValue &reg_value)
385 {
386     StreamFile strm (stdout, false);
387     strm.Printf ("  Read Register (%s)\n", reg_info->name);
388     lldb::RegisterKind reg_kind;
389     uint32_t reg_num;
390     if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
391         reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
392     else
393         reg_value.SetUInt64(0);
394
395     return true;
396 }
397
398 bool   
399 EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
400                                           void *baton,
401                                           const Context &context, 
402                                           const RegisterInfo *reg_info,
403                                           const RegisterValue &reg_value)
404 {
405     StreamFile strm (stdout, false);
406     strm.Printf ("    Write to Register (name = %s, value = " , reg_info->name);
407     reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
408     strm.PutCString (", context = ");
409     context.Dump (strm, instruction);        
410     strm.EOL();
411     return true;
412 }
413
414 void
415 EmulateInstruction::Context::Dump (Stream &strm, 
416                                    EmulateInstruction *instruction) const
417 {
418     switch (type)
419     {
420         case eContextReadOpcode:
421             strm.PutCString ("reading opcode");
422             break;
423             
424         case eContextImmediate:
425             strm.PutCString ("immediate");
426             break;
427             
428         case eContextPushRegisterOnStack:
429             strm.PutCString ("push register");
430             break;
431             
432         case eContextPopRegisterOffStack:
433             strm.PutCString ("pop register");
434             break;
435             
436         case eContextAdjustStackPointer:
437             strm.PutCString ("adjust sp");
438             break;
439             
440         case eContextSetFramePointer:
441             strm.PutCString ("set frame pointer");
442             break;
443             
444         case eContextAdjustBaseRegister:
445             strm.PutCString ("adjusting (writing value back to) a base register");
446             break;
447             
448         case eContextRegisterPlusOffset:
449             strm.PutCString ("register + offset");
450             break;
451             
452         case eContextRegisterStore:
453             strm.PutCString ("store register");
454             break;
455             
456         case eContextRegisterLoad:
457             strm.PutCString ("load register");
458             break;
459             
460         case eContextRelativeBranchImmediate:
461             strm.PutCString ("relative branch immediate");
462             break;
463             
464         case eContextAbsoluteBranchRegister:
465             strm.PutCString ("absolute branch register");
466             break;
467             
468         case eContextSupervisorCall:
469             strm.PutCString ("supervisor call");
470             break;
471             
472         case eContextTableBranchReadMemory:
473             strm.PutCString ("table branch read memory");
474             break;
475             
476         case eContextWriteRegisterRandomBits:
477             strm.PutCString ("write random bits to a register");
478             break;
479             
480         case eContextWriteMemoryRandomBits:
481             strm.PutCString ("write random bits to a memory address");
482             break;
483             
484         case eContextArithmetic:
485             strm.PutCString ("arithmetic");
486             break;
487             
488         case eContextReturnFromException:
489             strm.PutCString ("return from exception");
490             break;
491             
492         default:
493             strm.PutCString ("unrecognized context.");
494             break;
495     }
496     
497     switch (info_type)
498     {
499     case eInfoTypeRegisterPlusOffset:
500         strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
501                     info.RegisterPlusOffset.reg.name,
502                     info.RegisterPlusOffset.signed_offset);
503         break;
504
505     case eInfoTypeRegisterPlusIndirectOffset:
506         strm.Printf(" (reg_plus_reg = %s + %s)",
507                     info.RegisterPlusIndirectOffset.base_reg.name,
508                     info.RegisterPlusIndirectOffset.offset_reg.name);
509         break;
510
511     case eInfoTypeRegisterToRegisterPlusOffset:
512         strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
513                     info.RegisterToRegisterPlusOffset.base_reg.name,
514                     info.RegisterToRegisterPlusOffset.offset,
515                     info.RegisterToRegisterPlusOffset.data_reg.name);
516         break;
517
518     case eInfoTypeRegisterToRegisterPlusIndirectOffset:
519         strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
520                     info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
521                     info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
522                     info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
523         break;
524     
525     case eInfoTypeRegisterRegisterOperands:
526         strm.Printf(" (register to register binary op: %s and %s)",
527                     info.RegisterRegisterOperands.operand1.name,
528                     info.RegisterRegisterOperands.operand2.name);
529         break;
530
531     case eInfoTypeOffset:
532         strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
533         break;
534         
535     case eInfoTypeRegister:
536         strm.Printf (" (reg = %s)", info.reg.name);
537         break;
538         
539     case eInfoTypeImmediate:
540         strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
541                      info.unsigned_immediate, 
542                      info.unsigned_immediate);
543         break;
544
545     case eInfoTypeImmediateSigned:
546         strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
547                      info.signed_immediate, 
548                      info.signed_immediate);
549         break;
550         
551     case eInfoTypeAddress:
552         strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
553         break;
554         
555     case eInfoTypeISAAndImmediate:
556         strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))", 
557                      info.ISAAndImmediate.isa,
558                      info.ISAAndImmediate.unsigned_data32,
559                      info.ISAAndImmediate.unsigned_data32);
560         break;
561         
562     case eInfoTypeISAAndImmediateSigned:
563         strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))", 
564                      info.ISAAndImmediateSigned.isa,
565                      info.ISAAndImmediateSigned.signed_data32,
566                      info.ISAAndImmediateSigned.signed_data32);
567         break;
568         
569     case eInfoTypeISA:
570         strm.Printf (" (isa = %u)", info.isa);
571         break;
572         
573     case eInfoTypeNoArgs:
574         break;
575     }
576 }
577
578 bool
579 EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
580 {
581     m_opcode = opcode;
582     m_addr = LLDB_INVALID_ADDRESS;
583     if (inst_addr.IsValid())
584     {
585         if (target != nullptr)
586             m_addr = inst_addr.GetLoadAddress (target);
587         if (m_addr == LLDB_INVALID_ADDRESS)
588             m_addr = inst_addr.GetFileAddress ();
589     }
590     return true;
591 }
592
593 bool
594 EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, 
595                                                   lldb::RegisterKind &reg_kind,
596                                                   uint32_t &reg_num)
597 {
598     // Generic and DWARF should be the two most popular register kinds when
599     // emulating instructions since they are the most platform agnostic...
600     reg_num = reg_info->kinds[eRegisterKindGeneric];
601     if (reg_num != LLDB_INVALID_REGNUM)
602     {
603         reg_kind = eRegisterKindGeneric;
604         return true;
605     }
606     
607     reg_num = reg_info->kinds[eRegisterKindDWARF];
608     if (reg_num != LLDB_INVALID_REGNUM)
609     {
610         reg_kind = eRegisterKindDWARF;
611         return true;
612     }
613
614     reg_num = reg_info->kinds[eRegisterKindLLDB];
615     if (reg_num != LLDB_INVALID_REGNUM)
616     {
617         reg_kind = eRegisterKindLLDB;
618         return true;
619     }
620
621     reg_num = reg_info->kinds[eRegisterKindEHFrame];
622     if (reg_num != LLDB_INVALID_REGNUM)
623     {
624         reg_kind = eRegisterKindEHFrame;
625         return true;
626     }
627
628     reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
629     if (reg_num != LLDB_INVALID_REGNUM)
630     {
631         reg_kind = eRegisterKindProcessPlugin;
632         return true;
633     }
634     return false;
635 }
636
637 uint32_t
638 EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
639 {
640     lldb::RegisterKind reg_kind;
641     uint32_t reg_num;
642     if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
643         return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
644     return LLDB_INVALID_REGNUM;
645 }
646
647 bool
648 EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
649 {
650     unwind_plan.Clear();
651     return false;
652 }