summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Target/Process.h38
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp20
-rw-r--r--lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp4
-rw-r--r--lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h6
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/elf-core/ProcessElfCore.h8
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h6
-rw-r--r--lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp4
-rw-r--r--lldb/source/Plugins/Process/mach-core/ProcessMachCore.h8
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp4
-rw-r--r--lldb/source/Plugins/Process/minidump/ProcessMinidump.h6
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp4
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.h6
-rw-r--r--lldb/source/Target/Process.cpp23
-rw-r--r--lldb/test/API/linux/aarch64/tagged_memory_region/Makefile3
-rw-r--r--lldb/test/API/linux/aarch64/tagged_memory_region/TestAArch64LinuxTaggedMemoryRegion.py70
-rw-r--r--lldb/test/API/linux/aarch64/tagged_memory_region/main.c17
-rw-r--r--llvm/docs/ReleaseNotes.rst6
19 files changed, 192 insertions, 49 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 12ed1e09227c..7911dac40b70 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1759,7 +1759,7 @@ public:
///
/// If load_addr is within the address space the process has mapped
/// range_info will be filled in with the start and end of that range as
- /// well as the permissions for that range and range_info.GetMapped will
+ /// well as the permissions for that range and range_info. GetMapped will
/// return true.
///
/// If load_addr is outside any mapped region then range_info will have its
@@ -1768,23 +1768,21 @@ public:
/// there are no valid mapped ranges between load_addr and the end of the
/// process address space.
///
- /// GetMemoryRegionInfo will only return an error if it is unimplemented for
- /// the current process.
+ /// GetMemoryRegionInfo calls DoGetMemoryRegionInfo. Override that function in
+ /// process subclasses.
///
/// \param[in] load_addr
- /// The load address to query the range_info for.
+ /// The load address to query the range_info for. May include non
+ /// address bits, these will be removed by the the ABI plugin if there is
+ /// one.
///
/// \param[out] range_info
/// An range_info value containing the details of the range.
///
/// \return
/// An error value.
- virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) {
- Status error;
- error.SetErrorString("Process::GetMemoryRegionInfo() not supported");
- return error;
- }
+ Status GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info);
/// Obtain all the mapped memory regions within this process.
///
@@ -2604,6 +2602,26 @@ protected:
virtual size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
Status &error) = 0;
+ /// DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has
+ /// removed non address bits from load_addr. Override this method in
+ /// subclasses of Process.
+ ///
+ /// See GetMemoryRegionInfo for details of the logic.
+ ///
+ /// \param[in] load_addr
+ /// The load address to query the range_info for. (non address bits
+ /// removed)
+ ///
+ /// \param[out] range_info
+ /// An range_info value containing the details of the range.
+ ///
+ /// \return
+ /// An error value.
+ virtual Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ return Status("Process::DoGetMemoryRegionInfo() not supported");
+ }
+
lldb::StateType GetPrivateState();
/// The "private" side of resuming a process. This doesn't alter the state
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index 1b44a1bd709a..1033d13f9f26 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -1665,14 +1665,11 @@ protected:
m_prev_end_addr = LLDB_INVALID_ADDRESS;
const size_t argc = command.GetArgumentCount();
- if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS)) {
- result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n",
- m_cmd_name.c_str(), m_cmd_syntax.c_str());
- return false;
- }
+ const lldb::ABISP &abi = process_sp->GetABI();
if (argc == 1) {
auto load_addr_str = command[0].ref();
+ // Non-address bits in this will be handled later by GetMemoryRegion
load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
LLDB_INVALID_ADDRESS, &error);
if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
@@ -1680,6 +1677,19 @@ protected:
command[0].c_str(), error.AsCString());
return false;
}
+ } else if (argc > 1 ||
+ // When we're repeating the command, the previous end address is
+ // used for load_addr. If that was 0xF...F then we must have
+ // reached the end of memory.
+ (argc == 0 && load_addr == LLDB_INVALID_ADDRESS) ||
+ // If the target has non-address bits (tags, limited virtual
+ // address size, etc.), the end of mappable memory will be lower
+ // than that. So if we find any non-address bit set, we must be
+ // at the end of the mappable range.
+ (abi && (abi->FixDataAddress(load_addr) != load_addr))) {
+ result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n",
+ m_cmd_name.c_str(), m_cmd_syntax.c_str());
+ return false;
}
lldb_private::MemoryRegionInfo range_info;
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
index 5398d16777ac..ba2ed2056d20 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
@@ -601,8 +601,8 @@ Status ProcessWindows::DoDeallocateMemory(lldb::addr_t ptr) {
return ProcessDebugger::DeallocateMemory(ptr);
}
-Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
- MemoryRegionInfo &info) {
+Status ProcessWindows::DoGetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) {
return ProcessDebugger::GetMemoryRegionInfo(vm_addr, info);
}
diff --git a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
index fc83649818ed..6f6f93f588e3 100644
--- a/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/ProcessWindows.h
@@ -78,8 +78,6 @@ public:
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
Status &error) override;
Status DoDeallocateMemory(lldb::addr_t ptr) override;
- Status GetMemoryRegionInfo(lldb::addr_t vm_addr,
- MemoryRegionInfo &info) override;
lldb::addr_t GetImageInfoAddress() override;
@@ -103,6 +101,10 @@ public:
Status EnableWatchpoint(Watchpoint *wp, bool notify = true) override;
Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override;
+protected:
+ Status DoGetMemoryRegionInfo(lldb::addr_t vm_addr,
+ MemoryRegionInfo &info) override;
+
private:
struct WatchpointInfo {
uint32_t slot_id;
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
index e1c0fd5ad98f..fe22bcbd75a1 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -286,8 +286,8 @@ size_t ProcessElfCore::ReadMemory(lldb::addr_t addr, void *buf, size_t size,
return DoReadMemory(addr, buf, size, error);
}
-Status ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessElfCore::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) {
region_info.Clear();
const VMRangeToPermissions::Entry *permission_entry =
m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
index 67df3c5fac76..fd36e5027816 100644
--- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
+++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -86,10 +86,6 @@ public:
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override;
- lldb_private::Status
- GetMemoryRegionInfo(lldb::addr_t load_addr,
- lldb_private::MemoryRegionInfo &region_info) override;
-
lldb::addr_t GetImageInfoAddress() override;
lldb_private::ArchSpec GetArchitecture();
@@ -105,6 +101,10 @@ protected:
bool DoUpdateThreadList(lldb_private::ThreadList &old_thread_list,
lldb_private::ThreadList &new_thread_list) override;
+ lldb_private::Status
+ DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
+
private:
struct NT_FILE_Entry {
lldb::addr_t start;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 03cd0b71c750..c40e738cae51 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -2962,8 +2962,8 @@ lldb::addr_t ProcessGDBRemote::DoAllocateMemory(size_t size,
return allocated_addr;
}
-Status ProcessGDBRemote::GetMemoryRegionInfo(addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
Status error(m_gdb_comm.GetMemoryRegionInfo(load_addr, region_info));
return error;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index bdf130e3ec11..dd907042608d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -143,9 +143,6 @@ public:
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
Status &error) override;
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region_info) override;
-
Status DoDeallocateMemory(lldb::addr_t ptr) override;
// Process STDIO
@@ -415,6 +412,9 @@ protected:
Status DoWriteMemoryTags(lldb::addr_t addr, size_t len, int32_t type,
const std::vector<uint8_t> &tags) override;
+ Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region_info) override;
+
private:
// For ProcessGDBRemote only
std::string m_partial_profile_data;
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index d23b05cadf51..a786021a0ac4 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -658,8 +658,8 @@ size_t ProcessMachCore::DoReadMemory(addr_t addr, void *buf, size_t size,
return bytes_read;
}
-Status ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr,
- MemoryRegionInfo &region_info) {
+Status ProcessMachCore::DoGetMemoryRegionInfo(addr_t load_addr,
+ MemoryRegionInfo &region_info) {
region_info.Clear();
const VMRangeToPermissions::Entry *permission_entry =
m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index e55bfcfcc723..b5ca515a7d3f 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -68,10 +68,6 @@ public:
size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
lldb_private::Status &error) override;
- lldb_private::Status
- GetMemoryRegionInfo(lldb::addr_t load_addr,
- lldb_private::MemoryRegionInfo &region_info) override;
-
lldb::addr_t GetImageInfoAddress() override;
protected:
@@ -84,6 +80,10 @@ protected:
lldb_private::ObjectFile *GetCoreObjectFile();
+ lldb_private::Status
+ DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ lldb_private::MemoryRegionInfo &region_info) override;
+
private:
bool GetDynamicLoaderAddress(lldb::addr_t addr);
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index 9d57509f4939..1b4406b88bb8 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -440,8 +440,8 @@ void ProcessMinidump::BuildMemoryRegions() {
llvm::sort(*m_memory_regions);
}
-Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region) {
+Status ProcessMinidump::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
BuildMemoryRegions();
region = MinidumpParser::GetMemoryRegionInfo(*m_memory_regions, load_addr);
return Status();
diff --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 3501d38a0f27..5360269199cd 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -75,9 +75,6 @@ public:
ArchSpec GetArchitecture();
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
Status GetMemoryRegions(
lldb_private::MemoryRegionInfos &region_list) override;
@@ -98,6 +95,9 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
+ Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
void ReadModuleList();
lldb::ModuleSP GetOrCreateModule(lldb_private::UUID minidump_uuid,
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index f952774b89ba..f98c415c2bdb 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -245,8 +245,8 @@ ArchSpec ScriptedProcess::GetArchitecture() {
return GetTarget().GetArchitecture();
}
-Status ScriptedProcess::GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &region) {
+Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &region) {
CheckInterpreterAndScriptObject();
Status error;
diff --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
index d56658a2e48a..c8355f35548a 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -84,9 +84,6 @@ public:
ArchSpec GetArchitecture();
- Status GetMemoryRegionInfo(lldb::addr_t load_addr,
- MemoryRegionInfo &range_info) override;
-
Status
GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) override;
@@ -100,6 +97,9 @@ protected:
bool DoUpdateThreadList(ThreadList &old_thread_list,
ThreadList &new_thread_list) override;
+ Status DoGetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) override;
+
private:
friend class ScriptedThread;
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 07eb895c40b2..8e1857ce4bfa 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -5842,12 +5842,18 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr,
return retval;
}
-Status
-Process::GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) {
+Status Process::GetMemoryRegionInfo(lldb::addr_t load_addr,
+ MemoryRegionInfo &range_info) {
+ if (const lldb::ABISP &abi = GetABI())
+ load_addr = abi->FixDataAddress(load_addr);
+ return DoGetMemoryRegionInfo(load_addr, range_info);
+}
+Status Process::GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) {
Status error;
lldb::addr_t range_end = 0;
+ const lldb::ABISP &abi = GetABI();
region_list.clear();
do {
@@ -5859,11 +5865,22 @@ Process::GetMemoryRegions(lldb_private::MemoryRegionInfos &region_list) {
break;
}
+ // We only check the end address, not start and end, because we assume that
+ // the start will not have non-address bits until the first unmappable
+ // region. We will have exited the loop by that point because the previous
+ // region, the last mappable region, will have non-address bits in its end
+ // address.
range_end = region_info.GetRange().GetRangeEnd();
if (region_info.GetMapped() == MemoryRegionInfo::eYes) {
region_list.push_back(std::move(region_info));
}
- } while (range_end != LLDB_INVALID_ADDRESS);
+ } while (
+ // For a process with no non-address bits, all address bits
+ // set means the end of memory.
+ range_end != LLDB_INVALID_ADDRESS &&
+ // If we have non-address bits and some are set then the end
+ // is at or beyond the end of mappable memory.
+ !(abi && (abi->FixDataAddress(range_end) != range_end)));
return error;
}
diff --git a/lldb/test/API/linux/aarch64/tagged_memory_region/Makefile b/lldb/test/API/linux/aarch64/tagged_memory_region/Makefile
new file mode 100644
index 000000000000..10495940055b
--- /dev/null
+++ b/lldb/test/API/linux/aarch64/tagged_memory_region/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/linux/aarch64/tagged_memory_region/TestAArch64LinuxTaggedMemoryRegion.py b/lldb/test/API/linux/aarch64/tagged_memory_region/TestAArch64LinuxTaggedMemoryRegion.py
new file mode 100644
index 000000000000..0b5f341574e0
--- /dev/null
+++ b/lldb/test/API/linux/aarch64/tagged_memory_region/TestAArch64LinuxTaggedMemoryRegion.py
@@ -0,0 +1,70 @@
+"""
+Test that "memory region" lookup uses the ABI plugin to remove
+non address bits from addresses before lookup.
+"""
+
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class AArch64LinuxTaggedMemoryRegionTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ # AArch64 Linux always enables the top byte ignore feature
+ @skipUnlessArch("aarch64")
+ @skipUnlessPlatform(["linux"])
+ def test_mte_regions(self):
+ self.build()
+ self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line(self, "main.c",
+ line_number('main.c', '// Set break point at this line.'),
+ num_expected_locations=1)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ if self.process().GetState() == lldb.eStateExited:
+ self.fail("Test program failed to run.")
+
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs=['stopped',
+ 'stop reason = breakpoint'])
+
+ # Despite the non address bits we should find a region
+ self.expect("memory region the_page", patterns=[
+ "\[0x[0-9A-Fa-f]+-0x[0-9A-Fa-f]+\) r-x"])
+
+ # Check that the usual error message is displayed after repeating
+ # the command until the last region.
+ self.runCmd("memory region 0")
+
+ # Count the number of repeats for use in the next check
+ repeats = 0
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+
+ while True:
+ interp.HandleCommand("memory region", result)
+ if result.Succeeded():
+ repeats += 1
+ else:
+ self.assertRegexpMatches(result.GetError(), "Usage: memory region ADDR")
+ break
+
+ # This time repeat until we get the last region. At that
+ # point the previous address will have non-address bits in it.
+ self.runCmd("memory region 0")
+ for i in range(repeats):
+ self.runCmd("memory region")
+
+ # This should not error, since the user supplied address overrides
+ # the previous end address.
+ self.expect("memory region the_page", patterns=[
+ "\[0x[0-9A-Fa-f]+-0x[0-9A-Fa-f]+\) r-x"])
diff --git a/lldb/test/API/linux/aarch64/tagged_memory_region/main.c b/lldb/test/API/linux/aarch64/tagged_memory_region/main.c
new file mode 100644
index 000000000000..29f99d73e12d
--- /dev/null
+++ b/lldb/test/API/linux/aarch64/tagged_memory_region/main.c
@@ -0,0 +1,17 @@
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+int main(int argc, char const *argv[]) {
+ void *the_page = mmap(0, sysconf(_SC_PAGESIZE), PROT_READ | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (the_page == MAP_FAILED)
+ return 1;
+
+ // Put something in the top byte (AArch64 Linux always enables top byte
+ // ignore)
+ the_page = (void *)((size_t)the_page | ((size_t)0x34 << 56));
+
+ return 0; // Set break point at this line.
+}
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 2f840a5f4c91..fb81e6567a23 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -145,6 +145,12 @@ Changes to the LLVM tools
Changes to LLDB
---------------------------------
+* The ``memory region`` command and ``GetMemoryRegionInfo`` API method now
+ ignore non-address bits in the address parameter. This also means that on
+ systems with non-address bits the last (usually unmapped) memory region
+ will not extend to 0xF...F. Instead it will end at the end of the mappable
+ range that the virtual address size allows.
+
Changes to Sanitizers
---------------------