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"
28#include "clang/AST/ASTContext.h"
51 : m_maker(maker), m_values() {}
57 if (!m_values.count(function)) {
58 llvm::Value *ret = m_maker(function);
59 m_values[function] = ret;
62 return m_values[function];
66 if (function->empty())
69 return function->getEntryBlock().getFirstNonPHIOrDbg();
76 const char *func_name)
84static std::string
PrintValue(
const Value *value,
bool truncate =
false) {
87 raw_string_ostream rso(s);
91 s.resize(s.length() - 1);
96static std::string
PrintType(
const llvm::Type *type,
bool truncate =
false) {
98 raw_string_ostream rso(s);
102 s.resize(s.length() - 1);
107 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
114 NamedMDNode *named_metadata =
115 module->getNamedMetadata(
"clang.global.decl.ptrs");
120 unsigned num_nodes = named_metadata->getNumOperands();
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));
129 if (metadata_node->getNumOperands() != 2)
132 if (mdconst::dyn_extract_or_null<GlobalValue>(
133 metadata_node->getOperand(0)) != global_val)
136 ConstantInt *constant_int =
137 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
142 uintptr_t ptr = constant_int->getZExtValue();
144 return reinterpret_cast<clang::NamedDecl *
>(ptr);
156 bool check_ms_abi =
true) {
157 bool result = mangled_symbol.startswith(
"_ZGV");
159 result |= mangled_symbol.endswith(
"@4IA");
171 ValueSymbolTable &value_symbol_table =
m_module->getValueSymbolTable();
173 llvm::StringRef result_name;
174 bool found_result =
false;
176 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
177 result_name = value_symbol.first();
183 if (result_name.contains(
"$__lldb_expr_result_ptr") && !is_guard_var) {
189 if (result_name.contains(
"$__lldb_expr_result") && !is_guard_var) {
197 LLDB_LOG(log,
"Couldn't find result variable");
202 LLDB_LOG(log,
"Result name: \"{0}\"", result_name);
204 Value *result_value =
m_module->getNamedValue(result_name);
207 LLDB_LOG(log,
"Result variable had no data");
210 "name ({0}) exists, but not its definition\n",
216 LLDB_LOG(log,
"Found result in the IR: \"{0}\"",
219 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
221 if (!result_global) {
222 LLDB_LOG(log,
"Result variable isn't a GlobalVariable");
225 "is defined, but is not a global variable\n",
231 clang::NamedDecl *result_decl =
DeclForGlobal(result_global);
233 LLDB_LOG(log,
"Result variable doesn't have a corresponding Decl");
236 "does not have a corresponding Clang entity\n",
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();
248 LLDB_LOG(log,
"Found result decl: \"{0}\"", decl_desc_str);
251 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
253 LLDB_LOG(log,
"Result variable Decl isn't a VarDecl");
256 "({0})'s corresponding Clang entity isn't a "
269 clang::QualType pointer_qual_type = result_var->getType();
270 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
272 const clang::PointerType *pointer_pointertype =
273 pointer_type->getAs<clang::PointerType>();
274 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
275 pointer_type->getAs<clang::ObjCObjectPointerType>();
277 if (pointer_pointertype) {
278 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
282 }
else if (pointer_objcobjpointertype) {
283 clang::QualType element_qual_type =
284 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
289 LLDB_LOG(log,
"Expected result to have pointer type, but it did not");
292 "is not a pointer variable\n",
303 std::optional<uint64_t> bit_size =
m_result_type.GetBitSize(target_sp.get());
308 LLDB_LOG(log,
"Result type has unknown size");
311 "couldn't be determined\n",
320 LLDB_LOG(log,
"Result decl type: \"{0}\"", type_desc_stream.
GetData());
325 LLDB_LOG(log,
"Creating a new result global: \"{0}\" with size {1}",
331 GlobalVariable *new_result_global =
new GlobalVariable(
332 (*
m_module), result_global->getValueType(),
false,
333 GlobalValue::ExternalLinkage,
nullptr,
343 ConstantInt *new_constant_int =
344 ConstantInt::get(llvm::Type::getInt64Ty(
m_module->getContext()),
345 reinterpret_cast<uintptr_t
>(result_decl),
false);
347 llvm::Metadata *values[2];
348 values[0] = ConstantAsMetadata::get(new_result_global);
349 values[1] = ConstantAsMetadata::get(new_constant_int);
351 ArrayRef<Metadata *> value_ref(values, 2);
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);
361 if (result_global->use_empty()) {
365 BasicBlock &entry_block(llvm_function.getEntryBlock());
366 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
368 if (!first_entry_instruction)
371 if (!result_global->hasInitializer()) {
372 LLDB_LOG(log,
"Couldn't find initializer for unused variable");
375 "({0}) has no writes and no initializer\n",
381 Constant *initializer = result_global->getInitializer();
383 StoreInst *synthesized_store =
384 new StoreInst(initializer, new_result_global, first_entry_instruction);
386 LLDB_LOG(log,
"Synthesized result store \"{0}\"\n",
389 result_global->replaceAllUsesWith(new_result_global);
396 result_global->eraseFromParent();
402 llvm::GlobalVariable *cstr) {
405 Type *ns_str_ty = ns_str->getType();
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());
415 "CFStringCreateWithBytes");
417 bool missing_weak =
false;
418 CFStringCreateWithBytes_addr =
422 LLDB_LOG(log,
"Couldn't find CFStringCreateWithBytes in the target");
425 "constant string requires "
426 "CFStringCreateWithBytes\n");
431 LLDB_LOG(log,
"Found CFStringCreateWithBytes at {0}",
432 CFStringCreateWithBytes_addr);
452 Type *arg_type_array[5];
454 arg_type_array[0] = i8_ptr_ty;
455 arg_type_array[1] = i8_ptr_ty;
457 arg_type_array[3] = i32_ty;
458 arg_type_array[4] = i8_ty;
460 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
462 llvm::FunctionType *CFSCWB_ty =
463 FunctionType::get(ns_str_ty, CFSCWB_arg_types,
false);
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)};
473 ConstantDataSequential *string_array =
nullptr;
476 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
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) {
485 encoding_flags = 0x08000100;
488 encoding_flags = 0x0100;
491 encoding_flags = 0x0c000100;
494 encoding_flags = 0x0600;
495 LLDB_LOG(log,
"Encountered an Objective-C constant string with unusual "
497 string_array->getElementByteSize());
499 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags,
false);
500 Constant *isExternal_arg =
501 ConstantInt::get(i8_ty, 0x0,
false);
503 Value *argument_array[5];
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;
511 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
514 [
this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
515 return CallInst::Create(
517 "CFStringCreateWithBytes",
518 llvm::cast<Instruction>(
524 LLDB_LOG(log,
"Couldn't replace the NSString with the result of the call");
527 "Objective-C constant string with a dynamic "
533 ns_str->eraseFromParent();
541 ValueSymbolTable &value_symbol_table =
m_module->getValueSymbolTable();
543 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
544 llvm::StringRef value_name = value_symbol.first();
546 if (value_name.contains(
"_unnamed_cfstring_")) {
547 Value *nsstring_value = value_symbol.second;
549 GlobalVariable *nsstring_global =
550 dyn_cast<GlobalVariable>(nsstring_value);
552 if (!nsstring_global) {
553 LLDB_LOG(log,
"NSString variable is not a GlobalVariable");
556 "constant string is not a global variable\n");
561 if (!nsstring_global->hasInitializer()) {
562 LLDB_LOG(log,
"NSString variable does not have an initializer");
565 "constant string does not have an initializer\n");
570 ConstantStruct *nsstring_struct =
571 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
573 if (!nsstring_struct) {
575 "NSString variable's initializer is not a ConstantStruct");
578 "constant string is not a structure constant\n");
592 if (nsstring_struct->getNumOperands() != 4) {
595 "NSString variable's initializer structure has an "
596 "unexpected number of members. Should be 4, is {0}",
597 nsstring_struct->getNumOperands());
600 "Objective-C constant string is not as "
606 Constant *nsstring_member = nsstring_struct->getOperand(2);
608 if (!nsstring_member) {
609 LLDB_LOG(log,
"NSString initializer's str element was empty");
612 "constant string does not have a string "
618 auto *cstr_global = dyn_cast<GlobalVariable>(nsstring_member);
621 "NSString initializer's str element is not a GlobalVariable");
624 "constant string initializer\n");
629 if (!cstr_global->hasInitializer()) {
630 LLDB_LOG(log,
"NSString initializer's str element does not have an "
634 "constant string's string initializer doesn't "
635 "point to initialized data\n");
670 ConstantDataArray *cstr_array =
671 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
674 LLDB_LOG(log,
"Found NSString constant {0}, which contains \"{1}\"",
675 value_name, cstr_array->getAsString());
677 LLDB_LOG(log,
"Found NSString constant {0}, which contains \"\"",
681 cstr_global =
nullptr;
684 LLDB_LOG(log,
"Error rewriting the constant string");
694 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
695 llvm::StringRef value_name = value_symbol.first();
697 if (value_name ==
"__CFConstantStringClassReference") {
698 GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
702 "__CFConstantStringClassReference is not a global variable");
705 "CFConstantStringClassReference, but it is not a "
711 gv->eraseFromParent();
721 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
723 return !(!global_variable || !global_variable->hasName() ||
724 !global_variable->getName().startswith(
"OBJC_SELECTOR_REFERENCES_"));
731 LoadInst *load = dyn_cast<LoadInst>(selector_load);
750 GlobalVariable *_objc_selector_references_ =
751 dyn_cast<GlobalVariable>(load->getPointerOperand());
753 if (!_objc_selector_references_ ||
754 !_objc_selector_references_->hasInitializer())
757 Constant *osr_initializer = _objc_selector_references_->getInitializer();
758 if (!osr_initializer)
763 GlobalVariable *_objc_meth_var_name_ =
764 dyn_cast<GlobalVariable>(osr_initializer);
766 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
769 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
771 ConstantDataArray *omvn_initializer_array =
772 dyn_cast<ConstantDataArray>(omvn_initializer);
774 if (!omvn_initializer_array->isString())
777 std::string omvn_initializer_string =
778 std::string(omvn_initializer_array->getAsString());
780 LLDB_LOG(log,
"Found Objective-C selector reference \"{0}\"",
781 omvn_initializer_string);
788 bool missing_weak =
false;
795 LLDB_LOG(log,
"Found sel_registerName at {0}", sel_registerName_addr);
804 Type *sel_ptr_type = Type::getInt8PtrTy(
m_module->getContext());
808 type_array[0] = llvm::Type::getInt8PtrTy(
m_module->getContext());
810 ArrayRef<Type *> srN_arg_types(type_array, 1);
812 llvm::FunctionType *srN_type =
813 FunctionType::get(sel_ptr_type, srN_arg_types,
false);
816 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
817 Constant *srN_addr_int =
818 ConstantInt::get(
m_intptr_ty, sel_registerName_addr,
false);
820 ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
825 "sel_registerName", selector_load);
829 selector_load->replaceAllUsesWith(srN_call);
831 selector_load->eraseFromParent();
841 for (Instruction &inst : basic_block) {
842 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
844 selector_loads.push_back(&inst);
847 for (Instruction *inst : selector_loads) {
850 "static reference to an Objective-C selector to a "
851 "dynamic reference\n");
853 LLDB_LOG(log,
"Couldn't rewrite a reference to an Objective-C selector");
863 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
865 return !(!global_variable || !global_variable->hasName() ||
866 !global_variable->getName().startswith(
"OBJC_CLASS_REFERENCES_"));
873 LoadInst *load = dyn_cast<LoadInst>(class_load);
888 GlobalVariable *_objc_class_references_ =
889 dyn_cast<GlobalVariable>(load->getPointerOperand());
891 if (!_objc_class_references_ ||
892 !_objc_class_references_->hasInitializer())
897 GlobalVariable *_objc_class_name_ =
898 dyn_cast<GlobalVariable>(_objc_class_references_->getInitializer());
900 if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
903 Constant *ocn_initializer = _objc_class_name_->getInitializer();
905 ConstantDataArray *ocn_initializer_array =
906 dyn_cast<ConstantDataArray>(ocn_initializer);
908 if (!ocn_initializer_array->isString())
911 std::string ocn_initializer_string =
912 std::string(ocn_initializer_array->getAsString());
914 LLDB_LOG(log,
"Found Objective-C class reference \"{0}\"",
915 ocn_initializer_string);
922 bool missing_weak =
false;
929 LLDB_LOG(log,
"Found objc_getClass at {0}", objc_getClass_addr);
933 Type *class_type = load->getType();
935 type_array[0] = llvm::Type::getInt8PtrTy(
m_module->getContext());
937 ArrayRef<Type *> ogC_arg_types(type_array, 1);
939 llvm::FunctionType *ogC_type =
940 FunctionType::get(class_type, ogC_arg_types,
false);
943 PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
944 Constant *ogC_addr_int =
945 ConstantInt::get(
m_intptr_ty, objc_getClass_addr,
false);
947 ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
950 CallInst *ogC_call = CallInst::Create(
m_objc_getClass, _objc_class_name_,
951 "objc_getClass", class_load);
955 class_load->replaceAllUsesWith(ogC_call);
957 class_load->eraseFromParent();
967 for (Instruction &inst : basic_block) {
968 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
970 class_loads.push_back(&inst);
973 for (Instruction *inst : class_loads) {
976 "static reference to an Objective-C class to a "
977 "dynamic reference\n");
979 LLDB_LOG(log,
"Couldn't rewrite a reference to an Objective-C class");
992 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
994 MDNode *alloc_md = alloc->getMetadata(
"clang.decl.ptr");
996 if (!alloc_md || !alloc_md->getNumOperands())
999 ConstantInt *constant_int =
1000 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
1007 uintptr_t ptr = constant_int->getZExtValue();
1009 clang::VarDecl *decl =
reinterpret_cast<clang::VarDecl *
>(ptr);
1014 StringRef decl_name(decl->getName());
1018 result_decl_type,
false,
false))
1021 GlobalVariable *persistent_global =
new GlobalVariable(
1022 (*
m_module), alloc->getType(),
false,
1023 GlobalValue::ExternalLinkage,
nullptr,
1024 alloc->getName().str());
1029 NamedMDNode *named_metadata =
1030 m_module->getOrInsertNamedMetadata(
"clang.global.decl.ptrs");
1032 llvm::Metadata *values[2];
1033 values[0] = ConstantAsMetadata::get(persistent_global);
1034 values[1] = ConstantAsMetadata::get(constant_int);
1036 ArrayRef<llvm::Metadata *> value_ref(values, 2);
1038 MDNode *persistent_global_md = MDNode::get(
m_module->getContext(), value_ref);
1039 named_metadata->addOperand(persistent_global_md);
1044 LoadInst *persistent_load =
new LoadInst(persistent_global->getValueType(),
1045 persistent_global,
"", alloc);
1050 alloc->replaceAllUsesWith(persistent_load);
1051 alloc->eraseFromParent();
1064 for (Instruction &inst : basic_block) {
1066 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1067 llvm::StringRef alloc_name = alloc->getName();
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.");
1074 "$1, ... are reserved for use as result "
1080 pvar_allocs.push_back(alloc);
1085 for (Instruction *inst : pvar_allocs) {
1088 "the creation of a persistent variable\n");
1090 LLDB_LOG(log,
"Couldn't rewrite the creation of a persistent variable");
1105 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1106 switch (constant_expr->getOpcode()) {
1109 case Instruction::GetElementPtr:
1110 case Instruction::BitCast:
1111 Value *s = constant_expr->getOperand(0);
1115 }
else if (GlobalVariable *global_variable =
1116 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1117 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1120 clang::NamedDecl *named_decl =
DeclForGlobal(global_variable);
1126 if (!global_variable->hasExternalLinkage())
1129 LLDB_LOG(log,
"Found global variable \"{0}\" without metadata",
1130 global_variable->getName());
1135 llvm::StringRef name(named_decl->getName());
1137 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1138 if (value_decl ==
nullptr)
1144 const Type *value_type =
nullptr;
1146 if (name.startswith(
"$")) {
1158 value_type = PointerType::get(global_variable->getType(), 0);
1160 value_type = global_variable->getType();
1164 std::optional<uint64_t> value_size = compiler_type.
GetByteSize(target);
1167 std::optional<size_t> opt_alignment = compiler_type.
GetTypeBitAlign(target);
1173 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1177 PrintType(value_type), *value_size, value_alignment);
1181 llvm_value_ptr, *value_size,
1183 }
else if (isa<llvm::Function>(llvm_value_ptr)) {
1184 LLDB_LOG(log,
"Function pointers aren't handled right now");
1202 LLDB_LOG(log,
"Symbol \"{0}\" had no address", name);
1207 LLDB_LOG(log,
"Found \"{0}\" at {1}", name, symbol_addr);
1209 Type *symbol_type = symbol->getType();
1211 Constant *symbol_addr_int = ConstantInt::get(
m_intptr_ty, symbol_addr,
false);
1213 Value *symbol_addr_ptr =
1214 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1219 symbol->replaceAllUsesWith(symbol_addr_ptr);
1229 for (
unsigned op_index = 0, num_ops = Old->arg_size();
1230 op_index < num_ops; ++op_index)
1234 "one of the arguments of a function call.\n");
1245 GlobalVariable *global_variable =
1246 dyn_cast<GlobalVariable>(classlist_reference);
1248 if (!global_variable)
1251 Constant *initializer = global_variable->getInitializer();
1256 if (!initializer->hasName())
1259 StringRef name(initializer->getName());
1264 LLDB_LOG(log,
"Found reference to Objective-C class {0} ({1})", name,
1265 (
unsigned long long)class_ptr);
1270 if (global_variable->use_empty())
1273 SmallVector<LoadInst *, 2> load_instructions;
1275 for (llvm::User *u : global_variable->users()) {
1276 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1277 load_instructions.push_back(load_instruction);
1280 if (load_instructions.empty())
1283 Constant *class_addr = ConstantInt::get(
m_intptr_ty, (uint64_t)class_ptr);
1285 for (LoadInst *load_instruction : load_instructions) {
1286 Constant *class_bitcast =
1287 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1289 load_instruction->replaceAllUsesWith(class_bitcast);
1291 load_instruction->eraseFromParent();
1298 std::vector<CallInst *> calls_to_remove;
1300 for (Instruction &inst : basic_block) {
1301 CallInst *call = dyn_cast<CallInst>(&inst);
1307 bool remove =
false;
1309 llvm::Function *func = call->getCalledFunction();
1311 if (func && func->getName() ==
"__cxa_atexit")
1314 llvm::Value *val = call->getCalledOperand();
1316 if (val && val->getName() ==
"__cxa_atexit")
1320 calls_to_remove.push_back(call);
1323 for (CallInst *ci : calls_to_remove)
1324 ci->eraseFromParent();
1332 for (Instruction &inst : basic_block) {
1333 CallInst *call = dyn_cast<CallInst>(&inst);
1346 for (GlobalVariable &global_var :
m_module->globals()) {
1347 llvm::StringRef global_name = global_var.getName();
1349 LLDB_LOG(log,
"Examining {0}, DeclForGlobalValue returns {1}", global_name,
1352 if (global_name.startswith(
"OBJC_IVAR")) {
1355 "indirect ivar symbol {0}\n",
1360 }
else if (global_name.contains(
"OBJC_CLASSLIST_REFERENCES_$")) {
1363 "for an Objective-C static method call\n");
1367 }
else if (global_name.contains(
"OBJC_CLASSLIST_SUP_REFS_$")) {
1370 "for an Objective-C static method call\n");
1377 "external variable {0}\n",
1389 GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
1398 Constant *zero(Constant::getNullValue(guard_load->getType()));
1399 guard_load->replaceAllUsesWith(zero);
1400 guard_load->eraseFromParent();
1404 guard_store->eraseFromParent();
1413 for (Instruction &inst : basic_block) {
1415 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1417 guard_loads.push_back(&inst);
1419 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1421 guard_stores.push_back(&inst);
1424 for (Instruction *inst : guard_loads)
1427 for (Instruction *inst : guard_stores)
1435 llvm::Function *llvm_function,
1439 SmallVector<User *, 16> users;
1443 for (llvm::User *u : old_constant->users())
1446 for (
size_t i = 0; i < users.size(); ++i) {
1447 User *user = users[i];
1449 if (Constant *constant = dyn_cast<Constant>(user)) {
1452 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1453 switch (constant_expr->getOpcode()) {
1455 error_stream.
Printf(
"error [IRForTarget internal]: Unhandled "
1456 "constant expression type: \"%s\"",
1459 case Instruction::BitCast: {
1461 [&value_maker, &entry_instruction_finder, old_constant,
1462 constant_expr](llvm::Function *function) -> llvm::Value * {
1466 if (constant_expr->getOperand(0) != old_constant)
1467 return constant_expr;
1469 return new BitCastInst(
1470 value_maker.
GetValue(function), constant_expr->getType(),
1471 "", llvm::cast<Instruction>(
1472 entry_instruction_finder.
GetValue(function)));
1475 if (!
UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1476 entry_instruction_finder, error_stream))
1479 case Instruction::GetElementPtr: {
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();
1490 if (ptr == old_constant)
1491 ptr = value_maker.
GetValue(function);
1493 std::vector<Value *> index_vector;
1494 for (Value *operand : gep->indices()) {
1495 if (operand == old_constant)
1496 operand = value_maker.
GetValue(function);
1498 index_vector.push_back(operand);
1501 ArrayRef<Value *> indices(index_vector);
1503 return GetElementPtrInst::Create(
1504 gep->getSourceElementType(), ptr, indices,
"",
1505 llvm::cast<Instruction>(
1506 entry_instruction_finder.
GetValue(function)));
1510 get_element_pointer_maker,
1511 entry_instruction_finder, error_stream))
1517 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
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");
1528 inst->replaceUsesOfWith(
1529 old_constant, value_maker.
GetValue(inst->getParent()->getParent()));
1532 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1539 if (!isa<GlobalValue>(old_constant)) {
1540 old_constant->destroyConstant();
1554 LLDB_LOG(log,
"Element arrangement:");
1565 Function::arg_iterator iter(llvm_function.arg_begin());
1567 if (iter == llvm_function.arg_end()) {
1569 "arguments (should take at least a struct pointer)");
1574 Argument *argument = &*iter;
1576 if (argument->getName().equals(
"this")) {
1579 if (iter == llvm_function.arg_end()) {
1581 "'this' argument (should take a struct pointer "
1588 }
else if (argument->getName().equals(
"self")) {
1591 if (iter == llvm_function.arg_end()) {
1593 "'self' argument (should take '_cmd' and a struct "
1599 if (!iter->getName().equals(
"_cmd")) {
1601 "after 'self' argument (should take '_cmd')",
1609 if (iter == llvm_function.arg_end()) {
1611 "'self' and '_cmd' arguments (should take a struct "
1620 if (!argument->getName().equals(
"$__lldb_arg")) {
1622 "argument named '{0}' instead of the struct pointer",
1623 argument->getName());
1630 BasicBlock &entry_block(llvm_function.getEntryBlock());
1631 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1633 if (!FirstEntryInstruction) {
1635 "first instruction in the wrapper for use in "
1641 LLVMContext &context(
m_module->getContext());
1642 IntegerType *offset_type(Type::getInt32Ty(context));
1646 "Internal error [IRForTarget]: Couldn't produce an offset type");
1651 for (element_index = 0; element_index < num_elements; ++element_index) {
1652 const clang::NamedDecl *decl =
nullptr;
1653 Value *value =
nullptr;
1660 "Internal error [IRForTarget]: Structure information is incomplete");
1665 LLDB_LOG(log,
" \"{0}\" (\"{1}\") placed at {2}", name,
1666 decl->getNameAsString(), offset);
1672 [
this, name, offset_type, offset, argument,
1673 value](llvm::Function *function) -> llvm::Value * {
1680 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
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);
1690 LoadInst *load =
new LoadInst(value->getType(), get_element_ptr,
1691 "", entry_instruction);
1695 return get_element_ptr;
1699 if (Constant *constant = dyn_cast<Constant>(value)) {
1704 }
else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1705 if (instruction->getParent()->getParent() != &llvm_function) {
1707 "expressions is unsupported.\n");
1710 value->replaceAllUsesWith(
1711 body_result_maker.GetValue(instruction->getParent()->getParent()));
1713 LLDB_LOG(log,
"Unhandled non-constant type: \"{0}\"",
1718 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1719 var->eraseFromParent();
1723 LLDB_LOG(log,
"Total structure [align {0}, size {1}]", (int64_t)alignment,
1739 raw_string_ostream oss(s);
1745 LLDB_LOG(log,
"Module as passed in to IRForTarget: \n\"{0}\"", s);
1748 Function *
const main_function =
1756 "'{0}' in the module",
1762 if (main_function) {
1764 LLDB_LOG(log,
"Couldn't fix the linkage for the function");
1770 llvm::Type *int8_ty = Type::getInt8Ty(
m_module->getContext());
1774 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
1775 "reloc_placeholder",
nullptr ,
1776 GlobalVariable::NotThreadLocal , 0 );
1782 if (main_function) {
1784 LLDB_LOG(log,
"CreateResultVariable() failed");
1794 raw_string_ostream oss(s);
1800 LLDB_LOG(log,
"Module after creating the result variable: \n\"{0}\"", s);
1803 for (llvm::Function &function : *
m_module) {
1804 for (BasicBlock &bb : function) {
1806 LLDB_LOG(log,
"RemoveGuards() failed");
1814 LLDB_LOG(log,
"RewritePersistentAllocs() failed");
1823 LLDB_LOG(log,
"RemoveCXAAtExit() failed");
1837 LLDB_LOG(log,
"RewriteObjCConstStrings() failed");
1844 for (llvm::Function &function : *
m_module) {
1845 for (llvm::BasicBlock &bb : function) {
1847 LLDB_LOG(log,
"RewriteObjCSelectors() failed");
1856 LLDB_LOG(log,
"RewriteObjCClassReferences() failed");
1865 for (llvm::Function &function : *
m_module) {
1866 for (BasicBlock &bb : function) {
1868 LLDB_LOG(log,
"ResolveCalls() failed");
1881 if (main_function) {
1883 LLDB_LOG(log,
"ResolveExternals() failed");
1891 LLDB_LOG(log,
"ReplaceVariables() failed");
1901 raw_string_ostream oss(s);
1907 LLDB_LOG(log,
"Module after preparing for execution: \n\"{0}\"", s);
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 bool IsObjCClassReference(Value *value)
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.
FunctionValueCache(Maker const &maker)
llvm::Value * GetValue(llvm::Function *function)
std::function< llvm::Value *(llvm::Function *)> Maker
std::unique_ptr< llvm::DataLayout > m_target_data
The target data for the module being processed, or NULL if there is no module.
llvm::FunctionCallee m_objc_getClass
The address of the function objc_getClass, cast to the appropriate function pointer type.
lldb_private::ConstString m_func_name
The name of the function to translate.
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.
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 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.
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.
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.
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 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
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].
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.
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.
bool IsEmpty() const
Test for empty string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
"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()
const char * GetData() const
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
CompilerType GetType(clang::QualType qt)
Creates a CompilerType from the given QualType with the current TypeSystemClang instance as the Compi...
#define LLDB_INVALID_ADDRESS
TaggedASTType< 0 > TypeFromParser
static clang::QualType GetQualType(const CompilerType &ct)