RegisterContext.cpp revision 263367
1//===-- RegisterContext.cpp -------------------------------------*- 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// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "lldb/Target/RegisterContext.h"
15#include "lldb/Core/DataExtractor.h"
16#include "lldb/Core/RegisterValue.h"
17#include "lldb/Core/Scalar.h"
18#include "lldb/Host/Endian.h"
19#include "lldb/Target/ExecutionContext.h"
20#include "lldb/Target/StackFrame.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/Thread.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
27RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) :
28    m_thread (thread),
29    m_concrete_frame_idx (concrete_frame_idx),
30    m_stop_id (thread.GetProcess()->GetStopID())
31{
32}
33
34//----------------------------------------------------------------------
35// Destructor
36//----------------------------------------------------------------------
37RegisterContext::~RegisterContext()
38{
39}
40
41void
42RegisterContext::InvalidateIfNeeded (bool force)
43{
44    ProcessSP process_sp (m_thread.GetProcess());
45    bool invalidate = force;
46    uint32_t process_stop_id = UINT32_MAX;
47
48    if (process_sp)
49        process_stop_id = process_sp->GetStopID();
50    else
51        invalidate = true;
52
53    if (!invalidate)
54        invalidate = process_stop_id != GetStopID();
55
56    if (invalidate)
57    {
58        InvalidateAllRegisters ();
59        SetStopID (process_stop_id);
60    }
61}
62
63
64const RegisterInfo *
65RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx)
66{
67    if (reg_name && reg_name[0])
68    {
69        const uint32_t num_registers = GetRegisterCount();
70        for (uint32_t reg = start_idx; reg < num_registers; ++reg)
71        {
72            const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
73
74            if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) ||
75                (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0))
76            {
77                return reg_info;
78            }
79        }
80    }
81    return NULL;
82}
83
84const RegisterInfo *
85RegisterContext::GetRegisterInfo (uint32_t kind, uint32_t num)
86{
87    const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
88    if (reg_num == LLDB_INVALID_REGNUM)
89        return NULL;
90    return GetRegisterInfoAtIndex (reg_num);
91}
92
93const char *
94RegisterContext::GetRegisterName (uint32_t reg)
95{
96    const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg);
97    if (reg_info)
98        return reg_info->name;
99    return NULL;
100}
101
102uint64_t
103RegisterContext::GetPC(uint64_t fail_value)
104{
105    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
106    return ReadRegisterAsUnsigned (reg, fail_value);
107}
108
109bool
110RegisterContext::SetPC(uint64_t pc)
111{
112    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
113    bool success = WriteRegisterFromUnsigned (reg, pc);
114    if (success)
115    {
116        StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx));
117        if (frame_sp)
118            frame_sp->ChangePC(pc);
119        else
120            m_thread.ClearStackFrames ();
121    }
122    return success;
123}
124
125bool
126RegisterContext::SetPC(Address addr)
127{
128    TargetSP target_sp = m_thread.CalculateTarget();
129    Target *target = target_sp.get();
130
131    lldb::addr_t callAddr = addr.GetCallableLoadAddress (target);
132    if (callAddr == LLDB_INVALID_ADDRESS)
133        return false;
134
135    return SetPC (callAddr);
136}
137
138uint64_t
139RegisterContext::GetSP(uint64_t fail_value)
140{
141    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
142    return ReadRegisterAsUnsigned (reg, fail_value);
143}
144
145bool
146RegisterContext::SetSP(uint64_t sp)
147{
148    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
149    return WriteRegisterFromUnsigned (reg, sp);
150}
151
152uint64_t
153RegisterContext::GetFP(uint64_t fail_value)
154{
155    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
156    return ReadRegisterAsUnsigned (reg, fail_value);
157}
158
159bool
160RegisterContext::SetFP(uint64_t fp)
161{
162    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
163    return WriteRegisterFromUnsigned (reg, fp);
164}
165
166uint64_t
167RegisterContext::GetReturnAddress (uint64_t fail_value)
168{
169    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA);
170    return ReadRegisterAsUnsigned (reg, fail_value);
171}
172
173uint64_t
174RegisterContext::GetFlags (uint64_t fail_value)
175{
176    uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
177    return ReadRegisterAsUnsigned (reg, fail_value);
178}
179
180
181uint64_t
182RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value)
183{
184    if (reg != LLDB_INVALID_REGNUM)
185        return ReadRegisterAsUnsigned (GetRegisterInfoAtIndex (reg), fail_value);
186    return fail_value;
187}
188
189uint64_t
190RegisterContext::ReadRegisterAsUnsigned (const RegisterInfo *reg_info, uint64_t fail_value)
191{
192    if (reg_info)
193    {
194        RegisterValue value;
195        if (ReadRegister (reg_info, value))
196            return value.GetAsUInt64();
197    }
198    return fail_value;
199}
200
201bool
202RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval)
203{
204    if (reg == LLDB_INVALID_REGNUM)
205        return false;
206    return WriteRegisterFromUnsigned (GetRegisterInfoAtIndex (reg), uval);
207}
208
209bool
210RegisterContext::WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval)
211{
212    if (reg_info)
213    {
214        RegisterValue value;
215        if (value.SetUInt(uval, reg_info->byte_size))
216            return WriteRegister (reg_info, value);
217    }
218    return false;
219}
220
221bool
222RegisterContext::CopyFromRegisterContext (lldb::RegisterContextSP context)
223{
224    uint32_t num_register_sets = context->GetRegisterSetCount();
225    // We don't know that two threads have the same register context, so require the threads to be the same.
226    if (context->GetThreadID() != GetThreadID())
227        return false;
228
229    if (num_register_sets != GetRegisterSetCount())
230        return false;
231
232    RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
233
234    for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx)
235    {
236        const RegisterSet * const reg_set = GetRegisterSet(set_idx);
237
238        const uint32_t num_registers = reg_set->num_registers;
239        for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
240        {
241            const uint32_t reg = reg_set->registers[reg_idx];
242            const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
243            if (!reg_info || reg_info->value_regs)
244                continue;
245            RegisterValue reg_value;
246
247            // If we can reconstruct the register from the frame we are copying from, then do so, otherwise
248            // use the value from frame 0.
249            if (context->ReadRegister(reg_info, reg_value))
250            {
251                WriteRegister(reg_info, reg_value);
252            }
253            else if (frame_zero_context->ReadRegister(reg_info, reg_value))
254            {
255                WriteRegister(reg_info, reg_value);
256            }
257        }
258    }
259    return true;
260}
261
262lldb::tid_t
263RegisterContext::GetThreadID() const
264{
265    return m_thread.GetID();
266}
267
268uint32_t
269RegisterContext::NumSupportedHardwareBreakpoints ()
270{
271    return 0;
272}
273
274uint32_t
275RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
276{
277    return LLDB_INVALID_INDEX32;
278}
279
280bool
281RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx)
282{
283    return false;
284}
285
286
287uint32_t
288RegisterContext::NumSupportedHardwareWatchpoints ()
289{
290    return 0;
291}
292
293uint32_t
294RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
295{
296    return LLDB_INVALID_INDEX32;
297}
298
299bool
300RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index)
301{
302    return false;
303}
304
305bool
306RegisterContext::HardwareSingleStep (bool enable)
307{
308    return false;
309}
310
311Error
312RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info,
313                                              lldb::addr_t src_addr,
314                                              uint32_t src_len,
315                                              RegisterValue &reg_value)
316{
317    Error error;
318    if (reg_info == NULL)
319    {
320        error.SetErrorString ("invalid register info argument.");
321        return error;
322    }
323
324
325    // Moving from addr into a register
326    //
327    // Case 1: src_len == dst_len
328    //
329    //   |AABBCCDD| Address contents
330    //   |AABBCCDD| Register contents
331    //
332    // Case 2: src_len > dst_len
333    //
334    //   Error!  (The register should always be big enough to hold the data)
335    //
336    // Case 3: src_len < dst_len
337    //
338    //   |AABB| Address contents
339    //   |AABB0000| Register contents [on little-endian hardware]
340    //   |0000AABB| Register contents [on big-endian hardware]
341    if (src_len > RegisterValue::kMaxRegisterByteSize)
342    {
343        error.SetErrorString ("register too small to receive memory data");
344        return error;
345    }
346
347    const uint32_t dst_len = reg_info->byte_size;
348
349    if (src_len > dst_len)
350    {
351        error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len);
352        return error;
353    }
354
355    ProcessSP process_sp (m_thread.GetProcess());
356    if (process_sp)
357    {
358        uint8_t src[RegisterValue::kMaxRegisterByteSize];
359
360        // Read the memory
361        const uint32_t bytes_read = process_sp->ReadMemory (src_addr, src, src_len, error);
362
363        // Make sure the memory read succeeded...
364        if (bytes_read != src_len)
365        {
366            if (error.Success())
367            {
368                // This might happen if we read _some_ bytes but not all
369                error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len);
370            }
371            return error;
372        }
373
374        // We now have a memory buffer that contains the part or all of the register
375        // value. Set the register value using this memory data.
376        // TODO: we might need to add a parameter to this function in case the byte
377        // order of the memory data doesn't match the process. For now we are assuming
378        // they are the same.
379        reg_value.SetFromMemoryData (reg_info,
380                                     src,
381                                     src_len,
382                                     process_sp->GetByteOrder(),
383                                     error);
384    }
385    else
386        error.SetErrorString("invalid process");
387
388    return error;
389}
390
391Error
392RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info,
393                                             lldb::addr_t dst_addr,
394                                             uint32_t dst_len,
395                                             const RegisterValue &reg_value)
396{
397
398    uint8_t dst[RegisterValue::kMaxRegisterByteSize];
399
400    Error error;
401
402    ProcessSP process_sp (m_thread.GetProcess());
403    if (process_sp)
404    {
405
406        // TODO: we might need to add a parameter to this function in case the byte
407        // order of the memory data doesn't match the process. For now we are assuming
408        // they are the same.
409
410        const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info,
411                                                                 dst,
412                                                                 dst_len,
413                                                                 process_sp->GetByteOrder(),
414                                                                 error);
415
416        if (error.Success())
417        {
418            if (bytes_copied == 0)
419            {
420                error.SetErrorString("byte copy failed.");
421            }
422            else
423            {
424                const uint32_t bytes_written = process_sp->WriteMemory (dst_addr, dst, bytes_copied, error);
425                if (bytes_written != bytes_copied)
426                {
427                    if (error.Success())
428                    {
429                        // This might happen if we read _some_ bytes but not all
430                        error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied);
431                    }
432                }
433            }
434        }
435    }
436    else
437        error.SetErrorString("invalid process");
438
439    return error;
440
441}
442
443bool
444RegisterContext::ReadAllRegisterValues (lldb_private::RegisterCheckpoint &reg_checkpoint)
445{
446    return ReadAllRegisterValues(reg_checkpoint.GetData());
447}
448
449bool
450RegisterContext::WriteAllRegisterValues (const lldb_private::RegisterCheckpoint &reg_checkpoint)
451{
452    return WriteAllRegisterValues(reg_checkpoint.GetData());
453}
454
455TargetSP
456RegisterContext::CalculateTarget ()
457{
458    return m_thread.CalculateTarget();
459}
460
461
462ProcessSP
463RegisterContext::CalculateProcess ()
464{
465    return m_thread.CalculateProcess ();
466}
467
468ThreadSP
469RegisterContext::CalculateThread ()
470{
471    return m_thread.shared_from_this();
472}
473
474StackFrameSP
475RegisterContext::CalculateStackFrame ()
476{
477    // Register contexts might belong to many frames if we have inlined
478    // functions inside a frame since all inlined functions share the
479    // same registers, so we can't definitively say which frame we come from...
480    return StackFrameSP();
481}
482
483void
484RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx)
485{
486    m_thread.CalculateExecutionContext (exe_ctx);
487}
488
489
490bool
491RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum)
492{
493    const uint32_t num_registers = GetRegisterCount();
494    for (uint32_t reg = 0; reg < num_registers; ++reg)
495    {
496        const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg);
497
498        if (reg_info->kinds[source_rk] == source_regnum)
499        {
500            target_regnum = reg_info->kinds[target_rk];
501            if (target_regnum == LLDB_INVALID_REGNUM)
502            {
503                return false;
504            }
505            else
506            {
507                return true;
508            }
509        }
510    }
511    return false;
512}
513
514//bool
515//RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value)
516//{
517//    DataExtractor data;
518//    if (!ReadRegisterBytes (reg, data))
519//        return false;
520//
521//    const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg);
522//    uint32_t offset = 0;
523//    switch (reg_info->encoding)
524//    {
525//    case eEncodingInvalid:
526//    case eEncodingVector:
527//        break;
528//
529//    case eEncodingUint:
530//        switch (reg_info->byte_size)
531//        {
532//        case 1:
533//            {
534//                value = data.GetU8 (&offset);
535//                return true;
536//            }
537//        case 2:
538//            {
539//                value = data.GetU16 (&offset);
540//                return true;
541//            }
542//        case 4:
543//            {
544//                value = data.GetU32 (&offset);
545//                return true;
546//            }
547//        case 8:
548//            {
549//                value = data.GetU64 (&offset);
550//                return true;
551//            }
552//        }
553//        break;
554//    case eEncodingSint:
555//        switch (reg_info->byte_size)
556//        {
557//        case 1:
558//            {
559//                int8_t v;
560//                if (data.ExtractBytes (0, sizeof (int8_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int8_t))
561//                    return false;
562//                value = v;
563//                return true;
564//            }
565//        case 2:
566//            {
567//                int16_t v;
568//                if (data.ExtractBytes (0, sizeof (int16_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int16_t))
569//                    return false;
570//                value = v;
571//                return true;
572//            }
573//        case 4:
574//            {
575//                int32_t v;
576//                if (data.ExtractBytes (0, sizeof (int32_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int32_t))
577//                    return false;
578//                value = v;
579//                return true;
580//            }
581//        case 8:
582//            {
583//                int64_t v;
584//                if (data.ExtractBytes (0, sizeof (int64_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int64_t))
585//                    return false;
586//                value = v;
587//                return true;
588//            }
589//        }
590//        break;
591//    case eEncodingIEEE754:
592//        switch (reg_info->byte_size)
593//        {
594//        case sizeof (float):
595//            {
596//                float v;
597//                if (data.ExtractBytes (0, sizeof (float), lldb::endian::InlHostByteOrder(), &v) != sizeof (float))
598//                    return false;
599//                value = v;
600//                return true;
601//            }
602//        case sizeof (double):
603//            {
604//                double v;
605//                if (data.ExtractBytes (0, sizeof (double), lldb::endian::InlHostByteOrder(), &v) != sizeof (double))
606//                    return false;
607//                value = v;
608//                return true;
609//            }
610//        case sizeof (long double):
611//            {
612//                double v;
613//                if (data.ExtractBytes (0, sizeof (long double), lldb::endian::InlHostByteOrder(), &v) != sizeof (long double))
614//                    return false;
615//                value = v;
616//                return true;
617//            }
618//        }
619//        break;
620//    }
621//    return false;
622//}
623//
624//bool
625//RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value)
626//{
627//    DataExtractor data;
628//    if (!value.IsValid())
629//        return false;
630//    if (!value.GetData (data))
631//        return false;
632//
633//    return WriteRegisterBytes (reg, data);
634//}
635