1 //===-- MICmnLLDBProxySBValue.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 #include <stdlib.h>
11
12 // Third Party Headers:
13 #include "lldb/API/SBError.h"
14
15 // In-house headers:
16 #include "MICmnLLDBDebugSessionInfo.h"
17 #include "MICmnLLDBProxySBValue.h"
18 #include "MIUtilString.h"
19
20 //++
21 //------------------------------------------------------------------------------------
22 // Details: Retrieve the numerical value from the SBValue object. If the
23 // function fails
24 // it could indicate the SBValue object does not represent an internal
25 // type.
26 // Type: Static method.
27 // Args: vrValue - (R) The SBValue object to get a value from.
28 // vwValue - (W) The numerical value.
29 // Return: MIstatus::success - Functionality succeeded.
30 // MIstatus::failure - Functionality failed.
31 // Throws: None.
32 //--
GetValueAsUnsigned(const lldb::SBValue & vrValue,MIuint64 & vwValue)33 bool CMICmnLLDBProxySBValue::GetValueAsUnsigned(const lldb::SBValue &vrValue,
34 MIuint64 &vwValue) {
35 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
36 bool bCompositeType = true;
37 MIuint64 nFailValue = 0;
38 MIuint64 nValue = rValue.GetValueAsUnsigned(nFailValue);
39 if (nValue == nFailValue) {
40 nFailValue = 5; // Some arbitrary number
41 nValue = rValue.GetValueAsUnsigned(nFailValue);
42 if (nValue != nFailValue) {
43 bCompositeType = false;
44 vwValue = nValue;
45 }
46 } else {
47 bCompositeType = false;
48 vwValue = nValue;
49 }
50
51 return (bCompositeType ? MIstatus::failure : MIstatus::success);
52 }
53
54 //++
55 //------------------------------------------------------------------------------------
56 // Details: Retrieve the numerical value from the SBValue object. If the
57 // function fails
58 // it could indicate the SBValue object does not represent an internal
59 // type.
60 // Type: Static method.
61 // Args: vrValue - (R) The SBValue object to get a value from.
62 // vwValue - (W) The numerical value.
63 // Return: MIstatus::success - Functionality succeeded.
64 // MIstatus::failure - Functionality failed.
65 // Throws: None.
66 //--
GetValueAsSigned(const lldb::SBValue & vrValue,MIint64 & vwValue)67 bool CMICmnLLDBProxySBValue::GetValueAsSigned(const lldb::SBValue &vrValue,
68 MIint64 &vwValue) {
69 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
70 bool bCompositeType = true;
71 MIuint64 nFailValue = 0;
72 MIuint64 nValue = rValue.GetValueAsSigned(nFailValue);
73 if (nValue == nFailValue) {
74 nFailValue = 5; // Some arbitrary number
75 nValue = rValue.GetValueAsSigned(nFailValue);
76 if (nValue != nFailValue) {
77 bCompositeType = false;
78 vwValue = nValue;
79 }
80 } else {
81 bCompositeType = false;
82 vwValue = nValue;
83 }
84
85 return (bCompositeType ? MIstatus::failure : MIstatus::success);
86 }
87
88 //++
89 //------------------------------------------------------------------------------------
90 // Details: Retrieve the NUL terminated string from the SBValue object if it of
91 // the type
92 // unsigned char *.
93 // Type: Static method.
94 // Args: vrValue - (R) The SBValue object to get a value from.
95 // vwCString - (W) The text data '\0' terminated.
96 // Return: MIstatus::success - Functionality succeeded.
97 // MIstatus::failure - Functionality failed, not suitable type.
98 // Throws: None.
99 //--
GetCString(const lldb::SBValue & vrValue,CMIUtilString & vwCString)100 bool CMICmnLLDBProxySBValue::GetCString(const lldb::SBValue &vrValue,
101 CMIUtilString &vwCString) {
102 lldb::SBValue &rValue = const_cast<lldb::SBValue &>(vrValue);
103 const char *pCType = rValue.GetTypeName();
104 if (pCType == nullptr)
105 return MIstatus::failure;
106
107 const char *pType = "unsigned char *";
108 if (!CMIUtilString::Compare(pCType, pType))
109 return MIstatus::failure;
110
111 const CMIUtilString strAddr(rValue.GetValue());
112 MIint64 nNum = 0;
113 if (!strAddr.ExtractNumber(nNum))
114 return MIstatus::failure;
115
116 CMICmnLLDBDebugSessionInfo &rSessionInfo(
117 CMICmnLLDBDebugSessionInfo::Instance());
118 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
119 MIuint nBufferSize = 64;
120 bool bNeedResize = false;
121 char *pBuffer = static_cast<char *>(::malloc(nBufferSize));
122 do {
123 lldb::SBError error;
124 const size_t nReadSize = sbProcess.ReadCStringFromMemory(
125 (lldb::addr_t)nNum, pBuffer, nBufferSize, error);
126 if (nReadSize == (nBufferSize - 1)) {
127 bNeedResize = true;
128 nBufferSize = nBufferSize << 1;
129 pBuffer = static_cast<char *>(::realloc(pBuffer, nBufferSize));
130 } else
131 bNeedResize = false;
132 } while (bNeedResize);
133
134 vwCString = pBuffer;
135 free((void *)pBuffer);
136
137 return MIstatus::success;
138 }
139