aboutsummaryrefslogtreecommitdiff
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Commands/CommandOptionsProcessLaunch.cpp4
-rw-r--r--lldb/source/Commands/Options.td5
-rw-r--r--lldb/source/Host/freebsd/Host.cpp3
-rw-r--r--lldb/source/Host/macosx/objcxx/Host.mm33
-rw-r--r--lldb/source/Host/windows/MainLoopWindows.cpp6
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp15
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp84
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h7
8 files changed, 113 insertions, 44 deletions
diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
index 21d94d6..8ae20bd 100644
--- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
+++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp
@@ -127,6 +127,10 @@ Status CommandOptionsProcessLaunch::SetOptionValue(
break;
}
+ case 'M':
+ launch_info.GetFlags().Set(eLaunchFlagMemoryTagging);
+ break;
+
case 'c':
if (!option_arg.empty())
launch_info.SetShell(FileSpec(option_arg));
diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index 595b3d0..a9f054e 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -1173,6 +1173,11 @@ let Command = "process launch" in {
Arg<"Boolean">,
Desc<"Set whether to shell expand arguments to the process when "
"launching.">;
+ def process_launch_memory_tagging
+ : Option<"memory-tagging", "M">,
+ Desc<"Set whether to explicitly enable memory tagging when launching "
+ "the process. Requires hardware support. "
+ "(Only supported on Darwin.)">;
}
let Command = "process attach" in {
diff --git a/lldb/source/Host/freebsd/Host.cpp b/lldb/source/Host/freebsd/Host.cpp
index fa7efad..dfdbfea 100644
--- a/lldb/source/Host/freebsd/Host.cpp
+++ b/lldb/source/Host/freebsd/Host.cpp
@@ -18,8 +18,6 @@
#include <dlfcn.h>
#include <execinfo.h>
-#include "llvm/Object/ELF.h"
-
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
@@ -32,6 +30,7 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/Object/ELF.h"
#include "llvm/TargetParser/Host.h"
namespace lldb_private {
diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm
index 3c1d117..7120892 100644
--- a/lldb/source/Host/macosx/objcxx/Host.mm
+++ b/lldb/source/Host/macosx/objcxx/Host.mm
@@ -1210,6 +1210,39 @@ static Status LaunchProcessPosixSpawn(const char *exe_path,
}
}
+ if (launch_info.GetFlags().Test(eLaunchFlagMemoryTagging)) {
+ // The following function configures the spawn attributes to launch the
+ // process with memory tagging explicitly enabled. We look it up
+ // dynamically since it is only available on newer OS. Does nothing on
+ // hardware which does not support MTE.
+ //
+ // int posix_spawnattr_set_use_sec_transition_shims_np(
+ // posix_spawnattr_t *attr, uint32_t flags);
+ //
+ using posix_spawnattr_set_use_sec_transition_shims_np_t =
+ int (*)(posix_spawnattr_t *attr, uint32_t flags);
+ auto posix_spawnattr_set_use_sec_transition_shims_np_fn =
+ (posix_spawnattr_set_use_sec_transition_shims_np_t)dlsym(
+ RTLD_DEFAULT, "posix_spawnattr_set_use_sec_transition_shims_np");
+ if (posix_spawnattr_set_use_sec_transition_shims_np_fn) {
+ error =
+ Status(posix_spawnattr_set_use_sec_transition_shims_np_fn(&attr, 0),
+ eErrorTypePOSIX);
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, "
+ "posix_spawnattr_set_use_sec_transition_shims_np(&attr, 0)",
+ error);
+ return error;
+ }
+ } else {
+ LLDB_LOG(log,
+ "error: posix_spawnattr_set_use_sec_transition_shims_np not "
+ "available",
+ error);
+ }
+ }
+
// Don't set the binpref if a shell was provided. After all, that's only
// going to affect what version of the shell is launched, not what fork of
// the binary is launched. We insert "arch --arch <ARCH> as part of the
diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp
index c0b1079..9b7df10 100644
--- a/lldb/source/Host/windows/MainLoopWindows.cpp
+++ b/lldb/source/Host/windows/MainLoopWindows.cpp
@@ -55,11 +55,7 @@ public:
if (m_monitor_thread.joinable()) {
m_stopped = true;
SetEvent(m_ready);
- // Keep trying to cancel ReadFile() until the thread exits.
- do {
- CancelIoEx(m_handle, /*lpOverlapped=*/NULL);
- } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) ==
- WAIT_TIMEOUT);
+ CancelIoEx(m_handle, /*lpOverlapped=*/NULL);
m_monitor_thread.join();
}
CloseHandle(m_event);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index 4b183a8..5588208 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -52,7 +52,7 @@ private:
ValueObject *m_tree = nullptr;
size_t m_num_elements = 0;
ValueObject *m_next_element = nullptr;
- std::vector<std::pair<ValueObject *, uint64_t>> m_elements_cache;
+ std::vector<ValueObject *> m_elements_cache;
};
class LibCxxUnorderedMapIteratorSyntheticFrontEnd
@@ -192,26 +192,25 @@ lldb::ValueObjectSP lldb_private::formatters::
return nullptr;
}
}
- m_elements_cache.push_back(
- {value_sp.get(), hash_sp->GetValueAsUnsigned(0)});
+ m_elements_cache.push_back(value_sp.get());
m_next_element = node_sp->GetChildMemberWithName("__next_").get();
if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0)
m_next_element = nullptr;
}
- std::pair<ValueObject *, uint64_t> val_hash = m_elements_cache[idx];
- if (!val_hash.first)
+ ValueObject *val_hash = m_elements_cache[idx];
+ if (!val_hash)
return lldb::ValueObjectSP();
StreamString stream;
stream.Printf("[%" PRIu64 "]", (uint64_t)idx);
DataExtractor data;
Status error;
- val_hash.first->GetData(data, error);
+ val_hash->GetData(data, error);
if (error.Fail())
return lldb::ValueObjectSP();
const bool thread_and_frame_only_if_stopped = true;
- ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock(
- thread_and_frame_only_if_stopped);
+ ExecutionContext exe_ctx =
+ val_hash->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped);
return CreateValueObjectFromData(stream.GetString(), data, exe_ctx,
m_element_type);
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
index cc0c9e7..6d8f41a 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp
@@ -14,6 +14,7 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"
+#include "llvm/ADT/Sequence.h"
using namespace lldb;
using namespace lldb_private;
@@ -266,22 +267,47 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process,
return true;
}
-bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
- lldb::addr_t relative_selector_base_addr,
- bool is_small, bool has_direct_sel) {
- size_t ptr_size = process->GetAddressByteSize();
- size_t size = GetSize(process, is_small);
+llvm::SmallVector<ClassDescriptorV2::method_t, 0>
+ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
+ lldb::addr_t relative_selector_base_addr,
+ bool is_small, bool has_direct_sel) const {
+ lldb_private::Process *process = m_runtime.GetProcess();
+ if (!process)
+ return {};
- DataBufferHeap buffer(size, '\0');
- Status error;
+ const size_t size = method_t::GetSize(process, is_small);
+ const size_t num_methods = addresses.size();
- process->ReadMemory(addr, buffer.GetBytes(), size, error);
- if (error.Fail()) {
- return false;
+ llvm::SmallVector<uint8_t, 0> buffer(num_methods * size, 0);
+ llvm::DenseSet<uint32_t> failed_indices;
+
+ for (auto [idx, addr] : llvm::enumerate(addresses)) {
+ Status error;
+ process->ReadMemory(addr, buffer.data() + idx * size, size, error);
+ if (error.Fail())
+ failed_indices.insert(idx);
}
- DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(),
- ptr_size);
+ llvm::SmallVector<method_t, 0> methods;
+ methods.reserve(num_methods);
+ for (auto [idx, addr] : llvm::enumerate(addresses)) {
+ if (failed_indices.contains(idx))
+ continue;
+ DataExtractor extractor(buffer.data() + idx * size, size,
+ process->GetByteOrder(),
+ process->GetAddressByteSize());
+ methods.push_back(method_t());
+ methods.back().Read(extractor, process, addr, relative_selector_base_addr,
+ is_small, has_direct_sel);
+ }
+
+ return methods;
+}
+
+bool ClassDescriptorV2::method_t::Read(DataExtractor &extractor,
+ Process *process, lldb::addr_t addr,
+ lldb::addr_t relative_selector_base_addr,
+ bool is_small, bool has_direct_sel) {
lldb::offset_t cursor = 0;
if (is_small) {
@@ -291,11 +317,11 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
m_name_ptr = addr + nameref_offset;
+ Status error;
if (!has_direct_sel) {
// The SEL offset points to a SELRef. We need to dereference twice.
- m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size,
- 0, error);
- if (!error.Success())
+ m_name_ptr = process->ReadPointerFromMemory(m_name_ptr, error);
+ if (error.Fail())
return false;
} else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) {
m_name_ptr = relative_selector_base_addr + nameref_offset;
@@ -308,13 +334,13 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr,
m_imp_ptr = extractor.GetAddress_unchecked(&cursor);
}
+ Status error;
process->ReadCStringFromMemory(m_name_ptr, m_name, error);
- if (error.Fail()) {
+ if (error.Fail())
return false;
- }
process->ReadCStringFromMemory(m_types_ptr, m_types, error);
- return !error.Fail();
+ return error.Success();
}
bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) {
@@ -447,17 +473,19 @@ ClassDescriptorV2::GetMethodList(Process *process,
bool ClassDescriptorV2::ProcessMethodList(
std::function<bool(const char *, const char *)> const &instance_method_func,
ClassDescriptorV2::method_list_t &method_list) const {
- lldb_private::Process *process = m_runtime.GetProcess();
- auto method = std::make_unique<method_t>();
- lldb::addr_t relative_selector_base_addr =
- m_runtime.GetRelativeSelectorBaseAddr();
- for (uint32_t i = 0, e = method_list.m_count; i < e; ++i) {
- method->Read(process, method_list.m_first_ptr + (i * method_list.m_entsize),
- relative_selector_base_addr, method_list.m_is_small,
- method_list.m_has_direct_selector);
- if (instance_method_func(method->m_name.c_str(), method->m_types.c_str()))
+ auto idx_to_method_addr = [&](uint32_t idx) {
+ return method_list.m_first_ptr + (idx * method_list.m_entsize);
+ };
+ llvm::SmallVector<addr_t> addresses = llvm::to_vector(llvm::map_range(
+ llvm::seq<uint32_t>(method_list.m_count), idx_to_method_addr));
+
+ llvm::SmallVector<method_t, 0> methods =
+ ReadMethods(addresses, m_runtime.GetRelativeSelectorBaseAddr(),
+ method_list.m_is_small, method_list.m_has_direct_selector);
+
+ for (const auto &method : methods)
+ if (instance_method_func(method.m_name.c_str(), method.m_types.c_str()))
break;
- }
return true;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
index 920a5eb..78b3311 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h
@@ -172,11 +172,16 @@ private:
+ field_size; // IMP imp;
}
- bool Read(Process *process, lldb::addr_t addr,
+ bool Read(DataExtractor &extractor, Process *process, lldb::addr_t addr,
lldb::addr_t relative_selector_base_addr, bool is_small,
bool has_direct_sel);
};
+ llvm::SmallVector<method_t, 0>
+ ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses,
+ lldb::addr_t relative_selector_base_addr, bool is_small,
+ bool has_direct_sel) const;
+
struct ivar_list_t {
uint32_t m_entsize;
uint32_t m_count;