Skip to content

Commit e69a3d1

Browse files
committed
[lldb] [gdb-remote] Support client fallback for servers without reg defs
Provide minimal register definition defaults for working with servers that implement neither target.xml nor qRegisterInfo packets. This is useful e.g. when interacting with FreeBSD's kernel minimal gdbserver that does not send target.xml but uses the same layout for its supported register subset as GDB. The prerequisite for this is the ability to determine the correct architecture, e.g. from the target executable. Differential Revision: https://reviews.llvm.org/D116896
1 parent 10d3bf9 commit e69a3d1

File tree

5 files changed

+464
-0
lines changed

5 files changed

+464
-0
lines changed

lldb/source/Plugins/Process/gdb-remote/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
2525
GDBRemoteCommunicationServerLLGS.cpp
2626
GDBRemoteCommunicationServerPlatform.cpp
2727
GDBRemoteRegisterContext.cpp
28+
GDBRemoteRegisterFallback.cpp
2829
ProcessGDBRemote.cpp
2930
ProcessGDBRemoteLog.cpp
3031
ThreadGDBRemote.cpp
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
//===-- GDBRemoteRegisterFallback.cpp -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "GDBRemoteRegisterFallback.h"
10+
11+
namespace lldb_private {
12+
namespace process_gdb_remote {
13+
14+
#define REG(name, size) \
15+
DynamicRegisterInfo::Register { \
16+
ConstString(#name), empty_alt_name, reg_set, size, LLDB_INVALID_INDEX32, \
17+
lldb::eEncodingUint, lldb::eFormatHex, LLDB_INVALID_REGNUM, \
18+
LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, {}, {} \
19+
}
20+
#define R64(name) REG(name, 8)
21+
#define R32(name) REG(name, 4)
22+
23+
static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() {
24+
ConstString empty_alt_name;
25+
ConstString reg_set{"general purpose registers"};
26+
27+
std::vector<DynamicRegisterInfo::Register> registers{
28+
R64(x0), R64(x1), R64(x2), R64(x3), R64(x4), R64(x5), R64(x6),
29+
R64(x7), R64(x8), R64(x9), R64(x10), R64(x11), R64(x12), R64(x13),
30+
R64(x14), R64(x15), R64(x16), R64(x17), R64(x18), R64(x19), R64(x20),
31+
R64(x21), R64(x22), R64(x23), R64(x24), R64(x25), R64(x26), R64(x27),
32+
R64(x28), R64(x29), R64(x30), R64(sp), R64(pc), R32(cpsr),
33+
};
34+
35+
return registers;
36+
}
37+
38+
static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86() {
39+
ConstString empty_alt_name;
40+
ConstString reg_set{"general purpose registers"};
41+
42+
std::vector<DynamicRegisterInfo::Register> registers{
43+
R32(eax), R32(ecx), R32(edx), R32(ebx), R32(esp), R32(ebp),
44+
R32(esi), R32(edi), R32(eip), R32(eflags), R32(cs), R32(ss),
45+
R32(ds), R32(es), R32(fs), R32(gs),
46+
};
47+
48+
return registers;
49+
}
50+
51+
static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86_64() {
52+
ConstString empty_alt_name;
53+
ConstString reg_set{"general purpose registers"};
54+
55+
std::vector<DynamicRegisterInfo::Register> registers{
56+
R64(rax), R64(rbx), R64(rcx), R64(rdx), R64(rsi), R64(rdi),
57+
R64(rbp), R64(rsp), R64(r8), R64(r9), R64(r10), R64(r11),
58+
R64(r12), R64(r13), R64(r14), R64(r15), R64(rip), R32(eflags),
59+
R32(cs), R32(ss), R32(ds), R32(es), R32(fs), R32(gs),
60+
};
61+
62+
return registers;
63+
}
64+
65+
#undef R32
66+
#undef R64
67+
#undef REG
68+
69+
std::vector<DynamicRegisterInfo::Register>
70+
GetFallbackRegisters(const ArchSpec &arch_to_use) {
71+
switch (arch_to_use.GetMachine()) {
72+
case llvm::Triple::aarch64:
73+
return GetRegisters_aarch64();
74+
case llvm::Triple::x86:
75+
return GetRegisters_x86();
76+
case llvm::Triple::x86_64:
77+
return GetRegisters_x86_64();
78+
default:
79+
break;
80+
}
81+
82+
return {};
83+
}
84+
85+
} // namespace process_gdb_remote
86+
} // namespace lldb_private
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- GDBRemoteRegisterFallback.h -----------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
10+
#define LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H
11+
12+
#include <vector>
13+
14+
#include "lldb/Target/DynamicRegisterInfo.h"
15+
#include "lldb/Utility/ArchSpec.h"
16+
17+
namespace lldb_private {
18+
namespace process_gdb_remote {
19+
20+
std::vector<DynamicRegisterInfo::Register>
21+
GetFallbackRegisters(const ArchSpec &arch_to_use);
22+
23+
} // namespace process_gdb_remote
24+
} // namespace lldb_private
25+
26+
#endif // LLDB_SOURCE_PLUGINS_PROCESS_GDB_REMOTE_GDBREMOTEREGISTERFALLBACK_H

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
#include <thread>
7373

7474
#include "GDBRemoteRegisterContext.h"
75+
#include "GDBRemoteRegisterFallback.h"
7576
#include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
7677
#include "Plugins/Process/Utility/GDBRemoteSignals.h"
7778
#include "Plugins/Process/Utility/InferiorCallPOSIX.h"
@@ -394,6 +395,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
394395
// 2 - If the target definition doesn't have any of the info from the
395396
// target.xml (registers) then proceed to read the target.xml.
396397
// 3 - Fall back on the qRegisterInfo packets.
398+
// 4 - Use hardcoded defaults if available.
397399

398400
FileSpec target_definition_fspec =
399401
GetGlobalPluginProperties().GetTargetDefinitionFile();
@@ -507,6 +509,9 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) {
507509
}
508510
}
509511

512+
if (registers.empty())
513+
registers = GetFallbackRegisters(arch_to_use);
514+
510515
AddRemoteRegisters(registers, arch_to_use);
511516
}
512517

0 commit comments

Comments
 (0)