summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTamas Berghammer <tberghammer@google.com>2015-06-18 20:43:56 +0000
committerTamas Berghammer <tberghammer@google.com>2015-06-18 20:43:56 +0000
commit783bfc8caa4c50c0248f90ea7adf2dbd1e48f4e7 (patch)
tree694f259f810cd5047c9525287ec609d39d78fede
parentd2158755eb718da05fc0ba817b9b7fb64d74a54f (diff)
downloadbcm5719-llvm-783bfc8caa4c50c0248f90ea7adf2dbd1e48f4e7.tar.gz
bcm5719-llvm-783bfc8caa4c50c0248f90ea7adf2dbd1e48f4e7.zip
Fetch object file load address if it isn't specified by the linker
Differential revision: http://reviews.llvm.org/D10490 llvm-svn: 240052
-rw-r--r--lldb/docs/lldb-gdb-remote.txt18
-rw-r--r--lldb/include/lldb/Host/common/NativeProcessProtocol.h4
-rw-r--r--lldb/include/lldb/Target/Process.h22
-rw-r--r--lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp11
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp33
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp31
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h3
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp41
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h7
-rw-r--r--lldb/source/Utility/StringExtractorGDBRemote.cpp4
-rw-r--r--lldb/source/Utility/StringExtractorGDBRemote.h1
12 files changed, 176 insertions, 2 deletions
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index 2b89c3451f0..b471b245f85 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -988,6 +988,24 @@ for this region.
//----------------------------------------------------------------------
//----------------------------------------------------------------------
+// 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>
//
// BRIEF
diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
index a1ddaec7f8a..f6a685aae14 100644
--- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -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;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 17bc88897a8..0e0838d4bc3 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -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:
//------------------------------------------------------------------
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
index 2d17fccd75a..b8cc286874c 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
@@ -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;
}
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index be07b436580..be4b3193050 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -3649,6 +3649,39 @@ NativeProcessLinux::GetLoadedModuleFileSpec(const char* module_path, FileSpec& f
}
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,
NativeThreadLinux::ResumeThreadFunction request_thread_resume_function,
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
index 137f7fdf8a9..1964aea6a19 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -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.
// ---------------------------------------------------------------------
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 8b31dbecec7..e8955ddbd6e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -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 ()
{
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index a5e2bbcc2be..1eda0b052bb 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -236,6 +236,9 @@ protected:
PacketResult
Handle_qWatchpointSupportInfo (StringExtractorGDBRemote &packet);
+ PacketResult
+ Handle_qFileLoadAddress (StringExtractorGDBRemote &packet);
+
void
SetCurrentThreadID (lldb::tid_t tid);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 355f052b786..64972dfda36 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -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:
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 21e633301d0..02f449ffca4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -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;
diff --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp
index 718c8f6e996..aeceaa00fa1 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -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;
diff --git a/lldb/source/Utility/StringExtractorGDBRemote.h b/lldb/source/Utility/StringExtractorGDBRemote.h
index 78f60217d86..beb07e5b57e 100644
--- a/lldb/source/Utility/StringExtractorGDBRemote.h
+++ b/lldb/source/Utility/StringExtractorGDBRemote.h
@@ -61,6 +61,7 @@ public:
eServerPacketType_qSpeedTest,
eServerPacketType_qUserName,
eServerPacketType_qGetWorkingDir,
+ eServerPacketType_qFileLoadAddress,
eServerPacketType_QEnvironment,
eServerPacketType_QLaunchArch,
eServerPacketType_QSetDisableASLR,
OpenPOWER on IntegriCloud