1//===-- IRForTarget.cpp ---------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "IRForTarget.h"
10
11#include "ClangExpressionDeclMap.h"
12#include "ClangUtil.h"
13
14#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
15#include "llvm/IR/Constants.h"
16#include "llvm/IR/DataLayout.h"
17#include "llvm/IR/Operator.h"
18#include "llvm/IR/InstrTypes.h"
19#include "llvm/IR/Instructions.h"
20#include "llvm/IR/Intrinsics.h"
21#include "llvm/IR/LegacyPassManager.h"
22#include "llvm/IR/Metadata.h"
23#include "llvm/IR/Module.h"
24#include "llvm/IR/ValueSymbolTable.h"
25#include "llvm/Support/raw_ostream.h"
26#include "llvm/Transforms/IPO.h"
27
28#include "clang/AST/ASTContext.h"
29
30#include "lldb/Core/dwarf.h"
31#include "lldb/Expression/IRExecutionUnit.h"
32#include "lldb/Expression/IRInterpreter.h"
33#include "lldb/Symbol/CompilerType.h"
34#include "lldb/Utility/ConstString.h"
35#include "lldb/Utility/DataBufferHeap.h"
36#include "lldb/Utility/Endian.h"
37#include "lldb/Utility/LLDBLog.h"
38#include "lldb/Utility/Log.h"
39#include "lldb/Utility/Scalar.h"
40#include "lldb/Utility/StreamString.h"
41
42#include <map>
43#include <optional>
44
45using namespace llvm;
46using lldb_private::LLDBLog;
47
48typedef SmallVector<Instruction *, 2> InstrList;
49
50IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
51 : m_maker(maker), m_values() {}
52
53IRForTarget::FunctionValueCache::~FunctionValueCache() = default;
54
55llvm::Value *
56IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
57 if (!m_values.count(x: function)) {
58 llvm::Value *ret = m_maker(function);
59 m_values[function] = ret;
60 return ret;
61 }
62 return m_values[function];
63}
64
65static llvm::Value *FindEntryInstruction(llvm::Function *function) {
66 if (function->empty())
67 return nullptr;
68
69 return function->getEntryBlock().getFirstNonPHIOrDbg();
70}
71
72IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
73 bool resolve_vars,
74 lldb_private::IRExecutionUnit &execution_unit,
75 lldb_private::Stream &error_stream,
76 const char *func_name)
77 : m_resolve_vars(resolve_vars), m_func_name(func_name),
78 m_decl_map(decl_map), m_error_stream(error_stream),
79 m_execution_unit(execution_unit),
80 m_entry_instruction_finder(FindEntryInstruction) {}
81
82/* Handy utility functions used at several places in the code */
83
84static std::string PrintValue(const Value *value, bool truncate = false) {
85 std::string s;
86 if (value) {
87 raw_string_ostream rso(s);
88 value->print(O&: rso);
89 rso.flush();
90 if (truncate)
91 s.resize(n: s.length() - 1);
92 }
93 return s;
94}
95
96static std::string PrintType(const llvm::Type *type, bool truncate = false) {
97 std::string s;
98 raw_string_ostream rso(s);
99 type->print(O&: rso);
100 rso.flush();
101 if (truncate)
102 s.resize(n: s.length() - 1);
103 return s;
104}
105
106bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
107 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
108
109 return true;
110}
111
112clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
113 Module *module) {
114 NamedMDNode *named_metadata =
115 module->getNamedMetadata(Name: "clang.global.decl.ptrs");
116
117 if (!named_metadata)
118 return nullptr;
119
120 unsigned num_nodes = named_metadata->getNumOperands();
121 unsigned node_index;
122
123 for (node_index = 0; node_index < num_nodes; ++node_index) {
124 llvm::MDNode *metadata_node =
125 dyn_cast<llvm::MDNode>(Val: named_metadata->getOperand(i: node_index));
126 if (!metadata_node)
127 return nullptr;
128
129 if (metadata_node->getNumOperands() != 2)
130 continue;
131
132 if (mdconst::dyn_extract_or_null<GlobalValue>(
133 MD: metadata_node->getOperand(I: 0)) != global_val)
134 continue;
135
136 ConstantInt *constant_int =
137 mdconst::dyn_extract<ConstantInt>(MD: metadata_node->getOperand(I: 1));
138
139 if (!constant_int)
140 return nullptr;
141
142 uintptr_t ptr = constant_int->getZExtValue();
143
144 return reinterpret_cast<clang::NamedDecl *>(ptr);
145 }
146
147 return nullptr;
148}
149
150clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
151 return DeclForGlobal(global_val, module: m_module);
152}
153
154/// Returns true iff the mangled symbol is for a static guard variable.
155static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,
156 bool check_ms_abi = true) {
157 bool result =
158 mangled_symbol.starts_with(Prefix: "_ZGV"); // Itanium ABI guard variable
159 if (check_ms_abi)
160 result |= mangled_symbol.ends_with(Suffix: "@4IA"); // Microsoft ABI
161 return result;
162}
163
164bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
165 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
166
167 if (!m_resolve_vars)
168 return true;
169
170 // Find the result variable. If it doesn't exist, we can give up right here.
171
172 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
173
174 llvm::StringRef result_name;
175 bool found_result = false;
176
177 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
178 result_name = value_symbol.first();
179
180 // Check if this is a guard variable. It seems this causes some hiccups
181 // on Windows, so let's only check for Itanium guard variables.
182 bool is_guard_var = isGuardVariableSymbol(mangled_symbol: result_name, /*MS ABI*/ check_ms_abi: false);
183
184 if (result_name.contains(Other: "$__lldb_expr_result_ptr") && !is_guard_var) {
185 found_result = true;
186 m_result_is_pointer = true;
187 break;
188 }
189
190 if (result_name.contains(Other: "$__lldb_expr_result") && !is_guard_var) {
191 found_result = true;
192 m_result_is_pointer = false;
193 break;
194 }
195 }
196
197 if (!found_result) {
198 LLDB_LOG(log, "Couldn't find result variable");
199
200 return true;
201 }
202
203 LLDB_LOG(log, "Result name: \"{0}\"", result_name);
204
205 Value *result_value = m_module->getNamedValue(Name: result_name);
206
207 if (!result_value) {
208 LLDB_LOG(log, "Result variable had no data");
209
210 m_error_stream.Format(format: "Internal error [IRForTarget]: Result variable's "
211 "name ({0}) exists, but not its definition\n",
212 args&: result_name);
213
214 return false;
215 }
216
217 LLDB_LOG(log, "Found result in the IR: \"{0}\"",
218 PrintValue(result_value, false));
219
220 GlobalVariable *result_global = dyn_cast<GlobalVariable>(Val: result_value);
221
222 if (!result_global) {
223 LLDB_LOG(log, "Result variable isn't a GlobalVariable");
224
225 m_error_stream.Format(format: "Internal error [IRForTarget]: Result variable ({0}) "
226 "is defined, but is not a global variable\n",
227 args&: result_name);
228
229 return false;
230 }
231
232 clang::NamedDecl *result_decl = DeclForGlobal(global_val: result_global);
233 if (!result_decl) {
234 LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
235
236 m_error_stream.Format(format: "Internal error [IRForTarget]: Result variable ({0}) "
237 "does not have a corresponding Clang entity\n",
238 args&: result_name);
239
240 return false;
241 }
242
243 if (log) {
244 std::string decl_desc_str;
245 raw_string_ostream decl_desc_stream(decl_desc_str);
246 result_decl->print(decl_desc_stream);
247 decl_desc_stream.flush();
248
249 LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
250 }
251
252 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(Val: result_decl);
253 if (!result_var) {
254 LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
255
256 m_error_stream.Format(format: "Internal error [IRForTarget]: Result variable "
257 "({0})'s corresponding Clang entity isn't a "
258 "variable\n",
259 args&: result_name);
260
261 return false;
262 }
263
264 // Get the next available result name from m_decl_map and create the
265 // persistent variable for it
266
267 // If the result is an Lvalue, it is emitted as a pointer; see
268 // ASTResultSynthesizer::SynthesizeBodyResult.
269 if (m_result_is_pointer) {
270 clang::QualType pointer_qual_type = result_var->getType();
271 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
272
273 const clang::PointerType *pointer_pointertype =
274 pointer_type->getAs<clang::PointerType>();
275 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
276 pointer_type->getAs<clang::ObjCObjectPointerType>();
277
278 if (pointer_pointertype) {
279 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
280
281 m_result_type = lldb_private::TypeFromParser(
282 m_decl_map->GetTypeSystem()->GetType(qt: element_qual_type));
283 } else if (pointer_objcobjpointertype) {
284 clang::QualType element_qual_type =
285 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
286
287 m_result_type = lldb_private::TypeFromParser(
288 m_decl_map->GetTypeSystem()->GetType(qt: element_qual_type));
289 } else {
290 LLDB_LOG(log, "Expected result to have pointer type, but it did not");
291
292 m_error_stream.Format(format: "Internal error [IRForTarget]: Lvalue result ({0}) "
293 "is not a pointer variable\n",
294 args&: result_name);
295
296 return false;
297 }
298 } else {
299 m_result_type = lldb_private::TypeFromParser(
300 m_decl_map->GetTypeSystem()->GetType(qt: result_var->getType()));
301 }
302
303 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
304 std::optional<uint64_t> bit_size = m_result_type.GetBitSize(exe_scope: target_sp.get());
305 if (!bit_size) {
306 lldb_private::StreamString type_desc_stream;
307 m_result_type.DumpTypeDescription(s: &type_desc_stream);
308
309 LLDB_LOG(log, "Result type has unknown size");
310
311 m_error_stream.Printf(format: "Error [IRForTarget]: Size of result type '%s' "
312 "couldn't be determined\n",
313 type_desc_stream.GetData());
314 return false;
315 }
316
317 if (log) {
318 lldb_private::StreamString type_desc_stream;
319 m_result_type.DumpTypeDescription(s: &type_desc_stream);
320
321 LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
322 }
323
324 m_result_name = lldb_private::ConstString("$RESULT_NAME");
325
326 LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
327 m_result_name,
328 m_result_type.GetByteSize(target_sp.get()).value_or(0));
329
330 // Construct a new result global and set up its metadata
331
332 GlobalVariable *new_result_global = new GlobalVariable(
333 (*m_module), result_global->getValueType(), false, /* not constant */
334 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
335 m_result_name.GetCString());
336
337 // It's too late in compilation to create a new VarDecl for this, but we
338 // don't need to. We point the metadata at the old VarDecl. This creates an
339 // odd anomaly: a variable with a Value whose name is something like $0 and a
340 // Decl whose name is $__lldb_expr_result. This condition is handled in
341 // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
342 // fixed up.
343
344 ConstantInt *new_constant_int =
345 ConstantInt::get(Ty: llvm::Type::getInt64Ty(C&: m_module->getContext()),
346 V: reinterpret_cast<uintptr_t>(result_decl), IsSigned: false);
347
348 llvm::Metadata *values[2];
349 values[0] = ConstantAsMetadata::get(C: new_result_global);
350 values[1] = ConstantAsMetadata::get(C: new_constant_int);
351
352 ArrayRef<Metadata *> value_ref(values, 2);
353
354 MDNode *persistent_global_md = MDNode::get(Context&: m_module->getContext(), MDs: value_ref);
355 NamedMDNode *named_metadata =
356 m_module->getNamedMetadata(Name: "clang.global.decl.ptrs");
357 named_metadata->addOperand(M: persistent_global_md);
358
359 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
360 PrintValue(new_result_global));
361
362 if (result_global->use_empty()) {
363 // We need to synthesize a store for this variable, because otherwise
364 // there's nothing to put into its equivalent persistent variable.
365
366 BasicBlock &entry_block(llvm_function.getEntryBlock());
367 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
368
369 if (!first_entry_instruction)
370 return false;
371
372 if (!result_global->hasInitializer()) {
373 LLDB_LOG(log, "Couldn't find initializer for unused variable");
374
375 m_error_stream.Format(format: "Internal error [IRForTarget]: Result variable "
376 "({0}) has no writes and no initializer\n",
377 args&: result_name);
378
379 return false;
380 }
381
382 Constant *initializer = result_global->getInitializer();
383
384 StoreInst *synthesized_store =
385 new StoreInst(initializer, new_result_global, first_entry_instruction);
386
387 LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
388 PrintValue(synthesized_store));
389 } else {
390 result_global->replaceAllUsesWith(V: new_result_global);
391 }
392
393 if (!m_decl_map->AddPersistentVariable(
394 decl: result_decl, name: m_result_name, type: m_result_type, is_result: true, is_lvalue: m_result_is_pointer))
395 return false;
396
397 result_global->eraseFromParent();
398
399 return true;
400}
401
402bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
403 llvm::GlobalVariable *cstr) {
404 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
405
406 Type *ns_str_ty = ns_str->getType();
407
408 Type *i8_ptr_ty = PointerType::getUnqual(C&: m_module->getContext());
409 Type *i32_ty = Type::getInt32Ty(C&: m_module->getContext());
410 Type *i8_ty = Type::getInt8Ty(C&: m_module->getContext());
411
412 if (!m_CFStringCreateWithBytes) {
413 lldb::addr_t CFStringCreateWithBytes_addr;
414
415 static lldb_private::ConstString g_CFStringCreateWithBytes_str(
416 "CFStringCreateWithBytes");
417
418 bool missing_weak = false;
419 CFStringCreateWithBytes_addr =
420 m_execution_unit.FindSymbol(name: g_CFStringCreateWithBytes_str,
421 missing_weak);
422 if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
423 LLDB_LOG(log, "Couldn't find CFStringCreateWithBytes in the target");
424
425 m_error_stream.Printf(format: "Error [IRForTarget]: Rewriting an Objective-C "
426 "constant string requires "
427 "CFStringCreateWithBytes\n");
428
429 return false;
430 }
431
432 LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
433 CFStringCreateWithBytes_addr);
434
435 // Build the function type:
436 //
437 // CFStringRef CFStringCreateWithBytes (
438 // CFAllocatorRef alloc,
439 // const UInt8 *bytes,
440 // CFIndex numBytes,
441 // CFStringEncoding encoding,
442 // Boolean isExternalRepresentation
443 // );
444 //
445 // We make the following substitutions:
446 //
447 // CFStringRef -> i8*
448 // CFAllocatorRef -> i8*
449 // UInt8 * -> i8*
450 // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
451 // pointer size for now) CFStringEncoding -> i32 Boolean -> i8
452
453 Type *arg_type_array[5];
454
455 arg_type_array[0] = i8_ptr_ty;
456 arg_type_array[1] = i8_ptr_ty;
457 arg_type_array[2] = m_intptr_ty;
458 arg_type_array[3] = i32_ty;
459 arg_type_array[4] = i8_ty;
460
461 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
462
463 llvm::FunctionType *CFSCWB_ty =
464 FunctionType::get(Result: ns_str_ty, Params: CFSCWB_arg_types, isVarArg: false);
465
466 // Build the constant containing the pointer to the function
467 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(ElementType: CFSCWB_ty);
468 Constant *CFSCWB_addr_int =
469 ConstantInt::get(Ty: m_intptr_ty, V: CFStringCreateWithBytes_addr, IsSigned: false);
470 m_CFStringCreateWithBytes = {
471 CFSCWB_ty, ConstantExpr::getIntToPtr(C: CFSCWB_addr_int, Ty: CFSCWB_ptr_ty)};
472 }
473
474 ConstantDataSequential *string_array = nullptr;
475
476 if (cstr)
477 string_array = dyn_cast<ConstantDataSequential>(Val: cstr->getInitializer());
478
479 Constant *alloc_arg = Constant::getNullValue(Ty: i8_ptr_ty);
480 Constant *bytes_arg = cstr ? cstr : Constant::getNullValue(Ty: i8_ptr_ty);
481 Constant *numBytes_arg = ConstantInt::get(
482 Ty: m_intptr_ty, V: cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, IsSigned: false);
483 int encoding_flags = 0;
484 switch (cstr ? string_array->getElementByteSize() : 1) {
485 case 1:
486 encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
487 break;
488 case 2:
489 encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
490 break;
491 case 4:
492 encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
493 break;
494 default:
495 encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
496 LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
497 "element size {0}",
498 string_array->getElementByteSize());
499 }
500 Constant *encoding_arg = ConstantInt::get(Ty: i32_ty, V: encoding_flags, IsSigned: false);
501 Constant *isExternal_arg =
502 ConstantInt::get(Ty: i8_ty, V: 0x0, IsSigned: false); /* 0x0 is false */
503
504 Value *argument_array[5];
505
506 argument_array[0] = alloc_arg;
507 argument_array[1] = bytes_arg;
508 argument_array[2] = numBytes_arg;
509 argument_array[3] = encoding_arg;
510 argument_array[4] = isExternal_arg;
511
512 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
513
514 FunctionValueCache CFSCWB_Caller(
515 [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
516 return CallInst::Create(
517 Func: m_CFStringCreateWithBytes, Args: CFSCWB_arguments,
518 NameStr: "CFStringCreateWithBytes",
519 InsertBefore: llvm::cast<Instruction>(
520 Val: m_entry_instruction_finder.GetValue(function)));
521 });
522
523 if (!UnfoldConstant(old_constant: ns_str, llvm_function: nullptr, value_maker&: CFSCWB_Caller, entry_instruction_finder&: m_entry_instruction_finder,
524 error_stream&: m_error_stream)) {
525 LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
526
527 m_error_stream.Printf(format: "error [IRForTarget internal]: Couldn't replace an "
528 "Objective-C constant string with a dynamic "
529 "string\n");
530
531 return false;
532 }
533
534 ns_str->eraseFromParent();
535
536 return true;
537}
538
539bool IRForTarget::RewriteObjCConstStrings() {
540 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
541
542 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
543
544 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
545 llvm::StringRef value_name = value_symbol.first();
546
547 if (value_name.contains(Other: "_unnamed_cfstring_")) {
548 Value *nsstring_value = value_symbol.second;
549
550 GlobalVariable *nsstring_global =
551 dyn_cast<GlobalVariable>(Val: nsstring_value);
552
553 if (!nsstring_global) {
554 LLDB_LOG(log, "NSString variable is not a GlobalVariable");
555
556 m_error_stream.Printf(format: "Internal error [IRForTarget]: An Objective-C "
557 "constant string is not a global variable\n");
558
559 return false;
560 }
561
562 if (!nsstring_global->hasInitializer()) {
563 LLDB_LOG(log, "NSString variable does not have an initializer");
564
565 m_error_stream.Printf(format: "Internal error [IRForTarget]: An Objective-C "
566 "constant string does not have an initializer\n");
567
568 return false;
569 }
570
571 ConstantStruct *nsstring_struct =
572 dyn_cast<ConstantStruct>(Val: nsstring_global->getInitializer());
573
574 if (!nsstring_struct) {
575 LLDB_LOG(log,
576 "NSString variable's initializer is not a ConstantStruct");
577
578 m_error_stream.Printf(format: "Internal error [IRForTarget]: An Objective-C "
579 "constant string is not a structure constant\n");
580
581 return false;
582 }
583
584 // We expect the following structure:
585 //
586 // struct {
587 // int *isa;
588 // int flags;
589 // char *str;
590 // long length;
591 // };
592
593 if (nsstring_struct->getNumOperands() != 4) {
594
595 LLDB_LOG(log,
596 "NSString variable's initializer structure has an "
597 "unexpected number of members. Should be 4, is {0}",
598 nsstring_struct->getNumOperands());
599
600 m_error_stream.Printf(format: "Internal error [IRForTarget]: The struct for an "
601 "Objective-C constant string is not as "
602 "expected\n");
603
604 return false;
605 }
606
607 Constant *nsstring_member = nsstring_struct->getOperand(i_nocapture: 2);
608
609 if (!nsstring_member) {
610 LLDB_LOG(log, "NSString initializer's str element was empty");
611
612 m_error_stream.Printf(format: "Internal error [IRForTarget]: An Objective-C "
613 "constant string does not have a string "
614 "initializer\n");
615
616 return false;
617 }
618
619 auto *cstr_global = dyn_cast<GlobalVariable>(Val: nsstring_member);
620 if (!cstr_global) {
621 LLDB_LOG(log,
622 "NSString initializer's str element is not a GlobalVariable");
623
624 m_error_stream.Printf(format: "Internal error [IRForTarget]: Unhandled"
625 "constant string initializer\n");
626
627 return false;
628 }
629
630 if (!cstr_global->hasInitializer()) {
631 LLDB_LOG(log, "NSString initializer's str element does not have an "
632 "initializer");
633
634 m_error_stream.Printf(format: "Internal error [IRForTarget]: An Objective-C "
635 "constant string's string initializer doesn't "
636 "point to initialized data\n");
637
638 return false;
639 }
640
641 /*
642 if (!cstr_array)
643 {
644 if (log)
645 log->PutCString("NSString initializer's str element is not a
646 ConstantArray");
647
648 if (m_error_stream)
649 m_error_stream.Printf("Internal error [IRForTarget]: An
650 Objective-C constant string's string initializer doesn't point to an
651 array\n");
652
653 return false;
654 }
655
656 if (!cstr_array->isCString())
657 {
658 if (log)
659 log->PutCString("NSString initializer's str element is not a C
660 string array");
661
662 if (m_error_stream)
663 m_error_stream.Printf("Internal error [IRForTarget]: An
664 Objective-C constant string's string initializer doesn't point to a C
665 string\n");
666
667 return false;
668 }
669 */
670
671 ConstantDataArray *cstr_array =
672 dyn_cast<ConstantDataArray>(Val: cstr_global->getInitializer());
673
674 if (cstr_array)
675 LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
676 value_name, cstr_array->getAsString());
677 else
678 LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
679 value_name);
680
681 if (!cstr_array)
682 cstr_global = nullptr;
683
684 if (!RewriteObjCConstString(ns_str: nsstring_global, cstr: cstr_global)) {
685 LLDB_LOG(log, "Error rewriting the constant string");
686
687 // We don't print an error message here because RewriteObjCConstString
688 // has done so for us.
689
690 return false;
691 }
692 }
693 }
694
695 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
696 llvm::StringRef value_name = value_symbol.first();
697
698 if (value_name == "__CFConstantStringClassReference") {
699 GlobalVariable *gv = dyn_cast<GlobalVariable>(Val: value_symbol.second);
700
701 if (!gv) {
702 LLDB_LOG(log,
703 "__CFConstantStringClassReference is not a global variable");
704
705 m_error_stream.Printf(format: "Internal error [IRForTarget]: Found a "
706 "CFConstantStringClassReference, but it is not a "
707 "global object\n");
708
709 return false;
710 }
711
712 gv->eraseFromParent();
713
714 break;
715 }
716 }
717
718 return true;
719}
720
721static bool IsObjCSelectorRef(Value *value) {
722 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(Val: value);
723
724 return !(
725 !global_variable || !global_variable->hasName() ||
726 !global_variable->getName().starts_with(Prefix: "OBJC_SELECTOR_REFERENCES_"));
727}
728
729// This function does not report errors; its callers are responsible.
730bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
731 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
732
733 LoadInst *load = dyn_cast<LoadInst>(Val: selector_load);
734
735 if (!load)
736 return false;
737
738 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
739 // gets represented as
740 //
741 // %sel = load ptr, ptr @OBJC_SELECTOR_REFERENCES_, align 8
742 // call i8 @objc_msgSend(ptr %obj, ptr %sel, ...)
743 //
744 // where %obj is the object pointer and %sel is the selector.
745 //
746 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
747 // @"\01L_OBJC_METH_VAR_NAME_".
748 // @"\01L_OBJC_METH_VAR_NAME_" contains the string.
749
750 // Find the pointer's initializer and get the string from its target.
751
752 GlobalVariable *_objc_selector_references_ =
753 dyn_cast<GlobalVariable>(Val: load->getPointerOperand());
754
755 if (!_objc_selector_references_ ||
756 !_objc_selector_references_->hasInitializer())
757 return false;
758
759 Constant *osr_initializer = _objc_selector_references_->getInitializer();
760 if (!osr_initializer)
761 return false;
762
763 // Find the string's initializer (a ConstantArray) and get the string from it
764
765 GlobalVariable *_objc_meth_var_name_ =
766 dyn_cast<GlobalVariable>(Val: osr_initializer);
767
768 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
769 return false;
770
771 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
772
773 ConstantDataArray *omvn_initializer_array =
774 dyn_cast<ConstantDataArray>(Val: omvn_initializer);
775
776 if (!omvn_initializer_array->isString())
777 return false;
778
779 std::string omvn_initializer_string =
780 std::string(omvn_initializer_array->getAsString());
781
782 LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
783 omvn_initializer_string);
784
785 // Construct a call to sel_registerName
786
787 if (!m_sel_registerName) {
788 lldb::addr_t sel_registerName_addr;
789
790 bool missing_weak = false;
791 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
792 sel_registerName_addr = m_execution_unit.FindSymbol(name: g_sel_registerName_str,
793 missing_weak);
794 if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
795 return false;
796
797 LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
798
799 // Build the function type: struct objc_selector
800 // *sel_registerName(uint8_t*)
801
802 // The below code would be "more correct," but in actuality what's required
803 // is uint8_t*
804 // Type *sel_type = StructType::get(m_module->getContext());
805 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
806 Type *sel_ptr_type = PointerType::getUnqual(C&: m_module->getContext());
807
808 Type *type_array[1];
809
810 type_array[0] = llvm::PointerType::getUnqual(C&: m_module->getContext());
811
812 ArrayRef<Type *> srN_arg_types(type_array, 1);
813
814 llvm::FunctionType *srN_type =
815 FunctionType::get(Result: sel_ptr_type, Params: srN_arg_types, isVarArg: false);
816
817 // Build the constant containing the pointer to the function
818 PointerType *srN_ptr_ty = PointerType::getUnqual(ElementType: srN_type);
819 Constant *srN_addr_int =
820 ConstantInt::get(Ty: m_intptr_ty, V: sel_registerName_addr, IsSigned: false);
821 m_sel_registerName = {srN_type,
822 ConstantExpr::getIntToPtr(C: srN_addr_int, Ty: srN_ptr_ty)};
823 }
824
825 CallInst *srN_call =
826 CallInst::Create(Func: m_sel_registerName, Args: _objc_meth_var_name_,
827 NameStr: "sel_registerName", InsertBefore: selector_load);
828
829 // Replace the load with the call in all users
830
831 selector_load->replaceAllUsesWith(V: srN_call);
832
833 selector_load->eraseFromParent();
834
835 return true;
836}
837
838bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
839 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
840
841 InstrList selector_loads;
842
843 for (Instruction &inst : basic_block) {
844 if (LoadInst *load = dyn_cast<LoadInst>(Val: &inst))
845 if (IsObjCSelectorRef(value: load->getPointerOperand()))
846 selector_loads.push_back(Elt: &inst);
847 }
848
849 for (Instruction *inst : selector_loads) {
850 if (!RewriteObjCSelector(selector_load: inst)) {
851 m_error_stream.Printf(format: "Internal error [IRForTarget]: Couldn't change a "
852 "static reference to an Objective-C selector to a "
853 "dynamic reference\n");
854
855 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
856
857 return false;
858 }
859 }
860
861 return true;
862}
863
864// This function does not report errors; its callers are responsible.
865bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
866 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
867
868 AllocaInst *alloc = dyn_cast<AllocaInst>(Val: persistent_alloc);
869
870 MDNode *alloc_md = alloc->getMetadata(Kind: "clang.decl.ptr");
871
872 if (!alloc_md || !alloc_md->getNumOperands())
873 return false;
874
875 ConstantInt *constant_int =
876 mdconst::dyn_extract<ConstantInt>(MD: alloc_md->getOperand(I: 0));
877
878 if (!constant_int)
879 return false;
880
881 // We attempt to register this as a new persistent variable with the DeclMap.
882
883 uintptr_t ptr = constant_int->getZExtValue();
884
885 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
886
887 lldb_private::TypeFromParser result_decl_type(
888 m_decl_map->GetTypeSystem()->GetType(qt: decl->getType()));
889
890 StringRef decl_name(decl->getName());
891 lldb_private::ConstString persistent_variable_name(decl_name.data(),
892 decl_name.size());
893 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
894 result_decl_type, false, false))
895 return false;
896
897 GlobalVariable *persistent_global = new GlobalVariable(
898 (*m_module), alloc->getType(), false, /* not constant */
899 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
900 alloc->getName().str());
901
902 // What we're going to do here is make believe this was a regular old
903 // external variable. That means we need to make the metadata valid.
904
905 NamedMDNode *named_metadata =
906 m_module->getOrInsertNamedMetadata(Name: "clang.global.decl.ptrs");
907
908 llvm::Metadata *values[2];
909 values[0] = ConstantAsMetadata::get(C: persistent_global);
910 values[1] = ConstantAsMetadata::get(C: constant_int);
911
912 ArrayRef<llvm::Metadata *> value_ref(values, 2);
913
914 MDNode *persistent_global_md = MDNode::get(Context&: m_module->getContext(), MDs: value_ref);
915 named_metadata->addOperand(M: persistent_global_md);
916
917 // Now, since the variable is a pointer variable, we will drop in a load of
918 // that pointer variable.
919
920 LoadInst *persistent_load = new LoadInst(persistent_global->getValueType(),
921 persistent_global, "", alloc);
922
923 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
924 PrintValue(persistent_load));
925
926 alloc->replaceAllUsesWith(V: persistent_load);
927 alloc->eraseFromParent();
928
929 return true;
930}
931
932bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
933 if (!m_resolve_vars)
934 return true;
935
936 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
937
938 InstrList pvar_allocs;
939
940 for (Instruction &inst : basic_block) {
941
942 if (AllocaInst *alloc = dyn_cast<AllocaInst>(Val: &inst)) {
943 llvm::StringRef alloc_name = alloc->getName();
944
945 if (alloc_name.starts_with(Prefix: "$") && !alloc_name.starts_with(Prefix: "$__lldb")) {
946 if (alloc_name.find_first_of(Chars: "0123456789") == 1) {
947 LLDB_LOG(log, "Rejecting a numeric persistent variable.");
948
949 m_error_stream.Printf(format: "Error [IRForTarget]: Names starting with $0, "
950 "$1, ... are reserved for use as result "
951 "names\n");
952
953 return false;
954 }
955
956 pvar_allocs.push_back(Elt: alloc);
957 }
958 }
959 }
960
961 for (Instruction *inst : pvar_allocs) {
962 if (!RewritePersistentAlloc(persistent_alloc: inst)) {
963 m_error_stream.Printf(format: "Internal error [IRForTarget]: Couldn't rewrite "
964 "the creation of a persistent variable\n");
965
966 LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
967
968 return false;
969 }
970 }
971
972 return true;
973}
974
975// This function does not report errors; its callers are responsible.
976bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
977 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
978
979 LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
980
981 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(Val: llvm_value_ptr)) {
982 switch (constant_expr->getOpcode()) {
983 default:
984 break;
985 case Instruction::GetElementPtr:
986 case Instruction::BitCast:
987 Value *s = constant_expr->getOperand(i_nocapture: 0);
988 if (!MaybeHandleVariable(llvm_value_ptr: s))
989 return false;
990 }
991 } else if (GlobalVariable *global_variable =
992 dyn_cast<GlobalVariable>(Val: llvm_value_ptr)) {
993 if (!GlobalValue::isExternalLinkage(Linkage: global_variable->getLinkage()))
994 return true;
995
996 clang::NamedDecl *named_decl = DeclForGlobal(global_val: global_variable);
997
998 if (!named_decl) {
999 if (IsObjCSelectorRef(value: llvm_value_ptr))
1000 return true;
1001
1002 if (!global_variable->hasExternalLinkage())
1003 return true;
1004
1005 LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
1006 global_variable->getName());
1007
1008 return false;
1009 }
1010
1011 llvm::StringRef name(named_decl->getName());
1012
1013 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(Val: named_decl);
1014 if (value_decl == nullptr)
1015 return false;
1016
1017 lldb_private::CompilerType compiler_type =
1018 m_decl_map->GetTypeSystem()->GetType(qt: value_decl->getType());
1019
1020 const Type *value_type = nullptr;
1021
1022 if (name.starts_with(Prefix: "$")) {
1023 // The $__lldb_expr_result name indicates the return value has allocated
1024 // as a static variable. Per the comment at
1025 // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
1026 // variable need to be redirected to the result of dereferencing a
1027 // pointer that is passed in as one of the arguments.
1028 //
1029 // Consequently, when reporting the size of the type, we report a pointer
1030 // type pointing to the type of $__lldb_expr_result, not the type itself.
1031 //
1032 // We also do this for any user-declared persistent variables.
1033 compiler_type = compiler_type.GetPointerType();
1034 value_type = PointerType::get(ElementType: global_variable->getType(), AddressSpace: 0);
1035 } else {
1036 value_type = global_variable->getType();
1037 }
1038
1039 auto *target = m_execution_unit.GetTarget().get();
1040 std::optional<uint64_t> value_size = compiler_type.GetByteSize(exe_scope: target);
1041 if (!value_size)
1042 return false;
1043 std::optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(exe_scope: target);
1044 if (!opt_alignment)
1045 return false;
1046 lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
1047
1048 LLDB_LOG(log,
1049 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1050 "align {4}]",
1051 name,
1052 lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
1053 PrintType(value_type), *value_size, value_alignment);
1054
1055 if (named_decl)
1056 m_decl_map->AddValueToStruct(decl: named_decl, name: lldb_private::ConstString(name),
1057 value: llvm_value_ptr, size: *value_size,
1058 alignment: value_alignment);
1059 } else if (isa<llvm::Function>(Val: llvm_value_ptr)) {
1060 LLDB_LOG(log, "Function pointers aren't handled right now");
1061
1062 return false;
1063 }
1064
1065 return true;
1066}
1067
1068// This function does not report errors; its callers are responsible.
1069bool IRForTarget::HandleSymbol(Value *symbol) {
1070 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
1071
1072 lldb_private::ConstString name(symbol->getName().str().c_str());
1073
1074 lldb::addr_t symbol_addr =
1075 m_decl_map->GetSymbolAddress(name, symbol_type: lldb::eSymbolTypeAny);
1076
1077 if (symbol_addr == LLDB_INVALID_ADDRESS) {
1078 LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
1079
1080 return false;
1081 }
1082
1083 LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
1084
1085 Type *symbol_type = symbol->getType();
1086
1087 Constant *symbol_addr_int = ConstantInt::get(Ty: m_intptr_ty, V: symbol_addr, IsSigned: false);
1088
1089 Value *symbol_addr_ptr =
1090 ConstantExpr::getIntToPtr(C: symbol_addr_int, Ty: symbol_type);
1091
1092 LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
1093 PrintValue(symbol_addr_ptr));
1094
1095 symbol->replaceAllUsesWith(V: symbol_addr_ptr);
1096
1097 return true;
1098}
1099
1100bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1101 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
1102
1103 LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
1104
1105 for (unsigned op_index = 0, num_ops = Old->arg_size();
1106 op_index < num_ops; ++op_index)
1107 // conservatively believe that this is a store
1108 if (!MaybeHandleVariable(llvm_value_ptr: Old->getArgOperand(i: op_index))) {
1109 m_error_stream.Printf(format: "Internal error [IRForTarget]: Couldn't rewrite "
1110 "one of the arguments of a function call.\n");
1111
1112 return false;
1113 }
1114
1115 return true;
1116}
1117
1118bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1119 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
1120
1121 GlobalVariable *global_variable =
1122 dyn_cast<GlobalVariable>(Val: classlist_reference);
1123
1124 if (!global_variable)
1125 return false;
1126
1127 Constant *initializer = global_variable->getInitializer();
1128
1129 if (!initializer)
1130 return false;
1131
1132 if (!initializer->hasName())
1133 return false;
1134
1135 StringRef name(initializer->getName());
1136 lldb_private::ConstString name_cstr(name.str().c_str());
1137 lldb::addr_t class_ptr =
1138 m_decl_map->GetSymbolAddress(name: name_cstr, symbol_type: lldb::eSymbolTypeObjCClass);
1139
1140 LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
1141 (unsigned long long)class_ptr);
1142
1143 if (class_ptr == LLDB_INVALID_ADDRESS)
1144 return false;
1145
1146 if (global_variable->use_empty())
1147 return false;
1148
1149 SmallVector<LoadInst *, 2> load_instructions;
1150
1151 for (llvm::User *u : global_variable->users()) {
1152 if (LoadInst *load_instruction = dyn_cast<LoadInst>(Val: u))
1153 load_instructions.push_back(Elt: load_instruction);
1154 }
1155
1156 if (load_instructions.empty())
1157 return false;
1158
1159 Constant *class_addr = ConstantInt::get(Ty: m_intptr_ty, V: (uint64_t)class_ptr);
1160
1161 for (LoadInst *load_instruction : load_instructions) {
1162 Constant *class_bitcast =
1163 ConstantExpr::getIntToPtr(C: class_addr, Ty: load_instruction->getType());
1164
1165 load_instruction->replaceAllUsesWith(V: class_bitcast);
1166
1167 load_instruction->eraseFromParent();
1168 }
1169
1170 return true;
1171}
1172
1173bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
1174 std::vector<CallInst *> calls_to_remove;
1175
1176 for (Instruction &inst : basic_block) {
1177 CallInst *call = dyn_cast<CallInst>(Val: &inst);
1178
1179 // MaybeHandleCallArguments handles error reporting; we are silent here
1180 if (!call)
1181 continue;
1182
1183 bool remove = false;
1184
1185 llvm::Function *func = call->getCalledFunction();
1186
1187 if (func && func->getName() == "__cxa_atexit")
1188 remove = true;
1189
1190 llvm::Value *val = call->getCalledOperand();
1191
1192 if (val && val->getName() == "__cxa_atexit")
1193 remove = true;
1194
1195 if (remove)
1196 calls_to_remove.push_back(x: call);
1197 }
1198
1199 for (CallInst *ci : calls_to_remove)
1200 ci->eraseFromParent();
1201
1202 return true;
1203}
1204
1205bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
1206 // Prepare the current basic block for execution in the remote process
1207
1208 for (Instruction &inst : basic_block) {
1209 CallInst *call = dyn_cast<CallInst>(Val: &inst);
1210
1211 // MaybeHandleCallArguments handles error reporting; we are silent here
1212 if (call && !MaybeHandleCallArguments(Old: call))
1213 return false;
1214 }
1215
1216 return true;
1217}
1218
1219bool IRForTarget::ResolveExternals(Function &llvm_function) {
1220 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
1221
1222 for (GlobalVariable &global_var : m_module->globals()) {
1223 llvm::StringRef global_name = global_var.getName();
1224
1225 LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
1226 static_cast<void *>(DeclForGlobal(&global_var)));
1227
1228 if (global_name.starts_with(Prefix: "OBJC_IVAR")) {
1229 if (!HandleSymbol(symbol: &global_var)) {
1230 m_error_stream.Format(format: "Error [IRForTarget]: Couldn't find Objective-C "
1231 "indirect ivar symbol {0}\n",
1232 args&: global_name);
1233
1234 return false;
1235 }
1236 } else if (global_name.contains(Other: "OBJC_CLASSLIST_REFERENCES_$")) {
1237 if (!HandleObjCClass(classlist_reference: &global_var)) {
1238 m_error_stream.Printf(format: "Error [IRForTarget]: Couldn't resolve the class "
1239 "for an Objective-C static method call\n");
1240
1241 return false;
1242 }
1243 } else if (global_name.contains(Other: "OBJC_CLASSLIST_SUP_REFS_$")) {
1244 if (!HandleObjCClass(classlist_reference: &global_var)) {
1245 m_error_stream.Printf(format: "Error [IRForTarget]: Couldn't resolve the class "
1246 "for an Objective-C static method call\n");
1247
1248 return false;
1249 }
1250 } else if (DeclForGlobal(global_val: &global_var)) {
1251 if (!MaybeHandleVariable(llvm_value_ptr: &global_var)) {
1252 m_error_stream.Format(format: "Internal error [IRForTarget]: Couldn't rewrite "
1253 "external variable {0}\n",
1254 args&: global_name);
1255
1256 return false;
1257 }
1258 }
1259 }
1260
1261 return true;
1262}
1263
1264static bool isGuardVariableRef(Value *V) {
1265 GlobalVariable *GV = dyn_cast<GlobalVariable>(Val: V);
1266
1267 if (!GV || !GV->hasName() || !isGuardVariableSymbol(mangled_symbol: GV->getName()))
1268 return false;
1269
1270 return true;
1271}
1272
1273void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1274 Constant *zero(Constant::getNullValue(Ty: guard_load->getType()));
1275 guard_load->replaceAllUsesWith(V: zero);
1276 guard_load->eraseFromParent();
1277}
1278
1279static void ExciseGuardStore(Instruction *guard_store) {
1280 guard_store->eraseFromParent();
1281}
1282
1283bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
1284 // Eliminate any reference to guard variables found.
1285
1286 InstrList guard_loads;
1287 InstrList guard_stores;
1288
1289 for (Instruction &inst : basic_block) {
1290
1291 if (LoadInst *load = dyn_cast<LoadInst>(Val: &inst))
1292 if (isGuardVariableRef(V: load->getPointerOperand()))
1293 guard_loads.push_back(Elt: &inst);
1294
1295 if (StoreInst *store = dyn_cast<StoreInst>(Val: &inst))
1296 if (isGuardVariableRef(V: store->getPointerOperand()))
1297 guard_stores.push_back(Elt: &inst);
1298 }
1299
1300 for (Instruction *inst : guard_loads)
1301 TurnGuardLoadIntoZero(guard_load: inst);
1302
1303 for (Instruction *inst : guard_stores)
1304 ExciseGuardStore(guard_store: inst);
1305
1306 return true;
1307}
1308
1309// This function does not report errors; its callers are responsible.
1310bool IRForTarget::UnfoldConstant(Constant *old_constant,
1311 llvm::Function *llvm_function,
1312 FunctionValueCache &value_maker,
1313 FunctionValueCache &entry_instruction_finder,
1314 lldb_private::Stream &error_stream) {
1315 SmallVector<User *, 16> users;
1316
1317 // We do this because the use list might change, invalidating our iterator.
1318 // Much better to keep a work list ourselves.
1319 for (llvm::User *u : old_constant->users())
1320 users.push_back(Elt: u);
1321
1322 for (size_t i = 0; i < users.size(); ++i) {
1323 User *user = users[i];
1324
1325 if (Constant *constant = dyn_cast<Constant>(Val: user)) {
1326 // synthesize a new non-constant equivalent of the constant
1327
1328 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(Val: constant)) {
1329 switch (constant_expr->getOpcode()) {
1330 default:
1331 error_stream.Printf(format: "error [IRForTarget internal]: Unhandled "
1332 "constant expression type: \"%s\"",
1333 PrintValue(value: constant_expr).c_str());
1334 return false;
1335 case Instruction::BitCast: {
1336 FunctionValueCache bit_cast_maker(
1337 [&value_maker, &entry_instruction_finder, old_constant,
1338 constant_expr](llvm::Function *function) -> llvm::Value * {
1339 // UnaryExpr
1340 // OperandList[0] is value
1341
1342 if (constant_expr->getOperand(i_nocapture: 0) != old_constant)
1343 return constant_expr;
1344
1345 return new BitCastInst(
1346 value_maker.GetValue(function), constant_expr->getType(),
1347 "", llvm::cast<Instruction>(
1348 Val: entry_instruction_finder.GetValue(function)));
1349 });
1350
1351 if (!UnfoldConstant(old_constant: constant_expr, llvm_function, value_maker&: bit_cast_maker,
1352 entry_instruction_finder, error_stream))
1353 return false;
1354 } break;
1355 case Instruction::GetElementPtr: {
1356 // GetElementPtrConstantExpr
1357 // OperandList[0] is base
1358 // OperandList[1]... are indices
1359
1360 FunctionValueCache get_element_pointer_maker(
1361 [&value_maker, &entry_instruction_finder, old_constant,
1362 constant_expr](llvm::Function *function) -> llvm::Value * {
1363 auto *gep = cast<llvm::GEPOperator>(Val: constant_expr);
1364 Value *ptr = gep->getPointerOperand();
1365
1366 if (ptr == old_constant)
1367 ptr = value_maker.GetValue(function);
1368
1369 std::vector<Value *> index_vector;
1370 for (Value *operand : gep->indices()) {
1371 if (operand == old_constant)
1372 operand = value_maker.GetValue(function);
1373
1374 index_vector.push_back(x: operand);
1375 }
1376
1377 ArrayRef<Value *> indices(index_vector);
1378
1379 return GetElementPtrInst::Create(
1380 PointeeType: gep->getSourceElementType(), Ptr: ptr, IdxList: indices, NameStr: "",
1381 InsertBefore: llvm::cast<Instruction>(
1382 Val: entry_instruction_finder.GetValue(function)));
1383 });
1384
1385 if (!UnfoldConstant(old_constant: constant_expr, llvm_function,
1386 value_maker&: get_element_pointer_maker,
1387 entry_instruction_finder, error_stream))
1388 return false;
1389 } break;
1390 }
1391 } else {
1392 error_stream.Printf(
1393 format: "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1394 PrintValue(value: constant).c_str());
1395 return false;
1396 }
1397 } else {
1398 if (Instruction *inst = llvm::dyn_cast<Instruction>(Val: user)) {
1399 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1400 error_stream.PutCString(cstr: "error: Capturing non-local variables in "
1401 "expressions is unsupported.\n");
1402 return false;
1403 }
1404 inst->replaceUsesOfWith(
1405 From: old_constant, To: value_maker.GetValue(function: inst->getParent()->getParent()));
1406 } else {
1407 error_stream.Printf(
1408 format: "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1409 PrintValue(value: user).c_str());
1410 return false;
1411 }
1412 }
1413 }
1414
1415 if (!isa<GlobalValue>(Val: old_constant)) {
1416 old_constant->destroyConstant();
1417 }
1418
1419 return true;
1420}
1421
1422bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1423 if (!m_resolve_vars)
1424 return true;
1425
1426 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
1427
1428 m_decl_map->DoStructLayout();
1429
1430 LLDB_LOG(log, "Element arrangement:");
1431
1432 uint32_t num_elements;
1433 uint32_t element_index;
1434
1435 size_t size;
1436 lldb::offset_t alignment;
1437
1438 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1439 return false;
1440
1441 Function::arg_iterator iter(llvm_function.arg_begin());
1442
1443 if (iter == llvm_function.arg_end()) {
1444 m_error_stream.Printf(format: "Internal error [IRForTarget]: Wrapper takes no "
1445 "arguments (should take at least a struct pointer)");
1446
1447 return false;
1448 }
1449
1450 Argument *argument = &*iter;
1451
1452 if (argument->getName().equals(RHS: "this")) {
1453 ++iter;
1454
1455 if (iter == llvm_function.arg_end()) {
1456 m_error_stream.Printf(format: "Internal error [IRForTarget]: Wrapper takes only "
1457 "'this' argument (should take a struct pointer "
1458 "too)");
1459
1460 return false;
1461 }
1462
1463 argument = &*iter;
1464 } else if (argument->getName().equals(RHS: "self")) {
1465 ++iter;
1466
1467 if (iter == llvm_function.arg_end()) {
1468 m_error_stream.Printf(format: "Internal error [IRForTarget]: Wrapper takes only "
1469 "'self' argument (should take '_cmd' and a struct "
1470 "pointer too)");
1471
1472 return false;
1473 }
1474
1475 if (!iter->getName().equals(RHS: "_cmd")) {
1476 m_error_stream.Format(format: "Internal error [IRForTarget]: Wrapper takes '{0}' "
1477 "after 'self' argument (should take '_cmd')",
1478 args: iter->getName());
1479
1480 return false;
1481 }
1482
1483 ++iter;
1484
1485 if (iter == llvm_function.arg_end()) {
1486 m_error_stream.Printf(format: "Internal error [IRForTarget]: Wrapper takes only "
1487 "'self' and '_cmd' arguments (should take a struct "
1488 "pointer too)");
1489
1490 return false;
1491 }
1492
1493 argument = &*iter;
1494 }
1495
1496 if (!argument->getName().equals(RHS: "$__lldb_arg")) {
1497 m_error_stream.Format(format: "Internal error [IRForTarget]: Wrapper takes an "
1498 "argument named '{0}' instead of the struct pointer",
1499 args: argument->getName());
1500
1501 return false;
1502 }
1503
1504 LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
1505
1506 BasicBlock &entry_block(llvm_function.getEntryBlock());
1507 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1508
1509 if (!FirstEntryInstruction) {
1510 m_error_stream.Printf(format: "Internal error [IRForTarget]: Couldn't find the "
1511 "first instruction in the wrapper for use in "
1512 "rewriting");
1513
1514 return false;
1515 }
1516
1517 LLVMContext &context(m_module->getContext());
1518 IntegerType *offset_type(Type::getInt32Ty(C&: context));
1519
1520 if (!offset_type) {
1521 m_error_stream.Printf(
1522 format: "Internal error [IRForTarget]: Couldn't produce an offset type");
1523
1524 return false;
1525 }
1526
1527 for (element_index = 0; element_index < num_elements; ++element_index) {
1528 const clang::NamedDecl *decl = nullptr;
1529 Value *value = nullptr;
1530 lldb::offset_t offset;
1531 lldb_private::ConstString name;
1532
1533 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1534 index: element_index)) {
1535 m_error_stream.Printf(
1536 format: "Internal error [IRForTarget]: Structure information is incomplete");
1537
1538 return false;
1539 }
1540
1541 LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name,
1542 decl->getNameAsString(), offset);
1543
1544 if (value) {
1545 LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
1546
1547 FunctionValueCache body_result_maker(
1548 [this, name, offset_type, offset, argument,
1549 value](llvm::Function *function) -> llvm::Value * {
1550 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
1551 // in cases where the result variable is an rvalue, we have to
1552 // synthesize a dereference of the appropriate structure entry in
1553 // order to produce the static variable that the AST thinks it is
1554 // accessing.
1555
1556 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1557 Val: m_entry_instruction_finder.GetValue(function));
1558
1559 Type *int8Ty = Type::getInt8Ty(C&: function->getContext());
1560 ConstantInt *offset_int(
1561 ConstantInt::get(Ty: offset_type, V: offset, IsSigned: true));
1562 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1563 PointeeType: int8Ty, Ptr: argument, IdxList: offset_int, NameStr: "", InsertBefore: entry_instruction);
1564
1565 if (name == m_result_name && !m_result_is_pointer) {
1566 LoadInst *load = new LoadInst(value->getType(), get_element_ptr,
1567 "", entry_instruction);
1568
1569 return load;
1570 } else {
1571 return get_element_ptr;
1572 }
1573 });
1574
1575 if (Constant *constant = dyn_cast<Constant>(Val: value)) {
1576 if (!UnfoldConstant(old_constant: constant, llvm_function: &llvm_function, value_maker&: body_result_maker,
1577 entry_instruction_finder&: m_entry_instruction_finder, error_stream&: m_error_stream)) {
1578 return false;
1579 }
1580 } else if (Instruction *instruction = dyn_cast<Instruction>(Val: value)) {
1581 if (instruction->getParent()->getParent() != &llvm_function) {
1582 m_error_stream.PutCString(cstr: "error: Capturing non-local variables in "
1583 "expressions is unsupported.\n");
1584 return false;
1585 }
1586 value->replaceAllUsesWith(
1587 V: body_result_maker.GetValue(function: instruction->getParent()->getParent()));
1588 } else {
1589 LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
1590 PrintValue(value));
1591 return false;
1592 }
1593
1594 if (GlobalVariable *var = dyn_cast<GlobalVariable>(Val: value))
1595 var->eraseFromParent();
1596 }
1597 }
1598
1599 LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
1600 (uint64_t)size);
1601
1602 return true;
1603}
1604
1605bool IRForTarget::runOnModule(Module &llvm_module) {
1606 lldb_private::Log *log(GetLog(mask: LLDBLog::Expressions));
1607
1608 m_module = &llvm_module;
1609 m_target_data = std::make_unique<DataLayout>(args&: m_module);
1610 m_intptr_ty = llvm::Type::getIntNTy(C&: m_module->getContext(),
1611 N: m_target_data->getPointerSizeInBits());
1612
1613 if (log) {
1614 std::string s;
1615 raw_string_ostream oss(s);
1616
1617 m_module->print(OS&: oss, AAW: nullptr);
1618
1619 oss.flush();
1620
1621 LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
1622 }
1623
1624 Function *const main_function =
1625 m_func_name.IsEmpty() ? nullptr
1626 : m_module->getFunction(Name: m_func_name.GetStringRef());
1627
1628 if (!m_func_name.IsEmpty() && !main_function) {
1629 LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
1630
1631 m_error_stream.Format(format: "Internal error [IRForTarget]: Couldn't find wrapper "
1632 "'{0}' in the module",
1633 args&: m_func_name);
1634
1635 return false;
1636 }
1637
1638 if (main_function) {
1639 if (!FixFunctionLinkage(llvm_function&: *main_function)) {
1640 LLDB_LOG(log, "Couldn't fix the linkage for the function");
1641
1642 return false;
1643 }
1644 }
1645
1646 ////////////////////////////////////////////////////////////
1647 // Replace $__lldb_expr_result with a persistent variable
1648 //
1649
1650 if (main_function) {
1651 if (!CreateResultVariable(llvm_function&: *main_function)) {
1652 LLDB_LOG(log, "CreateResultVariable() failed");
1653
1654 // CreateResultVariable() reports its own errors, so we don't do so here
1655
1656 return false;
1657 }
1658 }
1659
1660 if (log && log->GetVerbose()) {
1661 std::string s;
1662 raw_string_ostream oss(s);
1663
1664 m_module->print(OS&: oss, AAW: nullptr);
1665
1666 oss.flush();
1667
1668 LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
1669 }
1670
1671 for (llvm::Function &function : *m_module) {
1672 for (BasicBlock &bb : function) {
1673 if (!RemoveGuards(basic_block&: bb)) {
1674 LLDB_LOG(log, "RemoveGuards() failed");
1675
1676 // RemoveGuards() reports its own errors, so we don't do so here
1677
1678 return false;
1679 }
1680
1681 if (!RewritePersistentAllocs(basic_block&: bb)) {
1682 LLDB_LOG(log, "RewritePersistentAllocs() failed");
1683
1684 // RewritePersistentAllocs() reports its own errors, so we don't do so
1685 // here
1686
1687 return false;
1688 }
1689
1690 if (!RemoveCXAAtExit(basic_block&: bb)) {
1691 LLDB_LOG(log, "RemoveCXAAtExit() failed");
1692
1693 // RemoveCXAAtExit() reports its own errors, so we don't do so here
1694
1695 return false;
1696 }
1697 }
1698 }
1699
1700 ///////////////////////////////////////////////////////////////////////////////
1701 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
1702 //
1703
1704 if (!RewriteObjCConstStrings()) {
1705 LLDB_LOG(log, "RewriteObjCConstStrings() failed");
1706
1707 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
1708
1709 return false;
1710 }
1711
1712 for (llvm::Function &function : *m_module) {
1713 for (llvm::BasicBlock &bb : function) {
1714 if (!RewriteObjCSelectors(basic_block&: bb)) {
1715 LLDB_LOG(log, "RewriteObjCSelectors() failed");
1716
1717 // RewriteObjCSelectors() reports its own errors, so we don't do so
1718 // here
1719
1720 return false;
1721 }
1722 }
1723 }
1724
1725 for (llvm::Function &function : *m_module) {
1726 for (BasicBlock &bb : function) {
1727 if (!ResolveCalls(basic_block&: bb)) {
1728 LLDB_LOG(log, "ResolveCalls() failed");
1729
1730 // ResolveCalls() reports its own errors, so we don't do so here
1731
1732 return false;
1733 }
1734 }
1735 }
1736
1737 ////////////////////////////////////////////////////////////////////////
1738 // Run function-level passes that only make sense on the main function
1739 //
1740
1741 if (main_function) {
1742 if (!ResolveExternals(llvm_function&: *main_function)) {
1743 LLDB_LOG(log, "ResolveExternals() failed");
1744
1745 // ResolveExternals() reports its own errors, so we don't do so here
1746
1747 return false;
1748 }
1749
1750 if (!ReplaceVariables(llvm_function&: *main_function)) {
1751 LLDB_LOG(log, "ReplaceVariables() failed");
1752
1753 // ReplaceVariables() reports its own errors, so we don't do so here
1754
1755 return false;
1756 }
1757 }
1758
1759 if (log && log->GetVerbose()) {
1760 std::string s;
1761 raw_string_ostream oss(s);
1762
1763 m_module->print(OS&: oss, AAW: nullptr);
1764
1765 oss.flush();
1766
1767 LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
1768 }
1769
1770 return true;
1771}
1772

source code of lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp