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