LLDB mainline
IRForTarget.cpp
Go to the documentation of this file.
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
12#include "ClangUtil.h"
13
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"
36#include "lldb/Utility/Endian.h"
38#include "lldb/Utility/Log.h"
39#include "lldb/Utility/Scalar.h"
41
42#include <map>
43#include <optional>
44
45using namespace llvm;
47
48typedef SmallVector<Instruction *, 2> InstrList;
49
51 : m_maker(maker), m_values() {}
52
54
55llvm::Value *
57 if (!m_values.count(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
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),
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(rso);
89 rso.flush();
90 if (truncate)
91 s.resize(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(rso);
100 rso.flush();
101 if (truncate)
102 s.resize(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("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>(named_metadata->getOperand(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 metadata_node->getOperand(0)) != global_val)
134 continue;
135
136 ConstantInt *constant_int =
137 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(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, 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 = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable
158 if (check_ms_abi)
159 result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
160 return result;
161}
162
163bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
164 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
165
166 if (!m_resolve_vars)
167 return true;
168
169 // Find the result variable. If it doesn't exist, we can give up right here.
170
171 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
172
173 llvm::StringRef result_name;
174 bool found_result = false;
175
176 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
177 result_name = value_symbol.first();
178
179 // Check if this is a guard variable. It seems this causes some hiccups
180 // on Windows, so let's only check for Itanium guard variables.
181 bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);
182
183 if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
184 found_result = true;
185 m_result_is_pointer = true;
186 break;
187 }
188
189 if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {
190 found_result = true;
191 m_result_is_pointer = false;
192 break;
193 }
194 }
195
196 if (!found_result) {
197 LLDB_LOG(log, "Couldn't find result variable");
198
199 return true;
200 }
201
202 LLDB_LOG(log, "Result name: \"{0}\"", result_name);
203
204 Value *result_value = m_module->getNamedValue(result_name);
205
206 if (!result_value) {
207 LLDB_LOG(log, "Result variable had no data");
208
209 m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
210 "name ({0}) exists, but not its definition\n",
211 result_name);
212
213 return false;
214 }
215
216 LLDB_LOG(log, "Found result in the IR: \"{0}\"",
217 PrintValue(result_value, false));
218
219 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
220
221 if (!result_global) {
222 LLDB_LOG(log, "Result variable isn't a GlobalVariable");
223
224 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
225 "is defined, but is not a global variable\n",
226 result_name);
227
228 return false;
229 }
230
231 clang::NamedDecl *result_decl = DeclForGlobal(result_global);
232 if (!result_decl) {
233 LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
234
235 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
236 "does not have a corresponding Clang entity\n",
237 result_name);
238
239 return false;
240 }
241
242 if (log) {
243 std::string decl_desc_str;
244 raw_string_ostream decl_desc_stream(decl_desc_str);
245 result_decl->print(decl_desc_stream);
246 decl_desc_stream.flush();
247
248 LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
249 }
250
251 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
252 if (!result_var) {
253 LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
254
255 m_error_stream.Format("Internal error [IRForTarget]: Result variable "
256 "({0})'s corresponding Clang entity isn't a "
257 "variable\n",
258 result_name);
259
260 return false;
261 }
262
263 // Get the next available result name from m_decl_map and create the
264 // persistent variable for it
265
266 // If the result is an Lvalue, it is emitted as a pointer; see
267 // ASTResultSynthesizer::SynthesizeBodyResult.
269 clang::QualType pointer_qual_type = result_var->getType();
270 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
271
272 const clang::PointerType *pointer_pointertype =
273 pointer_type->getAs<clang::PointerType>();
274 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
275 pointer_type->getAs<clang::ObjCObjectPointerType>();
276
277 if (pointer_pointertype) {
278 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
279
281 m_decl_map->GetTypeSystem()->GetType(element_qual_type));
282 } else if (pointer_objcobjpointertype) {
283 clang::QualType element_qual_type =
284 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
285
287 m_decl_map->GetTypeSystem()->GetType(element_qual_type));
288 } else {
289 LLDB_LOG(log, "Expected result to have pointer type, but it did not");
290
291 m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
292 "is not a pointer variable\n",
293 result_name);
294
295 return false;
296 }
297 } else {
299 m_decl_map->GetTypeSystem()->GetType(result_var->getType()));
300 }
301
302 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
303 std::optional<uint64_t> bit_size = m_result_type.GetBitSize(target_sp.get());
304 if (!bit_size) {
305 lldb_private::StreamString type_desc_stream;
306 m_result_type.DumpTypeDescription(&type_desc_stream);
307
308 LLDB_LOG(log, "Result type has unknown size");
309
310 m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
311 "couldn't be determined\n",
312 type_desc_stream.GetData());
313 return false;
314 }
315
316 if (log) {
317 lldb_private::StreamString type_desc_stream;
318 m_result_type.DumpTypeDescription(&type_desc_stream);
319
320 LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
321 }
322
324
325 LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
327 m_result_type.GetByteSize(target_sp.get()).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 */
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(llvm::Type::getInt64Ty(m_module->getContext()),
345 reinterpret_cast<uintptr_t>(result_decl), false);
346
347 llvm::Metadata *values[2];
348 values[0] = ConstantAsMetadata::get(new_result_global);
349 values[1] = ConstantAsMetadata::get(new_constant_int);
350
351 ArrayRef<Metadata *> value_ref(values, 2);
352
353 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
354 NamedMDNode *named_metadata =
355 m_module->getNamedMetadata("clang.global.decl.ptrs");
356 named_metadata->addOperand(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("Internal error [IRForTarget]: Result variable "
375 "({0}) has no writes and no initializer\n",
376 result_name);
377
378 return false;
379 }
380
381 Constant *initializer = result_global->getInitializer();
382
383 StoreInst *synthesized_store =
384 new StoreInst(initializer, new_result_global, first_entry_instruction);
385
386 LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
387 PrintValue(synthesized_store));
388 } else {
389 result_global->replaceAllUsesWith(new_result_global);
390 }
391
393 result_decl, m_result_name, m_result_type, true, 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(LLDBLog::Expressions));
404
405 Type *ns_str_ty = ns_str->getType();
406
407 Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
408 Type *i32_ty = Type::getInt32Ty(m_module->getContext());
409 Type *i8_ty = Type::getInt8Ty(m_module->getContext());
410
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 =
419 m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
420 missing_weak);
421 if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
422 LLDB_LOG(log, "Couldn't find CFStringCreateWithBytes in the target");
423
424 m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
425 "constant string requires "
426 "CFStringCreateWithBytes\n");
427
428 return false;
429 }
430
431 LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
432 CFStringCreateWithBytes_addr);
433
434 // Build the function type:
435 //
436 // CFStringRef CFStringCreateWithBytes (
437 // CFAllocatorRef alloc,
438 // const UInt8 *bytes,
439 // CFIndex numBytes,
440 // CFStringEncoding encoding,
441 // Boolean isExternalRepresentation
442 // );
443 //
444 // We make the following substitutions:
445 //
446 // CFStringRef -> i8*
447 // CFAllocatorRef -> i8*
448 // UInt8 * -> i8*
449 // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
450 // pointer size for now) CFStringEncoding -> i32 Boolean -> i8
451
452 Type *arg_type_array[5];
453
454 arg_type_array[0] = i8_ptr_ty;
455 arg_type_array[1] = i8_ptr_ty;
456 arg_type_array[2] = m_intptr_ty;
457 arg_type_array[3] = i32_ty;
458 arg_type_array[4] = i8_ty;
459
460 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
461
462 llvm::FunctionType *CFSCWB_ty =
463 FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
464
465 // Build the constant containing the pointer to the function
466 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
467 Constant *CFSCWB_addr_int =
468 ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
470 CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};
471 }
472
473 ConstantDataSequential *string_array = nullptr;
474
475 if (cstr)
476 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
477
478 Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
479 Constant *bytes_arg = cstr ? cstr : Constant::getNullValue(i8_ptr_ty);
480 Constant *numBytes_arg = ConstantInt::get(
481 m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
482 int encoding_flags = 0;
483 switch (cstr ? string_array->getElementByteSize() : 1) {
484 case 1:
485 encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
486 break;
487 case 2:
488 encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
489 break;
490 case 4:
491 encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
492 break;
493 default:
494 encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
495 LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
496 "element size {0}",
497 string_array->getElementByteSize());
498 }
499 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
500 Constant *isExternal_arg =
501 ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
502
503 Value *argument_array[5];
504
505 argument_array[0] = alloc_arg;
506 argument_array[1] = bytes_arg;
507 argument_array[2] = numBytes_arg;
508 argument_array[3] = encoding_arg;
509 argument_array[4] = isExternal_arg;
510
511 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
512
513 FunctionValueCache CFSCWB_Caller(
514 [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
515 return CallInst::Create(
516 m_CFStringCreateWithBytes, CFSCWB_arguments,
517 "CFStringCreateWithBytes",
518 llvm::cast<Instruction>(
520 });
521
522 if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
524 LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
525
526 m_error_stream.Printf("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
539 lldb_private::Log *log(GetLog(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("_unnamed_cfstring_")) {
547 Value *nsstring_value = value_symbol.second;
548
549 GlobalVariable *nsstring_global =
550 dyn_cast<GlobalVariable>(nsstring_value);
551
552 if (!nsstring_global) {
553 LLDB_LOG(log, "NSString variable is not a GlobalVariable");
554
555 m_error_stream.Printf("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("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>(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("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("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(2);
607
608 if (!nsstring_member) {
609 LLDB_LOG(log, "NSString initializer's str element was empty");
610
611 m_error_stream.Printf("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>(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("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("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>(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(nsstring_global, 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>(value_symbol.second);
699
700 if (!gv) {
701 LLDB_LOG(log,
702 "__CFConstantStringClassReference is not a global variable");
703
704 m_error_stream.Printf("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>(value);
722
723 return !(!global_variable || !global_variable->hasName() ||
724 !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
725}
726
727// This function does not report errors; its callers are responsible.
728bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
729 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
730
731 LoadInst *load = dyn_cast<LoadInst>(selector_load);
732
733 if (!load)
734 return false;
735
736 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
737 // gets represented as
738 //
739 // %sel = load ptr, ptr @OBJC_SELECTOR_REFERENCES_, align 8
740 // call i8 @objc_msgSend(ptr %obj, ptr %sel, ...)
741 //
742 // where %obj is the object pointer and %sel is the selector.
743 //
744 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
745 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
746 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
747
748 // Find the pointer's initializer and get the string from its target.
749
750 GlobalVariable *_objc_selector_references_ =
751 dyn_cast<GlobalVariable>(load->getPointerOperand());
752
753 if (!_objc_selector_references_ ||
754 !_objc_selector_references_->hasInitializer())
755 return false;
756
757 Constant *osr_initializer = _objc_selector_references_->getInitializer();
758 if (!osr_initializer)
759 return false;
760
761 // Find the string's initializer (a ConstantArray) and get the string from it
762
763 GlobalVariable *_objc_meth_var_name_ =
764 dyn_cast<GlobalVariable>(osr_initializer);
765
766 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
767 return false;
768
769 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
770
771 ConstantDataArray *omvn_initializer_array =
772 dyn_cast<ConstantDataArray>(omvn_initializer);
773
774 if (!omvn_initializer_array->isString())
775 return false;
776
777 std::string omvn_initializer_string =
778 std::string(omvn_initializer_array->getAsString());
779
780 LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
781 omvn_initializer_string);
782
783 // Construct a call to sel_registerName
784
785 if (!m_sel_registerName) {
786 lldb::addr_t sel_registerName_addr;
787
788 bool missing_weak = false;
789 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
790 sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str,
791 missing_weak);
792 if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
793 return false;
794
795 LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
796
797 // Build the function type: struct objc_selector
798 // *sel_registerName(uint8_t*)
799
800 // The below code would be "more correct," but in actuality what's required
801 // is uint8_t*
802 // Type *sel_type = StructType::get(m_module->getContext());
803 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
804 Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
805
806 Type *type_array[1];
807
808 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
809
810 ArrayRef<Type *> srN_arg_types(type_array, 1);
811
812 llvm::FunctionType *srN_type =
813 FunctionType::get(sel_ptr_type, srN_arg_types, false);
814
815 // Build the constant containing the pointer to the function
816 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
817 Constant *srN_addr_int =
818 ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
819 m_sel_registerName = {srN_type,
820 ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
821 }
822
823 CallInst *srN_call =
824 CallInst::Create(m_sel_registerName, _objc_meth_var_name_,
825 "sel_registerName", selector_load);
826
827 // Replace the load with the call in all users
828
829 selector_load->replaceAllUsesWith(srN_call);
830
831 selector_load->eraseFromParent();
832
833 return true;
834}
835
836bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
837 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
838
839 InstrList selector_loads;
840
841 for (Instruction &inst : basic_block) {
842 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
843 if (IsObjCSelectorRef(load->getPointerOperand()))
844 selector_loads.push_back(&inst);
845 }
846
847 for (Instruction *inst : selector_loads) {
848 if (!RewriteObjCSelector(inst)) {
849 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
850 "static reference to an Objective-C selector to a "
851 "dynamic reference\n");
852
853 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
854
855 return false;
856 }
857 }
858
859 return true;
860}
861
862static bool IsObjCClassReference(Value *value) {
863 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
864
865 return !(!global_variable || !global_variable->hasName() ||
866 !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
867}
868
869// This function does not report errors; its callers are responsible.
870bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
871 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
872
873 LoadInst *load = dyn_cast<LoadInst>(class_load);
874
875 if (!load)
876 return false;
877
878 // Unpack the class name from the reference. In LLVM IR, a reference to an
879 // Objective-C class gets represented as
880 //
881 // %tmp = load ptr, ptr @OBJC_CLASS_REFERENCES_, align 4
882 //
883 // @OBJC_CLASS_REFERENCES_ is a reference to a character array called
884 // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.
885
886 // Find the pointer's initializer and get the string from its target
887
888 GlobalVariable *_objc_class_references_ =
889 dyn_cast<GlobalVariable>(load->getPointerOperand());
890
891 if (!_objc_class_references_ ||
892 !_objc_class_references_->hasInitializer())
893 return false;
894
895 // Find the string's initializer (a ConstantArray) and get the string from it
896
897 GlobalVariable *_objc_class_name_ =
898 dyn_cast<GlobalVariable>(_objc_class_references_->getInitializer());
899
900 if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
901 return false;
902
903 Constant *ocn_initializer = _objc_class_name_->getInitializer();
904
905 ConstantDataArray *ocn_initializer_array =
906 dyn_cast<ConstantDataArray>(ocn_initializer);
907
908 if (!ocn_initializer_array->isString())
909 return false;
910
911 std::string ocn_initializer_string =
912 std::string(ocn_initializer_array->getAsString());
913
914 LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
915 ocn_initializer_string);
916
917 // Construct a call to objc_getClass
918
919 if (!m_objc_getClass) {
920 lldb::addr_t objc_getClass_addr;
921
922 bool missing_weak = false;
923 static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
924 objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str,
925 missing_weak);
926 if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
927 return false;
928
929 LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);
930
931 // Build the function type: %struct._objc_class *objc_getClass(i8*)
932
933 Type *class_type = load->getType();
934 Type *type_array[1];
935 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
936
937 ArrayRef<Type *> ogC_arg_types(type_array, 1);
938
939 llvm::FunctionType *ogC_type =
940 FunctionType::get(class_type, ogC_arg_types, false);
941
942 // Build the constant containing the pointer to the function
943 PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
944 Constant *ogC_addr_int =
945 ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
946 m_objc_getClass = {ogC_type,
947 ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
948 }
949
950 CallInst *ogC_call = CallInst::Create(m_objc_getClass, _objc_class_name_,
951 "objc_getClass", class_load);
952
953 // Replace the load with the call in all users
954
955 class_load->replaceAllUsesWith(ogC_call);
956
957 class_load->eraseFromParent();
958
959 return true;
960}
961
962bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
963 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
964
965 InstrList class_loads;
966
967 for (Instruction &inst : basic_block) {
968 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
969 if (IsObjCClassReference(load->getPointerOperand()))
970 class_loads.push_back(&inst);
971 }
972
973 for (Instruction *inst : class_loads) {
974 if (!RewriteObjCClassReference(inst)) {
975 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
976 "static reference to an Objective-C class to a "
977 "dynamic reference\n");
978
979 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");
980
981 return false;
982 }
983 }
984
985 return true;
986}
987
988// This function does not report errors; its callers are responsible.
989bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
990 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
991
992 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
993
994 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
995
996 if (!alloc_md || !alloc_md->getNumOperands())
997 return false;
998
999 ConstantInt *constant_int =
1000 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
1001
1002 if (!constant_int)
1003 return false;
1004
1005 // We attempt to register this as a new persistent variable with the DeclMap.
1006
1007 uintptr_t ptr = constant_int->getZExtValue();
1008
1009 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
1010
1011 lldb_private::TypeFromParser result_decl_type(
1012 m_decl_map->GetTypeSystem()->GetType(decl->getType()));
1013
1014 StringRef decl_name(decl->getName());
1015 lldb_private::ConstString persistent_variable_name(decl_name.data(),
1016 decl_name.size());
1017 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1018 result_decl_type, false, false))
1019 return false;
1020
1021 GlobalVariable *persistent_global = new GlobalVariable(
1022 (*m_module), alloc->getType(), false, /* not constant */
1023 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
1024 alloc->getName().str());
1025
1026 // What we're going to do here is make believe this was a regular old
1027 // external variable. That means we need to make the metadata valid.
1028
1029 NamedMDNode *named_metadata =
1030 m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
1031
1032 llvm::Metadata *values[2];
1033 values[0] = ConstantAsMetadata::get(persistent_global);
1034 values[1] = ConstantAsMetadata::get(constant_int);
1035
1036 ArrayRef<llvm::Metadata *> value_ref(values, 2);
1037
1038 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1039 named_metadata->addOperand(persistent_global_md);
1040
1041 // Now, since the variable is a pointer variable, we will drop in a load of
1042 // that pointer variable.
1043
1044 LoadInst *persistent_load = new LoadInst(persistent_global->getValueType(),
1045 persistent_global, "", alloc);
1046
1047 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
1048 PrintValue(persistent_load));
1049
1050 alloc->replaceAllUsesWith(persistent_load);
1051 alloc->eraseFromParent();
1052
1053 return true;
1054}
1055
1056bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1057 if (!m_resolve_vars)
1058 return true;
1059
1060 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1061
1062 InstrList pvar_allocs;
1063
1064 for (Instruction &inst : basic_block) {
1065
1066 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1067 llvm::StringRef alloc_name = alloc->getName();
1068
1069 if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1070 if (alloc_name.find_first_of("0123456789") == 1) {
1071 LLDB_LOG(log, "Rejecting a numeric persistent variable.");
1072
1073 m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1074 "$1, ... are reserved for use as result "
1075 "names\n");
1076
1077 return false;
1078 }
1079
1080 pvar_allocs.push_back(alloc);
1081 }
1082 }
1083 }
1084
1085 for (Instruction *inst : pvar_allocs) {
1086 if (!RewritePersistentAlloc(inst)) {
1087 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1088 "the creation of a persistent variable\n");
1089
1090 LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
1091
1092 return false;
1093 }
1094 }
1095
1096 return true;
1097}
1098
1099// This function does not report errors; its callers are responsible.
1100bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1101 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1102
1103 LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
1104
1105 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1106 switch (constant_expr->getOpcode()) {
1107 default:
1108 break;
1109 case Instruction::GetElementPtr:
1110 case Instruction::BitCast:
1111 Value *s = constant_expr->getOperand(0);
1112 if (!MaybeHandleVariable(s))
1113 return false;
1114 }
1115 } else if (GlobalVariable *global_variable =
1116 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1117 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1118 return true;
1119
1120 clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1121
1122 if (!named_decl) {
1123 if (IsObjCSelectorRef(llvm_value_ptr))
1124 return true;
1125
1126 if (!global_variable->hasExternalLinkage())
1127 return true;
1128
1129 LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
1130 global_variable->getName());
1131
1132 return false;
1133 }
1134
1135 llvm::StringRef name(named_decl->getName());
1136
1137 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1138 if (value_decl == nullptr)
1139 return false;
1140
1141 lldb_private::CompilerType compiler_type =
1142 m_decl_map->GetTypeSystem()->GetType(value_decl->getType());
1143
1144 const Type *value_type = nullptr;
1145
1146 if (name.startswith("$")) {
1147 // The $__lldb_expr_result name indicates the return value has allocated
1148 // as a static variable. Per the comment at
1149 // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
1150 // variable need to be redirected to the result of dereferencing a
1151 // pointer that is passed in as one of the arguments.
1152 //
1153 // Consequently, when reporting the size of the type, we report a pointer
1154 // type pointing to the type of $__lldb_expr_result, not the type itself.
1155 //
1156 // We also do this for any user-declared persistent variables.
1157 compiler_type = compiler_type.GetPointerType();
1158 value_type = PointerType::get(global_variable->getType(), 0);
1159 } else {
1160 value_type = global_variable->getType();
1161 }
1162
1163 auto *target = m_execution_unit.GetTarget().get();
1164 std::optional<uint64_t> value_size = compiler_type.GetByteSize(target);
1165 if (!value_size)
1166 return false;
1167 std::optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(target);
1168 if (!opt_alignment)
1169 return false;
1170 lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
1171
1172 LLDB_LOG(log,
1173 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1174 "align {4}]",
1175 name,
1176 lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
1177 PrintType(value_type), *value_size, value_alignment);
1178
1179 if (named_decl)
1181 llvm_value_ptr, *value_size,
1182 value_alignment);
1183 } else if (isa<llvm::Function>(llvm_value_ptr)) {
1184 LLDB_LOG(log, "Function pointers aren't handled right now");
1185
1186 return false;
1187 }
1188
1189 return true;
1190}
1191
1192// This function does not report errors; its callers are responsible.
1193bool IRForTarget::HandleSymbol(Value *symbol) {
1194 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1195
1196 lldb_private::ConstString name(symbol->getName().str().c_str());
1197
1198 lldb::addr_t symbol_addr =
1200
1201 if (symbol_addr == LLDB_INVALID_ADDRESS) {
1202 LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
1203
1204 return false;
1205 }
1206
1207 LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
1208
1209 Type *symbol_type = symbol->getType();
1210
1211 Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1212
1213 Value *symbol_addr_ptr =
1214 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1215
1216 LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
1217 PrintValue(symbol_addr_ptr));
1218
1219 symbol->replaceAllUsesWith(symbol_addr_ptr);
1220
1221 return true;
1222}
1223
1225 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1226
1227 LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
1228
1229 for (unsigned op_index = 0, num_ops = Old->arg_size();
1230 op_index < num_ops; ++op_index)
1231 // conservatively believe that this is a store
1232 if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
1233 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1234 "one of the arguments of a function call.\n");
1235
1236 return false;
1237 }
1238
1239 return true;
1240}
1241
1242bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1243 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1244
1245 GlobalVariable *global_variable =
1246 dyn_cast<GlobalVariable>(classlist_reference);
1247
1248 if (!global_variable)
1249 return false;
1250
1251 Constant *initializer = global_variable->getInitializer();
1252
1253 if (!initializer)
1254 return false;
1255
1256 if (!initializer->hasName())
1257 return false;
1258
1259 StringRef name(initializer->getName());
1260 lldb_private::ConstString name_cstr(name.str().c_str());
1261 lldb::addr_t class_ptr =
1263
1264 LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
1265 (unsigned long long)class_ptr);
1266
1267 if (class_ptr == LLDB_INVALID_ADDRESS)
1268 return false;
1269
1270 if (global_variable->use_empty())
1271 return false;
1272
1273 SmallVector<LoadInst *, 2> load_instructions;
1274
1275 for (llvm::User *u : global_variable->users()) {
1276 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1277 load_instructions.push_back(load_instruction);
1278 }
1279
1280 if (load_instructions.empty())
1281 return false;
1282
1283 Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1284
1285 for (LoadInst *load_instruction : load_instructions) {
1286 Constant *class_bitcast =
1287 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1288
1289 load_instruction->replaceAllUsesWith(class_bitcast);
1290
1291 load_instruction->eraseFromParent();
1292 }
1293
1294 return true;
1295}
1296
1297bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
1298 std::vector<CallInst *> calls_to_remove;
1299
1300 for (Instruction &inst : basic_block) {
1301 CallInst *call = dyn_cast<CallInst>(&inst);
1302
1303 // MaybeHandleCallArguments handles error reporting; we are silent here
1304 if (!call)
1305 continue;
1306
1307 bool remove = false;
1308
1309 llvm::Function *func = call->getCalledFunction();
1310
1311 if (func && func->getName() == "__cxa_atexit")
1312 remove = true;
1313
1314 llvm::Value *val = call->getCalledOperand();
1315
1316 if (val && val->getName() == "__cxa_atexit")
1317 remove = true;
1318
1319 if (remove)
1320 calls_to_remove.push_back(call);
1321 }
1322
1323 for (CallInst *ci : calls_to_remove)
1324 ci->eraseFromParent();
1325
1326 return true;
1327}
1328
1329bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
1330 // Prepare the current basic block for execution in the remote process
1331
1332 for (Instruction &inst : basic_block) {
1333 CallInst *call = dyn_cast<CallInst>(&inst);
1334
1335 // MaybeHandleCallArguments handles error reporting; we are silent here
1336 if (call && !MaybeHandleCallArguments(call))
1337 return false;
1338 }
1339
1340 return true;
1341}
1342
1343bool IRForTarget::ResolveExternals(Function &llvm_function) {
1344 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1345
1346 for (GlobalVariable &global_var : m_module->globals()) {
1347 llvm::StringRef global_name = global_var.getName();
1348
1349 LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
1350 static_cast<void *>(DeclForGlobal(&global_var)));
1351
1352 if (global_name.startswith("OBJC_IVAR")) {
1353 if (!HandleSymbol(&global_var)) {
1354 m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
1355 "indirect ivar symbol {0}\n",
1356 global_name);
1357
1358 return false;
1359 }
1360 } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
1361 if (!HandleObjCClass(&global_var)) {
1362 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1363 "for an Objective-C static method call\n");
1364
1365 return false;
1366 }
1367 } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
1368 if (!HandleObjCClass(&global_var)) {
1369 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1370 "for an Objective-C static method call\n");
1371
1372 return false;
1373 }
1374 } else if (DeclForGlobal(&global_var)) {
1375 if (!MaybeHandleVariable(&global_var)) {
1376 m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
1377 "external variable {0}\n",
1378 global_name);
1379
1380 return false;
1381 }
1382 }
1383 }
1384
1385 return true;
1386}
1387
1388static bool isGuardVariableRef(Value *V) {
1389 GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
1390
1391 if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))
1392 return false;
1393
1394 return true;
1395}
1396
1397void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1398 Constant *zero(Constant::getNullValue(guard_load->getType()));
1399 guard_load->replaceAllUsesWith(zero);
1400 guard_load->eraseFromParent();
1401}
1402
1403static void ExciseGuardStore(Instruction *guard_store) {
1404 guard_store->eraseFromParent();
1405}
1406
1407bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
1408 // Eliminate any reference to guard variables found.
1409
1410 InstrList guard_loads;
1411 InstrList guard_stores;
1412
1413 for (Instruction &inst : basic_block) {
1414
1415 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1416 if (isGuardVariableRef(load->getPointerOperand()))
1417 guard_loads.push_back(&inst);
1418
1419 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1420 if (isGuardVariableRef(store->getPointerOperand()))
1421 guard_stores.push_back(&inst);
1422 }
1423
1424 for (Instruction *inst : guard_loads)
1426
1427 for (Instruction *inst : guard_stores)
1428 ExciseGuardStore(inst);
1429
1430 return true;
1431}
1432
1433// This function does not report errors; its callers are responsible.
1434bool IRForTarget::UnfoldConstant(Constant *old_constant,
1435 llvm::Function *llvm_function,
1436 FunctionValueCache &value_maker,
1437 FunctionValueCache &entry_instruction_finder,
1438 lldb_private::Stream &error_stream) {
1439 SmallVector<User *, 16> users;
1440
1441 // We do this because the use list might change, invalidating our iterator.
1442 // Much better to keep a work list ourselves.
1443 for (llvm::User *u : old_constant->users())
1444 users.push_back(u);
1445
1446 for (size_t i = 0; i < users.size(); ++i) {
1447 User *user = users[i];
1448
1449 if (Constant *constant = dyn_cast<Constant>(user)) {
1450 // synthesize a new non-constant equivalent of the constant
1451
1452 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1453 switch (constant_expr->getOpcode()) {
1454 default:
1455 error_stream.Printf("error [IRForTarget internal]: Unhandled "
1456 "constant expression type: \"%s\"",
1457 PrintValue(constant_expr).c_str());
1458 return false;
1459 case Instruction::BitCast: {
1460 FunctionValueCache bit_cast_maker(
1461 [&value_maker, &entry_instruction_finder, old_constant,
1462 constant_expr](llvm::Function *function) -> llvm::Value * {
1463 // UnaryExpr
1464 // OperandList[0] is value
1465
1466 if (constant_expr->getOperand(0) != old_constant)
1467 return constant_expr;
1468
1469 return new BitCastInst(
1470 value_maker.GetValue(function), constant_expr->getType(),
1471 "", llvm::cast<Instruction>(
1472 entry_instruction_finder.GetValue(function)));
1473 });
1474
1475 if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1476 entry_instruction_finder, error_stream))
1477 return false;
1478 } break;
1479 case Instruction::GetElementPtr: {
1480 // GetElementPtrConstantExpr
1481 // OperandList[0] is base
1482 // OperandList[1]... are indices
1483
1484 FunctionValueCache get_element_pointer_maker(
1485 [&value_maker, &entry_instruction_finder, old_constant,
1486 constant_expr](llvm::Function *function) -> llvm::Value * {
1487 auto *gep = cast<llvm::GEPOperator>(constant_expr);
1488 Value *ptr = gep->getPointerOperand();
1489
1490 if (ptr == old_constant)
1491 ptr = value_maker.GetValue(function);
1492
1493 std::vector<Value *> index_vector;
1494 for (Value *operand : gep->indices()) {
1495 if (operand == old_constant)
1496 operand = value_maker.GetValue(function);
1497
1498 index_vector.push_back(operand);
1499 }
1500
1501 ArrayRef<Value *> indices(index_vector);
1502
1503 return GetElementPtrInst::Create(
1504 gep->getSourceElementType(), ptr, indices, "",
1505 llvm::cast<Instruction>(
1506 entry_instruction_finder.GetValue(function)));
1507 });
1508
1509 if (!UnfoldConstant(constant_expr, llvm_function,
1510 get_element_pointer_maker,
1511 entry_instruction_finder, error_stream))
1512 return false;
1513 } break;
1514 }
1515 } else {
1516 error_stream.Printf(
1517 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1518 PrintValue(constant).c_str());
1519 return false;
1520 }
1521 } else {
1522 if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1523 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1524 error_stream.PutCString("error: Capturing non-local variables in "
1525 "expressions is unsupported.\n");
1526 return false;
1527 }
1528 inst->replaceUsesOfWith(
1529 old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1530 } else {
1531 error_stream.Printf(
1532 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1533 PrintValue(user).c_str());
1534 return false;
1535 }
1536 }
1537 }
1538
1539 if (!isa<GlobalValue>(old_constant)) {
1540 old_constant->destroyConstant();
1541 }
1542
1543 return true;
1544}
1545
1546bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1547 if (!m_resolve_vars)
1548 return true;
1549
1550 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1551
1553
1554 LLDB_LOG(log, "Element arrangement:");
1555
1556 uint32_t num_elements;
1557 uint32_t element_index;
1558
1559 size_t size;
1560 lldb::offset_t alignment;
1561
1562 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1563 return false;
1564
1565 Function::arg_iterator iter(llvm_function.arg_begin());
1566
1567 if (iter == llvm_function.arg_end()) {
1568 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1569 "arguments (should take at least a struct pointer)");
1570
1571 return false;
1572 }
1573
1574 Argument *argument = &*iter;
1575
1576 if (argument->getName().equals("this")) {
1577 ++iter;
1578
1579 if (iter == llvm_function.arg_end()) {
1580 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1581 "'this' argument (should take a struct pointer "
1582 "too)");
1583
1584 return false;
1585 }
1586
1587 argument = &*iter;
1588 } else if (argument->getName().equals("self")) {
1589 ++iter;
1590
1591 if (iter == llvm_function.arg_end()) {
1592 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1593 "'self' argument (should take '_cmd' and a struct "
1594 "pointer too)");
1595
1596 return false;
1597 }
1598
1599 if (!iter->getName().equals("_cmd")) {
1600 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
1601 "after 'self' argument (should take '_cmd')",
1602 iter->getName());
1603
1604 return false;
1605 }
1606
1607 ++iter;
1608
1609 if (iter == llvm_function.arg_end()) {
1610 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1611 "'self' and '_cmd' arguments (should take a struct "
1612 "pointer too)");
1613
1614 return false;
1615 }
1616
1617 argument = &*iter;
1618 }
1619
1620 if (!argument->getName().equals("$__lldb_arg")) {
1621 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
1622 "argument named '{0}' instead of the struct pointer",
1623 argument->getName());
1624
1625 return false;
1626 }
1627
1628 LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
1629
1630 BasicBlock &entry_block(llvm_function.getEntryBlock());
1631 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1632
1633 if (!FirstEntryInstruction) {
1634 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1635 "first instruction in the wrapper for use in "
1636 "rewriting");
1637
1638 return false;
1639 }
1640
1641 LLVMContext &context(m_module->getContext());
1642 IntegerType *offset_type(Type::getInt32Ty(context));
1643
1644 if (!offset_type) {
1646 "Internal error [IRForTarget]: Couldn't produce an offset type");
1647
1648 return false;
1649 }
1650
1651 for (element_index = 0; element_index < num_elements; ++element_index) {
1652 const clang::NamedDecl *decl = nullptr;
1653 Value *value = nullptr;
1654 lldb::offset_t offset;
1656
1657 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1658 element_index)) {
1660 "Internal error [IRForTarget]: Structure information is incomplete");
1661
1662 return false;
1663 }
1664
1665 LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name,
1666 decl->getNameAsString(), offset);
1667
1668 if (value) {
1669 LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
1670
1671 FunctionValueCache body_result_maker(
1672 [this, name, offset_type, offset, argument,
1673 value](llvm::Function *function) -> llvm::Value * {
1674 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
1675 // in cases where the result variable is an rvalue, we have to
1676 // synthesize a dereference of the appropriate structure entry in
1677 // order to produce the static variable that the AST thinks it is
1678 // accessing.
1679
1680 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1682
1683 Type *int8Ty = Type::getInt8Ty(function->getContext());
1684 ConstantInt *offset_int(
1685 ConstantInt::get(offset_type, offset, true));
1686 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1687 int8Ty, argument, offset_int, "", entry_instruction);
1688
1689 if (name == m_result_name && !m_result_is_pointer) {
1690 LoadInst *load = new LoadInst(value->getType(), get_element_ptr,
1691 "", entry_instruction);
1692
1693 return load;
1694 } else {
1695 return get_element_ptr;
1696 }
1697 });
1698
1699 if (Constant *constant = dyn_cast<Constant>(value)) {
1700 if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
1702 return false;
1703 }
1704 } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1705 if (instruction->getParent()->getParent() != &llvm_function) {
1706 m_error_stream.PutCString("error: Capturing non-local variables in "
1707 "expressions is unsupported.\n");
1708 return false;
1709 }
1710 value->replaceAllUsesWith(
1711 body_result_maker.GetValue(instruction->getParent()->getParent()));
1712 } else {
1713 LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
1714 PrintValue(value));
1715 return false;
1716 }
1717
1718 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1719 var->eraseFromParent();
1720 }
1721 }
1722
1723 LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
1724 (uint64_t)size);
1725
1726 return true;
1727}
1728
1729bool IRForTarget::runOnModule(Module &llvm_module) {
1730 lldb_private::Log *log(GetLog(LLDBLog::Expressions));
1731
1732 m_module = &llvm_module;
1733 m_target_data = std::make_unique<DataLayout>(m_module);
1734 m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
1735 m_target_data->getPointerSizeInBits());
1736
1737 if (log) {
1738 std::string s;
1739 raw_string_ostream oss(s);
1740
1741 m_module->print(oss, nullptr);
1742
1743 oss.flush();
1744
1745 LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
1746 }
1747
1748 Function *const main_function =
1749 m_func_name.IsEmpty() ? nullptr
1750 : m_module->getFunction(m_func_name.GetStringRef());
1751
1752 if (!m_func_name.IsEmpty() && !main_function) {
1753 LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
1754
1755 m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
1756 "'{0}' in the module",
1757 m_func_name);
1758
1759 return false;
1760 }
1761
1762 if (main_function) {
1763 if (!FixFunctionLinkage(*main_function)) {
1764 LLDB_LOG(log, "Couldn't fix the linkage for the function");
1765
1766 return false;
1767 }
1768 }
1769
1770 llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
1771
1772 m_reloc_placeholder = new llvm::GlobalVariable(
1773 (*m_module), int8_ty, false /* IsConstant */,
1774 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
1775 "reloc_placeholder", nullptr /* InsertBefore */,
1776 GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
1777
1778 ////////////////////////////////////////////////////////////
1779 // Replace $__lldb_expr_result with a persistent variable
1780 //
1781
1782 if (main_function) {
1783 if (!CreateResultVariable(*main_function)) {
1784 LLDB_LOG(log, "CreateResultVariable() failed");
1785
1786 // CreateResultVariable() reports its own errors, so we don't do so here
1787
1788 return false;
1789 }
1790 }
1791
1792 if (log && log->GetVerbose()) {
1793 std::string s;
1794 raw_string_ostream oss(s);
1795
1796 m_module->print(oss, nullptr);
1797
1798 oss.flush();
1799
1800 LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
1801 }
1802
1803 for (llvm::Function &function : *m_module) {
1804 for (BasicBlock &bb : function) {
1805 if (!RemoveGuards(bb)) {
1806 LLDB_LOG(log, "RemoveGuards() failed");
1807
1808 // RemoveGuards() reports its own errors, so we don't do so here
1809
1810 return false;
1811 }
1812
1813 if (!RewritePersistentAllocs(bb)) {
1814 LLDB_LOG(log, "RewritePersistentAllocs() failed");
1815
1816 // RewritePersistentAllocs() reports its own errors, so we don't do so
1817 // here
1818
1819 return false;
1820 }
1821
1822 if (!RemoveCXAAtExit(bb)) {
1823 LLDB_LOG(log, "RemoveCXAAtExit() failed");
1824
1825 // RemoveCXAAtExit() reports its own errors, so we don't do so here
1826
1827 return false;
1828 }
1829 }
1830 }
1831
1832 ///////////////////////////////////////////////////////////////////////////////
1833 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
1834 //
1835
1836 if (!RewriteObjCConstStrings()) {
1837 LLDB_LOG(log, "RewriteObjCConstStrings() failed");
1838
1839 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
1840
1841 return false;
1842 }
1843
1844 for (llvm::Function &function : *m_module) {
1845 for (llvm::BasicBlock &bb : function) {
1846 if (!RewriteObjCSelectors(bb)) {
1847 LLDB_LOG(log, "RewriteObjCSelectors() failed");
1848
1849 // RewriteObjCSelectors() reports its own errors, so we don't do so
1850 // here
1851
1852 return false;
1853 }
1854
1855 if (!RewriteObjCClassReferences(bb)) {
1856 LLDB_LOG(log, "RewriteObjCClassReferences() failed");
1857
1858 // RewriteObjCClasses() reports its own errors, so we don't do so here
1859
1860 return false;
1861 }
1862 }
1863 }
1864
1865 for (llvm::Function &function : *m_module) {
1866 for (BasicBlock &bb : function) {
1867 if (!ResolveCalls(bb)) {
1868 LLDB_LOG(log, "ResolveCalls() failed");
1869
1870 // ResolveCalls() reports its own errors, so we don't do so here
1871
1872 return false;
1873 }
1874 }
1875 }
1876
1877 ////////////////////////////////////////////////////////////////////////
1878 // Run function-level passes that only make sense on the main function
1879 //
1880
1881 if (main_function) {
1882 if (!ResolveExternals(*main_function)) {
1883 LLDB_LOG(log, "ResolveExternals() failed");
1884
1885 // ResolveExternals() reports its own errors, so we don't do so here
1886
1887 return false;
1888 }
1889
1890 if (!ReplaceVariables(*main_function)) {
1891 LLDB_LOG(log, "ReplaceVariables() failed");
1892
1893 // ReplaceVariables() reports its own errors, so we don't do so here
1894
1895 return false;
1896 }
1897 }
1898
1899 if (log && log->GetVerbose()) {
1900 std::string s;
1901 raw_string_ostream oss(s);
1902
1903 m_module->print(oss, nullptr);
1904
1905 oss.flush();
1906
1907 LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
1908 }
1909
1910 return true;
1911}
static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol, bool check_ms_abi=true)
Returns true iff the mangled symbol is for a static guard variable.
static std::string PrintValue(const Value *value, bool truncate=false)
Definition: IRForTarget.cpp:84
static void ExciseGuardStore(Instruction *guard_store)
static llvm::Value * FindEntryInstruction(llvm::Function *function)
Definition: IRForTarget.cpp:65
static bool IsObjCSelectorRef(Value *value)
SmallVector< Instruction *, 2 > InstrList
Definition: IRForTarget.cpp:48
static bool isGuardVariableRef(Value *V)
static bool IsObjCClassReference(Value *value)
static std::string PrintType(const llvm::Type *type, bool truncate=false)
Definition: IRForTarget.cpp:96
static std::string PrintValue(const Value *value, bool truncate=false)
static std::string PrintType(const Type *type, bool truncate=false)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:337
FunctionValueCache(Maker const &maker)
Definition: IRForTarget.cpp:50
llvm::Value * GetValue(llvm::Function *function)
Definition: IRForTarget.cpp:56
std::function< llvm::Value *(llvm::Function *)> Maker
Definition: IRForTarget.h:449
std::unique_ptr< llvm::DataLayout > m_target_data
The target data for the module being processed, or NULL if there is no module.
Definition: IRForTarget.h:419
llvm::FunctionCallee m_objc_getClass
The address of the function objc_getClass, cast to the appropriate function pointer type.
Definition: IRForTarget.h:430
lldb_private::ConstString m_func_name
The name of the function to translate.
Definition: IRForTarget.h:410
bool MaybeHandleVariable(llvm::Value *value)
A function-level pass to find all external variables and functions used in the IR.
llvm::GlobalVariable * m_reloc_placeholder
A placeholder that will be replaced by a pointer to the final location of the static allocation.
Definition: IRForTarget.h:445
bool FixFunctionLinkage(llvm::Function &llvm_function)
Ensures that the current function's linkage is set to external.
lldb_private::IRExecutionUnit & m_execution_unit
The execution unit containing the IR being created.
Definition: IRForTarget.h:436
bool RewriteObjCClassReference(llvm::Instruction *class_load)
A basic block-level pass to find all Objective-C class references that use the old-style Objective-C ...
bool CreateResultVariable(llvm::Function &llvm_function)
The top-level pass implementation.
llvm::Module * m_module
The module being processed, or NULL if that has not been determined yet.
Definition: IRForTarget.h:416
IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map, bool resolve_vars, lldb_private::IRExecutionUnit &execution_unit, lldb_private::Stream &error_stream, const char *func_name="$__lldb_expr")
Constructor.
Definition: IRForTarget.cpp:72
bool HandleSymbol(llvm::Value *symbol)
Handle a single externally-defined symbol.
bool RewriteObjCConstStrings()
The top-level pass implementation.
bool ResolveCalls(llvm::BasicBlock &basic_block)
Resolve variable references in calls to external functions.
bool m_result_is_pointer
True if the function's result in the AST is a pointer (see comments in ASTResultSynthesizer::Synthesi...
Definition: IRForTarget.h:442
bool RewriteObjCConstString(llvm::GlobalVariable *NSStr, llvm::GlobalVariable *CStr)
A module-level pass to find Objective-C constant strings and transform them to calls to CFStringCreat...
bool RemoveGuards(llvm::BasicBlock &basic_block)
The top-level pass implementation.
lldb_private::Stream & m_error_stream
The stream on which errors should be printed.
Definition: IRForTarget.h:434
bool HandleObjCClass(llvm::Value *classlist_reference)
Handle a single externally-defined Objective-C class.
bool m_resolve_vars
True if external variable references and persistent variable references should be resolved.
Definition: IRForTarget.h:408
static clang::NamedDecl * DeclForGlobal(const llvm::GlobalValue *global_val, llvm::Module *module)
A function-level pass to take the generated global value $__lldb_expr_result and make it into a persi...
lldb_private::TypeFromParser m_result_type
The type of the result variable.
Definition: IRForTarget.h:414
llvm::FunctionCallee m_CFStringCreateWithBytes
The address of the function CFStringCreateWithBytes, cast to the appropriate function pointer type.
Definition: IRForTarget.h:424
bool MaybeHandleCallArguments(llvm::CallInst *call_inst)
Handle all the arguments to a function call.
bool runOnModule(llvm::Module &llvm_module)
Run this IR transformer on a single module.
bool RewriteObjCSelectors(llvm::BasicBlock &basic_block)
The top-level pass implementation.
lldb_private::ConstString m_result_name
The name of the result variable ($0, $1, ...)
Definition: IRForTarget.h:412
lldb_private::ClangExpressionDeclMap * m_decl_map
The DeclMap containing the Decls.
Definition: IRForTarget.h:421
bool RewriteObjCClassReferences(llvm::BasicBlock &basic_block)
The top-level pass implementation.
bool RemoveCXAAtExit(llvm::BasicBlock &basic_block)
Remove calls to __cxa_atexit, which should never be generated by expressions.
bool RewritePersistentAllocs(llvm::BasicBlock &basic_block)
The top-level pass implementation.
bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc)
A basic block-level pass to find all newly-declared persistent variables and register them with the C...
void TurnGuardLoadIntoZero(llvm::Instruction *guard_load)
A basic block-level pass to excise guard variables from the code.
FunctionValueCache m_entry_instruction_finder
Definition: IRForTarget.h:461
llvm::FunctionCallee m_sel_registerName
The address of the function sel_registerName, cast to the appropriate function pointer type.
Definition: IRForTarget.h:427
llvm::IntegerType * m_intptr_ty
The type of an integer large enough to hold a pointer.
Definition: IRForTarget.h:432
bool RewriteObjCSelector(llvm::Instruction *selector_load)
A basic block-level pass to find all Objective-C method calls and rewrite them to use sel_registerNam...
bool ResolveExternals(llvm::Function &llvm_function)
The top-level pass implementation.
bool ReplaceVariables(llvm::Function &llvm_function)
A function-level pass to make all external variable references point at the correct offsets from the ...
static bool UnfoldConstant(llvm::Constant *old_constant, llvm::Function *llvm_function, FunctionValueCache &value_maker, FunctionValueCache &entry_instruction_finder, lldb_private::Stream &error_stream)
UnfoldConstant operates on a constant [Old] which has just been replaced with a value [New].
TypeSystemClang * GetTypeSystem() const
Returns the TypeSystem that uses this ClangASTSource instance as it's ExternalASTSource.
"lldb/Expression/ClangExpressionDeclMap.h" Manages named entities that are defined in LLDB's debug in...
bool AddPersistentVariable(const clang::NamedDecl *decl, ConstString name, TypeFromParser type, bool is_result, bool is_lvalue)
[Used by IRForTarget] Add a variable to the list of persistent variables for the process.
bool GetStructElement(const clang::NamedDecl *&decl, llvm::Value *&value, lldb::offset_t &offset, ConstString &name, uint32_t index)
[Used by IRForTarget] Get specific information about one field of the laid-out struct after DoStructL...
bool DoStructLayout()
[Used by IRForTarget] Finalize the struct, laying out the position of each object in it.
bool AddValueToStruct(const clang::NamedDecl *decl, ConstString name, llvm::Value *value, size_t size, lldb::offset_t alignment)
[Used by IRForTarget] Add a variable to the struct that needs to be materialized each time the expres...
lldb::addr_t GetSymbolAddress(Target &target, Process *process, ConstString name, lldb::SymbolType symbol_type, Module *module=nullptr)
[Used by IRForTarget] Get the address of a symbol given nothing but its name.
bool GetStructInfo(uint32_t &num_elements, size_t &size, lldb::offset_t &alignment)
[Used by IRForTarget] Get general information about the laid-out struct after DoStructLayout() has be...
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
std::optional< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
std::optional< size_t > GetTypeBitAlign(ExecutionContextScope *exe_scope) const
A uniqued constant string class.
Definition: ConstString.h:40
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:309
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:207
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:221
"lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT- compiled code for a module.
lldb::addr_t FindSymbol(ConstString name, bool &missing_weak)
lldb::TargetSP GetTarget()
Definition: IRMemoryMap.h:80
bool GetVerbose() const
Definition: Log.cpp:298
const char * GetData() const
Definition: StreamString.h:43
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void Format(const char *format, Args &&... args)
Definition: Stream.h:309
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
CompilerType GetType(clang::QualType qt)
Creates a CompilerType from the given QualType with the current TypeSystemClang instance as the Compi...
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
TaggedASTType< 0 > TypeFromParser
Definition: TaggedASTType.h:40
uint64_t offset_t
Definition: lldb-types.h:83
@ eSymbolTypeObjCClass
uint64_t addr_t
Definition: lldb-types.h:79
Definition: Debugger.h:52
static clang::QualType GetQualType(const CompilerType &ct)
Definition: ClangUtil.cpp:36