The same thing for me as I wrote in http://reviews.llvm.org/rL235109.
Thanks, Ilia On Apr 17, 2015 12:35 AM, "Chuck Ries" <[email protected]> wrote: > After this change I am seeing the cmake build broken on mac os. > > FAILED: /usr/bin/c++ -DGTEST_HAS_RTTI=0 -DHAVE_ROUND -DLIBXML2_DEFINED > -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS > -D__STDC_LIMIT_MACROS -fPIC -fvisibility-inlines-hidden -Wall -W > -Wno-unused-parameter -Wwrite-strings -Wcast-qual > -Wmissing-field-initializers -pedantic -Wno-long-long > -Wcovered-switch-default -std=c++11 -fcolor-diagnostics > -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-deprecated-register > -fno-exceptions -fno-rtti -fPIC -fPIC -g > -Itools/lldb/source/Plugins/Process/gdb-remote > -I/Users/chuckr/llama/llvm/tools/lldb/source/Plugins/Process/gdb-remote > -I/Users/chuckr/llama/llvm/tools/lldb/include -Itools/lldb/include > -Iinclude -I/Users/chuckr/llama/llvm/include > -I/System/Library/Frameworks/Python.framework/Headers > -I/Users/chuckr/llama/llvm/tools/lldb/../clang/include > -Itools/lldb/../clang/include > -I/Users/chuckr/llama/llvm/tools/lldb/source/. -fno-exceptions -fno-rtti > -MMD -MT tools/lldb/source/Plugins/Process/gdb-remote/CMakeFiles/lldbPl! > uginProcessGDBRemote.dir/ProcessGDBRemote.cpp.o -MF > tools/lldb/source/Plugins/Process/gdb-remote/CMakeFiles/lldbPluginProcessGDBRemote.dir/ProcessGDBRemote.cpp.o.d > -o > tools/lldb/source/Plugins/Process/gdb-remote/CMakeFiles/lldbPluginProcessGDBRemote.dir/ProcessGDBRemote.cpp.o > -c > /Users/chuckr/llama/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp > /Users/chuckr/llama/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp:31:10: > fatal error: 'libxml/xmlreader.h' file not found > #include <libxml/xmlreader.h> > ^ > 1 error generated. > > -----Original Message----- > From: [email protected] [mailto: > [email protected]] On Behalf Of Colin Riley > Sent: Thursday, April 16, 2015 8:52 AM > To: [email protected] > Subject: [Lldb-commits] [lldb] r235109 - Adds lldb support for querying > the register mapping from gdbserver remote targets using > qXfer:features:read packet. Only enabled if libxml2 enabled in build. > > Author: domipheus > Date: Thu Apr 16 10:51:33 2015 > New Revision: 235109 > > URL: http://llvm.org/viewvc/llvm-project?rev=235109&view=rev > Log: > Adds lldb support for querying the register mapping from gdbserver remote > targets using qXfer:features:read packet. Only enabled if libxml2 enabled > in build. > > Differential Revision: http://reviews.llvm.org/D8999 > > Modified: > lldb/trunk/cmake/modules/LLDBConfig.cmake > lldb/trunk/source/Commands/CommandObjectRegister.cpp > > lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp > > lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h > lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp > lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h > > Modified: lldb/trunk/cmake/modules/LLDBConfig.cmake > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/cmake/modules/LLDBConfig.cmake?rev=235109&r1=235108&r2=235109&view=diff > > ============================================================================== > --- lldb/trunk/cmake/modules/LLDBConfig.cmake (original) > +++ lldb/trunk/cmake/modules/LLDBConfig.cmake Thu Apr 16 10:51:33 2015 > @@ -187,29 +187,39 @@ install(DIRECTORY include/ > DESTINATION include > FILES_MATCHING > PATTERN "*.h" > - PATTERN ".svn" EXCLUDE > - ) > - > - > -# Find libraries or frameworks that may be needed -if (CMAKE_SYSTEM_NAME > MATCHES "Darwin") > + PATTERN ".svn" EXCLUDE > + ) > + > +if (NOT LIBXML2_FOUND) > + find_package(LibXml2) > +endif() > + > +# Find libraries or frameworks that may be needed if (CMAKE_SYSTEM_NAME > +MATCHES "Darwin") > find_library(CARBON_LIBRARY Carbon) > find_library(FOUNDATION_LIBRARY Foundation) > find_library(CORE_FOUNDATION_LIBRARY CoreFoundation) > find_library(CORE_SERVICES_LIBRARY CoreServices) > - find_library(SECURITY_LIBRARY Security) > - find_library(DEBUG_SYMBOLS_LIBRARY DebugSymbols PATHS > "/System/Library/PrivateFrameworks") > - > - if (NOT LIBXML2_FOUND) > - find_package(LibXml2) > - endif () > - list(APPEND system_libs xml2 ncurses panel) > - list(APPEND system_libs ${CARBON_LIBRARY} ${FOUNDATION_LIBRARY} > - ${CORE_FOUNDATION_LIBRARY} ${CORE_SERVICES_LIBRARY} ${SECURITY_LIBRARY} > - ${DEBUG_SYMBOLS_LIBRARY}) > -endif() > - > -if(LLDB_REQUIRES_EH) > + find_library(SECURITY_LIBRARY Security) > + find_library(DEBUG_SYMBOLS_LIBRARY DebugSymbols PATHS > + "/System/Library/PrivateFrameworks") > + > + add_definitions( -DLIBXML2_DEFINED ) > + list(APPEND system_libs xml2 ncurses panel) list(APPEND system_libs > + ${CARBON_LIBRARY} ${FOUNDATION_LIBRARY} ${CORE_FOUNDATION_LIBRARY} > + ${CORE_SERVICES_LIBRARY} ${SECURITY_LIBRARY} > + ${DEBUG_SYMBOLS_LIBRARY}) > + > +else() > + > + if (LIBXML2_FOUND) > + add_definitions( -DLIBXML2_DEFINED ) > + list(APPEND system_libs ${LIBXML2_LIBRARIES}) > + include_directories(${LIBXML2_INCLUDE_DIR}) > + endif() > + > +endif() > + > +if(LLDB_REQUIRES_EH) > set(LLDB_REQUIRES_RTTI ON) > else() > if(LLVM_COMPILER_IS_GCC_COMPATIBLE) > > Modified: lldb/trunk/source/Commands/CommandObjectRegister.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectRegister.cpp?rev=235109&r1=235108&r2=235109&view=diff > > ============================================================================== > --- lldb/trunk/source/Commands/CommandObjectRegister.cpp (original) > +++ lldb/trunk/source/Commands/CommandObjectRegister.cpp Thu Apr 16 > +++ 10:51:33 2015 > @@ -144,7 +144,7 @@ public: > const RegisterSet * const reg_set = > reg_ctx->GetRegisterSet(set_idx); > if (reg_set) > { > - strm.Printf ("%s:\n", reg_set->name); > + strm.Printf ("%s:\n", (reg_set->name ? reg_set->name : > + "unknown") ); > strm.IndentMore (); > const size_t num_registers = reg_set->num_registers; > for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) > > Modified: > lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=235109&r1=235108&r2=235109&view=diff > > ============================================================================== > --- > lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp > (original) > +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationC > +++ lient.cpp Thu Apr 16 10:51:33 2015 > @@ -79,6 +79,7 @@ GDBRemoteCommunicationClient::GDBRemoteC > m_supports_QSaveRegisterState (eLazyBoolCalculate), > m_supports_qXfer_auxv_read (eLazyBoolCalculate), > m_supports_qXfer_libraries_read (eLazyBoolCalculate), > + m_supports_qXfer_features_read (eLazyBoolCalculate), > m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate), > m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate), > m_supports_jThreadExtendedInfo (eLazyBoolCalculate), @@ -214,6 > +215,16 @@ GDBRemoteCommunicationClient::GetQXferAu > return (m_supports_qXfer_auxv_read == eLazyBoolYes); } > > +bool > +GDBRemoteCommunicationClient::GetQXferFeaturesReadSupported () { > + if (m_supports_qXfer_features_read == eLazyBoolCalculate) > + { > + GetRemoteQSupported(); > + } > + return (m_supports_qXfer_features_read == eLazyBoolYes); } > + > uint64_t > GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() > { > @@ -335,6 +346,7 @@ GDBRemoteCommunicationClient::ResetDisco > m_supports_qXfer_auxv_read = eLazyBoolCalculate; > m_supports_qXfer_libraries_read = eLazyBoolCalculate; > m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate; > + m_supports_qXfer_features_read = eLazyBoolCalculate; > m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate; > > m_supports_qProcessInfoPID = true; > @@ -373,10 +385,21 @@ GDBRemoteCommunicationClient::GetRemoteQ > m_supports_qXfer_libraries_read = eLazyBoolNo; > m_supports_qXfer_libraries_svr4_read = eLazyBoolNo; > m_supports_augmented_libraries_svr4_read = eLazyBoolNo; > + m_supports_qXfer_features_read = eLazyBoolNo; > m_max_packet_size = UINT64_MAX; // It's supposed to always be there, > but if not, we assume no limit > > + // build the qSupported packet > + std::vector<std::string> features = {"xmlRegisters=i386,arm,mips"}; > + StreamString packet; > + packet.PutCString( "qSupported" ); > + for ( uint32_t i = 0; i < features.size( ); ++i ) > + { > + packet.PutCString( i==0 ? ":" : ";"); > + packet.PutCString( features[i].c_str( ) ); > + } > + > StringExtractorGDBRemote response; > - if (SendPacketAndWaitForResponse("qSupported", > + if (SendPacketAndWaitForResponse(packet.GetData(), > response, > /*send_async=*/false) == > PacketResult::Success) > { > @@ -392,6 +415,8 @@ GDBRemoteCommunicationClient::GetRemoteQ > } > if (::strstr (response_cstr, "qXfer:libraries:read+")) > m_supports_qXfer_libraries_read = eLazyBoolYes; > + if (::strstr (response_cstr, "qXfer:features:read+")) > + m_supports_qXfer_features_read = eLazyBoolYes; > > const char *packet_size_str = ::strstr (response_cstr, > "PacketSize="); > if (packet_size_str) > @@ -3776,3 +3801,74 @@ GDBRemoteCommunicationClient::GetModuleI > > return true; > } > + > +// query the target remote for extended information using the qXfer > +packet // // example: object='features', annex='target.xml', out=<xml > +output> // return: 'true' on success > +// 'false' on failure (err set) > +bool > +GDBRemoteCommunicationClient::ReadExtFeature (const > lldb_private::ConstString object, > + const > lldb_private::ConstString annex, > + std::string & out, > + lldb_private::Error & > +err) { > + > + std::stringstream output; > + StringExtractorGDBRemote chunk; > + > + const int size = 0xfff; > + int offset = 0; > + bool active = true; > + > + // loop until all data has been read > + while ( active ) { > + > + // send query extended feature packet > + std::stringstream packet; > + packet << "qXfer:" > + << object.AsCString( ) << ":read:" > + << annex.AsCString( ) << ":" > + << std::hex << offset << "," > + << std::hex << size; > + > + GDBRemoteCommunication::PacketResult res = > + SendPacketAndWaitForResponse( packet.str().c_str(), > + chunk, > + false ); > + > + if ( res != GDBRemoteCommunication::PacketResult::Success ) { > + err.SetErrorString( "Error sending $qXfer packet" ); > + return false; > + } > + > + const std::string & str = chunk.GetStringRef( ); > + if ( str.length() == 0 ) { > + // should have some data in chunk > + err.SetErrorString( "Empty response from $qXfer packet" ); > + return false; > + } > + > + // check packet code > + switch ( str[0] ) { > + // last chunk > + case ( 'l' ): > + active = false; > + // fall through intensional > + > + // more chunks > + case ( 'm' ) : > + if ( str.length() > 1 ) > + output << &str[1]; > + break; > + > + // unknown chunk > + default: > + err.SetErrorString( "Invalid continuation code from $qXfer > packet" ); > + return false; > + } > + } > + > + out = output.str( ); > + err.Success( ); > + return true; > +} > > Modified: > lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=235109&r1=235108&r2=235109&view=diff > > ============================================================================== > --- > lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h > (original) > +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationC > +++ lient.h Thu Apr 16 10:51:33 2015 > @@ -426,6 +426,9 @@ public: > bool > GetAugmentedLibrariesSVR4ReadSupported (); > > + bool > + GetQXferFeaturesReadSupported (); > + > LazyBool > SupportsAllocDeallocMemory () // const > { > @@ -533,6 +536,12 @@ public: > const ArchSpec& arch_spec, > ModuleSpec &module_spec); > > + bool > + ReadExtFeature (const lldb_private::ConstString object, > + const lldb_private::ConstString annex, > + std::string & out, > + lldb_private::Error & err); > + > protected: > > PacketResult > @@ -576,6 +585,7 @@ protected: > LazyBool m_supports_qXfer_auxv_read; > LazyBool m_supports_qXfer_libraries_read; > LazyBool m_supports_qXfer_libraries_svr4_read; > + LazyBool m_supports_qXfer_features_read; > LazyBool m_supports_augmented_libraries_svr4_read; > LazyBool m_supports_jThreadExtendedInfo; > > > Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=235109&r1=235108&r2=235109&view=diff > > ============================================================================== > --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp > (original) > +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp > +++ Thu Apr 16 10:51:33 2015 > @@ -27,6 +27,9 @@ > #include <mutex> > > // Other libraries and framework includes > +#if defined( LIBXML2_DEFINED ) > +#include <libxml/xmlreader.h> > +#endif > > #include "lldb/Breakpoint/Watchpoint.h" > #include "lldb/Interpreter/Args.h" > @@ -571,6 +574,10 @@ ProcessGDBRemote::BuildDynamicRegisterIn > > if (reg_num == 0) > { > + // try to extract information from servers target.xml > + if ( GetGDBServerInfo( ) ) > + return; > + > FileSpec target_definition_fspec = > GetGlobalPluginProperties()->GetTargetDefinitionFile (); > > if (target_definition_fspec) > @@ -3429,6 +3436,465 @@ ProcessGDBRemote::GetModuleSpec(const Fi > return true; > } > > +#if defined( LIBXML2_DEFINED ) > +namespace { > + > +typedef std::vector<std::string> stringVec; typedef > +std::vector<xmlNodePtr> xmlNodePtrVec; > + > +struct GdbServerRegisterInfo { > + > + struct { > + bool m_has_name : 1; > + bool m_has_bitSize : 1; > + bool m_has_type : 1; > + bool m_has_group : 1; > + bool m_has_regNum : 1; > + } > + m_flags; > + > + std::string m_name; > + std::string m_group; > + uint32_t m_bitSize; > + uint32_t m_regNum; > + > + enum RegType { > + eUnknown , > + eCodePtr , > + eDataPtr , > + eInt32 , > + eI387Ext , > + } > + m_type; > + > + void clear( ) { > + memset( &m_flags, 0, sizeof( m_flags ) ); > + } > +}; > + > +typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec; > + > +struct GdbServerTargetInfo { > + > + std::string m_arch; > + std::string m_osabi; > +}; > + > +// conversion table between gdb register type and enum struct { > + const char * m_name; > + GdbServerRegisterInfo::RegType m_type; } RegTypeTable[] = { > + { "int32" , GdbServerRegisterInfo::eInt32 }, > + { "int" , GdbServerRegisterInfo::eInt32 }, > + { "data_ptr", GdbServerRegisterInfo::eDataPtr }, > + { "code_ptr", GdbServerRegisterInfo::eCodePtr }, > + { "i387_ext", GdbServerRegisterInfo::eI387Ext }, // 80bit fpu > + { nullptr } // sentinel > +}; > + > +// find the first sibling with a matching name xmlNodePtr > +xmlExFindSibling (xmlNodePtr node, > + const std::string & name) { > + > + if ( !node ) return nullptr; > + // iterate through all siblings > + for ( xmlNodePtr temp = node; temp; temp=temp->next ) { > + // we are looking for elements > + if ( temp->type != XML_ELEMENT_NODE ) > + continue; > + // check element name matches > + if ( !temp->name ) continue; > + if ( std::strcmp((const char*)temp->name, name.c_str() ) == 0 ) > + return temp; > + } > + // no sibling found > + return nullptr; > +} > + > +// find an element from a given element path xmlNodePtr > +xmlExFindElement (xmlNodePtr node, > + const stringVec & path) { > + > + if ( !node ) return nullptr; > + xmlNodePtr temp = node; > + // iterate all elements in path > + for ( uint32_t i = 0; i < path.size( ); i++ ) { > + > + // search for a sibling with this name > + temp = xmlExFindSibling( temp, path[i] ); > + if ( !temp ) > + return nullptr; > + // enter this node if we still need to search > + if ( (i+1) < path.size() ) > + // enter the node we have found > + temp = temp->children; > + } > + // note: node may still be nullptr at this step > + return temp; > +} > + > +// locate a specific attribute in an element xmlAttr * > +xmlExFindAttribute (xmlNodePtr node, > + const std::string & name) { > + > + if ( !node ) > + return nullptr; > + if ( node->type != XML_ELEMENT_NODE ) > + return nullptr; > + // iterate over all attributes > + for ( xmlAttrPtr attr = node->properties; attr != nullptr; > attr=attr->next ) { > + // check if name matches > + if ( !attr->name ) continue; > + if ( std::strcmp( (const char*)attr->name, name.c_str( ) ) == 0 ) > + return attr; > + } > + return nullptr; > +} > + > +// find all child elements with given name and add them to a vector // > +// input: node = xml element to search > +// name = name used when matching child elements > +// output: out = list of matches > +// return: number of children added to 'out' > +int > +xmlExFindChildren (xmlNodePtr node, > + const std::string & name, > + xmlNodePtrVec & out) { > + > + if ( !node ) return 0; > + int count = 0; > + // iterate over all children > + for ( xmlNodePtr child = node->children; child; child = child->next ) > { > + // if name matches > + if ( !child->name ) continue; > + if ( std::strcmp( (const char*)child->name, name.c_str( ) ) == 0 > ) { > + // add to output list > + out.push_back( child ); > + ++count; > + } > + } > + return count; > +} > + > +// get the text content from an attribute std::string > +xmlExGetTextContent (xmlAttrPtr attr) { > + > + if ( !attr ) > + return std::string( ); > + if ( attr->type != XML_ATTRIBUTE_NODE ) > + return std::string( ); > + // check child is a text node > + xmlNodePtr child = attr->children; > + if ( child->type != XML_TEXT_NODE ) > + return std::string( ); > + // access the content > + assert( child->content != nullptr ); > + return std::string( (const char*) child->content ); } > + > +// get the text content from an node > +std::string > +xmlExGetTextContent (xmlNodePtr node) { > + > + if ( !node ) > + return std::string( ); > + if ( node->type != XML_ELEMENT_NODE ) > + return std::string( ); > + // check child is a text node > + xmlNodePtr child = node->children; > + if ( child->type != XML_TEXT_NODE ) > + return std::string( ); > + // access the content > + assert( child->content != nullptr ); > + return std::string( (const char*) child->content ); } > + > +// compile a list of xml includes from the target file > +// input: doc = target.xml > +// output: includes = list of .xml names specified in target.xml // > +return: number of .xml files specified in target.xml and added to > +includes int parseTargetIncludes (xmlDocPtr doc, stringVec & includes) > +{ > + > + if ( !doc ) return 0; > + int count = 0; > + xmlNodePtr elm = xmlExFindElement( doc->children, { "target" } ); > + if (! elm ) return 0; > + xmlNodePtrVec nodes; > + xmlExFindChildren( elm, "xi:include", nodes ); > + // iterate over all includes > + for ( uint32_t i = 0; i < nodes.size(); i++ ) { > + xmlAttrPtr attr = xmlExFindAttribute( nodes[i], "href" ); > + if ( attr != nullptr ) { > + std::string text = xmlExGetTextContent( attr ); > + includes.push_back( text ); > + ++count; > + } > + } > + return count; > +} > + > +// extract target arch information from the target.xml file > +// input: doc = target.xml document > +// output: out = remote target information // return: 'true' on > +success > +// 'false' on failure > +bool > +parseTargetInfo (xmlDocPtr doc, GdbServerTargetInfo & out) { > + > + if ( !doc ) return false; > + xmlNodePtr e1 = xmlExFindElement( doc->children, { "target", > "architecture" } ); > + if ( !e1 ) return false; > + out.m_arch = xmlExGetTextContent( e1 ); > + > + xmlNodePtr e2 = xmlExFindElement( doc->children, { "target", "osabi" > } ); > + if ( !e2 ) return false; > + out.m_osabi = xmlExGetTextContent( e2 ); > + > + return true; > +} > + > +// extract register information from one of the xml files specified in > target.xml > +// input: doc = xml document > +// output: regList = list of extracted register info // return: > +'true' on success > +// 'false' on failure > +bool > +parseRegisters (xmlDocPtr doc, GDBServerRegisterVec & regList) { > + > + if ( !doc ) return false; > + xmlNodePtr elm = xmlExFindElement( doc->children, { "feature" } ); > + if ( !elm ) return false; > + > + xmlAttrPtr attr = nullptr; > + > + xmlNodePtrVec regs; > + xmlExFindChildren( elm, "reg", regs ); > + for ( int i = 0; i < regs.size( ); i++ ) { > + > + GdbServerRegisterInfo reg; > + reg.clear( ); > + > + if ( attr = xmlExFindAttribute( regs[i], "name" ) ) { > + reg.m_name = xmlExGetTextContent( attr ).c_str(); > + reg.m_flags.m_has_name = true; > + } > + > + if ( attr = xmlExFindAttribute( regs[i], "bitsize" ) ) { > + const std::string v = xmlExGetTextContent( attr ); > + reg.m_bitSize = atoi( v.c_str( ) ); > + reg.m_flags.m_has_bitSize = true; > + } > + > + if ( attr = xmlExFindAttribute( regs[i], "type" ) ) { > + const std::string v = xmlExGetTextContent( attr ); > + reg.m_type = GdbServerRegisterInfo::eUnknown; > + > + // search the type table for a match > + for ( int j = 0; RegTypeTable[j].m_name !=nullptr ;++j ) { > + if (RegTypeTable[j].m_name == v) { > + reg.m_type = RegTypeTable[j].m_type; > + break; > + } > + } > + > + reg.m_flags.m_has_type = (reg.m_type != > GdbServerRegisterInfo::eUnknown); > + } > + > + if ( attr = xmlExFindAttribute( regs[i], "group" ) ) { > + reg.m_group = xmlExGetTextContent( attr ); > + reg.m_flags.m_has_group = true; > + } > + > + if ( attr = xmlExFindAttribute( regs[i], "regnum" ) ) { > + const std::string v = xmlExGetTextContent( attr ); > + reg.m_regNum = atoi( v.c_str( ) ); > + reg.m_flags.m_has_regNum = true; > + } > + > + regList.push_back( reg ); > + } > + > + //TODO: there is also a "vector" element to parse > + //TODO: there is also eflags to parse > + > + return true; > +} > + > +// build lldb gdb-remote's dynamic register info from a vector of gdb > provided registers > +// input: regList = register information provided by gdbserver > +// output: regInfo = dynamic register information required by > +gdb-remote void BuildRegisters (const GDBServerRegisterVec & regList, > + GDBRemoteDynamicRegisterInfo & regInfo) { > + > + using namespace lldb_private; > + > + const uint32_t defSize = 32; > + uint32_t regNum = 0; > + uint32_t byteOffset = 0; > + > + for ( uint32_t i = 0; i < regList.size( ); ++i ) { > + > + const GdbServerRegisterInfo & gdbReg = regList[i]; > + > + std::string name = gdbReg.m_flags.m_has_name ? > gdbReg.m_name : "unknown"; > + std::string group = gdbReg.m_flags.m_has_group ? > gdbReg.m_group : "general"; > + uint32_t byteSize = gdbReg.m_flags.m_has_bitSize ? > (gdbReg.m_bitSize/8) : defSize; > + > + if ( gdbReg.m_flags.m_has_regNum ) > + regNum = gdbReg.m_regNum; > + > + uint32_t regNumGcc = LLDB_INVALID_REGNUM; > + uint32_t regNumDwarf = LLDB_INVALID_REGNUM; > + uint32_t regNumGeneric = LLDB_INVALID_REGNUM; > + uint32_t regNumGdb = regNum; > + uint32_t regNumNative = regNum; > + > + if ( name == "eip" || name == "pc" ) { > + regNumGeneric = LLDB_REGNUM_GENERIC_PC; > + } > + if ( name == "esp" || name == "sp" ) { > + regNumGeneric = LLDB_REGNUM_GENERIC_SP; > + } > + if ( name == "ebp") { > + regNumGeneric = LLDB_REGNUM_GENERIC_FP; > + } > + if ( name == "lr" ) { > + regNumGeneric = LLDB_REGNUM_GENERIC_RA; > + } > + > + RegisterInfo info = { > + name.c_str(), > + nullptr , > + byteSize , > + byteOffset , > + lldb::Encoding::eEncodingUint, > + lldb::Format::eFormatDefault, > + { regNumGcc , > + regNumDwarf , > + regNumGeneric, > + regNumGdb , > + regNumNative }, > + nullptr, > + nullptr > + }; > + > + ConstString regName = ConstString( gdbReg.m_name ); > + ConstString regAltName = ConstString( ); > + ConstString regGroup = ConstString( group ); > + regInfo.AddRegister( info, regName, regAltName, regGroup ); > + > + // advance register info > + byteOffset += byteSize; > + regNum += 1; > + } > + > + regInfo.Finalize (); > +} > + > +} // namespace {} > + > +void XMLCDECL > +libxml2NullErrorFunc (void *ctx, const char *msg, ...) { > + // do nothing currently > +} > + > +// query the target of gdb-remote for extended target information // > +return: 'true' on success > +// 'false' on failure > +bool > +ProcessGDBRemote::GetGDBServerInfo () > +{ > + > + // redirect libxml2's error handler since the default prints to stdout > + xmlGenericErrorFunc func = libxml2NullErrorFunc; > + initGenericErrorDefaultFunc( &func ); > + > + GDBRemoteCommunicationClient & comm = m_gdb_comm; > + GDBRemoteDynamicRegisterInfo & regInfo = m_register_info; > + > + // check that we have extended feature read support > + if ( !comm.GetQXferFeaturesReadSupported( ) ) > + return false; > + > + // request the target xml file > + std::string raw; > + lldb_private::Error lldberr; > + if (! comm.ReadExtFeature( ConstString( "features" ), > + ConstString( "target.xml" ), > + raw, > + lldberr ) ) { > + return false; > + } > + > + // parse the xml file in memory > + xmlDocPtr doc = xmlReadMemory( raw.c_str( ), raw.size( ), > "noname.xml", nullptr, 0 ); > + if ( doc == nullptr ) > + return false; > + > + // extract target info from target.xml > + GdbServerTargetInfo gdbInfo; > + if ( parseTargetInfo( doc, gdbInfo ) ) { > + // NOTE: We could deduce triple from gdbInfo if lldb doesn't > already have one set > + } > + > + // collect registers from all of the includes > + GDBServerRegisterVec regList; > + stringVec includes; > + if ( parseTargetIncludes( doc, includes ) > 0 ) { > + > + for ( uint32_t i = 0; i < includes.size( ); ++i ) { > + > + // request register file > + if ( !comm.ReadExtFeature( ConstString( "features" ), > + ConstString( includes[i] ), > + raw, > + lldberr ) ) > + continue; > + > + // parse register file > + xmlDocPtr regXml = xmlReadMemory( raw.c_str(), > + raw.size( ), > + includes[i].c_str(), > + nullptr, > + 0 ); > + if ( !regXml ) > + continue; > + > + // pass registers to lldb > + parseRegisters( regXml, regList ); > + } > + } > + > + // pass all of these registers to lldb > + BuildRegisters( regList, regInfo ); > + > + return true; > +} > + > +#else // if defined( LIBXML2_DEFINED ) > + > +using namespace lldb_private::process_gdb_remote; > + > +bool > +ProcessGDBRemote::GetGDBServerInfo () > +{ > + // stub (libxml2 not present) > + return false; > +} > + > +#endif // if defined( LIBXML2_DEFINED ) > + > + > class CommandObjectProcessGDBRemotePacketHistory : public > CommandObjectParsed { > private: > > Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h > URL: > http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=235109&r1=235108&r2=235109&view=diff > > ============================================================================== > --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h > (original) > +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Thu > +++ Apr 16 10:51:33 2015 > @@ -241,6 +241,10 @@ public: > const ArchSpec& arch, > ModuleSpec &module_spec) override; > > + // query remote gdbserver for information > + bool > + GetGDBServerInfo ( ); > + > protected: > friend class ThreadGDBRemote; > friend class GDBRemoteCommunicationClient; > > > _______________________________________________ > lldb-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits > > _______________________________________________ > lldb-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits >
_______________________________________________ lldb-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits
