Skip to content

Commit

Permalink
Adds lldb support for querying the register mapping from gdbserver re…
Browse files Browse the repository at this point in the history
…mote targets using qXfer:features:read packet. Only enabled if libxml2 enabled in build.

Differential Revision: http://reviews.llvm.org/D8999

llvm-svn: 235109
  • Loading branch information
Domipheus committed Apr 16, 2015
1 parent a9e2057 commit c3c95b2
Show file tree
Hide file tree
Showing 6 changed files with 607 additions and 21 deletions.
48 changes: 29 additions & 19 deletions lldb/cmake/modules/LLDBConfig.cmake
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Commands/CommandObjectRegister.cpp
Expand Up @@ -144,7 +144,7 @@ class CommandObjectRegisterRead : public CommandObjectParsed
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)
Expand Down
Expand Up @@ -79,6 +79,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
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),
Expand Down Expand Up @@ -214,6 +215,16 @@ GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
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()
{
Expand Down Expand Up @@ -335,6 +346,7 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
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;
Expand Down Expand Up @@ -373,10 +385,21 @@ GDBRemoteCommunicationClient::GetRemoteQSupported ()
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)
{
Expand All @@ -392,6 +415,8 @@ GDBRemoteCommunicationClient::GetRemoteQSupported ()
}
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)
Expand Down Expand Up @@ -3776,3 +3801,74 @@ GDBRemoteCommunicationClient::GetModuleInfo (const FileSpec& module_file_spec,
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;
}
Expand Up @@ -426,6 +426,9 @@ class GDBRemoteCommunicationClient : public GDBRemoteCommunication
bool
GetAugmentedLibrariesSVR4ReadSupported ();

bool
GetQXferFeaturesReadSupported ();

LazyBool
SupportsAllocDeallocMemory () // const
{
Expand Down Expand Up @@ -533,6 +536,12 @@ class GDBRemoteCommunicationClient : public GDBRemoteCommunication
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
Expand Down Expand Up @@ -576,6 +585,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteCommunication
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;

Expand Down

0 comments on commit c3c95b2

Please sign in to comment.