forked from OSchip/llvm-project
Fetch object file load address if it isn't specified by the linker
Differential revision: http://reviews.llvm.org/D10490 llvm-svn: 240052
This commit is contained in:
parent
d2158755eb
commit
783bfc8caa
lldb
docs
include/lldb
source
Plugins
DynamicLoader/POSIX-DYLD
Process
Utility
|
@ -987,6 +987,24 @@ for this region.
|
|||
// for the QSaveRegisterState is added.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// qFileLoadAddress:<file_path>
|
||||
//
|
||||
// BRIEF
|
||||
// Get the load address of a memory mapped file.
|
||||
// The load address is defined as the address of the first memory
|
||||
// region what contains data mapped from the specified file.
|
||||
//
|
||||
// RESPONSE
|
||||
// <unsinged-hex64> - Load address of the file in big endian encoding
|
||||
// "E01" - the requested file isn't loaded
|
||||
// "EXX" - for any other errors
|
||||
//
|
||||
// PRIORITY TO IMPLEMENT
|
||||
// Low, required if dynamic linker don't fill in the load address of
|
||||
// some object file in the rendezvous data structure.
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// qModuleInfo:<module_path>;<arch triple>
|
||||
//
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "lldb/lldb-types.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
#include "NativeBreakpointList.h"
|
||||
#include "NativeWatchpointList.h"
|
||||
|
@ -293,6 +294,9 @@ namespace lldb_private
|
|||
virtual Error
|
||||
GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) = 0;
|
||||
|
||||
virtual Error
|
||||
GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) = 0;
|
||||
|
||||
protected:
|
||||
lldb::pid_t m_pid;
|
||||
|
||||
|
|
|
@ -3036,6 +3036,28 @@ public:
|
|||
virtual bool
|
||||
GetModuleSpec(const FileSpec& module_file_spec, const ArchSpec& arch, ModuleSpec &module_spec);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Try to find the load address of a file.
|
||||
/// The load address is defined as the address of the first memory
|
||||
/// region what contains data mapped from the specified file.
|
||||
///
|
||||
/// @param[in] file
|
||||
/// The name of the file whose load address we are looking for
|
||||
///
|
||||
/// @param[out] is_loaded
|
||||
/// \b True if the file is loaded into the memory and false
|
||||
/// otherwise.
|
||||
///
|
||||
/// @param[out] load_addr
|
||||
/// The load address of the file if it is loaded into the
|
||||
/// processes address space, LLDB_INVALID_ADDRESS otherwise.
|
||||
//------------------------------------------------------------------
|
||||
virtual Error
|
||||
GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr)
|
||||
{
|
||||
return Error("Not supported");
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -412,6 +412,17 @@ DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry)
|
|||
|
||||
entry.file_spec.SetFile(ReadStringFromMemory(entry.path_addr), false);
|
||||
|
||||
// The base_addr is not filled in for some case.
|
||||
// Try to figure it out based on the load address of the object file.
|
||||
if (entry.base_addr == 0)
|
||||
{
|
||||
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
|
||||
bool is_loaded = false;
|
||||
Error error = m_process->GetFileLoadAddress(entry.file_spec, is_loaded, load_addr);
|
||||
if (error.Success() && is_loaded)
|
||||
entry.base_addr = load_addr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3648,6 +3648,39 @@ NativeProcessLinux::GetLoadedModuleFileSpec(const char* module_path, FileSpec& f
|
|||
module_file_spec.GetFilename().AsCString(), GetID());
|
||||
}
|
||||
|
||||
Error
|
||||
NativeProcessLinux::GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr)
|
||||
{
|
||||
load_addr = LLDB_INVALID_ADDRESS;
|
||||
Error error = ProcFileReader::ProcessLineByLine (GetID (), "maps",
|
||||
[&] (const std::string &line) -> bool
|
||||
{
|
||||
StringRef maps_row(line);
|
||||
|
||||
SmallVector<StringRef, 16> maps_columns;
|
||||
maps_row.split(maps_columns, StringRef(" "), -1, false);
|
||||
|
||||
if (maps_columns.size() < 6)
|
||||
{
|
||||
// Return true to continue reading the proc file
|
||||
return true;
|
||||
}
|
||||
|
||||
if (maps_columns[5] == file_name)
|
||||
{
|
||||
StringExtractor addr_extractor(maps_columns[0].str().c_str());
|
||||
load_addr = addr_extractor.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
|
||||
|
||||
// Return false to stop reading the proc file further
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true to continue reading the proc file
|
||||
return true;
|
||||
});
|
||||
return error;
|
||||
}
|
||||
|
||||
Error
|
||||
NativeProcessLinux::ResumeThread(
|
||||
lldb::tid_t tid,
|
||||
|
|
|
@ -152,6 +152,9 @@ namespace process_linux {
|
|||
Error
|
||||
GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
|
||||
|
||||
Error
|
||||
GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) override;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Interface used by NativeRegisterContext-derived classes.
|
||||
// ---------------------------------------------------------------------
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace lldb_private::process_gdb_remote;
|
||||
using namespace llvm;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// GDBRemote Errors
|
||||
|
@ -134,6 +135,8 @@ GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers()
|
|||
&GDBRemoteCommunicationServerLLGS::Handle_qC);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
|
||||
&GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qFileLoadAddress,
|
||||
&GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir,
|
||||
&GDBRemoteCommunicationServerLLGS::Handle_qGetWorkingDir);
|
||||
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qMemoryRegionInfo,
|
||||
|
@ -2600,6 +2603,34 @@ GDBRemoteCommunicationServerLLGS::Handle_qWatchpointSupportInfo (StringExtractor
|
|||
return SendPacketNoLock(response.GetData(), response.GetSize());
|
||||
}
|
||||
|
||||
GDBRemoteCommunication::PacketResult
|
||||
GDBRemoteCommunicationServerLLGS::Handle_qFileLoadAddress (StringExtractorGDBRemote &packet)
|
||||
{
|
||||
// Fail if we don't have a current process.
|
||||
if (!m_debugged_process_sp ||
|
||||
m_debugged_process_sp->GetID () == LLDB_INVALID_PROCESS_ID)
|
||||
return SendErrorResponse(67);
|
||||
|
||||
packet.SetFilePos(strlen("qFileLoadAddress:"));
|
||||
if (packet.GetBytesLeft() == 0)
|
||||
return SendErrorResponse(68);
|
||||
|
||||
std::string file_name;
|
||||
packet.GetHexByteString(file_name);
|
||||
|
||||
lldb::addr_t file_load_address = LLDB_INVALID_ADDRESS;
|
||||
Error error = m_debugged_process_sp->GetFileLoadAddress(file_name, file_load_address);
|
||||
if (error.Fail())
|
||||
return SendErrorResponse(69);
|
||||
|
||||
if (file_load_address == LLDB_INVALID_ADDRESS)
|
||||
return SendErrorResponse(1); // File not loaded
|
||||
|
||||
StreamGDBRemote response;
|
||||
response.PutHex64(file_load_address);
|
||||
return SendPacketNoLock(response.GetData(), response.GetSize());
|
||||
}
|
||||
|
||||
void
|
||||
GDBRemoteCommunicationServerLLGS::FlushInferiorOutput ()
|
||||
{
|
||||
|
|
|
@ -236,6 +236,9 @@ protected:
|
|||
PacketResult
|
||||
Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
|
||||
|
||||
PacketResult
|
||||
Handle_qFileLoadAddress (StringExtractorGDBRemote &packet);
|
||||
|
||||
void
|
||||
SetCurrentThreadID (lldb::tid_t tid);
|
||||
|
||||
|
|
|
@ -4121,6 +4121,47 @@ ProcessGDBRemote::LoadModules ()
|
|||
return new_modules.GetSize();
|
||||
}
|
||||
|
||||
Error
|
||||
ProcessGDBRemote::GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr)
|
||||
{
|
||||
is_loaded = false;
|
||||
load_addr = LLDB_INVALID_ADDRESS;
|
||||
|
||||
std::string file_path = file.GetPath(false);
|
||||
if (file_path.empty ())
|
||||
return Error("Empty file name specified");
|
||||
|
||||
StreamString packet;
|
||||
packet.PutCString("qFileLoadAddress:");
|
||||
packet.PutCStringAsRawHex8(file_path.c_str());
|
||||
|
||||
StringExtractorGDBRemote response;
|
||||
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), response, false) != GDBRemoteCommunication::PacketResult::Success)
|
||||
return Error("Sending qFileLoadAddress packet failed");
|
||||
|
||||
if (response.IsErrorResponse())
|
||||
{
|
||||
if (response.GetError() == 1)
|
||||
{
|
||||
// The file is not loaded into the inferior
|
||||
is_loaded = false;
|
||||
load_addr = LLDB_INVALID_ADDRESS;
|
||||
return Error();
|
||||
}
|
||||
|
||||
return Error("Fetching file load address from remote server returned an error");
|
||||
}
|
||||
|
||||
if (response.IsNormalResponse())
|
||||
{
|
||||
is_loaded = true;
|
||||
load_addr = response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
|
||||
return Error();
|
||||
}
|
||||
|
||||
return Error("Unknown error happened during sending the load address packet");
|
||||
}
|
||||
|
||||
class CommandObjectProcessGDBRemoteSpeedTest: public CommandObjectParsed
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -238,8 +238,11 @@ public:
|
|||
const ArchSpec& arch,
|
||||
ModuleSpec &module_spec) override;
|
||||
|
||||
virtual size_t
|
||||
LoadModules () override;
|
||||
size_t
|
||||
LoadModules() override;
|
||||
|
||||
Error
|
||||
GetFileLoadAddress(const FileSpec& file, bool& is_loaded, lldb::addr_t& load_addr) override;
|
||||
|
||||
protected:
|
||||
friend class ThreadGDBRemote;
|
||||
|
|
|
@ -144,6 +144,10 @@ StringExtractorGDBRemote::GetServerPacketType () const
|
|||
if (PACKET_STARTS_WITH ("qEcho:")) return eServerPacketType_qEcho;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
if (PACKET_STARTS_WITH ("qFileLoadAddress:")) return eServerPacketType_qFileLoadAddress;
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
if (PACKET_STARTS_WITH ("qGroupName:")) return eServerPacketType_qGroupName;
|
||||
if (PACKET_MATCHES ("qGetWorkingDir")) return eServerPacketType_qGetWorkingDir;
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
eServerPacketType_qSpeedTest,
|
||||
eServerPacketType_qUserName,
|
||||
eServerPacketType_qGetWorkingDir,
|
||||
eServerPacketType_qFileLoadAddress,
|
||||
eServerPacketType_QEnvironment,
|
||||
eServerPacketType_QLaunchArch,
|
||||
eServerPacketType_QSetDisableASLR,
|
||||
|
|
Loading…
Reference in New Issue