//===-- MICmnLLDBUtilSBValue.cpp --------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //++ // File: MICmnLLDBUtilSBValue.cpp // // Overview: CMICmnLLDBUtilSBValue implementation. // // Environment: Compilers: Visual C++ 12. // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 // Libraries: See MIReadmetxt. // // Copyright: None. //-- // In-house headers: #include "MICmnLLDBUtilSBValue.h" #include "MIUtilString.h" #include "MICmnLLDBDebugSessionInfo.h" //++ ------------------------------------------------------------------------------------ // Details: CMICmnLLDBUtilSBValue constructor. // Type: Method. // Args: vrValue - (R) The LLDb value object. // vbHandleCharType - (R) True = Yes return text molding to char type, // False = just return data. // Return: None. // Throws: None. //-- CMICmnLLDBUtilSBValue::CMICmnLLDBUtilSBValue(const lldb::SBValue &vrValue, const bool vbHandleCharType /* = false */) : m_rValue(const_cast(vrValue)) , m_pUnkwn("??") , m_bHandleCharType(vbHandleCharType) { m_bValidSBValue = m_rValue.IsValid(); } //++ ------------------------------------------------------------------------------------ // Details: CMICmnLLDBUtilSBValue destructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmnLLDBUtilSBValue::~CMICmnLLDBUtilSBValue(void) { } //++ ------------------------------------------------------------------------------------ // Details: Retrieve from the LLDB SB Value object the name of the variable. If the name // is invalid (or the SBValue object invalid) then "??" is returned. // Type: Method. // Args: None. // Return: CMIUtilString - Name of the variable or "??" for unknown. // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::GetName(void) const { const MIchar *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr; const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn); return text; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve from the LLDB SB Value object the value of the variable described in // text. If the value is invalid (or the SBValue object invalid) then "??" is // returned. // Type: Method. // Args: None. // Return: CMIUtilString - Text description of the variable's value or "??". // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::GetValue(void) const { CMIUtilString text; if (m_bHandleCharType && IsCharType()) { const lldb::addr_t addr = m_rValue.GetLoadAddress(); text = CMIUtilString::Format("0x%08x", addr); const CMIUtilString cString(GetValueCString()); if (!cString.empty()) text += CMIUtilString::Format(" %s", cString.c_str()); } else { const MIchar *pValue = m_bValidSBValue ? m_rValue.GetValue() : nullptr; text = (pValue != nullptr) ? pValue : m_pUnkwn; } return text; } //++ ------------------------------------------------------------------------------------ // Details: If the LLDB SB Value object is a char type then form the text data string // otherwise return nothing. m_bHandleCharType must be true to return text data // if any. // Type: Method. // Args: None. // Return: CMIUtilString - Text description of the variable's value. // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::GetValueCString(void) const { CMIUtilString text; if (m_bHandleCharType && IsCharType()) { text = ReadCStringFromHostMemory(m_rValue); } return text; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the flag stating whether this value object is a char type or some // other type. Char type can be signed or unsigned. // Type: Method. // Args: None. // Return: bool - True = Yes is a char type, false = some other type. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::IsCharType(void) const { const MIchar *pName = m_rValue.GetName(); MIunused(pName); const lldb::BasicType eType = m_rValue.GetType().GetBasicType(); return ((eType == lldb::eBasicTypeChar) || (eType == lldb::eBasicTypeSignedChar) || (eType == lldb::eBasicTypeUnsignedChar)); } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the flag stating whether any child value object of *this object is a // char type or some other type. Returns false if there are not children. Char // type can be signed or unsigned. // Type: Method. // Args: None. // Return: bool - True = Yes is a char type, false = some other type. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::IsChildCharType(void) const { const MIuint nChildren = m_rValue.GetNumChildren(); // Is it a basic type if (nChildren == 0) return false; // Is it a composite type if (nChildren > 1) return false; lldb::SBValue member = m_rValue.GetChildAtIndex(0); const CMICmnLLDBUtilSBValue utilValue(member); return utilValue.IsCharType(); } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the C string data for a child of char type (one and only child) for // the parent value object. If the child is not a char type or the parent has // more than one child then an empty string is returned. Char type can be // signed or unsigned. // Type: Method. // Args: None. // Return: CMIUtilString - Text description of the variable's value. // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::GetChildValueCString(void) const { CMIUtilString text; const MIuint nChildren = m_rValue.GetNumChildren(); // Is it a basic type if (nChildren == 0) return text; // Is it a composite type if (nChildren > 1) return text; lldb::SBValue member = m_rValue.GetChildAtIndex(0); const CMICmnLLDBUtilSBValue utilValue(member); if (m_bHandleCharType && utilValue.IsCharType()) { text = ReadCStringFromHostMemory(member); } return text; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the C string data of value object by read the memory where the // variable is held. // Type: Method. // Args: vrValueObj - (R) LLDB SBValue variable object. // Return: CMIUtilString - Text description of the variable's value. // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::ReadCStringFromHostMemory(const lldb::SBValue &vrValueObj) const { CMIUtilString text; lldb::SBValue &rValue = const_cast(vrValueObj); const lldb::addr_t addr = rValue.GetLoadAddress(); CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); const MIuint nBytes(128); const MIchar *pBufferMemory = new MIchar[nBytes]; lldb::SBError error; const MIuint64 nReadBytes = rSessionInfo.GetProcess().ReadMemory(addr, (void *)pBufferMemory, nBytes, error); MIunused(nReadBytes); text = CMIUtilString::Format("\\\"%s\\\"", pBufferMemory); delete[] pBufferMemory; return text; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the state of the value object's name. // Type: Method. // Args: None. // Return: bool - True = yes name is indeterminate, false = name is valid. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::IsNameUnknown(void) const { const CMIUtilString name(GetName()); return (name == m_pUnkwn); } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the state of the value object's value data. // Type: Method. // Args: None. // Return: bool - True = yes value is indeterminate, false = value valid. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::IsValueUnknown(void) const { const CMIUtilString value(GetValue()); return (value == m_pUnkwn); } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the value object's type name if valid. // Type: Method. // Args: None. // Return: CMIUtilString - The type name or "??". // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::GetTypeName(void) const { const MIchar *pName = m_bValidSBValue ? m_rValue.GetTypeName() : nullptr; const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn); return text; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the value object's display type name if valid. // Type: Method. // Args: None. // Return: CMIUtilString - The type name or "??". // Throws: None. //-- CMIUtilString CMICmnLLDBUtilSBValue::GetTypeNameDisplay(void) const { const MIchar *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr; const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn); return text; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve whether the value object's is valid or not. // Type: Method. // Args: None. // Return: bool - True = valid, false = not valid. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::IsValid(void) const { return m_bValidSBValue; } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the value object' has a name. A value object can be valid but still // have no name which suggest it is not a variable. // Type: Method. // Args: None. // Return: bool - True = valid, false = not valid. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::HasName(void) const { bool bHasAName = false; const MIchar *pName = m_bValidSBValue ? m_rValue.GetDisplayTypeName() : nullptr; if (pName != nullptr) { bHasAName = (CMIUtilString(pName).length() > 0); } return bHasAName; } //++ ------------------------------------------------------------------------------------ // Details: Determine if the value object' respresents a LLDB variable i.e. "$0". // Type: Method. // Args: None. // Return: bool - True = Yes LLDB variable, false = no. // Throws: None. //-- bool CMICmnLLDBUtilSBValue::IsLLDBVariable(void) const { return (GetName().at(0) == '$'); }