16#include "llvm/IR/Constants.h"
17#include "llvm/IR/DataLayout.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/Operator.h"
25#include "llvm/IR/ValueSymbolTable.h"
26#include "llvm/Support/ErrorExtras.h"
27#include "llvm/Support/raw_ostream.h"
28#include "llvm/Transforms/IPO.h"
30#include "clang/AST/ASTContext.h"
60 llvm::Value *ret =
m_maker(function);
68 if (function->empty())
71 return &*function->getEntryBlock().getFirstNonPHIOrPseudoProbe();
79 const char *func_name)
91 raw_string_ostream rso(s);
96static std::string
PrintType(
const llvm::Type *type) {
100 raw_string_ostream rso(s);
106 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
113 NamedMDNode *named_metadata =
114 module->getNamedMetadata("clang.global.decl.ptrs");
119 unsigned num_nodes = named_metadata->getNumOperands();
122 for (node_index = 0; node_index < num_nodes; ++node_index) {
123 llvm::MDNode *metadata_node =
124 dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
128 if (metadata_node->getNumOperands() != 2)
131 if (mdconst::dyn_extract_or_null<GlobalValue>(
132 metadata_node->getOperand(0)) != global_val)
135 ConstantInt *constant_int =
136 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
141 uintptr_t ptr = constant_int->getZExtValue();
143 return reinterpret_cast<clang::NamedDecl *
>(ptr);
155 bool check_ms_abi =
true) {
157 mangled_symbol.starts_with(
"_ZGV");
159 result |= mangled_symbol.ends_with(
"@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();
185 if (!isa<GlobalVariable>(value_symbol.second))
188 if (result_name.contains(
"$__lldb_expr_result_ptr") && !is_guard_var) {
194 if (result_name.contains(
"$__lldb_expr_result") && !is_guard_var) {
202 LLDB_LOG(log,
"Couldn't find result variable");
207 LLDB_LOG(log,
"Result name: \"{0}\"", result_name);
209 Value *result_value =
m_module->getNamedValue(result_name);
212 LLDB_LOG(log,
"Result variable had no data");
214 m_error_stream.Format(
"Internal error [IRForTarget]: Result variable's "
215 "name ({0}) exists, but not its definition\n",
223 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
225 if (!result_global) {
226 LLDB_LOG(log,
"Result variable isn't a GlobalVariable");
228 m_error_stream.Format(
"Internal error [IRForTarget]: Result variable ({0}) "
229 "is defined, but is not a global variable\n",
235 clang::NamedDecl *result_decl =
DeclForGlobal(result_global);
237 LLDB_LOG(log,
"Result variable doesn't have a corresponding Decl");
239 m_error_stream.Format(
"Internal error [IRForTarget]: Result variable ({0}) "
240 "does not have a corresponding Clang entity\n",
247 std::string decl_desc_str;
248 raw_string_ostream decl_desc_stream(decl_desc_str);
249 result_decl->print(decl_desc_stream);
251 LLDB_LOG(log,
"Found result decl: \"{0}\"", decl_desc_str);
254 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
256 LLDB_LOG(log,
"Result variable Decl isn't a VarDecl");
258 m_error_stream.Format(
"Internal error [IRForTarget]: Result variable "
259 "({0})'s corresponding Clang entity isn't a "
272 clang::QualType pointer_qual_type = result_var->getType();
273 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
275 const clang::PointerType *pointer_pointertype =
276 pointer_type->getAs<clang::PointerType>();
277 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
278 pointer_type->getAs<clang::ObjCObjectPointerType>();
280 if (pointer_pointertype) {
281 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
284 m_decl_map->GetTypeSystem()->GetType(element_qual_type));
285 }
else if (pointer_objcobjpointertype) {
286 clang::QualType element_qual_type =
287 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
290 m_decl_map->GetTypeSystem()->GetType(element_qual_type));
292 LLDB_LOG(log,
"Expected result to have pointer type, but it did not");
294 m_error_stream.Format(
"Internal error [IRForTarget]: Lvalue result ({0}) "
295 "is not a pointer variable\n",
302 m_decl_map->GetTypeSystem()->GetType(result_var->getType()));
306 auto bit_size_or_err =
m_result_type.GetBitSize(target_sp.get());
307 if (!bit_size_or_err) {
311 LLDB_LOG(log,
"Result type has unknown size");
313 m_error_stream.Printf(
"Error [IRForTarget]: Size of result type '%s' "
314 "couldn't be determined\n%s",
316 llvm::toString(bit_size_or_err.takeError()).c_str());
324 LLDB_LOG(log,
"Result decl type: \"{0}\"", type_desc_stream.
GetData());
329 LLDB_LOG(log,
"Creating a new result global: \"{0}\" with size {1}",
331 llvm::expectedToOptional(
m_result_type.GetByteSize(target_sp.get()))
336 GlobalVariable *new_result_global =
new GlobalVariable(
337 (*
m_module), result_global->getValueType(),
false,
338 GlobalValue::ExternalLinkage,
nullptr,
348 ConstantInt *new_constant_int =
349 ConstantInt::get(llvm::Type::getInt64Ty(
m_module->getContext()),
350 reinterpret_cast<uintptr_t
>(result_decl),
false);
352 llvm::Metadata *values[2];
353 values[0] = ConstantAsMetadata::get(new_result_global);
354 values[1] = ConstantAsMetadata::get(new_constant_int);
356 ArrayRef<Metadata *> value_ref(values, 2);
358 MDNode *persistent_global_md = MDNode::get(
m_module->getContext(), value_ref);
359 NamedMDNode *named_metadata =
360 m_module->getNamedMetadata(
"clang.global.decl.ptrs");
361 named_metadata->addOperand(persistent_global_md);
366 if (result_global->use_empty()) {
370 BasicBlock &entry_block(llvm_function.getEntryBlock());
371 Instruction *first_entry_instruction(
372 &*entry_block.getFirstNonPHIOrPseudoProbe());
374 if (!first_entry_instruction)
377 if (!result_global->hasInitializer()) {
378 LLDB_LOG(log,
"Couldn't find initializer for unused variable");
380 m_error_stream.Format(
"Internal error [IRForTarget]: Result variable "
381 "({0}) has no writes and no initializer\n",
387 Constant *initializer = result_global->getInitializer();
389 StoreInst *synthesized_store =
new StoreInst(
390 initializer, new_result_global, first_entry_instruction->getIterator());
392 LLDB_LOG(log,
"Synthesized result store \"{0}\"\n",
395 result_global->replaceAllUsesWith(new_result_global);
402 result_global->eraseFromParent();
408 llvm::GlobalVariable *cstr) {
411 Type *ns_str_ty = ns_str->getType();
413 Type *i8_ptr_ty = PointerType::getUnqual(
m_module->getContext());
414 Type *i32_ty = Type::getInt32Ty(
m_module->getContext());
415 Type *i8_ty = Type::getInt8Ty(
m_module->getContext());
421 "CFStringCreateWithBytes");
423 bool missing_weak =
false;
425 g_CFStringCreateWithBytes_str, missing_weak);
427 LLDB_LOG(log,
"Couldn't find CFStringCreateWithBytes in the target");
429 m_error_stream.Printf(
"Error [IRForTarget]: Rewriting an Objective-C "
430 "constant string requires "
431 "CFStringCreateWithBytes\n");
436 LLDB_LOG(log,
"Found CFStringCreateWithBytes at {0:x}",
437 CFStringCreateWithBytes_addr);
457 Type *arg_type_array[5];
459 arg_type_array[0] = i8_ptr_ty;
460 arg_type_array[1] = i8_ptr_ty;
462 arg_type_array[3] = i32_ty;
463 arg_type_array[4] = i8_ty;
465 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
467 llvm::FunctionType *CFSCWB_ty =
468 FunctionType::get(ns_str_ty, CFSCWB_arg_types,
false);
471 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(
m_module->getContext());
472 Constant *CFSCWB_addr_int =
473 ConstantInt::get(
m_intptr_ty, CFStringCreateWithBytes_addr,
false);
475 CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};
478 ConstantDataSequential *string_array =
nullptr;
481 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
483 Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
484 Constant *bytes_arg = cstr ? cstr : Constant::getNullValue(i8_ptr_ty);
485 Constant *numBytes_arg = ConstantInt::get(
486 m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0,
false);
487 int encoding_flags = 0;
488 switch (cstr ? string_array->getElementByteSize() : 1) {
490 encoding_flags = 0x08000100;
493 encoding_flags = 0x0100;
496 encoding_flags = 0x0c000100;
499 encoding_flags = 0x0600;
500 LLDB_LOG(log,
"Encountered an Objective-C constant string with unusual "
502 string_array->getElementByteSize());
504 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags,
false);
505 Constant *isExternal_arg =
506 ConstantInt::get(i8_ty, 0x0,
false);
508 Value *argument_array[5];
510 argument_array[0] = alloc_arg;
511 argument_array[1] = bytes_arg;
512 argument_array[2] = numBytes_arg;
513 argument_array[3] = encoding_arg;
514 argument_array[4] = isExternal_arg;
516 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
519 [
this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
520 return CallInst::Create(
522 "CFStringCreateWithBytes",
523 llvm::cast<Instruction>(
530 std::string error_msg = llvm::toString(std::move(err));
532 "Couldn't replace the NSString with the result of the call: {0}",
535 m_error_stream.Format(
"error [IRForTarget internal]: Couldn't replace an "
536 "Objective-C constant string with a dynamic "
543 ns_str->eraseFromParent();
551 ValueSymbolTable &value_symbol_table =
m_module->getValueSymbolTable();
553 std::vector<std::pair<GlobalVariable *, GlobalVariable *>>
554 nsstring_to_cstr_list;
556 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
557 llvm::StringRef value_name = value_symbol.first();
559 if (value_name.contains(
"_unnamed_cfstring_")) {
560 Value *nsstring_value = value_symbol.second;
562 GlobalVariable *nsstring_global =
563 dyn_cast<GlobalVariable>(nsstring_value);
565 if (!nsstring_global) {
566 LLDB_LOG(log,
"NSString variable is not a GlobalVariable");
568 m_error_stream.Printf(
"Internal error [IRForTarget]: An Objective-C "
569 "constant string is not a global variable\n");
574 if (!nsstring_global->hasInitializer()) {
575 LLDB_LOG(log,
"NSString variable does not have an initializer");
577 m_error_stream.Printf(
"Internal error [IRForTarget]: An Objective-C "
578 "constant string does not have an initializer\n");
583 ConstantStruct *nsstring_struct =
584 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
586 if (!nsstring_struct) {
588 "NSString variable's initializer is not a ConstantStruct");
590 m_error_stream.Printf(
"Internal error [IRForTarget]: An Objective-C "
591 "constant string is not a structure constant\n");
605 if (nsstring_struct->getNumOperands() != 4) {
608 "NSString variable's initializer structure has an "
609 "unexpected number of members. Should be 4, is {0}",
610 nsstring_struct->getNumOperands());
612 m_error_stream.Printf(
"Internal error [IRForTarget]: The struct for an "
613 "Objective-C constant string is not as "
619 Constant *nsstring_member = nsstring_struct->getOperand(2);
621 if (!nsstring_member) {
622 LLDB_LOG(log,
"NSString initializer's str element was empty");
624 m_error_stream.Printf(
"Internal error [IRForTarget]: An Objective-C "
625 "constant string does not have a string "
631 auto *cstr_global = dyn_cast<GlobalVariable>(nsstring_member);
634 "NSString initializer's str element is not a GlobalVariable");
637 "constant string initializer\n");
642 if (!cstr_global->hasInitializer()) {
643 LLDB_LOG(log,
"NSString initializer's str element does not have an "
646 m_error_stream.Printf(
"Internal error [IRForTarget]: An Objective-C "
647 "constant string's string initializer doesn't "
648 "point to initialized data\n");
683 ConstantDataArray *cstr_array =
684 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
687 LLDB_LOG(log,
"Found NSString constant {0}, which contains \"{1}\"",
688 value_name, cstr_array->getAsString());
690 LLDB_LOG(log,
"Found NSString constant {0}, which contains \"\"",
694 cstr_global =
nullptr;
698 nsstring_to_cstr_list.emplace_back(nsstring_global, cstr_global);
702 for (
auto [nsstring_global, cstr_global] : nsstring_to_cstr_list) {
704 LLDB_LOG(log,
"Error rewriting the constant string");
709 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
710 llvm::StringRef value_name = value_symbol.first();
712 if (value_name ==
"__CFConstantStringClassReference") {
713 GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
717 "__CFConstantStringClassReference is not a global variable");
720 "CFConstantStringClassReference, but it is not a "
726 gv->eraseFromParent();
736 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
739 !global_variable || !global_variable->hasName() ||
740 !global_variable->getName().starts_with(
"OBJC_SELECTOR_REFERENCES_"));
747 LoadInst *load = dyn_cast<LoadInst>(selector_load);
766 GlobalVariable *_objc_selector_references_ =
767 dyn_cast<GlobalVariable>(load->getPointerOperand());
769 if (!_objc_selector_references_ ||
770 !_objc_selector_references_->hasInitializer())
773 Constant *osr_initializer = _objc_selector_references_->getInitializer();
774 if (!osr_initializer)
779 GlobalVariable *_objc_meth_var_name_ =
780 dyn_cast<GlobalVariable>(osr_initializer);
782 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
785 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
787 ConstantDataArray *omvn_initializer_array =
788 dyn_cast<ConstantDataArray>(omvn_initializer);
790 if (!omvn_initializer_array->isString())
793 std::string omvn_initializer_string =
794 std::string(omvn_initializer_array->getAsString());
796 LLDB_LOG(log,
"Found Objective-C selector reference \"{0}\"",
797 omvn_initializer_string);
804 bool missing_weak =
false;
811 LLDB_LOG(log,
"Found sel_registerName at {0:x}", sel_registerName_addr);
820 Type *sel_ptr_type = PointerType::getUnqual(
m_module->getContext());
824 type_array[0] = llvm::PointerType::getUnqual(
m_module->getContext());
826 ArrayRef<Type *> srN_arg_types(type_array, 1);
828 llvm::FunctionType *srN_type =
829 FunctionType::get(sel_ptr_type, srN_arg_types,
false);
832 PointerType *srN_ptr_ty = PointerType::getUnqual(
m_module->getContext());
833 Constant *srN_addr_int =
834 ConstantInt::get(
m_intptr_ty, sel_registerName_addr,
false);
836 ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
841 "sel_registerName", selector_load->getIterator());
845 selector_load->replaceAllUsesWith(srN_call);
847 selector_load->eraseFromParent();
857 for (Instruction &inst : basic_block) {
858 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
860 selector_loads.push_back(&inst);
863 for (Instruction *inst : selector_loads) {
865 m_error_stream.Printf(
"Internal error [IRForTarget]: Couldn't change a "
866 "static reference to an Objective-C selector to a "
867 "dynamic reference\n");
869 LLDB_LOG(log,
"Couldn't rewrite a reference to an Objective-C selector");
882 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
884 MDNode *alloc_md = alloc->getMetadata(
"clang.decl.ptr");
886 if (!alloc_md || !alloc_md->getNumOperands())
889 ConstantInt *constant_int =
890 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
897 uintptr_t ptr = constant_int->getZExtValue();
899 clang::VarDecl *decl =
reinterpret_cast<clang::VarDecl *
>(ptr);
902 m_decl_map->GetTypeSystem()->GetType(decl->getType()));
904 StringRef decl_name(decl->getName());
906 if (!
m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
907 result_decl_type,
false,
false))
910 GlobalVariable *persistent_global =
new GlobalVariable(
911 (*
m_module), alloc->getType(),
false,
912 GlobalValue::ExternalLinkage,
nullptr,
913 alloc->getName().str());
918 NamedMDNode *named_metadata =
919 m_module->getOrInsertNamedMetadata(
"clang.global.decl.ptrs");
921 llvm::Metadata *values[2];
922 values[0] = ConstantAsMetadata::get(persistent_global);
923 values[1] = ConstantAsMetadata::get(constant_int);
925 ArrayRef<llvm::Metadata *> value_ref(values, 2);
927 MDNode *persistent_global_md = MDNode::get(
m_module->getContext(), value_ref);
928 named_metadata->addOperand(persistent_global_md);
933 LoadInst *persistent_load =
934 new LoadInst(persistent_global->getValueType(), persistent_global,
"",
935 alloc->getIterator());
940 alloc->replaceAllUsesWith(persistent_load);
941 alloc->eraseFromParent();
954 for (Instruction &inst : basic_block) {
956 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
957 llvm::StringRef alloc_name = alloc->getName();
959 if (alloc_name.starts_with(
"$") && !alloc_name.starts_with(
"$__lldb")) {
960 if (alloc_name.find_first_of(
"0123456789") == 1) {
961 LLDB_LOG(log,
"Rejecting a numeric persistent variable.");
963 m_error_stream.Printf(
"Error [IRForTarget]: Names starting with $0, "
964 "$1, ... are reserved for use as result "
970 pvar_allocs.push_back(alloc);
975 for (Instruction *inst : pvar_allocs) {
977 m_error_stream.Printf(
"Internal error [IRForTarget]: Couldn't rewrite "
978 "the creation of a persistent variable\n");
980 LLDB_LOG(log,
"Couldn't rewrite the creation of a persistent variable");
995 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
996 switch (constant_expr->getOpcode()) {
999 case Instruction::GetElementPtr:
1000 case Instruction::BitCast:
1001 Value *s = constant_expr->getOperand(0);
1005 }
else if (GlobalVariable *global_variable =
1006 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1007 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1010 clang::NamedDecl *named_decl =
DeclForGlobal(global_variable);
1016 if (!global_variable->hasExternalLinkage())
1019 LLDB_LOG(log,
"Found global variable \"{0}\" without metadata",
1020 global_variable->getName());
1025 llvm::StringRef name(named_decl->getName());
1027 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1028 if (value_decl ==
nullptr)
1032 m_decl_map->GetTypeSystem()->GetType(value_decl->getType());
1034 const Type *value_type =
nullptr;
1036 if (name.starts_with(
"$")) {
1048 value_type = PointerType::getUnqual(global_variable->getContext());
1050 value_type = global_variable->getType();
1054 std::optional<uint64_t> value_size =
1055 llvm::expectedToOptional(compiler_type.
GetByteSize(target));
1058 std::optional<size_t> opt_alignment = compiler_type.
GetTypeBitAlign(target);
1064 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1068 PrintType(value_type), *value_size, value_alignment);
1072 llvm_value_ptr, *value_size,
1074 }
else if (isa<llvm::Function>(llvm_value_ptr)) {
1075 LLDB_LOG(log,
"Function pointers aren't handled right now");
1093 LLDB_LOG(log,
"Symbol \"{0}\" had no address", name);
1098 LLDB_LOG(log,
"Found \"{0}\" at {1:x}", name, symbol_addr);
1100 Type *symbol_type = symbol->getType();
1102 Constant *symbol_addr_int = ConstantInt::get(
m_intptr_ty, symbol_addr,
false);
1104 Value *symbol_addr_ptr =
1105 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1110 symbol->replaceAllUsesWith(symbol_addr_ptr);
1120 for (
unsigned op_index = 0, num_ops = Old->arg_size();
1121 op_index < num_ops; ++op_index)
1124 m_error_stream.Printf(
"Internal error [IRForTarget]: Couldn't rewrite "
1125 "one of the arguments of a function call.\n");
1136 GlobalVariable *global_variable =
1137 dyn_cast<GlobalVariable>(classlist_reference);
1139 if (!global_variable)
1142 Constant *initializer = global_variable->getInitializer();
1147 if (!initializer->hasName())
1150 StringRef name(initializer->getName());
1155 LLDB_LOG(log,
"Found reference to Objective-C class {0} ({1:x})", name,
1156 (
unsigned long long)class_ptr);
1161 if (global_variable->use_empty())
1164 SmallVector<LoadInst *, 2> load_instructions;
1166 for (llvm::User *u : global_variable->users()) {
1167 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1168 load_instructions.push_back(load_instruction);
1171 if (load_instructions.empty())
1174 Constant *class_addr = ConstantInt::get(
m_intptr_ty, (uint64_t)class_ptr);
1176 for (LoadInst *load_instruction : load_instructions) {
1177 Constant *class_bitcast =
1178 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1180 load_instruction->replaceAllUsesWith(class_bitcast);
1182 load_instruction->eraseFromParent();
1189 std::vector<CallInst *> calls_to_remove;
1190 llvm::SmallVector<llvm::Function *, 2> dead_atexit_callbacks;
1192 for (Instruction &inst : basic_block) {
1193 CallInst *call = dyn_cast<CallInst>(&inst);
1199 bool remove =
false;
1201 llvm::Function *func = call->getCalledFunction();
1205 (func->getName() ==
"__cxa_atexit" || func->getName() ==
"atexit"))
1208 llvm::Value *val = call->getCalledOperand();
1210 if (val && (val->getName() ==
"__cxa_atexit" || val->getName() ==
"atexit"))
1216 if (call->arg_size() > 0)
1217 if (
auto *cb = dyn_cast<llvm::Function>(
1218 call->getArgOperand(0)->stripPointerCasts()))
1219 if (cb->hasInternalLinkage() && cb->getName().starts_with(
"??__F"))
1220 dead_atexit_callbacks.push_back(cb);
1221 calls_to_remove.push_back(call);
1225 for (CallInst *ci : calls_to_remove)
1226 ci->eraseFromParent();
1230 for (llvm::Function *cb : dead_atexit_callbacks) {
1231 if (!cb->use_empty())
1234 llvm::BasicBlock *entry =
1235 llvm::BasicBlock::Create(cb->getContext(),
"", cb);
1236 llvm::ReturnInst::Create(cb->getContext(), entry);
1245 for (Instruction &inst : basic_block) {
1246 CallInst *call = dyn_cast<CallInst>(&inst);
1259 for (GlobalVariable &global_var :
m_module->globals()) {
1260 llvm::StringRef global_name = global_var.getName();
1262 LLDB_LOG(log,
"Examining {0}, DeclForGlobalValue returns {1}", global_name,
1265 if (global_name.starts_with(
"OBJC_IVAR")) {
1267 m_error_stream.Format(
"Error [IRForTarget]: Couldn't find Objective-C "
1268 "indirect ivar symbol {0}\n",
1273 }
else if (global_name.contains(
"OBJC_CLASSLIST_REFERENCES_$")) {
1275 m_error_stream.Printf(
"Error [IRForTarget]: Couldn't resolve the class "
1276 "for an Objective-C static method call\n");
1280 }
else if (global_name.contains(
"OBJC_CLASSLIST_SUP_REFS_$")) {
1282 m_error_stream.Printf(
"Error [IRForTarget]: Couldn't resolve the class "
1283 "for an Objective-C static method call\n");
1289 m_error_stream.Format(
"Internal error [IRForTarget]: Couldn't rewrite "
1290 "external variable {0}\n",
1302 GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
1311 Constant *zero(Constant::getNullValue(guard_load->getType()));
1312 guard_load->replaceAllUsesWith(zero);
1313 guard_load->eraseFromParent();
1317 guard_store->eraseFromParent();
1326 for (Instruction &inst : basic_block) {
1328 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1330 guard_loads.push_back(&inst);
1332 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1334 guard_stores.push_back(&inst);
1337 for (Instruction *inst : guard_loads)
1340 for (Instruction *inst : guard_stores)
1348 llvm::Function *llvm_function,
1352 SmallVector<User *, 16> users;
1356 for (llvm::User *u : old_constant->users())
1359 for (User *user : users) {
1360 if (Constant *constant = dyn_cast<Constant>(user)) {
1363 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1364 switch (constant_expr->getOpcode()) {
1366 return llvm::createStringErrorV(
1367 "unhandled constant expression type: \"{0}\".",
1370 case Instruction::BitCast: {
1372 [&value_maker, &entry_instruction_finder, old_constant,
1373 constant_expr](llvm::Function *function) -> llvm::Value * {
1377 if (constant_expr->getOperand(0) != old_constant)
1378 return constant_expr;
1380 return new BitCastInst(
1381 value_maker.
GetValue(function), constant_expr->getType(),
1383 llvm::cast<Instruction>(
1384 entry_instruction_finder.
GetValue(function))
1390 entry_instruction_finder, error_stream))
1393 case Instruction::GetElementPtr: {
1399 [&value_maker, &entry_instruction_finder, old_constant,
1400 constant_expr](llvm::Function *function) -> llvm::Value * {
1401 auto *gep = cast<llvm::GEPOperator>(constant_expr);
1402 Value *ptr = gep->getPointerOperand();
1404 if (ptr == old_constant)
1405 ptr = value_maker.
GetValue(function);
1407 std::vector<Value *> index_vector;
1408 for (Value *operand : gep->indices()) {
1409 if (operand == old_constant)
1410 operand = value_maker.
GetValue(function);
1412 index_vector.push_back(operand);
1415 ArrayRef<Value *> indices(index_vector);
1417 return GetElementPtrInst::Create(
1418 gep->getSourceElementType(), ptr, indices,
"",
1419 llvm::cast<Instruction>(
1420 entry_instruction_finder.
GetValue(function))
1425 get_element_pointer_maker,
1426 entry_instruction_finder, error_stream))
1430 }
else if (ConstantPtrAuth *constant_ptr_auth =
1431 dyn_cast<ConstantPtrAuth>(constant)) {
1434 if (constant_ptr_auth->hasAddressDiscriminator() &&
1435 constant_ptr_auth->getAddrDiscriminator() == old_constant)
1438 return llvm::createStringErrorV(
"unhandled constant type \"{0}\".",
1441 return llvm::createStringErrorV(
"unhandled constant type \"{0}\".",
1444 }
else if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1445 if (llvm_function && inst->getParent()->getParent() != llvm_function)
1446 return llvm::createStringError(
1447 "capturing non-local variables in expressions is unsupported.");
1449 inst->replaceUsesOfWith(
1450 old_constant, value_maker.
GetValue(inst->getParent()->getParent()));
1452 return llvm::createStringErrorV(
"unhandled non-constant type: \"{0}\".",
1457 if (!isa<GlobalValue>(old_constant)) {
1458 old_constant->destroyConstant();
1461 return llvm::Error::success();
1472 LLDB_LOG(log,
"Element arrangement:");
1474 uint32_t num_elements;
1475 uint32_t element_index;
1480 if (!
m_decl_map->GetStructInfo(num_elements, size, alignment))
1483 Function::arg_iterator iter(llvm_function.arg_begin());
1485 if (iter == llvm_function.arg_end()) {
1486 m_error_stream.Printf(
"Internal error [IRForTarget]: Wrapper takes no "
1487 "arguments (should take at least a struct pointer)");
1492 Argument *argument = &*iter;
1494 if (argument->getName() ==
"this") {
1497 if (iter == llvm_function.arg_end()) {
1498 m_error_stream.Printf(
"Internal error [IRForTarget]: Wrapper takes only "
1499 "'this' argument (should take a struct pointer "
1506 }
else if (argument->getName() ==
"self") {
1509 if (iter == llvm_function.arg_end()) {
1510 m_error_stream.Printf(
"Internal error [IRForTarget]: Wrapper takes only "
1511 "'self' argument (should take '_cmd' and a struct "
1517 if (iter->getName() !=
"_cmd") {
1518 m_error_stream.Format(
"Internal error [IRForTarget]: Wrapper takes '{0}' "
1519 "after 'self' argument (should take '_cmd')",
1527 if (iter == llvm_function.arg_end()) {
1528 m_error_stream.Printf(
"Internal error [IRForTarget]: Wrapper takes only "
1529 "'self' and '_cmd' arguments (should take a struct "
1538 if (argument->getName() !=
"$__lldb_arg") {
1539 m_error_stream.Format(
"Internal error [IRForTarget]: Wrapper takes an "
1540 "argument named '{0}' instead of the struct pointer",
1541 argument->getName());
1548 BasicBlock &entry_block(llvm_function.getEntryBlock());
1549 Instruction *FirstEntryInstruction(
1550 &*entry_block.getFirstNonPHIOrPseudoProbe());
1552 if (!FirstEntryInstruction) {
1553 m_error_stream.Printf(
"Internal error [IRForTarget]: Couldn't find the "
1554 "first instruction in the wrapper for use in "
1560 LLVMContext &context(
m_module->getContext());
1561 IntegerType *offset_type(Type::getInt32Ty(context));
1565 "Internal error [IRForTarget]: Couldn't produce an offset type");
1570 for (element_index = 0; element_index < num_elements; ++element_index) {
1571 const clang::NamedDecl *decl =
nullptr;
1572 Value *value =
nullptr;
1576 if (!
m_decl_map->GetStructElement(decl, value, offset, name,
1579 "Internal error [IRForTarget]: Structure information is incomplete");
1584 LLDB_LOG(log,
" \"{0}\" (\"{1}\") placed at {2}", name,
1585 decl->getNameAsString(), offset);
1591 [
this, name, offset_type, offset, argument,
1592 value](llvm::Function *function) -> llvm::Value * {
1599 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1602 Type *int8Ty = Type::getInt8Ty(function->getContext());
1603 ConstantInt *offset_int(
1604 ConstantInt::get(offset_type, offset,
true));
1605 GetElementPtrInst *get_element_ptr =
1606 GetElementPtrInst::Create(int8Ty, argument, offset_int,
"",
1607 entry_instruction->getIterator());
1611 new LoadInst(value->getType(), get_element_ptr,
"",
1612 entry_instruction->getIterator());
1616 return get_element_ptr;
1620 if (Constant *constant = dyn_cast<Constant>(value)) {
1627 }
else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1628 if (instruction->getParent()->getParent() != &llvm_function) {
1629 m_error_stream.PutCString(
"error: Capturing non-local variables in "
1630 "expressions is unsupported.\n");
1633 value->replaceAllUsesWith(
1634 body_result_maker.GetValue(instruction->getParent()->getParent()));
1636 LLDB_LOG(log,
"Unhandled non-constant type: \"{0}\"",
1641 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1642 var->eraseFromParent();
1646 LLDB_LOG(log,
"Total structure [align {0}, size {1}]", (int64_t)alignment,
1662 raw_string_ostream oss(s);
1666 LLDB_LOG(log,
"Module as passed in to IRForTarget: \n\"{0}\"", s);
1669 Function *
const main_function =
1676 m_error_stream.Format(
"Internal error [IRForTarget]: Couldn't find wrapper "
1677 "'{0}' in the module",
1683 if (main_function) {
1685 LLDB_LOG(log,
"Couldn't fix the linkage for the function");
1692 if (main_function) {
1694 LLDB_LOG(log,
"CreateResultVariable() failed");
1704 raw_string_ostream oss(s);
1708 LLDB_LOG(log,
"Module after creating the result variable: \n\"{0}\"", s);
1711 for (llvm::Function &function : *
m_module) {
1712 for (BasicBlock &bb : function) {
1714 LLDB_LOG(log,
"RemoveGuards() failed");
1722 LLDB_LOG(log,
"RewritePersistentAllocs() failed");
1731 LLDB_LOG(log,
"RemoveCXAAtExit() failed");
1742 LLDB_LOG(log,
"RewriteObjCConstStrings() failed");
1749 for (llvm::Function &function : *
m_module) {
1750 for (llvm::BasicBlock &bb : function) {
1752 LLDB_LOG(log,
"RewriteObjCSelectors() failed");
1762 for (llvm::Function &function : *
m_module) {
1763 for (BasicBlock &bb : function) {
1765 LLDB_LOG(log,
"ResolveCalls() failed");
1775 if (main_function) {
1777 LLDB_LOG(log,
"ResolveExternals() failed");
1785 LLDB_LOG(log,
"ReplaceVariables() failed");
1794 if (llvm::Error
error =
1797 "InsertPointerSigningFixups() failed: {0}");
1803 raw_string_ostream oss(s);
1807 LLDB_LOG(log,
"Module after preparing for execution: \n\"{0}\"", s);
static llvm::raw_ostream & error(Stream &strm)
static std::string PrintValue(const Value *value)
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 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)
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.
#define LLDB_LOG_ERROR(log, error,...)
FunctionValueCache(Maker const &maker)
llvm::Value * GetValue(llvm::Function *function)
std::function< llvm::Value *(llvm::Function *)> Maker
FunctionValueMap m_values
static llvm::Error 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_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 ...
"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.
"lldb/Expression/IRExecutionUnit.h" Contains the IR and, optionally, JIT- compiled code for a module.
const char * GetData() const
A stream class that can stream formatted output to a file.
#define LLDB_INVALID_ADDRESS
Error InjectPointerSigningFixupCode(llvm::Module &M, ExecutionPolicy execution_policy)
TaggedASTType< 0 > TypeFromParser
ExecutionPolicy
Expression execution policies.
std::shared_ptr< lldb_private::Target > TargetSP
static clang::QualType GetQualType(const CompilerType &ct)