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