aadsm created this revision.
aadsm added reviewers: clayborg, xiaobai.
Herald added subscribers: lldb-commits, krytarowski, srhines.
Herald added a project: LLDB.
aadsm added a parent revision: D62501: Implement GetSharedLibraryInfoAddress.
aadsm added a child revision: D62503: Add ReadCStringFromMemory for faster
string reads.
This is the fourth patch to improve module loading in a series that started
here (where I explain the motivation and solution): D62499
<https://reviews.llvm.org/D62499>
Implement the `xfer:libraries-svr4` packet by adding a new function that
generates the list and then in Handle_xfer I generate the XML for it. The XML
is really simple so I'm just using string concatenation because I believe it's
more readable than having to deal with a DOM api.
Concerns
--------
- I'm not sure about the having the ELFLinkMap and the SharedLibraryInfo struct
in there. I thought about creating a function or class outside of
NativeProcessLinux so it could be reusable in other contexts but the core
functions need to use ReadMemory so it was not convinent and I guess would have
forced me to pass a lambda as a wrapper to ReadMemory. This would introduce
more complexity to the code and I'm not sure if it would be worthwhile.
- On Handle_xfer function the backing buffer structure uses MemoryBuffers so I
had to create one out of the StreamString response I generate with the XML.
This kind of sucks because I'm copying all this data when I usually don't even
need it. And if I do need it still sucks because I'm copying something that I
just generated right there. I couldn't find a way to generate the XML into a
MemoryBuffer (as it requires to know the size before hand) or use another
structure that would make this easier. I've thought about changing the backing
structure to StringRefs but that object doesn't really own the underlying
"const char*" so I can't keep it without copying again. Any suggestions here?
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D62502
Files:
lldb/include/lldb/Host/common/NativeProcessProtocol.h
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -2760,6 +2760,28 @@
#else
return SendUnimplementedResponse("not implemented on this platform");
#endif
+ } else if (xfer_object == "libraries-svr4") {
+#if defined(__linux__)
+ std::vector<SharedLibraryInfo> library_list;
+ auto error =
+ m_debugged_process_up->GetLoadedSharedLibraries(library_list);
+ if (!error.Success())
+ return SendErrorResponse(error.GetError());
+
+ StreamString response;
+ response.Printf("<library-list-svr4 version=\"1.0\">");
+ for (auto const &library : library_list) {
+ response.Printf("<library name=\"%s\" ", library.name.c_str());
+ response.Printf("lm=\"0x%" PRIx64 "\" ", library.link_map);
+ response.Printf("l_addr=\"0x%" PRIx64 "\" ", library.base_addr);
+ response.Printf("l_ld=\"0x%" PRIx64 "\" />", library.ld_addr);
+ }
+ response.Printf("</library-list-svr4>");
+ memory_buffer_sp = std::move(
+ MemoryBuffer::getMemBufferCopy(response.GetString(), __FUNCTION__));
+#else
+ return SendUnimplementedResponse("not implemented on this platform");
+#endif
} else
return SendUnimplementedResponse("Xfer object not supported");
}
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -826,6 +826,9 @@
response.PutCString(";QPassSignals+");
response.PutCString(";qXfer:auxv:read+");
#endif
+#if defined(__linux__)
+ response.PutCString(";qXfer:libraries-svr4:read+");
+#endif
return SendPacketNoLock(response.GetString());
}
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -79,6 +79,9 @@
lldb::addr_t GetSharedLibraryInfoAddress() override;
+ Status GetLoadedSharedLibraries(
+ std::vector<SharedLibraryInfo> &library_list) override;
+
size_t UpdateThreads() override;
const ArchSpec &GetArchitecture() const override { return m_arch; }
@@ -133,6 +136,17 @@
template <typename ELF_EHDR, typename ELF_PHDR, typename ELF_DYN>
lldb::addr_t GetELFImageInfoAddress();
+ template <typename T> struct ELFLinkMap {
+ T l_addr;
+ T l_name;
+ T l_ld;
+ T l_next;
+ T l_prev;
+ };
+ template <typename T>
+ Status ReadSharedLibraryInfo(lldb::addr_t link_map_addr,
+ SharedLibraryInfo &info);
+
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -2169,3 +2169,76 @@
return LLDB_INVALID_ADDRESS;
}
+
+template <typename T>
+Status NativeProcessLinux::ReadSharedLibraryInfo(lldb::addr_t link_map_addr,
+ SharedLibraryInfo &info) {
+ ELFLinkMap<T> link_map;
+ size_t bytes_read;
+ auto error =
+ ReadMemory(link_map_addr, &link_map, sizeof(link_map), bytes_read);
+ if (!error.Success())
+ return error;
+
+ char name_buffer[PATH_MAX];
+ error = ReadMemory(link_map.l_name, &name_buffer, sizeof(name_buffer),
+ bytes_read);
+ if (!error.Success())
+ return error;
+
+ info.name = std::string(name_buffer);
+ info.link_map = link_map_addr;
+ info.base_addr = link_map.l_addr;
+ info.ld_addr = link_map.l_ld;
+ info.next = link_map.l_next;
+#if defined(__linux__) && !defined(__ANDROID__)
+ // On non-android linux systems, main executable has an empty path.
+ info.main = info.main.empty();
+#elif defined(__linux__) && defined(__ANDROID__)
+ // On android, the main executable has a load address of 0.
+ info.main = info.ld_addr == 0;
+#else
+ info.main = false;
+#endif
+
+ return Status();
+}
+
+Status NativeProcessLinux::GetLoadedSharedLibraries(
+ std::vector<SharedLibraryInfo> &library_list) {
+ // Address of DT_DEBUG.d_ptr which points to r_debug
+ lldb::addr_t info_address = GetSharedLibraryInfoAddress();
+ if (info_address == LLDB_INVALID_ADDRESS)
+ return Status("Invalid shared library info address");
+ // Address of r_debug
+ lldb::addr_t address = 0;
+ size_t bytes_read;
+ auto error =
+ ReadMemory(info_address, &address, GetAddressByteSize(), bytes_read);
+ if (!error.Success())
+ return error;
+ if (address == 0)
+ return Status("Invalid r_debug address");
+ // Read r_debug.r_map
+ lldb::addr_t link_map = 0;
+ error = ReadMemory(address + GetAddressByteSize(), &link_map,
+ GetAddressByteSize(), bytes_read);
+ if (!error.Success())
+ return error;
+ if (address == 0)
+ return Status("Invalid link_map address");
+
+ while (link_map) {
+ SharedLibraryInfo info;
+ if (GetAddressByteSize() == 8)
+ error = ReadSharedLibraryInfo<uint64_t>(link_map, info);
+ else
+ error = ReadSharedLibraryInfo<uint32_t>(link_map, info);
+ if (!error.Success())
+ return error;
+ library_list.push_back(info);
+ link_map = info.next;
+ }
+
+ return Status();
+}
Index: lldb/include/lldb/Host/common/NativeProcessProtocol.h
===================================================================
--- lldb/include/lldb/Host/common/NativeProcessProtocol.h
+++ lldb/include/lldb/Host/common/NativeProcessProtocol.h
@@ -32,6 +32,15 @@
class MemoryRegionInfo;
class ResumeActionList;
+struct SharedLibraryInfo {
+ std::string name;
+ lldb::addr_t link_map;
+ lldb::addr_t base_addr;
+ lldb::addr_t ld_addr;
+ bool main;
+ lldb::addr_t next;
+};
+
// NativeProcessProtocol
class NativeProcessProtocol {
public:
@@ -86,6 +95,11 @@
virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
+ virtual Status
+ GetLoadedSharedLibraries(std::vector<SharedLibraryInfo> &library_list) {
+ return Status("Not implemented");
+ }
+
virtual bool IsAlive() const;
virtual size_t UpdateThreads() = 0;
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits