[Lldb-commits] [lldb] [lldb] Add AddressSpaceInfo and ProcessAddress utility classes (PR #206370)
satyanarayana reddy janga via lldb-commits
lldb-commits at lists.llvm.org
Thu Aug 6 11:54:22 PDT 2026
https://github.com/satyajanga updated https://github.com/llvm/llvm-project/pull/206370
>From 9a5bb192c785867465e880c8058986d80616ea58 Mon Sep 17 00:00:00 2001
From: satya janga <satyajanga at fb.com>
Date: Tue, 4 Aug 2026 12:15:29 -0700
Subject: [PATCH] [lldb] Add AddressSpaceInfo and ProcessAddress utility
classes
Add the two value types used by the upcoming generic address space
support. Nothing uses them yet; adopting them is done separately.
AddressSpaceInfo describes a single address space exposed by a process:
a name, a numeric id, and whether it is thread specific. It has JSON
serialization so it can be carried over the gdb-remote protocol.
ProcessAddress pairs an address with an address space id.
LLDB_DEFAULT_ADDRESS_SPACE_ID (0) is the default (flat) address space,
so a ProcessAddress with no explicit space behaves like a plain
lldb::addr_t. The constructor from lldb::addr_t is implicit so that
existing call sites keep working when the read memory APIs adopt it.
---
lldb/include/lldb/Utility/AddressSpace.h | 34 +++++++++++++
lldb/include/lldb/Utility/ProcessAddress.h | 45 +++++++++++++++++
lldb/include/lldb/lldb-defines.h | 2 +
lldb/include/lldb/lldb-forward.h | 1 +
lldb/source/Utility/AddressSpace.cpp | 28 +++++++++++
lldb/source/Utility/CMakeLists.txt | 1 +
lldb/unittests/Utility/AddressSpaceTest.cpp | 56 +++++++++++++++++++++
lldb/unittests/Utility/CMakeLists.txt | 1 +
8 files changed, 168 insertions(+)
create mode 100644 lldb/include/lldb/Utility/AddressSpace.h
create mode 100644 lldb/include/lldb/Utility/ProcessAddress.h
create mode 100644 lldb/source/Utility/AddressSpace.cpp
create mode 100644 lldb/unittests/Utility/AddressSpaceTest.cpp
diff --git a/lldb/include/lldb/Utility/AddressSpace.h b/lldb/include/lldb/Utility/AddressSpace.h
new file mode 100644
index 0000000000000..ce5119f573d8d
--- /dev/null
+++ b/lldb/include/lldb/Utility/AddressSpace.h
@@ -0,0 +1,34 @@
+//===-- AddressSpace.h ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_ADDRESSSPACE_H
+#define LLDB_UTILITY_ADDRESSSPACE_H
+
+#include "lldb/lldb-types.h"
+#include "llvm/Support/JSON.h"
+#include <string>
+#include <vector>
+
+namespace lldb_private {
+
+/// A single address space reported by a process (see the "jAddressSpacesInfo"
+/// packet in docs/resources/lldbgdbremote.md).
+struct AddressSpaceInfo {
+ std::string name;
+ uint64_t space_id = 0;
+ bool is_thread_specific = false;
+};
+
+bool fromJSON(const llvm::json::Value &value, AddressSpaceInfo &data,
+ llvm::json::Path path);
+
+llvm::json::Value toJSON(const AddressSpaceInfo &data);
+
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_ADDRESSSPACE_H
diff --git a/lldb/include/lldb/Utility/ProcessAddress.h b/lldb/include/lldb/Utility/ProcessAddress.h
new file mode 100644
index 0000000000000..edda59318b683
--- /dev/null
+++ b/lldb/include/lldb/Utility/ProcessAddress.h
@@ -0,0 +1,45 @@
+//===-- ProcessAddress.h --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_PROCESSADDRESS_H
+#define LLDB_UTILITY_PROCESSADDRESS_H
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-types.h"
+
+namespace lldb_private {
+
+/// An address in a process, qualified by an address space.
+///
+/// The address space is a numeric id reported by the process (see
+/// Process::GetAddressSpaces). LLDB_DEFAULT_ADDRESS_SPACE_ID is the default
+/// (flat) address space, so a ProcessAddress with no space behaves like a plain
+/// lldb::addr_t.
+class ProcessAddress {
+ lldb::addr_t m_value;
+ uint64_t m_addr_space = LLDB_DEFAULT_ADDRESS_SPACE_ID;
+
+public:
+ /// Implicit so existing lldb::addr_t call sites keep working.
+ ProcessAddress(lldb::addr_t load_addr) : m_value(load_addr) {}
+
+ ProcessAddress(lldb::addr_t addr, uint64_t addr_space)
+ : m_value(addr), m_addr_space(addr_space) {}
+
+ bool IsInDefaultAddressSpace() const {
+ return m_addr_space == LLDB_DEFAULT_ADDRESS_SPACE_ID;
+ }
+
+ lldb::addr_t GetValue() const { return m_value; }
+
+ uint64_t GetAddressSpace() const { return m_addr_space; }
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_PROCESSADDRESS_H
diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index e3f88c4681a53..347b5dfb3434d 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -80,6 +80,8 @@
/// Invalid value definitions
#define LLDB_INVALID_STOP_ID 0
#define LLDB_INVALID_ADDRESS UINT64_MAX
+#define LLDB_DEFAULT_ADDRESS_SPACE_ID 0
+#define LLDB_INVALID_ADDRESS_SPACE_ID UINT64_MAX
#define LLDB_INVALID_INDEX32 UINT32_MAX
#define LLDB_INVALID_INDEX64 UINT64_MAX
#define LLDB_INVALID_IVAR_OFFSET UINT32_MAX
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 47362915d6a56..f691b5a3a76e9 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -22,6 +22,7 @@ class AddressRange;
class AddressRanges;
class AddressRangeList;
class AddressResolver;
+class ProcessAddress;
class ArchSpec;
class Architecture;
class Args;
diff --git a/lldb/source/Utility/AddressSpace.cpp b/lldb/source/Utility/AddressSpace.cpp
new file mode 100644
index 0000000000000..b6fc9335e8113
--- /dev/null
+++ b/lldb/source/Utility/AddressSpace.cpp
@@ -0,0 +1,28 @@
+//===-- AddressSpace.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/AddressSpace.h"
+
+using namespace llvm;
+using namespace llvm::json;
+
+namespace lldb_private {
+
+bool fromJSON(const json::Value &value, AddressSpaceInfo &data, Path path) {
+ ObjectMapper o(value, path);
+ return o && o.map("name", data.name) && o.map("space_id", data.space_id) &&
+ o.map("is_thread_specific", data.is_thread_specific);
+}
+
+json::Value toJSON(const AddressSpaceInfo &data) {
+ return json::Value(Object{{"name", data.name},
+ {"space_id", data.space_id},
+ {"is_thread_specific", data.is_thread_specific}});
+}
+
+} // namespace lldb_private
diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt
index 8efcbe47dd19b..75749d60c4d0f 100644
--- a/lldb/source/Utility/CMakeLists.txt
+++ b/lldb/source/Utility/CMakeLists.txt
@@ -25,6 +25,7 @@ endif()
add_lldb_library(lldbUtility NO_INTERNAL_DEPENDENCIES
AddressableBits.cpp
+ AddressSpace.cpp
ArchSpec.cpp
Args.cpp
Baton.cpp
diff --git a/lldb/unittests/Utility/AddressSpaceTest.cpp b/lldb/unittests/Utility/AddressSpaceTest.cpp
new file mode 100644
index 0000000000000..5a5ccfd1b5b81
--- /dev/null
+++ b/lldb/unittests/Utility/AddressSpaceTest.cpp
@@ -0,0 +1,56 @@
+//===-- AddressSpaceTest.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/AddressSpace.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
+
+using namespace lldb_private;
+
+static std::string ToString(const llvm::json::Value &value) {
+ return llvm::formatv("{0}", value).str();
+}
+
+TEST(AddressSpaceTest, RoundTrip) {
+ AddressSpaceInfo info{"local", 2, /*is_thread_specific=*/true};
+ llvm::Expected<AddressSpaceInfo> parsed = llvm::json::parse<AddressSpaceInfo>(
+ ToString(toJSON(info)), "AddressSpaceInfo");
+ ASSERT_THAT_EXPECTED(parsed, llvm::Succeeded());
+ EXPECT_EQ(parsed->name, "local");
+ EXPECT_EQ(parsed->space_id, 2u);
+ EXPECT_TRUE(parsed->is_thread_specific);
+}
+
+TEST(AddressSpaceTest, ArrayRoundTrip) {
+ std::vector<AddressSpaceInfo> spaces = {
+ {"global", 1, false},
+ {"local", 2, true},
+ {"private", 3, false},
+ };
+ llvm::json::Array array;
+ for (const AddressSpaceInfo &space : spaces)
+ array.push_back(toJSON(space));
+
+ llvm::Expected<std::vector<AddressSpaceInfo>> parsed =
+ llvm::json::parse<std::vector<AddressSpaceInfo>>(
+ ToString(llvm::json::Value(std::move(array))), "AddressSpaceInfo");
+ ASSERT_THAT_EXPECTED(parsed, llvm::Succeeded());
+ ASSERT_EQ(parsed->size(), 3u);
+ EXPECT_EQ((*parsed)[1].name, "local");
+ EXPECT_EQ((*parsed)[1].space_id, 2u);
+ EXPECT_TRUE((*parsed)[1].is_thread_specific);
+ EXPECT_FALSE((*parsed)[0].is_thread_specific);
+}
+
+TEST(AddressSpaceTest, MissingFieldFails) {
+ // "space_id" is required.
+ llvm::Expected<AddressSpaceInfo> parsed = llvm::json::parse<AddressSpaceInfo>(
+ R"({"name":"global"})", "AddressSpaceInfo");
+ EXPECT_THAT_EXPECTED(parsed, llvm::Failed());
+}
diff --git a/lldb/unittests/Utility/CMakeLists.txt b/lldb/unittests/Utility/CMakeLists.txt
index ed159748838b5..e46a1774f020d 100644
--- a/lldb/unittests/Utility/CMakeLists.txt
+++ b/lldb/unittests/Utility/CMakeLists.txt
@@ -1,5 +1,6 @@
add_lldb_unittest(UtilityTests
AcceleratorGDBRemotePacketsTest.cpp
+ AddressSpaceTest.cpp
AnsiTerminalTest.cpp
ArgsTest.cpp
OptionsWithRawTest.cpp
More information about the lldb-commits
mailing list