//===-- 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< lldb::SBValue & >( 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< lldb::SBValue & >( 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.m_lldbProcess.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 ) == '$' ); }