blob: e70ab1ce8d5aed68c405ceb991d8beb3d1120c7f [file] [log] [blame]
Raphael Isemann80814282020-01-24 08:23:27 +01001//===-- IRForTarget.cpp ---------------------------------------------------===//
Sean Callanan2ab712f22010-07-03 01:35:46 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Sean Callanan2ab712f22010-07-03 01:35:46 +00006//
7//===----------------------------------------------------------------------===//
8
Sean Callanan4dbb2712015-09-25 20:35:58 +00009#include "IRForTarget.h"
10
11#include "ClangExpressionDeclMap.h"
Alex Langford8be30212020-01-29 11:59:28 -080012#include "ClangUtil.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000013
Alex Langford8be30212020-01-29 11:59:28 -080014#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000015#include "llvm/IR/Constants.h"
16#include "llvm/IR/DataLayout.h"
17#include "llvm/IR/InstrTypes.h"
18#include "llvm/IR/Instructions.h"
19#include "llvm/IR/Intrinsics.h"
Ilia Kc9a475d2015-02-13 10:49:18 +000020#include "llvm/IR/LegacyPassManager.h"
Zachary Turner543afa12014-12-09 22:29:47 +000021#include "llvm/IR/Metadata.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000022#include "llvm/IR/Module.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000023#include "llvm/IR/ValueSymbolTable.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "llvm/Support/raw_ostream.h"
25#include "llvm/Transforms/IPO.h"
Sean Callanan549c9f72010-07-13 21:41:46 +000026
27#include "clang/AST/ASTContext.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000028
Zachary Turnerd133f6a2016-03-28 22:53:41 +000029#include "lldb/Core/dwarf.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000030#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000031#include "lldb/Expression/IRInterpreter.h"
Greg Claytona1e5dc82015-08-11 22:53:00 +000032#include "lldb/Symbol/CompilerType.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000033#include "lldb/Utility/ConstString.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000034#include "lldb/Utility/DataBufferHeap.h"
Zachary Turner01c32432017-02-14 19:06:07 +000035#include "lldb/Utility/Endian.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000036#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000037#include "lldb/Utility/Scalar.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000038#include "lldb/Utility/StreamString.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000039
40#include <map>
41
42using namespace llvm;
43
Sean Callananeaacbc92010-08-18 18:50:51 +000044static char ID;
45
Raphael Isemannac42e742019-08-09 10:01:51 +000046typedef SmallVector<Instruction *, 2> InstrList;
47
Kate Stoneb9c1b512016-09-06 20:57:50 +000048IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
49 : m_maker(maker), m_values() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051IRForTarget::FunctionValueCache::~FunctionValueCache() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000052
Greg Clayton526ae042015-02-12 00:34:25 +000053llvm::Value *
Kate Stoneb9c1b512016-09-06 20:57:50 +000054IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
55 if (!m_values.count(function)) {
56 llvm::Value *ret = m_maker(function);
57 m_values[function] = ret;
58 return ret;
59 }
60 return m_values[function];
Sean Callanan1f9db3e2013-06-28 21:44:15 +000061}
62
Kate Stoneb9c1b512016-09-06 20:57:50 +000063static llvm::Value *FindEntryInstruction(llvm::Function *function) {
64 if (function->empty())
Konrad Kleine248a1302019-05-23 11:14:47 +000065 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 return function->getEntryBlock().getFirstNonPHIOrDbg();
Sean Callanan1f9db3e2013-06-28 21:44:15 +000068}
69
Kate Stoneb9c1b512016-09-06 20:57:50 +000070IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
71 bool resolve_vars,
72 lldb_private::IRExecutionUnit &execution_unit,
73 lldb_private::Stream &error_stream,
74 const char *func_name)
75 : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
Konrad Kleine248a1302019-05-23 11:14:47 +000076 m_module(nullptr), m_decl_map(decl_map),
77 m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
78 m_objc_getClass(nullptr), m_intptr_ty(nullptr),
79 m_error_stream(error_stream), m_execution_unit(execution_unit),
80 m_result_store(nullptr), m_result_is_pointer(false),
81 m_reloc_placeholder(nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 m_entry_instruction_finder(FindEntryInstruction) {}
Sean Callanan2ab712f22010-07-03 01:35:46 +000083
Sean Callanan038df5032010-09-30 21:18:25 +000084/* Handy utility functions used at several places in the code */
Sean Callanan2235f322010-08-11 03:57:18 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086static std::string PrintValue(const Value *value, bool truncate = false) {
87 std::string s;
88 if (value) {
Sean Callanan038df5032010-09-30 21:18:25 +000089 raw_string_ostream rso(s);
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 value->print(rso);
Sean Callanan038df5032010-09-30 21:18:25 +000091 rso.flush();
92 if (truncate)
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 s.resize(s.length() - 1);
94 }
95 return s;
Sean Callanan038df5032010-09-30 21:18:25 +000096}
97
Kate Stoneb9c1b512016-09-06 20:57:50 +000098static std::string PrintType(const llvm::Type *type, bool truncate = false) {
99 std::string s;
100 raw_string_ostream rso(s);
101 type->print(rso);
102 rso.flush();
103 if (truncate)
104 s.resize(s.length() - 1);
105 return s;
Sean Callanan2ab712f22010-07-03 01:35:46 +0000106}
107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108IRForTarget::~IRForTarget() {}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
111 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
112
113 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000114}
115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
117 Module *module) {
118 NamedMDNode *named_metadata =
119 module->getNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 if (!named_metadata)
Konrad Kleine248a1302019-05-23 11:14:47 +0000122 return nullptr;
Sean Callanan63697e52011-05-07 01:06:41 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 unsigned num_nodes = named_metadata->getNumOperands();
125 unsigned node_index;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 for (node_index = 0; node_index < num_nodes; ++node_index) {
128 llvm::MDNode *metadata_node =
129 dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
130 if (!metadata_node)
Konrad Kleine248a1302019-05-23 11:14:47 +0000131 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 if (metadata_node->getNumOperands() != 2)
134 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 if (mdconst::dyn_extract_or_null<GlobalValue>(
137 metadata_node->getOperand(0)) != global_val)
138 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 ConstantInt *constant_int =
141 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000142
Sean Callanan2235f322010-08-11 03:57:18 +0000143 if (!constant_int)
Konrad Kleine248a1302019-05-23 11:14:47 +0000144 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000145
Sean Callanan2235f322010-08-11 03:57:18 +0000146 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 return reinterpret_cast<clang::NamedDecl *>(ptr);
149 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000150
Konrad Kleine248a1302019-05-23 11:14:47 +0000151 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
155 return DeclForGlobal(global_val, m_module);
156}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000157
Raphael Isemann7f7b2962019-08-13 13:09:18 +0000158/// Returns true iff the mangled symbol is for a static guard variable.
Raphael Isemann66214b52019-08-14 21:21:14 +0000159static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,
160 bool check_ms_abi = true) {
161 bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable
162 if (check_ms_abi)
163 result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
164 return result;
Raphael Isemann7f7b2962019-08-13 13:09:18 +0000165}
166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
168 lldb_private::Log *log(
169 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000170
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 if (!m_resolve_vars)
172 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000173
Kate Stoneb9c1b512016-09-06 20:57:50 +0000174 // Find the result variable. If it doesn't exist, we can give up right here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000177
Raphael Isemann50f7e942019-08-08 22:19:16 +0000178 llvm::StringRef result_name;
179 bool found_result = false;
Sean Callanan2235f322010-08-11 03:57:18 +0000180
Raphael Isemanndced4452019-08-09 07:59:18 +0000181 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
182 result_name = value_symbol.first();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000183
Raphael Isemann66214b52019-08-14 21:21:14 +0000184 // Check if this is a guard variable. It seems this causes some hiccups
185 // on Windows, so let's only check for Itanium guard variables.
186 bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);
Raphael Isemann7f7b2962019-08-13 13:09:18 +0000187
188 if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
Raphael Isemann50f7e942019-08-08 22:19:16 +0000189 found_result = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 m_result_is_pointer = true;
191 break;
192 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000193
Raphael Isemann7f7b2962019-08-13 13:09:18 +0000194 if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {
Raphael Isemann50f7e942019-08-08 22:19:16 +0000195 found_result = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 m_result_is_pointer = false;
197 break;
198 }
199 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000200
Raphael Isemann50f7e942019-08-08 22:19:16 +0000201 if (!found_result) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000202 LLDB_LOG(log, "Couldn't find result variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000203
Sean Callanan2235f322010-08-11 03:57:18 +0000204 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 }
Sean Callanan2235f322010-08-11 03:57:18 +0000206
Raphael Isemann50f7e942019-08-08 22:19:16 +0000207 LLDB_LOG(log, "Result name: \"{0}\"", result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 Value *result_value = m_module->getNamedValue(result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 if (!result_value) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000212 LLDB_LOG(log, "Result variable had no data");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000213
Raphael Isemann50f7e942019-08-08 22:19:16 +0000214 m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
215 "name ({0}) exists, but not its definition\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000216 result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000217
Sean Callananc70ed462011-10-25 18:36:40 +0000218 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219 }
Sean Callananc70ed462011-10-25 18:36:40 +0000220
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000221 LLDB_LOG(log, "Found result in the IR: \"{0}\"",
222 PrintValue(result_value, false));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223
224 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
225
226 if (!result_global) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000227 LLDB_LOG(log, "Result variable isn't a GlobalVariable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228
Raphael Isemann50f7e942019-08-08 22:19:16 +0000229 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 "is defined, but is not a global variable\n",
231 result_name);
232
233 return false;
234 }
235
236 clang::NamedDecl *result_decl = DeclForGlobal(result_global);
237 if (!result_decl) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000238 LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239
Raphael Isemann50f7e942019-08-08 22:19:16 +0000240 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000241 "does not have a corresponding Clang entity\n",
242 result_name);
243
244 return false;
245 }
246
247 if (log) {
248 std::string decl_desc_str;
249 raw_string_ostream decl_desc_stream(decl_desc_str);
250 result_decl->print(decl_desc_stream);
251 decl_desc_stream.flush();
252
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000253 LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 }
255
256 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
257 if (!result_var) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000258 LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259
Raphael Isemann50f7e942019-08-08 22:19:16 +0000260 m_error_stream.Format("Internal error [IRForTarget]: Result variable "
261 "({0})'s corresponding Clang entity isn't a "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 "variable\n",
263 result_name);
264
265 return false;
266 }
267
268 // Get the next available result name from m_decl_map and create the
Adrian Prantl05097242018-04-30 16:49:04 +0000269 // persistent variable for it
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270
271 // If the result is an Lvalue, it is emitted as a pointer; see
272 // ASTResultSynthesizer::SynthesizeBodyResult.
273 if (m_result_is_pointer) {
274 clang::QualType pointer_qual_type = result_var->getType();
275 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
276
277 const clang::PointerType *pointer_pointertype =
278 pointer_type->getAs<clang::PointerType>();
279 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
280 pointer_type->getAs<clang::ObjCObjectPointerType>();
281
282 if (pointer_pointertype) {
283 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
284
285 m_result_type = lldb_private::TypeFromParser(
Raphael Isemanndf8a9862020-01-30 11:53:41 +0100286 m_decl_map->GetTypeSystem()->GetType(element_qual_type));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 } else if (pointer_objcobjpointertype) {
288 clang::QualType element_qual_type =
289 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
290
291 m_result_type = lldb_private::TypeFromParser(
Raphael Isemanndf8a9862020-01-30 11:53:41 +0100292 m_decl_map->GetTypeSystem()->GetType(element_qual_type));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 } else {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000294 LLDB_LOG(log, "Expected result to have pointer type, but it did not");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295
Raphael Isemann50f7e942019-08-08 22:19:16 +0000296 m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000297 "is not a pointer variable\n",
298 result_name);
299
300 return false;
301 }
302 } else {
303 m_result_type = lldb_private::TypeFromParser(
Raphael Isemanndf8a9862020-01-30 11:53:41 +0100304 m_decl_map->GetTypeSystem()->GetType(result_var->getType()));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000305 }
306
307 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
308 lldb_private::ExecutionContext exe_ctx(target_sp, true);
Adrian Prantld6a9bbf2019-01-15 20:33:58 +0000309 llvm::Optional<uint64_t> bit_size =
Adrian Prantld963a7c2019-01-15 18:07:52 +0000310 m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
311 if (!bit_size) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312 lldb_private::StreamString type_desc_stream;
313 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000314
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000315 LLDB_LOG(log, "Result type has unknown size");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000316
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
318 "couldn't be determined\n",
319 type_desc_stream.GetData());
320 return false;
321 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000322
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 if (log) {
324 lldb_private::StreamString type_desc_stream;
325 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000326
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000327 LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000329
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330 m_result_name = lldb_private::ConstString("$RESULT_NAME");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000331
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000332 LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
333 m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000334
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335 // Construct a new result global and set up its metadata
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000336
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 GlobalVariable *new_result_global = new GlobalVariable(
338 (*m_module), result_global->getType()->getElementType(),
Konrad Kleine248a1302019-05-23 11:14:47 +0000339 false, /* not constant */
340 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 m_result_name.GetCString());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Adrian Prantl05097242018-04-30 16:49:04 +0000343 // It's too late in compilation to create a new VarDecl for this, but we
344 // don't need to. We point the metadata at the old VarDecl. This creates an
345 // odd anomaly: a variable with a Value whose name is something like $0 and a
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 // Decl whose name is $__lldb_expr_result. This condition is handled in
347 // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
348 // fixed up.
Greg Clayton57ee3062013-07-11 22:46:58 +0000349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350 ConstantInt *new_constant_int =
351 ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
Jan Kratochvildf6879e2019-12-21 11:12:17 +0100352 reinterpret_cast<uintptr_t>(result_decl), false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000353
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 llvm::Metadata *values[2];
355 values[0] = ConstantAsMetadata::get(new_result_global);
356 values[1] = ConstantAsMetadata::get(new_constant_int);
Greg Clayton57ee3062013-07-11 22:46:58 +0000357
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 ArrayRef<Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000359
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
361 NamedMDNode *named_metadata =
362 m_module->getNamedMetadata("clang.global.decl.ptrs");
363 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000365 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
366 PrintValue(new_result_global));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000367
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368 if (result_global->use_empty()) {
369 // We need to synthesize a store for this variable, because otherwise
370 // there's nothing to put into its equivalent persistent variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000371
Greg Clayton1b95a6f2010-11-19 01:05:25 +0000372 BasicBlock &entry_block(llvm_function.getEntryBlock());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000373 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000374
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 if (!first_entry_instruction)
376 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000377
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 if (!result_global->hasInitializer()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000379 LLDB_LOG(log, "Couldn't find initializer for unused variable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380
Raphael Isemann50f7e942019-08-08 22:19:16 +0000381 m_error_stream.Format("Internal error [IRForTarget]: Result variable "
382 "({0}) has no writes and no initializer\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 result_name);
384
385 return false;
Sean Callanan3989fb92011-01-27 01:07:04 +0000386 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000387
Kate Stoneb9c1b512016-09-06 20:57:50 +0000388 Constant *initializer = result_global->getInitializer();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000389
Kate Stoneb9c1b512016-09-06 20:57:50 +0000390 StoreInst *synthesized_store =
391 new StoreInst(initializer, new_result_global, first_entry_instruction);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000392
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000393 LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
394 PrintValue(synthesized_store));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 } else {
396 result_global->replaceAllUsesWith(new_result_global);
397 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000398
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 if (!m_decl_map->AddPersistentVariable(
400 result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
401 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000402
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403 result_global->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000404
Kate Stoneb9c1b512016-09-06 20:57:50 +0000405 return true;
406}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
409 llvm::GlobalVariable *cstr) {
410 lldb_private::Log *log(
411 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000412
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 Type *ns_str_ty = ns_str->getType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000414
Kate Stoneb9c1b512016-09-06 20:57:50 +0000415 Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
416 Type *i32_ty = Type::getInt32Ty(m_module->getContext());
417 Type *i8_ty = Type::getInt8Ty(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000418
Kate Stoneb9c1b512016-09-06 20:57:50 +0000419 if (!m_CFStringCreateWithBytes) {
420 lldb::addr_t CFStringCreateWithBytes_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 static lldb_private::ConstString g_CFStringCreateWithBytes_str(
423 "CFStringCreateWithBytes");
Sean Callanan1f9db3e2013-06-28 21:44:15 +0000424
Jim Inghamf2128b22019-06-28 21:40:05 +0000425 bool missing_weak = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426 CFStringCreateWithBytes_addr =
Jim Inghamf2128b22019-06-28 21:40:05 +0000427 m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
428 missing_weak);
429 if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430 log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432 m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
433 "constant string requires "
434 "CFStringCreateWithBytes\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000435
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436 return false;
Sean Callanan549c9f72010-07-13 21:41:46 +0000437 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000438
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000439 LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
440 CFStringCreateWithBytes_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 // Build the function type:
443 //
444 // CFStringRef CFStringCreateWithBytes (
445 // CFAllocatorRef alloc,
446 // const UInt8 *bytes,
447 // CFIndex numBytes,
448 // CFStringEncoding encoding,
449 // Boolean isExternalRepresentation
450 // );
451 //
452 // We make the following substitutions:
453 //
454 // CFStringRef -> i8*
455 // CFAllocatorRef -> i8*
456 // UInt8 * -> i8*
457 // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
Adrian Prantl05097242018-04-30 16:49:04 +0000458 // pointer size for now) CFStringEncoding -> i32 Boolean -> i8
Kate Stoneb9c1b512016-09-06 20:57:50 +0000459
460 Type *arg_type_array[5];
461
462 arg_type_array[0] = i8_ptr_ty;
463 arg_type_array[1] = i8_ptr_ty;
464 arg_type_array[2] = m_intptr_ty;
465 arg_type_array[3] = i32_ty;
466 arg_type_array[4] = i8_ty;
467
468 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
469
James Y Knightae2f9512019-02-08 19:30:46 +0000470 llvm::FunctionType *CFSCWB_ty =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000471 FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
472
473 // Build the constant containing the pointer to the function
474 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
475 Constant *CFSCWB_addr_int =
476 ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +0000477 m_CFStringCreateWithBytes = {
478 CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 }
480
Konrad Kleine248a1302019-05-23 11:14:47 +0000481 ConstantDataSequential *string_array = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482
483 if (cstr)
484 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
485
486 Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
487 Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
488 : Constant::getNullValue(i8_ptr_ty);
489 Constant *numBytes_arg = ConstantInt::get(
Sean Callanancd1eb722016-12-01 17:46:51 +0000490 m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
491 int encoding_flags = 0;
Sean Callanan01341522016-12-01 19:14:55 +0000492 switch (cstr ? string_array->getElementByteSize() : 1) {
Sean Callanancd1eb722016-12-01 17:46:51 +0000493 case 1:
494 encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
495 break;
496 case 2:
497 encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
498 break;
499 case 4:
500 encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
501 break;
502 default:
503 encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
Pavel Labath107d9bb2017-01-18 11:00:26 +0000504 LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
Luke Drummond63dea592016-12-22 19:15:07 +0000505 "element size {0}",
Pavel Labath107d9bb2017-01-18 11:00:26 +0000506 string_array->getElementByteSize());
Sean Callanancd1eb722016-12-01 17:46:51 +0000507 }
508 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
509 Constant *isExternal_arg =
510 ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511
Sean Callanancd1eb722016-12-01 17:46:51 +0000512 Value *argument_array[5];
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513
Sean Callanancd1eb722016-12-01 17:46:51 +0000514 argument_array[0] = alloc_arg;
515 argument_array[1] = bytes_arg;
516 argument_array[2] = numBytes_arg;
517 argument_array[3] = encoding_arg;
518 argument_array[4] = isExternal_arg;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000519
Sean Callanancd1eb722016-12-01 17:46:51 +0000520 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521
Sean Callanancd1eb722016-12-01 17:46:51 +0000522 FunctionValueCache CFSCWB_Caller(
523 [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
524 return CallInst::Create(
525 m_CFStringCreateWithBytes, CFSCWB_arguments,
526 "CFStringCreateWithBytes",
527 llvm::cast<Instruction>(
528 m_entry_instruction_finder.GetValue(function)));
529 });
Kate Stoneb9c1b512016-09-06 20:57:50 +0000530
Sean Callanancd1eb722016-12-01 17:46:51 +0000531 if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
532 m_error_stream)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000533 LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534
Sean Callanancd1eb722016-12-01 17:46:51 +0000535 m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
536 "Objective-C constant string with a dynamic "
537 "string\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000538
Sean Callanancd1eb722016-12-01 17:46:51 +0000539 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000540 }
541
542 ns_str->eraseFromParent();
543
544 return true;
Sean Callanan549c9f72010-07-13 21:41:46 +0000545}
546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547bool IRForTarget::RewriteObjCConstStrings() {
548 lldb_private::Log *log(
549 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000552
Raphael Isemanndced4452019-08-09 07:59:18 +0000553 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
Raphael Isemann474d70b2019-08-09 08:10:02 +0000554 llvm::StringRef value_name = value_symbol.first();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000555
Raphael Isemann474d70b2019-08-09 08:10:02 +0000556 if (value_name.contains("_unnamed_cfstring_")) {
Raphael Isemanndced4452019-08-09 07:59:18 +0000557 Value *nsstring_value = value_symbol.second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000558
Kate Stoneb9c1b512016-09-06 20:57:50 +0000559 GlobalVariable *nsstring_global =
560 dyn_cast<GlobalVariable>(nsstring_value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000561
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 if (!nsstring_global) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000563 LLDB_LOG(log, "NSString variable is not a GlobalVariable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564
565 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
566 "constant string is not a global variable\n");
567
568 return false;
569 }
570
571 if (!nsstring_global->hasInitializer()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000572 LLDB_LOG(log, "NSString variable does not have an initializer");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573
574 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
575 "constant string does not have an initializer\n");
576
577 return false;
578 }
579
580 ConstantStruct *nsstring_struct =
581 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
582
583 if (!nsstring_struct) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000584 LLDB_LOG(log,
585 "NSString variable's initializer is not a ConstantStruct");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000586
587 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
588 "constant string is not a structure constant\n");
589
590 return false;
591 }
592
593 // We expect the following structure:
594 //
595 // struct {
596 // int *isa;
597 // int flags;
598 // char *str;
599 // long length;
600 // };
601
602 if (nsstring_struct->getNumOperands() != 4) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000603
604 LLDB_LOG(log,
605 "NSString variable's initializer structure has an "
606 "unexpected number of members. Should be 4, is {0}",
607 nsstring_struct->getNumOperands());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608
609 m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
610 "Objective-C constant string is not as "
611 "expected\n");
612
613 return false;
614 }
615
616 Constant *nsstring_member = nsstring_struct->getOperand(2);
617
618 if (!nsstring_member) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000619 LLDB_LOG(log, "NSString initializer's str element was empty");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620
621 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
622 "constant string does not have a string "
623 "initializer\n");
624
625 return false;
626 }
627
628 ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
629
630 if (!nsstring_expr) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000631 LLDB_LOG(log,
632 "NSString initializer's str element is not a ConstantExpr");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000633
634 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
635 "constant string's string initializer is not "
636 "constant\n");
637
638 return false;
639 }
640
Sean Callanancd1eb722016-12-01 17:46:51 +0000641 GlobalVariable *cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642
Sean Callanancd1eb722016-12-01 17:46:51 +0000643 if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
644 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
645 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
646 } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
647 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
648 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000649 }
650
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 if (!cstr_global) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000652 LLDB_LOG(log,
653 "NSString initializer's str element is not a GlobalVariable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654
Sean Callanancd1eb722016-12-01 17:46:51 +0000655 m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
656 "constant string initializer\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000657
658 return false;
659 }
660
661 if (!cstr_global->hasInitializer()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000662 LLDB_LOG(log, "NSString initializer's str element does not have an "
663 "initializer");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664
665 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
666 "constant string's string initializer doesn't "
667 "point to initialized data\n");
668
669 return false;
670 }
671
672 /*
673 if (!cstr_array)
674 {
675 if (log)
676 log->PutCString("NSString initializer's str element is not a
677 ConstantArray");
678
679 if (m_error_stream)
680 m_error_stream.Printf("Internal error [IRForTarget]: An
681 Objective-C constant string's string initializer doesn't point to an
682 array\n");
683
684 return false;
685 }
686
687 if (!cstr_array->isCString())
688 {
689 if (log)
690 log->PutCString("NSString initializer's str element is not a C
691 string array");
692
693 if (m_error_stream)
694 m_error_stream.Printf("Internal error [IRForTarget]: An
695 Objective-C constant string's string initializer doesn't point to a C
696 string\n");
697
698 return false;
699 }
700 */
701
702 ConstantDataArray *cstr_array =
703 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
704
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000705 if (cstr_array)
706 LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
707 value_name, cstr_array->getAsString());
708 else
709 LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
710 value_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711
712 if (!cstr_array)
Konrad Kleine248a1302019-05-23 11:14:47 +0000713 cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000714
715 if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000716 LLDB_LOG(log, "Error rewriting the constant string");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000717
718 // We don't print an error message here because RewriteObjCConstString
719 // has done so for us.
720
721 return false;
722 }
723 }
724 }
725
Raphael Isemanndced4452019-08-09 07:59:18 +0000726 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
Raphael Isemann474d70b2019-08-09 08:10:02 +0000727 llvm::StringRef value_name = value_symbol.first();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000728
Raphael Isemann474d70b2019-08-09 08:10:02 +0000729 if (value_name == "__CFConstantStringClassReference") {
Raphael Isemanndced4452019-08-09 07:59:18 +0000730 GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731
732 if (!gv) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000733 LLDB_LOG(log,
734 "__CFConstantStringClassReference is not a global variable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000735
736 m_error_stream.Printf("Internal error [IRForTarget]: Found a "
737 "CFConstantStringClassReference, but it is not a "
738 "global object\n");
739
740 return false;
741 }
742
743 gv->eraseFromParent();
744
745 break;
746 }
747 }
748
749 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000750}
751
Kate Stoneb9c1b512016-09-06 20:57:50 +0000752static bool IsObjCSelectorRef(Value *value) {
753 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000754
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000755 return !(!global_variable || !global_variable->hasName() ||
756 !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757}
758
759// This function does not report errors; its callers are responsible.
760bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
761 lldb_private::Log *log(
762 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
763
764 LoadInst *load = dyn_cast<LoadInst>(selector_load);
765
766 if (!load)
767 return false;
768
769 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
770 // gets represented as
771 //
Adrian Prantl05097242018-04-30 16:49:04 +0000772 // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call = call
773 // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 //
775 // where %obj is the object pointer and %tmp is the selector.
776 //
777 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
778 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
779 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
780
781 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
782 // and get the string from its target
783
784 GlobalVariable *_objc_selector_references_ =
785 dyn_cast<GlobalVariable>(load->getPointerOperand());
786
787 if (!_objc_selector_references_ ||
788 !_objc_selector_references_->hasInitializer())
789 return false;
790
791 Constant *osr_initializer = _objc_selector_references_->getInitializer();
792
793 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
794
795 if (!osr_initializer_expr ||
796 osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
797 return false;
798
799 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
800
801 if (!osr_initializer_base)
802 return false;
803
804 // Find the string's initializer (a ConstantArray) and get the string from it
805
806 GlobalVariable *_objc_meth_var_name_ =
807 dyn_cast<GlobalVariable>(osr_initializer_base);
808
809 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
810 return false;
811
812 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
813
814 ConstantDataArray *omvn_initializer_array =
815 dyn_cast<ConstantDataArray>(omvn_initializer);
816
817 if (!omvn_initializer_array->isString())
818 return false;
819
Benjamin Krameradcd0262020-01-28 20:23:46 +0100820 std::string omvn_initializer_string =
821 std::string(omvn_initializer_array->getAsString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000823 LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
824 omvn_initializer_string);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825
826 // Construct a call to sel_registerName
827
828 if (!m_sel_registerName) {
829 lldb::addr_t sel_registerName_addr;
830
Jim Inghamf2128b22019-06-28 21:40:05 +0000831 bool missing_weak = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
Jim Inghamf2128b22019-06-28 21:40:05 +0000833 sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str,
834 missing_weak);
835 if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000837
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000838 LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000839
Adrian Prantl05097242018-04-30 16:49:04 +0000840 // Build the function type: struct objc_selector
841 // *sel_registerName(uint8_t*)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000842
Kate Stoneb9c1b512016-09-06 20:57:50 +0000843 // The below code would be "more correct," but in actuality what's required
844 // is uint8_t*
845 // Type *sel_type = StructType::get(m_module->getContext());
846 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
847 Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000848
Kate Stoneb9c1b512016-09-06 20:57:50 +0000849 Type *type_array[1];
850
851 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
852
853 ArrayRef<Type *> srN_arg_types(type_array, 1);
854
James Y Knightae2f9512019-02-08 19:30:46 +0000855 llvm::FunctionType *srN_type =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 FunctionType::get(sel_ptr_type, srN_arg_types, false);
857
858 // Build the constant containing the pointer to the function
859 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
860 Constant *srN_addr_int =
861 ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +0000862 m_sel_registerName = {srN_type,
863 ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864 }
865
866 Value *argument_array[1];
867
868 Constant *omvn_pointer = ConstantExpr::getBitCast(
869 _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
870
871 argument_array[0] = omvn_pointer;
872
873 ArrayRef<Value *> srN_arguments(argument_array, 1);
874
875 CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
876 "sel_registerName", selector_load);
877
878 // Replace the load with the call in all users
879
880 selector_load->replaceAllUsesWith(srN_call);
881
882 selector_load->eraseFromParent();
883
884 return true;
885}
886
887bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
888 lldb_private::Log *log(
889 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000890
891 InstrList selector_loads;
892
Raphael Isemanndced4452019-08-09 07:59:18 +0000893 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000894 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
895 if (IsObjCSelectorRef(load->getPointerOperand()))
896 selector_loads.push_back(&inst);
897 }
898
Raphael Isemanndced4452019-08-09 07:59:18 +0000899 for (Instruction *inst : selector_loads) {
900 if (!RewriteObjCSelector(inst)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
902 "static reference to an Objective-C selector to a "
903 "dynamic reference\n");
904
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000905 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906
907 return false;
Sean Callananc70ed462011-10-25 18:36:40 +0000908 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000910
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911 return true;
912}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000913
Sean Callananac900582016-09-29 00:45:33 +0000914static bool IsObjCClassReference(Value *value) {
915 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
916
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000917 return !(!global_variable || !global_variable->hasName() ||
918 !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
Sean Callananac900582016-09-29 00:45:33 +0000919}
920
921// This function does not report errors; its callers are responsible.
922bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
923 lldb_private::Log *log(
924 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
925
926 LoadInst *load = dyn_cast<LoadInst>(class_load);
927
928 if (!load)
929 return false;
930
931 // Unpack the class name from the reference. In LLVM IR, a reference to an
932 // Objective-C class gets represented as
933 //
934 // %tmp = load %struct._objc_class*,
935 // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
936 //
937 // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
Adrian Prantl05097242018-04-30 16:49:04 +0000938 // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.
Sean Callananac900582016-09-29 00:45:33 +0000939
Adrian Prantl05097242018-04-30 16:49:04 +0000940 // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and
941 // get the string from its target
Sean Callananac900582016-09-29 00:45:33 +0000942
943 GlobalVariable *_objc_class_references_ =
944 dyn_cast<GlobalVariable>(load->getPointerOperand());
945
946 if (!_objc_class_references_ ||
947 !_objc_class_references_->hasInitializer())
948 return false;
949
950 Constant *ocr_initializer = _objc_class_references_->getInitializer();
951
952 ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
953
954 if (!ocr_initializer_expr ||
955 ocr_initializer_expr->getOpcode() != Instruction::BitCast)
956 return false;
957
958 Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
959
960 if (!ocr_initializer_base)
961 return false;
962
963 // Find the string's initializer (a ConstantArray) and get the string from it
964
965 GlobalVariable *_objc_class_name_ =
966 dyn_cast<GlobalVariable>(ocr_initializer_base);
967
968 if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
969 return false;
970
971 Constant *ocn_initializer = _objc_class_name_->getInitializer();
972
973 ConstantDataArray *ocn_initializer_array =
974 dyn_cast<ConstantDataArray>(ocn_initializer);
975
976 if (!ocn_initializer_array->isString())
977 return false;
978
Benjamin Krameradcd0262020-01-28 20:23:46 +0100979 std::string ocn_initializer_string =
980 std::string(ocn_initializer_array->getAsString());
Sean Callananac900582016-09-29 00:45:33 +0000981
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000982 LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
983 ocn_initializer_string);
Sean Callananac900582016-09-29 00:45:33 +0000984
985 // Construct a call to objc_getClass
986
987 if (!m_objc_getClass) {
988 lldb::addr_t objc_getClass_addr;
989
Jim Inghamf2128b22019-06-28 21:40:05 +0000990 bool missing_weak = false;
Sean Callananac900582016-09-29 00:45:33 +0000991 static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
Jim Inghamf2128b22019-06-28 21:40:05 +0000992 objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str,
993 missing_weak);
994 if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
Sean Callananac900582016-09-29 00:45:33 +0000995 return false;
996
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000997 LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);
Sean Callananac900582016-09-29 00:45:33 +0000998
999 // Build the function type: %struct._objc_class *objc_getClass(i8*)
1000
1001 Type *class_type = load->getType();
1002 Type *type_array[1];
1003 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
1004
1005 ArrayRef<Type *> ogC_arg_types(type_array, 1);
1006
James Y Knightae2f9512019-02-08 19:30:46 +00001007 llvm::FunctionType *ogC_type =
Sean Callananac900582016-09-29 00:45:33 +00001008 FunctionType::get(class_type, ogC_arg_types, false);
1009
1010 // Build the constant containing the pointer to the function
1011 PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
1012 Constant *ogC_addr_int =
1013 ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +00001014 m_objc_getClass = {ogC_type,
1015 ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
Sean Callananac900582016-09-29 00:45:33 +00001016 }
1017
1018 Value *argument_array[1];
1019
1020 Constant *ocn_pointer = ConstantExpr::getBitCast(
1021 _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
1022
1023 argument_array[0] = ocn_pointer;
1024
1025 ArrayRef<Value *> ogC_arguments(argument_array, 1);
1026
1027 CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
1028 "objc_getClass", class_load);
1029
1030 // Replace the load with the call in all users
1031
1032 class_load->replaceAllUsesWith(ogC_call);
1033
1034 class_load->eraseFromParent();
1035
1036 return true;
1037}
1038
1039bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
1040 lldb_private::Log *log(
1041 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1042
Sean Callananac900582016-09-29 00:45:33 +00001043 InstrList class_loads;
1044
Raphael Isemanndced4452019-08-09 07:59:18 +00001045 for (Instruction &inst : basic_block) {
Sean Callananac900582016-09-29 00:45:33 +00001046 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1047 if (IsObjCClassReference(load->getPointerOperand()))
1048 class_loads.push_back(&inst);
1049 }
1050
Raphael Isemanndced4452019-08-09 07:59:18 +00001051 for (Instruction *inst : class_loads) {
1052 if (!RewriteObjCClassReference(inst)) {
Sean Callananac900582016-09-29 00:45:33 +00001053 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
1054 "static reference to an Objective-C class to a "
1055 "dynamic reference\n");
1056
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001057 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");
Sean Callananac900582016-09-29 00:45:33 +00001058
1059 return false;
1060 }
1061 }
1062
1063 return true;
1064}
1065
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066// This function does not report errors; its callers are responsible.
1067bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
1068 lldb_private::Log *log(
1069 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001070
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001072
Kate Stoneb9c1b512016-09-06 20:57:50 +00001073 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001074
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 if (!alloc_md || !alloc_md->getNumOperands())
1076 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001077
Kate Stoneb9c1b512016-09-06 20:57:50 +00001078 ConstantInt *constant_int =
1079 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001080
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081 if (!constant_int)
1082 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001083
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084 // We attempt to register this as a new persistent variable with the DeclMap.
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001085
Kate Stoneb9c1b512016-09-06 20:57:50 +00001086 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001087
Kate Stoneb9c1b512016-09-06 20:57:50 +00001088 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001089
Kate Stoneb9c1b512016-09-06 20:57:50 +00001090 lldb_private::TypeFromParser result_decl_type(
Raphael Isemanndf8a9862020-01-30 11:53:41 +01001091 m_decl_map->GetTypeSystem()->GetType(decl->getType()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001092
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 StringRef decl_name(decl->getName());
1094 lldb_private::ConstString persistent_variable_name(decl_name.data(),
1095 decl_name.size());
1096 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1097 result_decl_type, false, false))
1098 return false;
Sean Callanan6e6d4a62012-07-21 02:02:15 +00001099
Kate Stoneb9c1b512016-09-06 20:57:50 +00001100 GlobalVariable *persistent_global = new GlobalVariable(
Konrad Kleine248a1302019-05-23 11:14:47 +00001101 (*m_module), alloc->getType(), false, /* not constant */
1102 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001103 alloc->getName().str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001104
Adrian Prantl05097242018-04-30 16:49:04 +00001105 // What we're going to do here is make believe this was a regular old
1106 // external variable. That means we need to make the metadata valid.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001107
Kate Stoneb9c1b512016-09-06 20:57:50 +00001108 NamedMDNode *named_metadata =
1109 m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001110
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111 llvm::Metadata *values[2];
1112 values[0] = ConstantAsMetadata::get(persistent_global);
1113 values[1] = ConstantAsMetadata::get(constant_int);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001114
Kate Stoneb9c1b512016-09-06 20:57:50 +00001115 ArrayRef<llvm::Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001116
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1118 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001119
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 // Now, since the variable is a pointer variable, we will drop in a load of
Adrian Prantl05097242018-04-30 16:49:04 +00001121 // that pointer variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001122
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123 LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001124
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001125 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
1126 PrintValue(persistent_load));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001127
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128 alloc->replaceAllUsesWith(persistent_load);
1129 alloc->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001130
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131 return true;
1132}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001133
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1135 if (!m_resolve_vars)
1136 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001137
Kate Stoneb9c1b512016-09-06 20:57:50 +00001138 lldb_private::Log *log(
1139 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001140
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 InstrList pvar_allocs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001142
Raphael Isemanndced4452019-08-09 07:59:18 +00001143 for (Instruction &inst : basic_block) {
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001144
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1146 llvm::StringRef alloc_name = alloc->getName();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001147
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148 if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1149 if (alloc_name.find_first_of("0123456789") == 1) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001150 LLDB_LOG(log, "Rejecting a numeric persistent variable.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001151
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1153 "$1, ... are reserved for use as result "
1154 "names\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001155
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 return false;
Sean Callanan00294b32016-03-22 21:05:51 +00001157 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001158
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159 pvar_allocs.push_back(alloc);
1160 }
Sean Callanan17827832010-12-13 22:46:15 +00001161 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001163
Raphael Isemanndced4452019-08-09 07:59:18 +00001164 for (Instruction *inst : pvar_allocs) {
1165 if (!RewritePersistentAlloc(inst)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1167 "the creation of a persistent variable\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001168
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001169 LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001170
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001172 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001173 }
1174
1175 return true;
1176}
1177
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178// This function does not report errors; its callers are responsible.
1179bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1180 lldb_private::Log *log(
1181 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1182
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001183 LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001184
1185 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1186 switch (constant_expr->getOpcode()) {
1187 default:
1188 break;
1189 case Instruction::GetElementPtr:
1190 case Instruction::BitCast:
1191 Value *s = constant_expr->getOperand(0);
1192 if (!MaybeHandleVariable(s))
1193 return false;
1194 }
1195 } else if (GlobalVariable *global_variable =
1196 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1197 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1198 return true;
1199
1200 clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1201
1202 if (!named_decl) {
Stella Stamenovae7daf782019-08-12 20:08:05 +00001203 if (IsObjCSelectorRef(llvm_value_ptr))
1204 return true;
1205
1206 if (!global_variable->hasExternalLinkage())
1207 return true;
1208
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001209 LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
1210 global_variable->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001211
Stella Stamenovae7daf782019-08-12 20:08:05 +00001212 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213 }
1214
Raphael Isemann7491f362019-08-08 21:22:21 +00001215 llvm::StringRef name(named_decl->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216
1217 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
Konrad Kleine248a1302019-05-23 11:14:47 +00001218 if (value_decl == nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001219 return false;
1220
Raphael Isemanndf8a9862020-01-30 11:53:41 +01001221 lldb_private::CompilerType compiler_type =
1222 m_decl_map->GetTypeSystem()->GetType(value_decl->getType());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001223
Konrad Kleine248a1302019-05-23 11:14:47 +00001224 const Type *value_type = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001225
Raphael Isemann7491f362019-08-08 21:22:21 +00001226 if (name.startswith("$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227 // The $__lldb_expr_result name indicates the return value has allocated
Adrian Prantl05097242018-04-30 16:49:04 +00001228 // as a static variable. Per the comment at
1229 // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
1230 // variable need to be redirected to the result of dereferencing a
1231 // pointer that is passed in as one of the arguments.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001232 //
1233 // Consequently, when reporting the size of the type, we report a pointer
Adrian Prantl05097242018-04-30 16:49:04 +00001234 // type pointing to the type of $__lldb_expr_result, not the type itself.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001235 //
1236 // We also do this for any user-declared persistent variables.
1237 compiler_type = compiler_type.GetPointerType();
1238 value_type = PointerType::get(global_variable->getType(), 0);
1239 } else {
1240 value_type = global_variable->getType();
1241 }
1242
Adrian Prantld6a9bbf2019-01-15 20:33:58 +00001243 llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
Adrian Prantld963a7c2019-01-15 18:07:52 +00001244 if (!value_size)
1245 return false;
Davide Italiano7f9bbe02019-08-12 21:49:54 +00001246 llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr);
Davide Italiano36f13e42019-08-12 20:03:19 +00001247 if (!opt_alignment)
1248 return false;
1249 lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001250
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001251 LLDB_LOG(log,
1252 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1253 "align {4}]",
1254 name,
1255 lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
1256 PrintType(value_type), *value_size, value_alignment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001257
Raphael Isemann0e5eef52019-08-08 16:41:32 +00001258 if (named_decl)
Raphael Isemann7491f362019-08-08 21:22:21 +00001259 m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
1260 llvm_value_ptr, *value_size,
1261 value_alignment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001262 } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001263 LLDB_LOG(log, "Function pointers aren't handled right now");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001264
1265 return false;
1266 }
1267
1268 return true;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001269}
1270
Kate Stoneb9c1b512016-09-06 20:57:50 +00001271// This function does not report errors; its callers are responsible.
1272bool IRForTarget::HandleSymbol(Value *symbol) {
1273 lldb_private::Log *log(
1274 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1275
1276 lldb_private::ConstString name(symbol->getName().str().c_str());
1277
1278 lldb::addr_t symbol_addr =
1279 m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1280
1281 if (symbol_addr == LLDB_INVALID_ADDRESS) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001282 LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001283
1284 return false;
1285 }
1286
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001287 LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001288
1289 Type *symbol_type = symbol->getType();
1290
1291 Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1292
1293 Value *symbol_addr_ptr =
1294 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1295
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001296 LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
1297 PrintValue(symbol_addr_ptr));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001298
1299 symbol->replaceAllUsesWith(symbol_addr_ptr);
1300
1301 return true;
1302}
1303
1304bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1305 lldb_private::Log *log(
1306 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1307
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001308 LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001309
1310 for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1311 op_index < num_ops; ++op_index)
Raphael Isemanndced4452019-08-09 07:59:18 +00001312 // conservatively believe that this is a store
1313 if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001314 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1315 "one of the arguments of a function call.\n");
1316
1317 return false;
1318 }
1319
1320 return true;
1321}
1322
1323bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1324 lldb_private::Log *log(
1325 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1326
1327 GlobalVariable *global_variable =
1328 dyn_cast<GlobalVariable>(classlist_reference);
1329
1330 if (!global_variable)
1331 return false;
1332
1333 Constant *initializer = global_variable->getInitializer();
1334
1335 if (!initializer)
1336 return false;
1337
1338 if (!initializer->hasName())
1339 return false;
1340
1341 StringRef name(initializer->getName());
1342 lldb_private::ConstString name_cstr(name.str().c_str());
1343 lldb::addr_t class_ptr =
1344 m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1345
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001346 LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
1347 (unsigned long long)class_ptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001348
1349 if (class_ptr == LLDB_INVALID_ADDRESS)
1350 return false;
1351
1352 if (global_variable->use_empty())
1353 return false;
1354
1355 SmallVector<LoadInst *, 2> load_instructions;
1356
1357 for (llvm::User *u : global_variable->users()) {
1358 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1359 load_instructions.push_back(load_instruction);
1360 }
1361
1362 if (load_instructions.empty())
1363 return false;
1364
1365 Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1366
1367 for (LoadInst *load_instruction : load_instructions) {
1368 Constant *class_bitcast =
1369 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1370
1371 load_instruction->replaceAllUsesWith(class_bitcast);
1372
1373 load_instruction->eraseFromParent();
1374 }
1375
1376 return true;
1377}
1378
1379bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001380 std::vector<CallInst *> calls_to_remove;
1381
Raphael Isemanndced4452019-08-09 07:59:18 +00001382 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001383 CallInst *call = dyn_cast<CallInst>(&inst);
1384
1385 // MaybeHandleCallArguments handles error reporting; we are silent here
1386 if (!call)
1387 continue;
1388
1389 bool remove = false;
1390
1391 llvm::Function *func = call->getCalledFunction();
1392
1393 if (func && func->getName() == "__cxa_atexit")
1394 remove = true;
1395
1396 llvm::Value *val = call->getCalledValue();
1397
1398 if (val && val->getName() == "__cxa_atexit")
1399 remove = true;
1400
1401 if (remove)
1402 calls_to_remove.push_back(call);
1403 }
1404
Raphael Isemanndced4452019-08-09 07:59:18 +00001405 for (CallInst *ci : calls_to_remove)
1406 ci->eraseFromParent();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001407
1408 return true;
1409}
1410
1411bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412 // Prepare the current basic block for execution in the remote process
Kate Stoneb9c1b512016-09-06 20:57:50 +00001413
Raphael Isemanndced4452019-08-09 07:59:18 +00001414 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001415 CallInst *call = dyn_cast<CallInst>(&inst);
1416
1417 // MaybeHandleCallArguments handles error reporting; we are silent here
1418 if (call && !MaybeHandleCallArguments(call))
1419 return false;
1420 }
1421
1422 return true;
1423}
1424
1425bool IRForTarget::ResolveExternals(Function &llvm_function) {
1426 lldb_private::Log *log(
1427 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1428
1429 for (GlobalVariable &global_var : m_module->globals()) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001430 llvm::StringRef global_name = global_var.getName();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001431
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001432 LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
1433 static_cast<void *>(DeclForGlobal(&global_var)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001434
Raphael Isemanna7040522019-08-08 21:43:21 +00001435 if (global_name.startswith("OBJC_IVAR")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001436 if (!HandleSymbol(&global_var)) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001437 m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
1438 "indirect ivar symbol {0}\n",
1439 global_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001440
1441 return false;
1442 }
Raphael Isemanna7040522019-08-08 21:43:21 +00001443 } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001444 if (!HandleObjCClass(&global_var)) {
1445 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1446 "for an Objective-C static method call\n");
1447
1448 return false;
1449 }
Raphael Isemanna7040522019-08-08 21:43:21 +00001450 } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001451 if (!HandleObjCClass(&global_var)) {
1452 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1453 "for an Objective-C static method call\n");
1454
1455 return false;
1456 }
1457 } else if (DeclForGlobal(&global_var)) {
1458 if (!MaybeHandleVariable(&global_var)) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001459 m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
1460 "external variable {0}\n",
1461 global_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001462
1463 return false;
1464 }
1465 }
1466 }
1467
1468 return true;
1469}
1470
1471static bool isGuardVariableRef(Value *V) {
Raphael Isemann7f7b2962019-08-13 13:09:18 +00001472 Constant *Old = dyn_cast<Constant>(V);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001473
Raphael Isemann7f7b2962019-08-13 13:09:18 +00001474 if (!Old)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001475 return false;
1476
Raphael Isemann7f7b2962019-08-13 13:09:18 +00001477 if (auto CE = dyn_cast<ConstantExpr>(V)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001478 if (CE->getOpcode() != Instruction::BitCast)
1479 return false;
1480
1481 Old = CE->getOperand(0);
1482 }
1483
1484 GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1485
Raphael Isemann7f7b2962019-08-13 13:09:18 +00001486 if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001487 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001488
1489 return true;
1490}
1491
1492void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1493 Constant *zero(Constant::getNullValue(guard_load->getType()));
1494 guard_load->replaceAllUsesWith(zero);
1495 guard_load->eraseFromParent();
1496}
1497
1498static void ExciseGuardStore(Instruction *guard_store) {
1499 guard_store->eraseFromParent();
1500}
1501
1502bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001503 // Eliminate any reference to guard variables found.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001504
1505 InstrList guard_loads;
1506 InstrList guard_stores;
1507
Raphael Isemanndced4452019-08-09 07:59:18 +00001508 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001509
1510 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1511 if (isGuardVariableRef(load->getPointerOperand()))
1512 guard_loads.push_back(&inst);
1513
1514 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1515 if (isGuardVariableRef(store->getPointerOperand()))
1516 guard_stores.push_back(&inst);
1517 }
1518
Raphael Isemanndced4452019-08-09 07:59:18 +00001519 for (Instruction *inst : guard_loads)
1520 TurnGuardLoadIntoZero(inst);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001521
Raphael Isemanndced4452019-08-09 07:59:18 +00001522 for (Instruction *inst : guard_stores)
1523 ExciseGuardStore(inst);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001524
1525 return true;
1526}
1527
1528// This function does not report errors; its callers are responsible.
1529bool IRForTarget::UnfoldConstant(Constant *old_constant,
1530 llvm::Function *llvm_function,
1531 FunctionValueCache &value_maker,
1532 FunctionValueCache &entry_instruction_finder,
1533 lldb_private::Stream &error_stream) {
1534 SmallVector<User *, 16> users;
1535
1536 // We do this because the use list might change, invalidating our iterator.
1537 // Much better to keep a work list ourselves.
1538 for (llvm::User *u : old_constant->users())
1539 users.push_back(u);
1540
1541 for (size_t i = 0; i < users.size(); ++i) {
1542 User *user = users[i];
1543
1544 if (Constant *constant = dyn_cast<Constant>(user)) {
1545 // synthesize a new non-constant equivalent of the constant
1546
1547 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1548 switch (constant_expr->getOpcode()) {
1549 default:
1550 error_stream.Printf("error [IRForTarget internal]: Unhandled "
1551 "constant expression type: \"%s\"",
1552 PrintValue(constant_expr).c_str());
1553 return false;
1554 case Instruction::BitCast: {
1555 FunctionValueCache bit_cast_maker(
1556 [&value_maker, &entry_instruction_finder, old_constant,
1557 constant_expr](llvm::Function *function) -> llvm::Value * {
1558 // UnaryExpr
1559 // OperandList[0] is value
1560
1561 if (constant_expr->getOperand(0) != old_constant)
1562 return constant_expr;
1563
1564 return new BitCastInst(
1565 value_maker.GetValue(function), constant_expr->getType(),
1566 "", llvm::cast<Instruction>(
1567 entry_instruction_finder.GetValue(function)));
1568 });
1569
1570 if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1571 entry_instruction_finder, error_stream))
1572 return false;
1573 } break;
1574 case Instruction::GetElementPtr: {
1575 // GetElementPtrConstantExpr
1576 // OperandList[0] is base
1577 // OperandList[1]... are indices
1578
1579 FunctionValueCache get_element_pointer_maker(
1580 [&value_maker, &entry_instruction_finder, old_constant,
1581 constant_expr](llvm::Function *function) -> llvm::Value * {
1582 Value *ptr = constant_expr->getOperand(0);
1583
1584 if (ptr == old_constant)
1585 ptr = value_maker.GetValue(function);
1586
1587 std::vector<Value *> index_vector;
1588
1589 unsigned operand_index;
1590 unsigned num_operands = constant_expr->getNumOperands();
1591
1592 for (operand_index = 1; operand_index < num_operands;
1593 ++operand_index) {
1594 Value *operand = constant_expr->getOperand(operand_index);
1595
1596 if (operand == old_constant)
1597 operand = value_maker.GetValue(function);
1598
1599 index_vector.push_back(operand);
1600 }
1601
1602 ArrayRef<Value *> indices(index_vector);
1603
1604 return GetElementPtrInst::Create(
1605 nullptr, ptr, indices, "",
1606 llvm::cast<Instruction>(
1607 entry_instruction_finder.GetValue(function)));
1608 });
1609
1610 if (!UnfoldConstant(constant_expr, llvm_function,
1611 get_element_pointer_maker,
1612 entry_instruction_finder, error_stream))
1613 return false;
1614 } break;
1615 }
1616 } else {
1617 error_stream.Printf(
1618 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1619 PrintValue(constant).c_str());
1620 return false;
1621 }
1622 } else {
1623 if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1624 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1625 error_stream.PutCString("error: Capturing non-local variables in "
1626 "expressions is unsupported.\n");
1627 return false;
1628 }
1629 inst->replaceUsesOfWith(
1630 old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1631 } else {
1632 error_stream.Printf(
1633 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1634 PrintValue(user).c_str());
1635 return false;
1636 }
1637 }
1638 }
1639
1640 if (!isa<GlobalValue>(old_constant)) {
1641 old_constant->destroyConstant();
1642 }
1643
1644 return true;
1645}
1646
1647bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1648 if (!m_resolve_vars)
1649 return true;
1650
1651 lldb_private::Log *log(
1652 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1653
1654 m_decl_map->DoStructLayout();
1655
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001656 LLDB_LOG(log, "Element arrangement:");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001657
1658 uint32_t num_elements;
1659 uint32_t element_index;
1660
1661 size_t size;
1662 lldb::offset_t alignment;
1663
1664 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1665 return false;
1666
Reid Kleckner20670ba2017-03-16 23:13:49 +00001667 Function::arg_iterator iter(llvm_function.arg_begin());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001668
Reid Kleckner20670ba2017-03-16 23:13:49 +00001669 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001670 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1671 "arguments (should take at least a struct pointer)");
1672
1673 return false;
1674 }
1675
1676 Argument *argument = &*iter;
1677
1678 if (argument->getName().equals("this")) {
1679 ++iter;
1680
Reid Kleckner20670ba2017-03-16 23:13:49 +00001681 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001682 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1683 "'this' argument (should take a struct pointer "
1684 "too)");
1685
1686 return false;
1687 }
1688
1689 argument = &*iter;
1690 } else if (argument->getName().equals("self")) {
1691 ++iter;
1692
Reid Kleckner20670ba2017-03-16 23:13:49 +00001693 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001694 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1695 "'self' argument (should take '_cmd' and a struct "
1696 "pointer too)");
1697
1698 return false;
1699 }
1700
1701 if (!iter->getName().equals("_cmd")) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001702 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
Kate Stoneb9c1b512016-09-06 20:57:50 +00001703 "after 'self' argument (should take '_cmd')",
Raphael Isemanna7040522019-08-08 21:43:21 +00001704 iter->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001705
1706 return false;
1707 }
1708
1709 ++iter;
1710
Reid Kleckner20670ba2017-03-16 23:13:49 +00001711 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001712 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1713 "'self' and '_cmd' arguments (should take a struct "
1714 "pointer too)");
1715
1716 return false;
1717 }
1718
1719 argument = &*iter;
1720 }
1721
1722 if (!argument->getName().equals("$__lldb_arg")) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001723 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
1724 "argument named '{0}' instead of the struct pointer",
1725 argument->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001726
1727 return false;
1728 }
1729
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001730 LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001731
1732 BasicBlock &entry_block(llvm_function.getEntryBlock());
1733 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1734
1735 if (!FirstEntryInstruction) {
1736 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1737 "first instruction in the wrapper for use in "
1738 "rewriting");
1739
1740 return false;
1741 }
1742
1743 LLVMContext &context(m_module->getContext());
1744 IntegerType *offset_type(Type::getInt32Ty(context));
1745
1746 if (!offset_type) {
1747 m_error_stream.Printf(
1748 "Internal error [IRForTarget]: Couldn't produce an offset type");
1749
1750 return false;
1751 }
1752
1753 for (element_index = 0; element_index < num_elements; ++element_index) {
Konrad Kleine248a1302019-05-23 11:14:47 +00001754 const clang::NamedDecl *decl = nullptr;
1755 Value *value = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001756 lldb::offset_t offset;
1757 lldb_private::ConstString name;
1758
1759 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1760 element_index)) {
1761 m_error_stream.Printf(
1762 "Internal error [IRForTarget]: Structure information is incomplete");
1763
1764 return false;
1765 }
1766
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001767 LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name,
1768 decl->getNameAsString(), offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001769
1770 if (value) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001771 LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001772
1773 FunctionValueCache body_result_maker(
1774 [this, name, offset_type, offset, argument,
1775 value](llvm::Function *function) -> llvm::Value * {
Adrian Prantl05097242018-04-30 16:49:04 +00001776 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
1777 // in cases where the result variable is an rvalue, we have to
1778 // synthesize a dereference of the appropriate structure entry in
1779 // order to produce the static variable that the AST thinks it is
1780 // accessing.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001781
1782 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1783 m_entry_instruction_finder.GetValue(function));
1784
1785 ConstantInt *offset_int(
1786 ConstantInt::get(offset_type, offset, true));
1787 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1788 nullptr, argument, offset_int, "", entry_instruction);
1789
1790 if (name == m_result_name && !m_result_is_pointer) {
1791 BitCastInst *bit_cast = new BitCastInst(
1792 get_element_ptr, value->getType()->getPointerTo(), "",
1793 entry_instruction);
1794
1795 LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1796
1797 return load;
1798 } else {
1799 BitCastInst *bit_cast = new BitCastInst(
1800 get_element_ptr, value->getType(), "", entry_instruction);
1801
1802 return bit_cast;
1803 }
1804 });
1805
1806 if (Constant *constant = dyn_cast<Constant>(value)) {
1807 if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
1808 m_entry_instruction_finder, m_error_stream)) {
1809 return false;
1810 }
1811 } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1812 if (instruction->getParent()->getParent() != &llvm_function) {
1813 m_error_stream.PutCString("error: Capturing non-local variables in "
1814 "expressions is unsupported.\n");
1815 return false;
1816 }
1817 value->replaceAllUsesWith(
1818 body_result_maker.GetValue(instruction->getParent()->getParent()));
1819 } else {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001820 LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
1821 PrintValue(value));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001822 return false;
1823 }
1824
1825 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1826 var->eraseFromParent();
1827 }
1828 }
1829
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001830 LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
1831 (uint64_t)size);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001832
1833 return true;
1834}
1835
Kate Stoneb9c1b512016-09-06 20:57:50 +00001836bool IRForTarget::runOnModule(Module &llvm_module) {
1837 lldb_private::Log *log(
1838 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1839
1840 m_module = &llvm_module;
1841 m_target_data.reset(new DataLayout(m_module));
1842 m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
1843 m_target_data->getPointerSizeInBits());
1844
1845 if (log) {
1846 std::string s;
1847 raw_string_ostream oss(s);
1848
Konrad Kleine248a1302019-05-23 11:14:47 +00001849 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001850
1851 oss.flush();
1852
Raphael Isemanna7040522019-08-08 21:43:21 +00001853 LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001854 }
1855
1856 Function *const main_function =
1857 m_func_name.IsEmpty() ? nullptr
1858 : m_module->getFunction(m_func_name.GetStringRef());
1859
1860 if (!m_func_name.IsEmpty() && !main_function) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001861 LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001862
Raphael Isemanna7040522019-08-08 21:43:21 +00001863 m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
1864 "'{0}' in the module",
1865 m_func_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001866
1867 return false;
1868 }
1869
1870 if (main_function) {
1871 if (!FixFunctionLinkage(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001872 LLDB_LOG(log, "Couldn't fix the linkage for the function");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001873
1874 return false;
1875 }
1876 }
1877
1878 llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
1879
1880 m_reloc_placeholder = new llvm::GlobalVariable(
1881 (*m_module), int8_ty, false /* IsConstant */,
1882 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
Konrad Kleine248a1302019-05-23 11:14:47 +00001883 "reloc_placeholder", nullptr /* InsertBefore */,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001884 GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
1885
1886 ////////////////////////////////////////////////////////////
1887 // Replace $__lldb_expr_result with a persistent variable
1888 //
1889
1890 if (main_function) {
1891 if (!CreateResultVariable(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001892 LLDB_LOG(log, "CreateResultVariable() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001893
1894 // CreateResultVariable() reports its own errors, so we don't do so here
1895
1896 return false;
1897 }
1898 }
1899
1900 if (log && log->GetVerbose()) {
1901 std::string s;
1902 raw_string_ostream oss(s);
1903
Konrad Kleine248a1302019-05-23 11:14:47 +00001904 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001905
1906 oss.flush();
1907
Raphael Isemanna7040522019-08-08 21:43:21 +00001908 LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001909 }
1910
Raphael Isemanndced4452019-08-09 07:59:18 +00001911 for (llvm::Function &function : *m_module) {
1912 for (BasicBlock &bb : function) {
1913 if (!RemoveGuards(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001914 LLDB_LOG(log, "RemoveGuards() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001915
1916 // RemoveGuards() reports its own errors, so we don't do so here
1917
1918 return false;
1919 }
1920
Raphael Isemanndced4452019-08-09 07:59:18 +00001921 if (!RewritePersistentAllocs(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001922 LLDB_LOG(log, "RewritePersistentAllocs() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001923
1924 // RewritePersistentAllocs() reports its own errors, so we don't do so
1925 // here
1926
1927 return false;
1928 }
1929
Raphael Isemanndced4452019-08-09 07:59:18 +00001930 if (!RemoveCXAAtExit(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001931 LLDB_LOG(log, "RemoveCXAAtExit() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001932
1933 // RemoveCXAAtExit() reports its own errors, so we don't do so here
1934
1935 return false;
1936 }
1937 }
1938 }
1939
1940 ///////////////////////////////////////////////////////////////////////////////
1941 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
1942 //
1943
1944 if (!RewriteObjCConstStrings()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001945 LLDB_LOG(log, "RewriteObjCConstStrings() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001946
1947 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
1948
1949 return false;
1950 }
1951
Raphael Isemanndced4452019-08-09 07:59:18 +00001952 for (llvm::Function &function : *m_module) {
1953 for (llvm::BasicBlock &bb : function) {
1954 if (!RewriteObjCSelectors(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001955 LLDB_LOG(log, "RewriteObjCSelectors() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001956
Adrian Prantl05097242018-04-30 16:49:04 +00001957 // RewriteObjCSelectors() reports its own errors, so we don't do so
1958 // here
Kate Stoneb9c1b512016-09-06 20:57:50 +00001959
1960 return false;
1961 }
Sean Callananac900582016-09-29 00:45:33 +00001962
Raphael Isemanndced4452019-08-09 07:59:18 +00001963 if (!RewriteObjCClassReferences(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001964 LLDB_LOG(log, "RewriteObjCClassReferences() failed");
Sean Callananac900582016-09-29 00:45:33 +00001965
1966 // RewriteObjCClasses() reports its own errors, so we don't do so here
1967
1968 return false;
1969 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001970 }
1971 }
1972
Raphael Isemanndced4452019-08-09 07:59:18 +00001973 for (llvm::Function &function : *m_module) {
1974 for (BasicBlock &bb : function) {
1975 if (!ResolveCalls(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001976 LLDB_LOG(log, "ResolveCalls() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001977
1978 // ResolveCalls() reports its own errors, so we don't do so here
1979
1980 return false;
1981 }
1982 }
1983 }
1984
1985 ////////////////////////////////////////////////////////////////////////
1986 // Run function-level passes that only make sense on the main function
1987 //
1988
1989 if (main_function) {
1990 if (!ResolveExternals(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001991 LLDB_LOG(log, "ResolveExternals() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001992
1993 // ResolveExternals() reports its own errors, so we don't do so here
1994
1995 return false;
1996 }
1997
1998 if (!ReplaceVariables(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001999 LLDB_LOG(log, "ReplaceVariables() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002000
2001 // ReplaceVariables() reports its own errors, so we don't do so here
2002
2003 return false;
2004 }
2005 }
2006
2007 if (log && log->GetVerbose()) {
2008 std::string s;
2009 raw_string_ostream oss(s);
2010
Konrad Kleine248a1302019-05-23 11:14:47 +00002011 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002012
2013 oss.flush();
2014
Raphael Isemanna7040522019-08-08 21:43:21 +00002015 LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002016 }
2017
2018 return true;
2019}
2020
2021void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2022 PassManagerType pass_mgr_type) {}
2023
2024PassManagerType IRForTarget::getPotentialPassManagerType() const {
2025 return PMT_ModulePassManager;
Sean Callanan2ab712f22010-07-03 01:35:46 +00002026}