Skip to content

Commit 246c9c0

Browse files
[android] implement support for qModuleInfo packet
## Purpose Properly respond to the GDB `qModuleInfo` packet, defined [here](https://lldb.llvm.org/resources/lldbgdbremote.html#qmoduleinfo-module-path-arch-triple), in the DS2 platform session. ## Overview * Implement basic support to parse the build ID out of an ELF executable file * Define a new `GetExecutableFileBuildID` method in the `Host::Platform` interface and implement a Linux and FreeBSD version based on the new ELF support to fetch build ID * Define a new `fileSize` method in the `Host::File` interface and implement a POSIX version based on `stat` * Define a new `onQueryModuleInfo` method in the `Session` interface and implement it in the platform session using the new file size and executable file build ID implementations If deemed important, we can eventually implement [`jModulesInfo`](https://lldb.llvm.org/resources/lldbgdbremote.html#jmodulesinfo-file-triple) using the bulk of this implementation. ## Problem Details Though `qModuleInfo` is documented as optional for lldb support, I have found it must be implemented on Android in order to properly resolve symbols of on-device executable files. ## Validation On an aarch64 Android device and x86_64 Android emulator, attach lldb to a ds2 instance running in the app sandbox. Verify that images are loaded with `(lldb) image list`. Verify Swift symbols from an Android test app can be looked-up in lldb: ``` (lldb) image lookup --name getSwiftGreeting 2 matches found in C:\Users\user\.lldb\module_cache\remote-android\.cache\2749C9AB-7810-6105\libSwiftMainActivity.so: Address: libSwiftMainActivity.so[0x0000000000006f40] (libSwiftMainActivity.so.PT_LOAD[1]..text + 864) Summary: libSwiftMainActivity.so`Java_com_thebrowsercompany_SwiftSupportTestApp_MainActivity_getSwiftGreeting at <compiler-generated> Address: libSwiftMainActivity.so[0x0000000000006f50] (libSwiftMainActivity.so.PT_LOAD[1]..text + 880) Summary: libSwiftMainActivity.so`SwiftMainActivity.getSwiftGreeting(Swift.UnsafeMutablePointer<Swift.Optional<Swift.UnsafePointer<__C.JNINativeInterface>>>, Swift.UnsafeMutableRawPointer) -> Swift.Optional<Swift.UnsafeMutableRawPointer> at MainActivity.swift:8 (lldb) ``` Build and execute on an AMD64 FreeBSD 14.0 host to verify the build is not broken. Co-authored-by: Saleem Abdulrasool <compnerd@compnerd.org>
1 parent 5935b73 commit 246c9c0

File tree

19 files changed

+205
-4
lines changed

19 files changed

+205
-4
lines changed

Headers/DebugServer2/GDBRemote/DummySessionDelegateImpl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ class DummySessionDelegateImpl : public SessionDelegate {
9595
ErrorCode onQuerySharedLibraryInfo(Session &session, std::string const &path,
9696
std::string const &triple,
9797
SharedLibraryInfo &info) const override;
98+
ErrorCode onQueryModuleInfo(Session &session, std::string &path,
99+
std::string &triple,
100+
ModuleInfo &info) const override;
98101

99102
ErrorCode onRestart(Session &session, ProcessId pid) override;
100103
ErrorCode onInterrupt(Session &session) override;

Headers/DebugServer2/GDBRemote/PlatformSessionImpl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ class PlatformSessionImplBase : public DummySessionDelegateImpl {
4343
ErrorCode onQueryGroupName(Session &session, GroupId const &gid,
4444
std::string &name) const override;
4545

46+
ErrorCode onQueryModuleInfo(Session &session, std::string &path,
47+
std::string &triple,
48+
ModuleInfo &info) const override;
49+
4650
protected:
4751
ErrorCode onLaunchDebugServer(Session &session, std::string const &host,
4852
uint16_t &port, ProcessId &pid) override;

Headers/DebugServer2/GDBRemote/SessionDelegate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ class SessionDelegate {
103103
std::string const &path,
104104
std::string const &triple,
105105
SharedLibraryInfo &info) const = 0;
106+
virtual ErrorCode onQueryModuleInfo(Session &session, std::string &path,
107+
std::string &triple,
108+
ModuleInfo &info) const = 0;
106109

107110
virtual ErrorCode onRestart(Session &session, ProcessId pid) = 0;
108111
virtual ErrorCode onInterrupt(Session &session) = 0;

Headers/DebugServer2/GDBRemote/Types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ struct MemoryRegionInfo : public ds2::MemoryRegionInfo {
3131
std::string encode() const;
3232
};
3333

34+
struct ModuleInfo : public ds2::ModuleInfo {
35+
std::string encode() const;
36+
};
37+
3438
struct StopInfo : public ds2::StopInfo {
3539
public:
3640
// Allow copying and constructing from a ds2::StopInfo directly.

Headers/DebugServer2/Host/File.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ class File {
6161
public:
6262
static ErrorCode createDirectory(std::string const &path, uint32_t flags);
6363

64+
public:
65+
static ErrorCode fileSize(std::string const &path, uint64_t &size);
66+
6467
protected:
6568
int _fd;
6669
ErrorCode _lastError;

Headers/DebugServer2/Host/Platform.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ class Platform {
7777

7878
public:
7979
static std::string GetThreadName(ProcessId pid, ThreadId tid);
80+
81+
public:
82+
static bool GetExecutableFileBuildID(std::string const &path, ByteVector &buildId);
8083
};
8184
} // namespace Host
8285
} // namespace ds2

Headers/DebugServer2/Support/POSIX/ELFSupport.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ class ELFSupport {
2525
public:
2626
static bool MachineTypeToCPUType(uint32_t machineType, bool is64Bit,
2727
CPUType &type, CPUSubType &subType);
28+
static bool GetELFFileBuildID(std::string const &path, ByteVector &buildID);
29+
private:
30+
template <typename ELFHeader, typename SectionHeader, typename NotesHeader>
31+
static bool ReadBuildID(int fd, const ELFHeader &ehdr, SectionHeader &shdr,
32+
NotesHeader &nhdr, ByteVector &id);
33+
34+
template <typename ELFHeader, typename SectionHeader>
35+
static bool ReadSectionHeader(int fd, const ELFHeader &ehdr, SectionHeader &shdr,
36+
size_t idx);
2837
};
2938
} // namespace Support
3039
} // namespace ds2

Headers/DebugServer2/Types.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,4 +410,13 @@ struct MappedFileInfo {
410410
uint64_t baseAddress;
411411
uint64_t size;
412412
};
413+
414+
struct ModuleInfo {
415+
std::string uuid;
416+
std::string triple;
417+
std::string file_path;
418+
uint64_t file_offset;
419+
uint64_t file_size;
420+
};
421+
413422
} // namespace ds2

Sources/GDBRemote/DummySessionDelegateImpl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ DUMMY_IMPL_EMPTY_CONST(onQuerySharedLibraryInfo, Session &,
159159
std::string const &path, std::string const &triple,
160160
SharedLibraryInfo &info)
161161

162+
DUMMY_IMPL_EMPTY_CONST(onQueryModuleInfo, Session &, std::string &path,
163+
std::string &triple, ModuleInfo &info)
164+
162165
DUMMY_IMPL_EMPTY(onRestart, Session &, ProcessId)
163166

164167
DUMMY_IMPL_EMPTY(onInterrupt, Session &)

Sources/GDBRemote/PlatformSessionImpl.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <sstream>
1818

19+
using ds2::Host::File;
1920
using ds2::Host::Platform;
2021
using ds2::Host::ProcessSpawner;
2122

@@ -95,6 +96,31 @@ ErrorCode PlatformSessionImplBase::onQueryGroupName(Session &,
9596
return kSuccess;
9697
}
9798

99+
ErrorCode PlatformSessionImplBase::onQueryModuleInfo(Session &session,
100+
std::string &path,
101+
std::string &triple,
102+
ModuleInfo &info) const {
103+
ByteVector buildId;
104+
if (!Platform::GetExecutableFileBuildID(path, buildId))
105+
return kErrorUnknown;
106+
107+
// send the uuid as a hex-encoded, upper-case string
108+
std::ostringstream ss;
109+
for(const auto b : buildId)
110+
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << int(b);
111+
112+
auto error = File::fileSize(path, info.file_size);
113+
if (error != kSuccess)
114+
return error;
115+
116+
info.uuid = ss.str();
117+
info.triple = triple;
118+
info.file_path = path;
119+
info.file_offset = 0;
120+
121+
return kSuccess;
122+
}
123+
98124
ErrorCode PlatformSessionImplBase::onLaunchDebugServer(Session &session,
99125
std::string const &host,
100126
uint16_t &port,

0 commit comments

Comments
 (0)