Skip to content

Commit 5ba06f5

Browse files
author
git apple-llvm automerger
committed
Merge commit '85f1a6791a7e' from swift/release/6.2 into stable/20240723
2 parents e541dfc + 85f1a67 commit 5ba06f5

File tree

5 files changed

+39
-126
lines changed

5 files changed

+39
-126
lines changed

lldb/examples/synthetic/libcxx.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,13 @@ def get_child_index(self, name):
694694
except:
695695
return -1
696696

697+
@staticmethod
698+
def _subscript(ptr: lldb.SBValue, idx: int, name: str) -> lldb.SBValue:
699+
"""Access a pointer value as if it was an array. Returns ptr[idx]."""
700+
deref_t = ptr.GetType().GetPointeeType()
701+
offset = idx * deref_t.GetByteSize()
702+
return ptr.CreateChildAtOffset(name, offset, deref_t)
703+
697704
def get_child_at_index(self, index):
698705
logger = lldb.formatters.Logger.Logger()
699706
logger.write("Fetching child " + str(index))
@@ -703,11 +710,8 @@ def get_child_at_index(self, index):
703710
return None
704711
try:
705712
i, j = divmod(self.start + index, self.block_size)
706-
707-
return self.first.CreateValueFromExpression(
708-
"[" + str(index) + "]",
709-
"*(*(%s + %d) + %d)" % (self.map_begin.get_expr_path(), i, j),
710-
)
713+
val = stddeque_SynthProvider._subscript(self.map_begin, i, "")
714+
return stddeque_SynthProvider._subscript(val, j, f"[{index}]")
711715
except:
712716
return None
713717

@@ -764,9 +768,10 @@ def update(self):
764768
map_.GetChildMemberWithName("__end_cap_")
765769
)
766770
else:
767-
map_endcap = map_.GetChildMemberWithName(
768-
"__end_cap_"
769-
).GetValueAsUnsigned(0)
771+
map_endcap = map_.GetChildMemberWithName("__cap_")
772+
if not map_endcap.IsValid():
773+
map_endcap = map_.GetChildMemberWithName("__end_cap_")
774+
map_endcap = map_endcap.GetValueAsUnsigned(0)
770775

771776
# check consistency
772777
if not map_first <= map_begin <= map_end <= map_endcap:

lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp

Lines changed: 12 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "lldb/Expression/UtilityFunction.h"
2020
#include "lldb/Target/ExecutionContext.h"
21+
#include "lldb/Target/Language.h"
2122
#include "lldb/Target/Process.h"
2223
#include "lldb/Target/StackFrame.h"
2324
#include "lldb/Target/Target.h"
@@ -32,36 +33,27 @@ using namespace lldb_private;
3233

3334
static char ID;
3435

35-
#define VALID_POINTER_CHECK_NAME "_$__lldb_valid_pointer_check"
3636
#define VALID_OBJC_OBJECT_CHECK_NAME "$__lldb_objc_object_check"
3737

38-
static const char g_valid_pointer_check_text[] =
39-
"extern \"C\" void\n"
40-
"_$__lldb_valid_pointer_check (unsigned char *$__lldb_arg_ptr)\n"
41-
"{\n"
42-
" unsigned char $__lldb_local_val = *$__lldb_arg_ptr;\n"
43-
"}";
44-
4538
ClangDynamicCheckerFunctions::ClangDynamicCheckerFunctions()
4639
: DynamicCheckerFunctions(DCF_Clang) {}
4740

4841
ClangDynamicCheckerFunctions::~ClangDynamicCheckerFunctions() = default;
4942

50-
llvm::Error ClangDynamicCheckerFunctions::Install(
51-
DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) {
52-
Expected<std::unique_ptr<UtilityFunction>> utility_fn =
53-
exe_ctx.GetTargetRef().CreateUtilityFunction(
54-
g_valid_pointer_check_text, VALID_POINTER_CHECK_NAME,
55-
lldb::eLanguageTypeC, exe_ctx);
56-
if (!utility_fn)
57-
return utility_fn.takeError();
58-
m_valid_pointer_check = std::move(*utility_fn);
59-
43+
llvm::Error
44+
ClangDynamicCheckerFunctions::Install(DiagnosticManager &diagnostic_manager,
45+
ExecutionContext &exe_ctx) {
6046
if (Process *process = exe_ctx.GetProcessPtr()) {
6147
ObjCLanguageRuntime *objc_language_runtime =
6248
ObjCLanguageRuntime::Get(*process);
6349

64-
if (objc_language_runtime) {
50+
SourceLanguage lang = process->GetTarget().GetLanguage();
51+
if (!lang)
52+
if (auto *frame = exe_ctx.GetFramePtr())
53+
lang = frame->GetLanguage();
54+
55+
if (objc_language_runtime &&
56+
Language::LanguageIsObjC(lang.AsLanguageType())) {
6557
Expected<std::unique_ptr<UtilityFunction>> checker_fn =
6658
objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME, exe_ctx);
6759
if (!checker_fn)
@@ -78,11 +70,7 @@ bool ClangDynamicCheckerFunctions::DoCheckersExplainStop(lldb::addr_t addr,
7870
// FIXME: We have to get the checkers to know why they scotched the call in
7971
// more detail,
8072
// so we can print a better message here.
81-
if (m_valid_pointer_check && m_valid_pointer_check->ContainsAddress(addr)) {
82-
message.Printf("Attempted to dereference an invalid pointer.");
83-
return true;
84-
} else if (m_objc_object_check &&
85-
m_objc_object_check->ContainsAddress(addr)) {
73+
if (m_objc_object_check && m_objc_object_check->ContainsAddress(addr)) {
8674
message.Printf("Attempted to dereference an invalid ObjC Object or send it "
8775
"an unrecognized selector");
8876
return true;
@@ -224,29 +212,6 @@ class Instrumenter {
224212
return true;
225213
}
226214

227-
/// Build a function pointer for a function with signature void
228-
/// (*)(uint8_t*) with a given address
229-
///
230-
/// \param[in] start_address
231-
/// The address of the function.
232-
///
233-
/// \return
234-
/// The function pointer, for use in a CallInst.
235-
llvm::FunctionCallee BuildPointerValidatorFunc(lldb::addr_t start_address) {
236-
llvm::Type *param_array[1];
237-
238-
param_array[0] = const_cast<llvm::PointerType *>(GetI8PtrTy());
239-
240-
ArrayRef<llvm::Type *> params(param_array, 1);
241-
242-
FunctionType *fun_ty = FunctionType::get(
243-
llvm::Type::getVoidTy(m_module.getContext()), params, true);
244-
PointerType *fun_ptr_ty = PointerType::getUnqual(fun_ty);
245-
Constant *fun_addr_int =
246-
ConstantInt::get(GetIntptrTy(), start_address, false);
247-
return {fun_ty, ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty)};
248-
}
249-
250215
/// Build a function pointer for a function with signature void
251216
/// (*)(uint8_t*, uint8_t*) with a given address
252217
///
@@ -301,53 +266,6 @@ class Instrumenter {
301266
IntegerType *m_intptr_ty = nullptr;
302267
};
303268

304-
class ValidPointerChecker : public Instrumenter {
305-
public:
306-
ValidPointerChecker(llvm::Module &module,
307-
std::shared_ptr<UtilityFunction> checker_function)
308-
: Instrumenter(module, checker_function),
309-
m_valid_pointer_check_func(nullptr) {}
310-
311-
~ValidPointerChecker() override = default;
312-
313-
protected:
314-
bool InstrumentInstruction(llvm::Instruction *inst) override {
315-
Log *log = GetLog(LLDBLog::Expressions);
316-
317-
LLDB_LOGF(log, "Instrumenting load/store instruction: %s\n",
318-
PrintValue(inst).c_str());
319-
320-
if (!m_valid_pointer_check_func)
321-
m_valid_pointer_check_func =
322-
BuildPointerValidatorFunc(m_checker_function->StartAddress());
323-
324-
llvm::Value *dereferenced_ptr = nullptr;
325-
326-
if (llvm::LoadInst *li = dyn_cast<llvm::LoadInst>(inst))
327-
dereferenced_ptr = li->getPointerOperand();
328-
else if (llvm::StoreInst *si = dyn_cast<llvm::StoreInst>(inst))
329-
dereferenced_ptr = si->getPointerOperand();
330-
else
331-
return false;
332-
333-
// Insert an instruction to call the helper with the result
334-
CallInst::Create(m_valid_pointer_check_func, dereferenced_ptr, "",
335-
inst->getIterator());
336-
337-
return true;
338-
}
339-
340-
bool InspectInstruction(llvm::Instruction &i) override {
341-
if (isa<llvm::LoadInst>(&i) || isa<llvm::StoreInst>(&i))
342-
RegisterInstruction(i);
343-
344-
return true;
345-
}
346-
347-
private:
348-
llvm::FunctionCallee m_valid_pointer_check_func;
349-
};
350-
351269
class ObjcObjectChecker : public Instrumenter {
352270
public:
353271
ObjcObjectChecker(llvm::Module &module,
@@ -528,16 +446,6 @@ bool IRDynamicChecks::runOnModule(llvm::Module &M) {
528446
return false;
529447
}
530448

531-
if (m_checker_functions.m_valid_pointer_check) {
532-
ValidPointerChecker vpc(M, m_checker_functions.m_valid_pointer_check);
533-
534-
if (!vpc.Inspect(*function))
535-
return false;
536-
537-
if (!vpc.Instrument())
538-
return false;
539-
}
540-
541449
if (m_checker_functions.m_objc_object_check) {
542450
ObjcObjectChecker ooc(M, m_checker_functions.m_objc_object_check);
543451

lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ class ClangDynamicCheckerFunctions
5353

5454
bool DoCheckersExplainStop(lldb::addr_t addr, Stream &message) override;
5555

56-
std::shared_ptr<UtilityFunction> m_valid_pointer_check;
5756
std::shared_ptr<UtilityFunction> m_objc_object_check;
5857
};
5958

lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,22 @@ static bool isUnorderedMap(ConstString type_name) {
103103

104104
CompilerType lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
105105
GetElementType(CompilerType table_type) {
106-
auto element_type = table_type.GetTypedefedType().GetTypeTemplateArgument(0);
106+
auto element_type =
107+
table_type.GetDirectNestedTypeWithName("value_type").GetTypedefedType();
108+
109+
// In newer unordered_map layouts, the std::pair element type isn't wrapped
110+
// in any helper types. So return it directly.
111+
if (isStdTemplate(element_type.GetTypeName(), "pair"))
112+
return element_type;
107113

108114
// This synthetic provider is used for both unordered_(multi)map and
109-
// unordered_(multi)set. For unordered_map, the element type has an
110-
// additional type layer, an internal struct (`__hash_value_type`)
111-
// that wraps a std::pair. Peel away the internal wrapper type - whose
112-
// structure is of no value to users, to expose the std::pair. This
113-
// matches the structure returned by the std::map synthetic provider.
114-
if (isUnorderedMap(m_backend.GetTypeName())) {
115+
// unordered_(multi)set. For older unordered_map layouts, the element type has
116+
// an additional type layer, an internal struct (`__hash_value_type`) that
117+
// wraps a std::pair. Peel away the internal wrapper type - whose structure is
118+
// of no value to users, to expose the std::pair. This matches the structure
119+
// returned by the std::map synthetic provider.
120+
if (isUnorderedMap(
121+
m_backend.GetCompilerType().GetCanonicalType().GetTypeName())) {
115122
std::string name;
116123
CompilerType field_type =
117124
element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr);

lldb/test/API/tools/lldb-dap/save-core/TestDAP_save_core.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,7 @@ def test_save_core(self):
3333
# Getting dap stack trace may trigger __lldb_caller_function JIT module to be created.
3434
self.get_stackFrames(startFrame=0)
3535

36-
# Evaluating an expression that cause "_$__lldb_valid_pointer_check" JIT module to be created.
37-
expression = 'printf("this is a test")'
38-
self.dap_server.request_evaluate(expression, context="watch")
39-
40-
# Verify "_$__lldb_valid_pointer_check" JIT module is created.
4136
modules = self.dap_server.get_modules()
42-
self.assertTrue(modules["_$__lldb_valid_pointer_check"])
4337
thread_count = len(self.dap_server.get_threads())
4438

4539
core_stack = self.getBuildArtifact("core.stack.dmp")

0 commit comments

Comments
 (0)