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