Skip to content

Commit ec76377

Browse files
committed
[DRAFT][lldb] Upstream lldb-rpc-gen and LLDB RPC server-side emitters
This commit upstreams lldb-rpc-gen, a tool that emits the client and server interfaces used for LLDB RPC. This is the initial commit in the upstreaming process for LLDB RPC. lldb-rpc-gen is a ClangTool that reads the LLDB SB API headers and uses their information to generate the interfaces for RPC. This commit specifically adds the server-side emitters for easier review. The client-side interface will be added in a later commit. RFC: https://discourse.llvm.org/t/rfc-upstreaming-lldb-rpc/85804
1 parent d35bf17 commit ec76377

27 files changed

+2598
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env python3
2+
# Usage: convert-lldb-header-to-rpc-header.py <path/to/input-header.h> <path/to/output-header.h>
3+
# This scripts takes common LLDB headers (such as lldb-defines.h) and replaces references to LLDB
4+
# with those for RPC. This happens for:
5+
# - namespace definitions
6+
# - namespace usage
7+
# - version string macros
8+
# - ifdef/ifndef lines
9+
10+
import argparse
11+
import os
12+
import re
13+
14+
def main():
15+
parser = argparse.ArgumentParser()
16+
parser.add_argument("input")
17+
parser.add_argument("output")
18+
args = parser.parse_args()
19+
input_path = str(args.input)
20+
output_path = str(args.output)
21+
with open(input_path, "r") as input_file:
22+
lines = input_file.readlines()
23+
24+
with open(output_path, "w") as output_file:
25+
for line in lines:
26+
# NOTE: We do not use lldb-forward.h or lldb-versioning.h in RPC, so remove
27+
# all includes that are found for these files.
28+
if re.match(
29+
r'#include "lldb/lldb-forward|#include "lldb/lldb-versioning', line
30+
):
31+
continue
32+
# For lldb-rpc-defines.h, replace the ifndef LLDB_LLDB_ portion with LLDB_RPC_ as we're not
33+
# using LLDB private definitions in RPC.
34+
elif re.match(r".+LLDB_LLDB_", line):
35+
output_file.write(re.sub(r"LLDB_LLDB_", r"LLDB_RPC_", line))
36+
# Similarly to lldb-rpc-defines.h, replace the ifndef for LLDB_API in SBDefines.h to LLDB_RPC_API_ for the same reason.
37+
elif re.match(r".+LLDB_API_", line):
38+
output_file.write(re.sub(r"LLDB_API_", r"LLDB_RPC_API_", line))
39+
# Replace the references for the macros that define the versioning strings in
40+
# lldb-rpc-defines.h.
41+
elif re.match(r".+LLDB_VERSION", line):
42+
output_file.write(re.sub(r"LLDB_VERSION", r"LLDB_RPC_VERSION", line))
43+
elif re.match(r".+LLDB_REVISION", line):
44+
output_file.write(re.sub(r"LLDB_REVISION", r"LLDB_RPC_REVISION", line))
45+
elif re.match(r".+LLDB_VERSION_STRING", line):
46+
output_file.write(
47+
re.sub(r"LLDB_VERSION_STRING", r"LLDB_RPC_VERSION_STRING", line)
48+
)
49+
# For local #includes
50+
elif re.match(r'#include "lldb/lldb-', line):
51+
output_file.write(re.sub(r"lldb/lldb-", r"lldb-rpc-", line))
52+
# Rename the lldb namespace definition to lldb-rpc.
53+
elif re.match(r"namespace lldb", line):
54+
output_file.write(re.sub(r"lldb", r"lldb_rpc", line))
55+
# Rename namespace references
56+
elif re.match(r".+lldb::", line):
57+
output_file.write(re.sub(r"lldb::", r"lldb_rpc::", line))
58+
else:
59+
# Write any line that doesn't need to be converted
60+
output_file.write(line)
61+
62+
63+
if __name__ == "__main__":
64+
main()
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#!/usr/bin/env python3
2+
# Usage: framework-header-include-fix.py <path/to/input-header.h> <path/to/output-header.h>
3+
# This script modifies all #include lines in all lldb-rpc headers
4+
# from either filesystem or local includes to liblldbrpc includes.
5+
6+
import argparse
7+
import os
8+
import re
9+
10+
def main():
11+
parser = argparse.ArgumentParser()
12+
parser.add_argument("input")
13+
parser.add_argument("output")
14+
args = parser.parse_args()
15+
input_path = str(args.input)
16+
output_path = str(args.output)
17+
with open(input_path, "r+") as input_file:
18+
lines = input_file.readlines()
19+
20+
with open(output_path, "w+") as output_file:
21+
for line in lines:
22+
# Replace includes from RPCCommon to liblldbrpc includes.
23+
# e.g. #include <lldb-rpc/common/RPCArgument.h> -> #include <LLDBRPC/RPCArgument.h>
24+
if re.match(r".+<lldb-rpc/common", line):
25+
output_file.write(re.sub(r"<lldb-rpc/common", r"<LLDBRPC", line))
26+
# Replace all local file includes to liblldbrpc includes.
27+
# e.g. #include "SBFoo.h" -> #include <LLDBRPC/SBFoo.h>
28+
elif re.match(r'#include "(.*)"', line):
29+
include_filename = re.search(r'#include "(.*)"', line).groups()[0]
30+
output_file.write(
31+
re.sub(
32+
r'#include "(.*)"',
33+
r"#include <LLDBRPC/" + include_filename + ">",
34+
line,
35+
)
36+
)
37+
else:
38+
# Write any line that doesn't need to be converted
39+
output_file.write(line)
40+
41+
42+
if __name__ == "__main__":
43+
main()
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env python3
2+
# Usage: framework-header-version-fix.py <path/to/input-header.h> <path/to/output-header.h> MAJOR MINOR PATCH
3+
# This script modifies lldb-rpc-defines.h to uncomment the macro defines used for the LLDB
4+
# major, minor and patch values as well as populating their definitions.
5+
6+
import argparse
7+
import os
8+
import re
9+
10+
def main():
11+
parser = argparse.ArgumentParser()
12+
parser.add_argument("input")
13+
parser.add_argument("output")
14+
parser.add_argument("lldb_version_major")
15+
parser.add_argument("lldb_version_minor")
16+
parser.add_argument("lldb_version_patch")
17+
args = parser.parse_args()
18+
input_path = str(args.input)
19+
output_path = str(args.output)
20+
lldb_version_major = args.lldb_version_major
21+
lldb_version_minor = args.lldb_version_minor
22+
lldb_version_patch = args.lldb_version_patch
23+
24+
with open(input_path, "r") as input_file:
25+
lines = input_file.readlines()
26+
27+
with open(output_path, "w") as output_file:
28+
for line in lines:
29+
# Uncomment the line that defines the LLDB major version and populate its value.
30+
if re.match(r"//#define LLDB_RPC_VERSION$", line):
31+
output_file.write(
32+
re.sub(
33+
r"//#define LLDB_RPC_VERSION",
34+
r"#define LLDB_RPC_VERSION " + lldb_version_major,
35+
line,
36+
)
37+
)
38+
# Uncomment the line that defines the LLDB minor version and populate its value.
39+
elif re.match(r"//#define LLDB_RPC_REVISION$", line):
40+
output_file.write(
41+
re.sub(
42+
r"//#define LLDB_RPC_REVISION",
43+
r"#define LLDB_RPC_REVISION " + lldb_version_minor,
44+
line,
45+
)
46+
)
47+
# Uncomment the line that defines the complete LLDB version string and populate its value.
48+
elif re.match(r"//#define LLDB_RPC_VERSION_STRING$", line):
49+
output_file.write(
50+
re.sub(
51+
r"//#define LLDB_RPC_VERSION_STRING",
52+
r'#define LLDB_RPC_VERSION_STRING "{0}.{1}.{2}"'.format(
53+
lldb_version_major, lldb_version_minor, lldb_version_patch
54+
),
55+
line,
56+
)
57+
)
58+
else:
59+
# Write any line that doesn't need to be converted
60+
output_file.write(line)
61+
62+
63+
if __name__ == "__main__":
64+
main()
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef LLDB_API_SBRPC_CHECKARRAYPTR_H
2+
#define LLDB_API_SBRPC_CHECKARRAYPTR_H
3+
4+
#include <cstddef>
5+
#include <cstdio>
6+
7+
#include "lldb/API/SBDefines.h"
8+
9+
namespace lldb {
10+
class LLDB_API SBRPC_CHECKARRAYPTR {
11+
public:
12+
// Pointers to arrays followed by length must use a
13+
// Bytes object constructed using that pointer and the sizeof()
14+
// the array object.
15+
int CheckArrayPtr(uint64_t *array, size_t array_len);
16+
17+
}; // class SBRPC_CHECKARRAYPTR
18+
} // namespace lldb
19+
20+
#endif // LLDB_API_SBRPC_CHECKARRAYPTR_H
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef LLDB_API_SBRPC_CHECKCONSTCHARPTRPTRWITHLEN_H
2+
#define LLDB_API_SBRPC_CHECKCONSTCHARPTRPTRWITHLEN_H
3+
4+
#include <cstddef>
5+
#include <cstdio>
6+
7+
#include "lldb/API/SBDefines.h"
8+
9+
namespace lldb {
10+
class LLDB_API SBRPC_CHECKCONSTCHARPTRPTRWITHLEN {
11+
public:
12+
// const char ** followed by len must use a StringList
13+
// when being encoded.
14+
int CheckConstCharPtrPtrWithLen(const char **arg1, size_t len);
15+
16+
}; // class SBRPC_CHECKCONSTCHARPTRPTRWITHLEN
17+
} // namespace lldb
18+
19+
#endif // LLDB_API_SBRPC_CHECKCONSTCHARPTRPTRWITHLEN_H
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef LLDB_API_SBRPC_CHECKCONSTSBREF_H
2+
#define LLDB_API_SBRPC_CHECKCONSTSBREF_H
3+
4+
#include <cstddef>
5+
#include <cstdio>
6+
7+
#include "lldb/API/SBDefines.h"
8+
9+
namespace lldb {
10+
class LLDB_API SBRPC_CHECKCONSTSBREF {
11+
public:
12+
// Const references to SB classes should be encoded as usual without
13+
// needing to create a new object with its own connection.
14+
int CheckConstSBRef(const SBDebugger &debugger_ref);
15+
16+
}; // class SBRPC_CHECKCONSTSBREF
17+
} // namespace lldb
18+
19+
#endif // LLDB_API_SBRPC_CHECKCONSTSBREF_H
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifndef LLDB_API_SBRPC_CHECKNONCONSTSBREF_H
2+
#define LLDB_API_SBRPC_CHECKNONCONSTSBREF_H
3+
4+
#include <cstddef>
5+
#include <cstdio>
6+
7+
#include "lldb/API/SBDefines.h"
8+
9+
namespace lldb {
10+
class LLDB_API SBRPC_CHECKNONCONSTSBREF {
11+
public:
12+
// Non-const references to SB classes will have new objects
13+
// of that class constructed with the connection as the first parameter
14+
// before being encoded if their existing connection is invalid.
15+
int CheckNonConstSBRef(SBDebugger &debugger_ref);
16+
17+
}; // class SBRPC_CHECKNONCONSTSBREF
18+
} // namespace lldb
19+
20+
#endif // LLDB_API_SBRPC_CHECKNONCONSTSBREF_H
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#ifndef LLDB_API_SBRPC_CHECKSBPTR_H
2+
#define LLDB_API_SBRPC_CHECKSBPTR_H
3+
4+
#include <cstddef>
5+
#include <cstdio>
6+
7+
#include "lldb/API/SBDefines.h"
8+
9+
namespace lldb {
10+
class LLDB_API SBRPC_CHECKSBPTR {
11+
public:
12+
// Pointers to SB objects must be checked to
13+
// see if they're null. If so, then a new object of the given
14+
// class must be created and encoded. Otherwise, the original
15+
// parameter will be encoded.
16+
int CheckSBPtr(SBDebugger *debugger_ptr);
17+
18+
}; // class SBRPC_CHECKSBPTR
19+
} // namespace lldb
20+
21+
#endif // LLDB_API_SBRPC_CHECKSBPTR_H
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef LLDB_API_SBRPC_CHECKVOIDPTR_H
2+
#define LLDB_API_SBRPC_CHECKVOIDPTR_H
3+
4+
#include <cstddef>
5+
#include <cstdio>
6+
7+
#include "lldb/API/SBDefines.h"
8+
9+
namespace lldb {
10+
class LLDB_API SBRPC_CHECKVOIDPTR {
11+
public:
12+
// void * followed by length must use a Bytes object
13+
// when being encoded.
14+
int CheckVoidPtr(void *buf, size_t len);
15+
16+
}; // class SBRPC_CHECKVOIDPTR
17+
} // namespace lldb
18+
19+
#endif // LLDB_API_SBRPC_CHECKVOIDPTR_H
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Skipping temporarily due to rdar://149500008
2+
# XFAIL: system-darwin
3+
# RUN: mkdir -p %t/server
4+
# RUN: mkdir -p %t/lib
5+
# RUN: %lldb-rpc-gen --output-dir=%t %S/../../Inputs/CheckArrayPointer.h
6+
7+
# RUN: cat %t/lib/CheckArrayPointer.cpp | FileCheck %s
8+
9+
// Pointers to arrays followed by length must use a
10+
// Bytes object constructed using that pointer and the sizeof()
11+
// the array object.
12+
# CHECK: lldb_rpc::SBRPC_CHECKARRAYPTR::CheckArrayPtr
13+
# CHECK: Bytes array_buffer(array, sizeof(uint64_t));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Skipping temporarily due to rdar://149500008
2+
# XFAIL: system-darwin
3+
# RUN: mkdir -p %t/server
4+
# RUN: mkdir -p %t/lib
5+
# RUN: %lldb-rpc-gen --output-dir=%t %S/../../Inputs/CheckConstCharPtrPtrWithLen.h
6+
7+
# RUN: cat %t/lib/CheckConstCharPtrPtrWithLen.cpp | FileCheck %s
8+
9+
// const char ** followed by len must use a StringList
10+
// when being encoded.
11+
# CHECK: lldb_rpc::SBRPC_CHECKCONSTCHARPTRPTRWITHLEN::CheckConstCharPtrPtrWithLen
12+
# CHECK: StringList arg1_list
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Skipping temporarily due to rdar://149500008
2+
# XFAIL: system-darwin
3+
# RUN: mkdir -p %t/server
4+
# RUN: mkdir -p %t/lib
5+
# RUN: %lldb-rpc-gen --output-dir=%t %S/../../Inputs/CheckConstSBRef.h
6+
7+
# RUN: cat %t/lib/CheckConstSBRef.cpp | FileCheck %s
8+
9+
// Const references to SB classes should be encoded as usual without
10+
// needing to create a new object with its own connection. Here
11+
// we're checking to make sure that the given SB object ref will get
12+
// encoded immediately after the previous argument gets encoded without
13+
// anything happening in between.
14+
# CHECK: lldb_rpc::SBRPC_CHECKCONSTSBREF::CheckConstSBRef
15+
# CHECK: RPCValueEncoder(send, rpc_common::RPCPacket::ValueType::Argument, *this);
16+
# CHECK: RPCValueEncoder(send, rpc_common::RPCPacket::ValueType::Argument, debugger_ref)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Skipping temporarily due to rdar://149500008
2+
# XFAIL: system-darwin
3+
# RUN: mkdir -p %t/server
4+
# RUN: mkdir -p %t/lib
5+
# RUN: %lldb-rpc-gen --output-dir=%t %S/../../Inputs/CheckNonConstSBRef.h
6+
7+
# RUN: cat %t/lib/CheckNonConstSBRef.cpp | FileCheck %s
8+
9+
// Non-const references to SB classes will have new objects
10+
// of that class constructed with the connection as the first parameter
11+
// before being encoded if their existing connection is invalid.
12+
# CHECK: lldb_rpc::SBRPC_CHECKNONCONSTSBREF::CheckNonConstSBRef
13+
# CHECK: if (connection_sp && !debugger_ref.ObjectRefIsValid())
14+
# CHECK: debugger_ref = lldb_rpc::SBDebugger(connection_sp);
15+
# CHECK: RPCValueEncoder(send, rpc_common::RPCPacket::ValueType::Argument, debugger_ref);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Skipping temporarily due to rdar://149500008
2+
# XFAIL: system-darwin
3+
# RUN: mkdir -p %t/server
4+
# RUN: mkdir -p %t/lib
5+
# RUN: %lldb-rpc-gen --output-dir=%t %S/../../Inputs/CheckSBPointer.h
6+
7+
# RUN: cat %t/lib/CheckSBPointer.cpp | FileCheck %s
8+
9+
// Pointers to SB objects must be checked to
10+
// see if they're null. If so, then a new object of the given
11+
// class must be created and encoded. Otherwise, the original
12+
// parameter will be encoded.
13+
# CHECK: lldb_rpc::SBRPC_CHECKSBPTR::CheckSBPtr
14+
# CHECK: if (debugger_ptr)
15+
# CHECK: RPCValueEncoder(send, rpc_common::RPCPacket::ValueType::Argument, *debugger_ptr);
16+
# CHECK: else
17+
# CHECK: RPCValueEncoder(send, rpc_common::RPCPacket::ValueType::Argument, rpc::ObjectRef(ObjectRefGetConnectionID(), eClass_lldb_SBDebugger, LLDB_RPC_INVALID_OBJECT_ID));
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Skipping temporarily due to rdar://149500008
2+
# XFAIL: system-darwin
3+
# RUN: mkdir -p %t/server
4+
# RUN: mkdir -p %t/lib
5+
# RUN: %lldb-rpc-gen --output-dir=%t %S/../../Inputs/CheckVoidPtr.h
6+
7+
# RUN: cat %t/lib/CheckVoidPtr.cpp | FileCheck %s
8+
9+
// void * followed by length must use a Bytes object
10+
// when being encoded.
11+
# CHECK: lldb_rpc::SBRPC_CHECKVOIDPTR::CheckVoidPtr
12+
# CHECK: Bytes buf_buffer(buf, len);

lldb/tools/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ add_subdirectory(intel-features)
77
# example is `check-lldb`. So, we pass EXCLUDE_FROM_ALL here.
88
add_subdirectory(lldb-test EXCLUDE_FROM_ALL)
99
add_subdirectory(lldb-fuzzer EXCLUDE_FROM_ALL)
10+
add_subdirectory(lldb-rpc EXCLUDE_FROM_ALL)
11+
1012

1113
add_lldb_tool_subdirectory(lldb-instr)
1214
add_lldb_tool_subdirectory(lldb-dap)

0 commit comments

Comments
 (0)