[Lldb-commits] [lldb] [debugserver] Support for `qMemTags` packet (PR #160952)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Sep 26 14:26:08 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lldb
Author: Julian Lettner (yln)
<details>
<summary>Changes</summary>
Support for `qMemTags` packet in debugserver which allows usage of LLDB's `memory tag read` on Darwin.
---
Patch is 26.64 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/160952.diff
16 Files Affected:
- (modified) lldb/packages/Python/lldbsuite/test/cpu_feature.py (+1-1)
- (added) lldb/test/API/macosx/mte/Makefile (+12)
- (added) lldb/test/API/macosx/mte/TestDarwinMTE.py (+90)
- (added) lldb/test/API/macosx/mte/main.c (+29)
- (added) lldb/test/API/macosx/mte/mte-entitlements.plist (+10)
- (modified) lldb/tools/debugserver/source/DNB.cpp (+10)
- (modified) lldb/tools/debugserver/source/DNB.h (+3)
- (modified) lldb/tools/debugserver/source/DNBDefs.h (+2-1)
- (modified) lldb/tools/debugserver/source/MacOSX/MachTask.h (+2)
- (modified) lldb/tools/debugserver/source/MacOSX/MachTask.mm (+19-2)
- (modified) lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp (+59)
- (modified) lldb/tools/debugserver/source/MacOSX/MachVMMemory.h (+2)
- (modified) lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp (+46)
- (modified) lldb/tools/debugserver/source/MacOSX/MachVMRegion.h (+2-1)
- (modified) lldb/tools/debugserver/source/RNBRemote.cpp (+104-1)
- (modified) lldb/tools/debugserver/source/RNBRemote.h (+2)
``````````diff
diff --git a/lldb/packages/Python/lldbsuite/test/cpu_feature.py b/lldb/packages/Python/lldbsuite/test/cpu_feature.py
index b46a5acc596f0..d7668c1884e40 100644
--- a/lldb/packages/Python/lldbsuite/test/cpu_feature.py
+++ b/lldb/packages/Python/lldbsuite/test/cpu_feature.py
@@ -62,7 +62,7 @@ def _is_supported_darwin(self, cmd_runner):
class AArch64:
FPMR = CPUFeature("fpmr")
GCS = CPUFeature("gcs")
- MTE = CPUFeature("mte")
+ MTE = CPUFeature("mte", "hw.optional.arm.FEAT_MTE4")
MTE_STORE_ONLY = CPUFeature("mtestoreonly")
PTR_AUTH = CPUFeature("paca", "hw.optional.arm.FEAT_PAuth2")
SME = CPUFeature("sme", "hw.optional.arm.FEAT_SME")
diff --git a/lldb/test/API/macosx/mte/Makefile b/lldb/test/API/macosx/mte/Makefile
new file mode 100644
index 0000000000000..cb20942805e2a
--- /dev/null
+++ b/lldb/test/API/macosx/mte/Makefile
@@ -0,0 +1,12 @@
+C_SOURCES := main.c
+
+EXE := uaf_mte
+
+all: uaf_mte sign
+
+include Makefile.rules
+
+sign: mte-entitlements.plist uaf_mte
+ifeq ($(OS),Darwin)
+ codesign -s - -f --entitlements $^
+endif
diff --git a/lldb/test/API/macosx/mte/TestDarwinMTE.py b/lldb/test/API/macosx/mte/TestDarwinMTE.py
new file mode 100644
index 0000000000000..787f29e3530cd
--- /dev/null
+++ b/lldb/test/API/macosx/mte/TestDarwinMTE.py
@@ -0,0 +1,90 @@
+"""Test MTE Memory Tagging on Apple platforms"""
+
+import lldb
+import re
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbsuite.test.cpu_feature as cpu_feature
+
+exe_name = "uaf_mte" # Must match Makefile
+
+
+class TestDarwinMTE(TestBase):
+ NO_DEBUG_INFO_TESTCASE = True
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_tag_fault(self):
+ self.build()
+ exe = self.getBuildArtifact(exe_name)
+
+ target = self.dbg.CreateTarget(exe)
+ self.assertTrue(target, VALID_TARGET)
+
+ process = target.LaunchSimple(None, None, None)
+ self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
+
+ self.expect(
+ "thread info",
+ substrs=["stop reason = EXC_ARM_MTE_TAG_FAULT", "MTE tag mismatch detected"],
+ )
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_memory_read_with_tags(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name
+ )
+
+ # (lldb) memory read ptr-16 ptr+48 --show-tags
+ # 0x7d2c00930: 00 00 00 00 00 00 00 00 d0 e3 a5 0a 02 00 00 00 ................ (tag: 0x3)
+ # 0x7d2c00940: 48 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 Hello........... (tag: 0xb)
+ # 0x7d2c00950: 57 6f 72 6c 64 00 00 00 00 00 00 00 00 00 00 00 World........... (tag: 0xb)
+ # 0x7d2c00960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ (tag: 0x9)
+ self.expect(
+ "memory read ptr-16 ptr+48 --show-tags",
+ substrs=[" Hello...........", " World..........."],
+ patterns=[r"(.*\(tag: 0x[0-9a-f]\)\n){4}"])
+
+ def _parse_pointer_tag(self):
+ return re.search(r"Logical tag: (0x[0-9a-f])", self.res.GetOutput()).group(1)
+
+ def _parse_memory_tags(self, expected_tag_count):
+ tags = re.findall(r"\): (0x[0-9a-f])", self.res.GetOutput())
+ self.assertEqual(len(tags), expected_tag_count)
+ return tags
+
+ @skipUnlessFeature(cpu_feature.AArch64.MTE)
+ def test_memory_tag_read(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "// before free", lldb.SBFileSpec("main.c"), exe_name=exe_name
+ )
+
+ # (lldb) memory tag read ptr-1 ptr+33
+ # Logical tag: 0x5
+ # Allocation tags:
+ # [0x100a65a40, 0x100a65a50): 0xf (mismatch)
+ # [0x100a65a50, 0x100a65a60): 0x5
+ # [0x100a65a60, 0x100a65a70): 0x5
+ # [0x100a65a70, 0x100a65a80): 0x2 (mismatch)
+ self.expect(
+ "memory tag read ptr-1 ptr+33",
+ substrs=["Logical tag: 0x", "Allocation tags:", "(mismatch)"],
+ patterns=[r"(\[.*\): 0x[0-9a-f].*\n){4}"]
+ )
+ self.assertEqual(self.res.GetOutput().count("(mismatch)"), 2)
+ ptr_tag = self._parse_pointer_tag()
+ tags = self._parse_memory_tags(4)
+ self.assertEqual(tags[1], ptr_tag)
+ self.assertEqual(tags[2], ptr_tag)
+ self.assertNotEqual(tags[0], ptr_tag)
+ self.assertNotEqual(tags[3], ptr_tag)
+
+ # Continue running until MTE fault
+ self.runCmd("process continue")
+
+ self.runCmd("memory tag read ptr-1 ptr+33")
+ self.assertEqual(self.res.GetOutput().count("(mismatch)"), 4)
+ tags = self._parse_memory_tags(4)
+ self.assertTrue(all(t != ptr_tag for t in tags))
diff --git a/lldb/test/API/macosx/mte/main.c b/lldb/test/API/macosx/mte/main.c
new file mode 100644
index 0000000000000..ca61c05b19a38
--- /dev/null
+++ b/lldb/test/API/macosx/mte/main.c
@@ -0,0 +1,29 @@
+#include <malloc/malloc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// Produce some names on the trace
+const size_t tag_granule = 16;
+uint8_t *my_malloc(void) { return malloc(2 * tag_granule); }
+uint8_t *allocate(void) { return my_malloc(); }
+
+void my_free(void *ptr) { free(ptr); }
+void deallocate(void *ptr) { my_free(ptr); }
+
+void touch_memory(uint8_t *ptr) { ptr[7] = 1; } // invalid access
+void modify(uint8_t *ptr) { touch_memory(ptr); }
+
+int main() {
+ uint8_t *ptr = allocate();
+ printf("ptr: %p\n", ptr);
+
+ strcpy((char *)ptr, "Hello");
+ strcpy((char *)ptr+16, "World");
+
+ deallocate(ptr); // before free
+
+ modify(ptr); // use-after-free
+
+ return 0;
+}
diff --git a/lldb/test/API/macosx/mte/mte-entitlements.plist b/lldb/test/API/macosx/mte/mte-entitlements.plist
new file mode 100644
index 0000000000000..6de5d5634d878
--- /dev/null
+++ b/lldb/test/API/macosx/mte/mte-entitlements.plist
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.hardened-process</key>
+ <true/>
+ <key>com.apple.security.hardened-process.checked-allocations</key>
+ <true/>
+</dict>
+</plist>
diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp
index f541134b43a1b..0cd48d91a682a 100644
--- a/lldb/tools/debugserver/source/DNB.cpp
+++ b/lldb/tools/debugserver/source/DNB.cpp
@@ -1386,6 +1386,16 @@ int DNBProcessMemoryRegionInfo(nub_process_t pid, nub_addr_t addr,
return -1;
}
+nub_bool_t DNBProcessGetMemoryTags(nub_process_t pid, nub_addr_t addr,
+ nub_size_t size,
+ std::vector<uint8_t> &tags) {
+ MachProcessSP procSP;
+ if (GetProcessSP(pid, procSP))
+ return procSP->Task().GetMemoryTags(addr, size, tags);
+
+ return false;
+}
+
std::string DNBProcessGetProfileData(nub_process_t pid,
DNBProfileDataScanType scanType) {
MachProcessSP procSP;
diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h
index 10d1f68794355..1f3d5392c588f 100644
--- a/lldb/tools/debugserver/source/DNB.h
+++ b/lldb/tools/debugserver/source/DNB.h
@@ -105,6 +105,9 @@ nub_bool_t DNBProcessMemoryDeallocate(nub_process_t pid,
nub_addr_t addr) DNB_EXPORT;
int DNBProcessMemoryRegionInfo(nub_process_t pid, nub_addr_t addr,
DNBRegionInfo *region_info) DNB_EXPORT;
+nub_bool_t DNBProcessGetMemoryTags(nub_process_t pid, nub_addr_t addr,
+ nub_size_t size,
+ std::vector<uint8_t> &tags) DNB_EXPORT;
std::string
DNBProcessGetProfileData(nub_process_t pid,
DNBProfileDataScanType scanType) DNB_EXPORT;
diff --git a/lldb/tools/debugserver/source/DNBDefs.h b/lldb/tools/debugserver/source/DNBDefs.h
index df8ca809d412c..d98399aed5e19 100644
--- a/lldb/tools/debugserver/source/DNBDefs.h
+++ b/lldb/tools/debugserver/source/DNBDefs.h
@@ -358,10 +358,11 @@ struct DNBExecutableImageInfo {
struct DNBRegionInfo {
public:
DNBRegionInfo()
- : addr(0), size(0), permissions(0), dirty_pages(), vm_types() {}
+ : addr(0), size(0), permissions(0), flags(), dirty_pages(), vm_types() {}
nub_addr_t addr;
nub_addr_t size;
uint32_t permissions;
+ std::vector<std::string> flags;
std::vector<nub_addr_t> dirty_pages;
std::vector<std::string> vm_types;
};
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.h b/lldb/tools/debugserver/source/MacOSX/MachTask.h
index 2284f6b99de91..c4a20b80fda95 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.h
@@ -56,6 +56,8 @@ class MachTask {
nub_size_t ReadMemory(nub_addr_t addr, nub_size_t size, void *buf);
nub_size_t WriteMemory(nub_addr_t addr, nub_size_t size, const void *buf);
int GetMemoryRegionInfo(nub_addr_t addr, DNBRegionInfo *region_info);
+ nub_bool_t GetMemoryTags(nub_addr_t addr, nub_size_t size,
+ std::vector<uint8_t> &tags);
std::string GetProfileData(DNBProfileDataScanType scanType);
nub_addr_t AllocateMemory(nub_size_t size, uint32_t permissions);
diff --git a/lldb/tools/debugserver/source/MacOSX/MachTask.mm b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
index 8ae9d4df99657..f25cfac7b030a 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachTask.mm
+++ b/lldb/tools/debugserver/source/MacOSX/MachTask.mm
@@ -213,7 +213,7 @@
}
//----------------------------------------------------------------------
-// MachTask::MemoryRegionInfo
+// MachTask::GetMemoryRegionInfo
//----------------------------------------------------------------------
int MachTask::GetMemoryRegionInfo(nub_addr_t addr, DNBRegionInfo *region_info) {
task_t task = TaskPort();
@@ -221,7 +221,7 @@
return -1;
int ret = m_vm_memory.GetMemoryRegionInfo(task, addr, region_info);
- DNBLogThreadedIf(LOG_MEMORY, "MachTask::MemoryRegionInfo ( addr = 0x%8.8llx "
+ DNBLogThreadedIf(LOG_MEMORY, "MachTask::GetMemoryRegionInfo ( addr = 0x%8.8llx "
") => %i (start = 0x%8.8llx, size = 0x%8.8llx, "
"permissions = %u)",
(uint64_t)addr, ret, (uint64_t)region_info->addr,
@@ -229,6 +229,23 @@
return ret;
}
+//----------------------------------------------------------------------
+// MachTask::GetMemoryTags
+//----------------------------------------------------------------------
+nub_bool_t MachTask::GetMemoryTags(nub_addr_t addr, nub_size_t size,
+ std::vector<uint8_t> &tags) {
+ task_t task = TaskPort();
+ if (task == TASK_NULL)
+ return false;
+
+ bool ok = m_vm_memory.GetMemoryTags(task, addr, size, tags);
+ DNBLogThreadedIf(LOG_MEMORY, "MachTask::GetMemoryTags ( addr = 0x%8.8llx, "
+ "size = 0x%8.8llx ) => %s ( tag count = %llu)",
+ (uint64_t)addr, (uint64_t)size, (ok ? "ok" : "err"),
+ (uint64_t)tags.size());
+ return ok;
+}
+
#define TIME_VALUE_TO_TIMEVAL(a, r) \
do { \
(r)->tv_sec = (a)->seconds; \
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
index f3aa4d7d980fd..7ecd57e7bbfeb 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.cpp
@@ -13,6 +13,7 @@
#include "MachVMMemory.h"
#include "DNBLog.h"
#include "MachVMRegion.h"
+#include <cassert>
#include <dlfcn.h>
#include <mach/mach_vm.h>
#include <mach/shared_region.h>
@@ -123,6 +124,7 @@ nub_bool_t MachVMMemory::GetMemoryRegionInfo(task_t task, nub_addr_t address,
region_info->addr = vmRegion.StartAddress();
region_info->size = vmRegion.GetByteSize();
region_info->permissions = vmRegion.GetDNBPermissions();
+ region_info->flags = vmRegion.GetFlags();
region_info->dirty_pages =
get_dirty_pages(task, vmRegion.StartAddress(), vmRegion.GetByteSize());
region_info->vm_types = vmRegion.GetMemoryTypes();
@@ -150,6 +152,63 @@ nub_bool_t MachVMMemory::GetMemoryRegionInfo(task_t task, nub_addr_t address,
return true;
}
+// API availability:
+// mach_vm_update_pointers_with_remote_tags() - 26.0
+// VM_OFFSET_LIST_MAX macro - 26.1
+#ifndef VM_OFFSET_LIST_MAX
+#define VM_OFFSET_LIST_MAX 512
+#endif
+using mach_vm_offset_list_t = mach_vm_offset_t *;
+using mach_vm_update_pointers_with_remote_tags_t = kern_return_t(
+ mach_port_name_t target, mach_vm_offset_list_t in_pointer_list,
+ mach_msg_type_number_t in_pointer_listCnt,
+ mach_vm_offset_list_t out_pointer_list,
+ mach_msg_type_number_t *out_pointer_listCnt);
+
+nub_bool_t MachVMMemory::GetMemoryTags(task_t task, nub_addr_t address,
+ nub_size_t size,
+ std::vector<uint8_t> &tags) {
+ static auto mach_vm_update_pointers_with_remote_tags =
+ (mach_vm_update_pointers_with_remote_tags_t *)dlsym(
+ RTLD_DEFAULT, "mach_vm_update_pointers_with_remote_tags");
+ assert(mach_vm_update_pointers_with_remote_tags);
+
+ // Max batch size supported by mach_vm_update_pointers_with_remote_tags()
+ constexpr uint32_t max_ptr_count = VM_OFFSET_LIST_MAX;
+ constexpr uint32_t tag_shift = 56;
+ constexpr nub_addr_t tag_mask =
+ ((nub_addr_t)0x0f << tag_shift); // Lower half of top byte
+ constexpr uint32_t tag_granule = 16;
+
+ mach_msg_type_number_t ptr_count =
+ (size / tag_granule) + ((size % tag_granule > 0) ? 1 : 0);
+ ptr_count = std::min(ptr_count, max_ptr_count);
+
+ auto ptr_arr = std::make_unique<mach_vm_offset_t[]>(ptr_count);
+ for (size_t i = 0; i < ptr_count; i++)
+ ptr_arr[i] = (address + i * tag_granule);
+
+ mach_msg_type_number_t ptr_count_out = ptr_count;
+ m_err = mach_vm_update_pointers_with_remote_tags(
+ task, ptr_arr.get(), ptr_count, ptr_arr.get(), &ptr_count_out);
+
+ const bool failed = (m_err.Fail() || (ptr_count != ptr_count_out));
+ if (failed || DNBLogCheckLogBit(LOG_MEMORY))
+ m_err.LogThreaded("::mach_vm_update_pointers_with_remote_tags ( task = "
+ "0x%4.4x, ptr_count = %d ) => %i ( ptr_count_out = %d)",
+ task, ptr_count, m_err.Status(), ptr_count_out);
+ if (failed)
+ return false;
+
+ tags.reserve(ptr_count);
+ for (size_t i = 0; i < ptr_count; i++) {
+ nub_addr_t tag = (ptr_arr[i] & tag_mask) >> tag_shift;
+ tags.push_back(tag);
+ }
+
+ return true;
+}
+
static uint64_t GetPhysicalMemory() {
// This doesn't change often at all. No need to poll each time.
static uint64_t physical_memory = 0;
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
index 05d2c029b9980..8a7616091fbb3 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMMemory.h
@@ -28,6 +28,8 @@ class MachVMMemory {
nub_size_t PageSize(task_t task);
nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address,
DNBRegionInfo *region_info);
+ nub_bool_t GetMemoryTags(task_t task, nub_addr_t address, nub_size_t size,
+ std::vector<uint8_t> &tags);
nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task,
struct task_basic_info ti, cpu_type_t cputype,
nub_process_t pid, vm_statistics64_data_t &vminfo,
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp
index 97908b4acaf28..9d0d60fdaaed9 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.cpp
@@ -114,6 +114,11 @@ bool MachVMRegion::RestoreProtections() {
return false;
}
+#ifdef VM_REGION_FLAG_JIT_ENABLED
+#define VM_REGION_HAS_FLAGS 1
+#else
+#define VM_REGION_HAS_FLAGS 0
+#endif
bool MachVMRegion::GetRegionForAddress(nub_addr_t addr) {
// Restore any original protections and clear our vars
Clear();
@@ -140,6 +145,30 @@ bool MachVMRegion::GetRegionForAddress(nub_addr_t addr) {
if (failed)
return false;
if (log_protections) {
+#if VM_REGION_HAS_FLAGS
+ DNBLogThreaded("info = { prot = %u, "
+ "max_prot = %u, "
+ "inheritance = 0x%8.8x, "
+ "offset = 0x%8.8llx, "
+ "user_tag = 0x%8.8x, "
+ "ref_count = %u, "
+ "shadow_depth = %u, "
+ "ext_pager = %u, "
+ "share_mode = %u, "
+ "is_submap = %d, "
+ "behavior = %d, "
+ "object_id = 0x%8.8x, "
+ "user_wired_count = 0x%4.4x, "
+ "flags = %d }",
+ m_data.protection, m_data.max_protection, m_data.inheritance,
+ (uint64_t)m_data.offset, m_data.user_tag, m_data.ref_count,
+ m_data.shadow_depth, m_data.external_pager,
+ m_data.share_mode, m_data.is_submap, m_data.behavior,
+ m_data.object_id, m_data.user_wired_count, m_data.flags);
+#else
+ // Duplicate log call instead of #if-defing printing of flags to avoid
+ // compiler warning: 'embedding a directive within macro arguments has
+ // undefined behavior'
DNBLogThreaded("info = { prot = %u, "
"max_prot = %u, "
"inheritance = 0x%8.8x, "
@@ -158,6 +187,7 @@ bool MachVMRegion::GetRegionForAddress(nub_addr_t addr) {
m_data.shadow_depth, m_data.external_pager,
m_data.share_mode, m_data.is_submap, m_data.behavior,
m_data.object_id, m_data.user_wired_count);
+#endif
}
m_curr_protection = m_data.protection;
@@ -183,6 +213,22 @@ uint32_t MachVMRegion::GetDNBPermissions() const {
return dnb_permissions;
}
+#ifndef VM_REGION_FLAG_MTE_ENABLED
+#define VM_REGION_FLAG_MTE_ENABLED 0x4
+#endif
+std::vector<std::string> MachVMRegion::GetFlags() const {
+ std::vector<std::string> flags;
+#if VM_REGION_HAS_FLAGS
+ if (m_data.flags & VM_REGION_FLAG_JIT_ENABLED)
+ flags.push_back("jit");
+ if (m_data.flags & VM_REGION_FLAG_TPRO_ENABLED)
+ flags.push_back("tpro");
+ if (m_data.flags & VM_REGION_FLAG_MTE_ENABLED)
+ flags.push_back("mt");
+#endif
+ return flags;
+}
+
std::vector<std::string> MachVMRegion::GetMemoryTypes() const {
std::vector<std::string> types;
if (m_data.user_tag == VM_MEMORY_STACK) {
diff --git a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
index cb7705893c7ed..ba6e1f3bfa70e 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachVMRegion.h
@@ -40,9 +40,10 @@ class MachVMRegion {
vm_prot_t prot);
bool RestoreProtections();
bool GetRegionForAddress(nub_addr_t addr);
- std::vector<std::string> GetMemoryTypes() const;
uint32_t GetDNBPermissions() const;
+ std::vector<std::string> GetFlags() const;
+ std::vector<std::string> GetMemoryTypes() const;
const DNBError &GetError() { return m_err; }
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index d9fb22c6a1c06..be7108f633517 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -22,6 +22,9 @@
#include <mach/mach_vm.h>
#include <mach/task_info.h>
#include <memory>
+#if __has_include(<os/security_config.h>)
+#include <os/security_config.h>
+#endif
#include <pwd.h>
#include <string>
#include <sys/stat.h>
@@ -502,6 +505,8 @@ void RNBRemote::CreatePacketTable() {
memory_region_info, &RNBRemote::HandlePacket_MemoryRegionInfo, NULL,
"qMemoryRegionInfo", "Return size and attributes of a memory region that...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/160952
More information about the lldb-commits
mailing list