blob: 53c57e9e319d0dadaade143f2835a312605a5406 [file] [log] [blame]
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
Sean Callanan2ab712f22010-07-03 01:35:46 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Sean Callanan4dbb2712015-09-25 20:35:58 +000010#include "IRForTarget.h"
11
12#include "ClangExpressionDeclMap.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000013
Chandler Carruth1e157582013-01-02 12:20:07 +000014#include "llvm/IR/Constants.h"
15#include "llvm/IR/DataLayout.h"
16#include "llvm/IR/InstrTypes.h"
17#include "llvm/IR/Instructions.h"
18#include "llvm/IR/Intrinsics.h"
Ilia Kc9a475d2015-02-13 10:49:18 +000019#include "llvm/IR/LegacyPassManager.h"
Zachary Turner543afa12014-12-09 22:29:47 +000020#include "llvm/IR/Metadata.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "llvm/IR/Module.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000022#include "llvm/IR/ValueSymbolTable.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "llvm/Support/raw_ostream.h"
24#include "llvm/Transforms/IPO.h"
Sean Callanan549c9f72010-07-13 21:41:46 +000025
26#include "clang/AST/ASTContext.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000027
Sean Callanan8dfb68e2013-03-19 00:10:07 +000028#include "lldb/Core/ConstString.h"
29#include "lldb/Core/DataBufferHeap.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000030#include "lldb/Core/Log.h"
31#include "lldb/Core/Scalar.h"
32#include "lldb/Core/StreamString.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000033#include "lldb/Core/dwarf.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000034#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000035#include "lldb/Expression/IRInterpreter.h"
Sean Callanan79763a42011-05-23 21:40:23 +000036#include "lldb/Host/Endian.h"
Sean Callanan63697e52011-05-07 01:06:41 +000037#include "lldb/Symbol/ClangASTContext.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000038#include "lldb/Symbol/ClangUtil.h"
Greg Claytona1e5dc82015-08-11 22:53:00 +000039#include "lldb/Symbol/CompilerType.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000040
41#include <map>
42
43using namespace llvm;
44
Sean Callananeaacbc92010-08-18 18:50:51 +000045static char ID;
46
Kate Stoneb9c1b512016-09-06 20:57:50 +000047IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
48 : m_maker(maker), m_values() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000049
Kate Stoneb9c1b512016-09-06 20:57:50 +000050IRForTarget::FunctionValueCache::~FunctionValueCache() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000051
Greg Clayton526ae042015-02-12 00:34:25 +000052llvm::Value *
Kate Stoneb9c1b512016-09-06 20:57:50 +000053IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
54 if (!m_values.count(function)) {
55 llvm::Value *ret = m_maker(function);
56 m_values[function] = ret;
57 return ret;
58 }
59 return m_values[function];
Sean Callanan1f9db3e2013-06-28 21:44:15 +000060}
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062static llvm::Value *FindEntryInstruction(llvm::Function *function) {
63 if (function->empty())
64 return NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 return function->getEntryBlock().getFirstNonPHIOrDbg();
Sean Callanan1f9db3e2013-06-28 21:44:15 +000067}
68
Kate Stoneb9c1b512016-09-06 20:57:50 +000069IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
70 bool resolve_vars,
71 lldb_private::IRExecutionUnit &execution_unit,
72 lldb_private::Stream &error_stream,
73 const char *func_name)
74 : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
75 m_module(NULL), m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL),
Sean Callananac900582016-09-29 00:45:33 +000076 m_sel_registerName(NULL), m_objc_getClass(NULL), m_intptr_ty(NULL),
77 m_error_stream(error_stream),
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 m_execution_unit(execution_unit), m_result_store(NULL),
79 m_result_is_pointer(false), m_reloc_placeholder(NULL),
80 m_entry_instruction_finder(FindEntryInstruction) {}
Sean Callanan2ab712f22010-07-03 01:35:46 +000081
Sean Callanan038df5032010-09-30 21:18:25 +000082/* Handy utility functions used at several places in the code */
Sean Callanan2235f322010-08-11 03:57:18 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084static std::string PrintValue(const Value *value, bool truncate = false) {
85 std::string s;
86 if (value) {
Sean Callanan038df5032010-09-30 21:18:25 +000087 raw_string_ostream rso(s);
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 value->print(rso);
Sean Callanan038df5032010-09-30 21:18:25 +000089 rso.flush();
90 if (truncate)
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 s.resize(s.length() - 1);
92 }
93 return s;
Sean Callanan038df5032010-09-30 21:18:25 +000094}
95
Kate Stoneb9c1b512016-09-06 20:57:50 +000096static std::string PrintType(const llvm::Type *type, bool truncate = false) {
97 std::string s;
98 raw_string_ostream rso(s);
99 type->print(rso);
100 rso.flush();
101 if (truncate)
102 s.resize(s.length() - 1);
103 return s;
Sean Callanan2ab712f22010-07-03 01:35:46 +0000104}
105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106IRForTarget::~IRForTarget() {}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
109 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
110
111 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000112}
113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
115 Module *module) {
116 NamedMDNode *named_metadata =
117 module->getNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 if (!named_metadata)
Sean Callanan63697e52011-05-07 01:06:41 +0000120 return NULL;
Sean Callanan63697e52011-05-07 01:06:41 +0000121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 unsigned num_nodes = named_metadata->getNumOperands();
123 unsigned node_index;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 for (node_index = 0; node_index < num_nodes; ++node_index) {
126 llvm::MDNode *metadata_node =
127 dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
128 if (!metadata_node)
129 return NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 if (metadata_node->getNumOperands() != 2)
132 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 if (mdconst::dyn_extract_or_null<GlobalValue>(
135 metadata_node->getOperand(0)) != global_val)
136 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000137
Kate Stoneb9c1b512016-09-06 20:57:50 +0000138 ConstantInt *constant_int =
139 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000140
Sean Callanan2235f322010-08-11 03:57:18 +0000141 if (!constant_int)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 return NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000143
Sean Callanan2235f322010-08-11 03:57:18 +0000144 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 return reinterpret_cast<clang::NamedDecl *>(ptr);
147 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000148
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 return NULL;
150}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000151
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
153 return DeclForGlobal(global_val, m_module);
154}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000155
Kate Stoneb9c1b512016-09-06 20:57:50 +0000156bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
157 lldb_private::Log *log(
158 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160 if (!m_resolve_vars)
161 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 // Find the result variable. If it doesn't exist, we can give up right here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 std::string result_name_str;
168 const char *result_name = NULL;
Sean Callanan2235f322010-08-11 03:57:18 +0000169
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
171 ve = value_symbol_table.end();
172 vi != ve; ++vi) {
173 result_name_str = vi->first().str();
174 const char *value_name = result_name_str.c_str();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 if (strstr(value_name, "$__lldb_expr_result_ptr") &&
177 strncmp(value_name, "_ZGV", 4)) {
178 result_name = value_name;
179 m_result_is_pointer = true;
180 break;
181 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000182
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 if (strstr(value_name, "$__lldb_expr_result") &&
184 strncmp(value_name, "_ZGV", 4)) {
185 result_name = value_name;
186 m_result_is_pointer = false;
187 break;
188 }
189 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 if (!result_name) {
Sean Callanane1175b72011-01-13 21:23:32 +0000192 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 log->PutCString("Couldn't find result variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000194
Sean Callanan2235f322010-08-11 03:57:18 +0000195 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000196 }
Sean Callanan2235f322010-08-11 03:57:18 +0000197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 if (log)
199 log->Printf("Result name: \"%s\"", result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000200
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 Value *result_value = m_module->getNamedValue(result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000202
Kate Stoneb9c1b512016-09-06 20:57:50 +0000203 if (!result_value) {
204 if (log)
205 log->PutCString("Result variable had no data");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
208 "name (%s) exists, but not its definition\n",
209 result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000210
Sean Callananc70ed462011-10-25 18:36:40 +0000211 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212 }
Sean Callananc70ed462011-10-25 18:36:40 +0000213
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 if (log)
215 log->Printf("Found result in the IR: \"%s\"",
216 PrintValue(result_value, false).c_str());
217
218 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
219
220 if (!result_global) {
221 if (log)
222 log->PutCString("Result variable isn't a GlobalVariable");
223
224 m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
225 "is defined, but is not a global variable\n",
226 result_name);
227
228 return false;
229 }
230
231 clang::NamedDecl *result_decl = DeclForGlobal(result_global);
232 if (!result_decl) {
233 if (log)
234 log->PutCString("Result variable doesn't have a corresponding Decl");
235
236 m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
237 "does not have a corresponding Clang entity\n",
238 result_name);
239
240 return false;
241 }
242
243 if (log) {
244 std::string decl_desc_str;
245 raw_string_ostream decl_desc_stream(decl_desc_str);
246 result_decl->print(decl_desc_stream);
247 decl_desc_stream.flush();
248
249 log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
250 }
251
252 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
253 if (!result_var) {
254 if (log)
255 log->PutCString("Result variable Decl isn't a VarDecl");
256
257 m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
258 "(%s)'s corresponding Clang entity isn't a "
259 "variable\n",
260 result_name);
261
262 return false;
263 }
264
265 // Get the next available result name from m_decl_map and create the
266 // persistent
267 // variable for it
268
269 // If the result is an Lvalue, it is emitted as a pointer; see
270 // ASTResultSynthesizer::SynthesizeBodyResult.
271 if (m_result_is_pointer) {
272 clang::QualType pointer_qual_type = result_var->getType();
273 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
274
275 const clang::PointerType *pointer_pointertype =
276 pointer_type->getAs<clang::PointerType>();
277 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
278 pointer_type->getAs<clang::ObjCObjectPointerType>();
279
280 if (pointer_pointertype) {
281 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
282
283 m_result_type = lldb_private::TypeFromParser(
284 element_qual_type.getAsOpaquePtr(),
285 lldb_private::ClangASTContext::GetASTContext(
286 &result_decl->getASTContext()));
287 } 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(
292 element_qual_type.getAsOpaquePtr(),
293 lldb_private::ClangASTContext::GetASTContext(
294 &result_decl->getASTContext()));
295 } else {
296 if (log)
297 log->PutCString("Expected result to have pointer type, but it did not");
298
299 m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
300 "is not a pointer variable\n",
301 result_name);
302
303 return false;
304 }
305 } else {
306 m_result_type = lldb_private::TypeFromParser(
307 result_var->getType().getAsOpaquePtr(),
308 lldb_private::ClangASTContext::GetASTContext(
309 &result_decl->getASTContext()));
310 }
311
312 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
313 lldb_private::ExecutionContext exe_ctx(target_sp, true);
314 if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) {
315 lldb_private::StreamString type_desc_stream;
316 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000317
Sean Callanand7a1ca22010-12-02 19:47:57 +0000318 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 log->Printf("Result type has size 0");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000320
Kate Stoneb9c1b512016-09-06 20:57:50 +0000321 m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
322 "couldn't be determined\n",
323 type_desc_stream.GetData());
324 return false;
325 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000326
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 if (log) {
328 lldb_private::StreamString type_desc_stream;
329 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000330
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331 log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
332 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000333
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334 m_result_name = lldb_private::ConstString("$RESULT_NAME");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336 if (log)
337 log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
338 m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000339
Kate Stoneb9c1b512016-09-06 20:57:50 +0000340 // Construct a new result global and set up its metadata
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000341
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342 GlobalVariable *new_result_global = new GlobalVariable(
343 (*m_module), result_global->getType()->getElementType(),
344 false, /* not constant */
345 GlobalValue::ExternalLinkage, NULL, /* no initializer */
346 m_result_name.GetCString());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000347
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348 // It's too late in compilation to create a new VarDecl for this, but we don't
349 // need to. We point the metadata at the old VarDecl. This creates an odd
350 // anomaly: a variable with a Value whose name is something like $0 and a
351 // Decl whose name is $__lldb_expr_result. This condition is handled in
352 // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
353 // fixed up.
Greg Clayton57ee3062013-07-11 22:46:58 +0000354
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 ConstantInt *new_constant_int =
356 ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
357 reinterpret_cast<uint64_t>(result_decl), false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 llvm::Metadata *values[2];
360 values[0] = ConstantAsMetadata::get(new_result_global);
361 values[1] = ConstantAsMetadata::get(new_constant_int);
Greg Clayton57ee3062013-07-11 22:46:58 +0000362
Kate Stoneb9c1b512016-09-06 20:57:50 +0000363 ArrayRef<Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
366 NamedMDNode *named_metadata =
367 m_module->getNamedMetadata("clang.global.decl.ptrs");
368 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000369
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370 if (log)
371 log->Printf("Replacing \"%s\" with \"%s\"",
372 PrintValue(result_global).c_str(),
373 PrintValue(new_result_global).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000374
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 if (result_global->use_empty()) {
376 // We need to synthesize a store for this variable, because otherwise
377 // there's nothing to put into its equivalent persistent variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000378
Greg Clayton1b95a6f2010-11-19 01:05:25 +0000379 BasicBlock &entry_block(llvm_function.getEntryBlock());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000381
Kate Stoneb9c1b512016-09-06 20:57:50 +0000382 if (!first_entry_instruction)
383 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000384
Kate Stoneb9c1b512016-09-06 20:57:50 +0000385 if (!result_global->hasInitializer()) {
386 if (log)
387 log->Printf("Couldn't find initializer for unused variable");
388
389 m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
390 "(%s) has no writes and no initializer\n",
391 result_name);
392
393 return false;
Sean Callanan3989fb92011-01-27 01:07:04 +0000394 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000395
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396 Constant *initializer = result_global->getInitializer();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000397
Kate Stoneb9c1b512016-09-06 20:57:50 +0000398 StoreInst *synthesized_store =
399 new StoreInst(initializer, new_result_global, first_entry_instruction);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000400
Kate Stoneb9c1b512016-09-06 20:57:50 +0000401 if (log)
402 log->Printf("Synthesized result store \"%s\"\n",
403 PrintValue(synthesized_store).c_str());
404 } else {
405 result_global->replaceAllUsesWith(new_result_global);
406 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000407
Kate Stoneb9c1b512016-09-06 20:57:50 +0000408 if (!m_decl_map->AddPersistentVariable(
409 result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
410 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000411
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412 result_global->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000413
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 return true;
415}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000416
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
418 llvm::GlobalVariable *cstr) {
419 lldb_private::Log *log(
420 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 Type *ns_str_ty = ns_str->getType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000423
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424 Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
425 Type *i32_ty = Type::getInt32Ty(m_module->getContext());
426 Type *i8_ty = Type::getInt8Ty(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 if (!m_CFStringCreateWithBytes) {
429 lldb::addr_t CFStringCreateWithBytes_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000430
Kate Stoneb9c1b512016-09-06 20:57:50 +0000431 static lldb_private::ConstString g_CFStringCreateWithBytes_str(
432 "CFStringCreateWithBytes");
Sean Callanan1f9db3e2013-06-28 21:44:15 +0000433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 CFStringCreateWithBytes_addr =
435 m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str);
436 if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) {
437 if (log)
438 log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000439
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440 m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
441 "constant string requires "
442 "CFStringCreateWithBytes\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 return false;
Sean Callanan549c9f72010-07-13 21:41:46 +0000445 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000446
Sean Callanan549c9f72010-07-13 21:41:46 +0000447 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448 log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
449 CFStringCreateWithBytes_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000450
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 // Build the function type:
452 //
453 // CFStringRef CFStringCreateWithBytes (
454 // CFAllocatorRef alloc,
455 // const UInt8 *bytes,
456 // CFIndex numBytes,
457 // CFStringEncoding encoding,
458 // Boolean isExternalRepresentation
459 // );
460 //
461 // We make the following substitutions:
462 //
463 // CFStringRef -> i8*
464 // CFAllocatorRef -> i8*
465 // UInt8 * -> i8*
466 // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
467 // pointer size for now)
468 // CFStringEncoding -> i32
469 // Boolean -> i8
470
471 Type *arg_type_array[5];
472
473 arg_type_array[0] = i8_ptr_ty;
474 arg_type_array[1] = i8_ptr_ty;
475 arg_type_array[2] = m_intptr_ty;
476 arg_type_array[3] = i32_ty;
477 arg_type_array[4] = i8_ty;
478
479 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
480
481 llvm::Type *CFSCWB_ty =
482 FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
483
484 // Build the constant containing the pointer to the function
485 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
486 Constant *CFSCWB_addr_int =
487 ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
488 m_CFStringCreateWithBytes =
489 ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
490 }
491
492 ConstantDataSequential *string_array = NULL;
493
494 if (cstr)
495 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
496
497 Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
498 Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
499 : Constant::getNullValue(i8_ptr_ty);
500 Constant *numBytes_arg = ConstantInt::get(
Sean Callanancd1eb722016-12-01 17:46:51 +0000501 m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
502 int encoding_flags = 0;
503 switch (string_array->getElementByteSize()) {
504 case 1:
505 encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
506 break;
507 case 2:
508 encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
509 break;
510 case 4:
511 encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
512 break;
513 default:
514 encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
515 if (log) {
516 log->Printf("Encountered an Objective-C constant string with unusual "
517 "element size %llu",
518 string_array->getElementByteSize());
519 }
520 }
521 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
522 Constant *isExternal_arg =
523 ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000524
Sean Callanancd1eb722016-12-01 17:46:51 +0000525 Value *argument_array[5];
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526
Sean Callanancd1eb722016-12-01 17:46:51 +0000527 argument_array[0] = alloc_arg;
528 argument_array[1] = bytes_arg;
529 argument_array[2] = numBytes_arg;
530 argument_array[3] = encoding_arg;
531 argument_array[4] = isExternal_arg;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000532
Sean Callanancd1eb722016-12-01 17:46:51 +0000533 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000534
Sean Callanancd1eb722016-12-01 17:46:51 +0000535 FunctionValueCache CFSCWB_Caller(
536 [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
537 return CallInst::Create(
538 m_CFStringCreateWithBytes, CFSCWB_arguments,
539 "CFStringCreateWithBytes",
540 llvm::cast<Instruction>(
541 m_entry_instruction_finder.GetValue(function)));
542 });
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543
Sean Callanancd1eb722016-12-01 17:46:51 +0000544 if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
545 m_error_stream)) {
546 if (log)
547 log->PutCString(
548 "Couldn't replace the NSString with the result of the call");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549
Sean Callanancd1eb722016-12-01 17:46:51 +0000550 m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
551 "Objective-C constant string with a dynamic "
552 "string\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553
Sean Callanancd1eb722016-12-01 17:46:51 +0000554 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 }
556
557 ns_str->eraseFromParent();
558
559 return true;
Sean Callanan549c9f72010-07-13 21:41:46 +0000560}
561
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562bool IRForTarget::RewriteObjCConstStrings() {
563 lldb_private::Log *log(
564 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000565
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000567
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568 for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
569 ve = value_symbol_table.end();
570 vi != ve; ++vi) {
571 std::string value_name = vi->first().str();
572 const char *value_name_cstr = value_name.c_str();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000573
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
575 Value *nsstring_value = vi->second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000576
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577 GlobalVariable *nsstring_global =
578 dyn_cast<GlobalVariable>(nsstring_value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000579
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 if (!nsstring_global) {
581 if (log)
582 log->PutCString("NSString variable is not a GlobalVariable");
583
584 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
585 "constant string is not a global variable\n");
586
587 return false;
588 }
589
590 if (!nsstring_global->hasInitializer()) {
591 if (log)
592 log->PutCString("NSString variable does not have an initializer");
593
594 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
595 "constant string does not have an initializer\n");
596
597 return false;
598 }
599
600 ConstantStruct *nsstring_struct =
601 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
602
603 if (!nsstring_struct) {
604 if (log)
605 log->PutCString(
606 "NSString variable's initializer is not a ConstantStruct");
607
608 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
609 "constant string is not a structure constant\n");
610
611 return false;
612 }
613
614 // We expect the following structure:
615 //
616 // struct {
617 // int *isa;
618 // int flags;
619 // char *str;
620 // long length;
621 // };
622
623 if (nsstring_struct->getNumOperands() != 4) {
624 if (log)
625 log->Printf("NSString variable's initializer structure has an "
626 "unexpected number of members. Should be 4, is %d",
627 nsstring_struct->getNumOperands());
628
629 m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
630 "Objective-C constant string is not as "
631 "expected\n");
632
633 return false;
634 }
635
636 Constant *nsstring_member = nsstring_struct->getOperand(2);
637
638 if (!nsstring_member) {
639 if (log)
640 log->PutCString("NSString initializer's str element was empty");
641
642 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
643 "constant string does not have a string "
644 "initializer\n");
645
646 return false;
647 }
648
649 ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
650
651 if (!nsstring_expr) {
652 if (log)
653 log->PutCString(
654 "NSString initializer's str element is not a ConstantExpr");
655
656 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
657 "constant string's string initializer is not "
658 "constant\n");
659
660 return false;
661 }
662
Sean Callanancd1eb722016-12-01 17:46:51 +0000663 GlobalVariable *cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664
Sean Callanancd1eb722016-12-01 17:46:51 +0000665 if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
666 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
667 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
668 } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
669 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
670 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000671 }
672
Kate Stoneb9c1b512016-09-06 20:57:50 +0000673 if (!cstr_global) {
674 if (log)
675 log->PutCString(
676 "NSString initializer's str element is not a GlobalVariable");
677
Sean Callanancd1eb722016-12-01 17:46:51 +0000678 m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
679 "constant string initializer\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680
681 return false;
682 }
683
684 if (!cstr_global->hasInitializer()) {
685 if (log)
686 log->PutCString("NSString initializer's str element does not have an "
687 "initializer");
688
689 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
690 "constant string's string initializer doesn't "
691 "point to initialized data\n");
692
693 return false;
694 }
695
696 /*
697 if (!cstr_array)
698 {
699 if (log)
700 log->PutCString("NSString initializer's str element is not a
701 ConstantArray");
702
703 if (m_error_stream)
704 m_error_stream.Printf("Internal error [IRForTarget]: An
705 Objective-C constant string's string initializer doesn't point to an
706 array\n");
707
708 return false;
709 }
710
711 if (!cstr_array->isCString())
712 {
713 if (log)
714 log->PutCString("NSString initializer's str element is not a C
715 string array");
716
717 if (m_error_stream)
718 m_error_stream.Printf("Internal error [IRForTarget]: An
719 Objective-C constant string's string initializer doesn't point to a C
720 string\n");
721
722 return false;
723 }
724 */
725
726 ConstantDataArray *cstr_array =
727 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
728
729 if (log) {
730 if (cstr_array)
731 log->Printf("Found NSString constant %s, which contains \"%s\"",
732 value_name_cstr, cstr_array->getAsString().str().c_str());
733 else
734 log->Printf("Found NSString constant %s, which contains \"\"",
735 value_name_cstr);
736 }
737
738 if (!cstr_array)
739 cstr_global = NULL;
740
741 if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
742 if (log)
743 log->PutCString("Error rewriting the constant string");
744
745 // We don't print an error message here because RewriteObjCConstString
746 // has done so for us.
747
748 return false;
749 }
750 }
751 }
752
753 for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
754 ve = value_symbol_table.end();
755 vi != ve; ++vi) {
756 std::string value_name = vi->first().str();
757 const char *value_name_cstr = value_name.c_str();
758
759 if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
760 GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
761
762 if (!gv) {
763 if (log)
764 log->PutCString(
765 "__CFConstantStringClassReference is not a global variable");
766
767 m_error_stream.Printf("Internal error [IRForTarget]: Found a "
768 "CFConstantStringClassReference, but it is not a "
769 "global object\n");
770
771 return false;
772 }
773
774 gv->eraseFromParent();
775
776 break;
777 }
778 }
779
780 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000781}
782
Kate Stoneb9c1b512016-09-06 20:57:50 +0000783static bool IsObjCSelectorRef(Value *value) {
784 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000785
Kate Stoneb9c1b512016-09-06 20:57:50 +0000786 if (!global_variable || !global_variable->hasName() ||
787 !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
788 return false;
789
790 return true;
791}
792
793// This function does not report errors; its callers are responsible.
794bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
795 lldb_private::Log *log(
796 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
797
798 LoadInst *load = dyn_cast<LoadInst>(selector_load);
799
800 if (!load)
801 return false;
802
803 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
804 // gets represented as
805 //
806 // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
807 // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...)
808 // ; <i8*>
809 //
810 // where %obj is the object pointer and %tmp is the selector.
811 //
812 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
813 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
814 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
815
816 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
817 // and get the string from its target
818
819 GlobalVariable *_objc_selector_references_ =
820 dyn_cast<GlobalVariable>(load->getPointerOperand());
821
822 if (!_objc_selector_references_ ||
823 !_objc_selector_references_->hasInitializer())
824 return false;
825
826 Constant *osr_initializer = _objc_selector_references_->getInitializer();
827
828 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
829
830 if (!osr_initializer_expr ||
831 osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
832 return false;
833
834 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
835
836 if (!osr_initializer_base)
837 return false;
838
839 // Find the string's initializer (a ConstantArray) and get the string from it
840
841 GlobalVariable *_objc_meth_var_name_ =
842 dyn_cast<GlobalVariable>(osr_initializer_base);
843
844 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
845 return false;
846
847 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
848
849 ConstantDataArray *omvn_initializer_array =
850 dyn_cast<ConstantDataArray>(omvn_initializer);
851
852 if (!omvn_initializer_array->isString())
853 return false;
854
855 std::string omvn_initializer_string = omvn_initializer_array->getAsString();
856
857 if (log)
858 log->Printf("Found Objective-C selector reference \"%s\"",
859 omvn_initializer_string.c_str());
860
861 // Construct a call to sel_registerName
862
863 if (!m_sel_registerName) {
864 lldb::addr_t sel_registerName_addr;
865
866 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
867 sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str);
868 if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
869 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000870
Sean Callananc70ed462011-10-25 18:36:40 +0000871 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 log->Printf("Found sel_registerName at 0x%" PRIx64,
873 sel_registerName_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000874
Kate Stoneb9c1b512016-09-06 20:57:50 +0000875 // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000876
Kate Stoneb9c1b512016-09-06 20:57:50 +0000877 // The below code would be "more correct," but in actuality what's required
878 // is uint8_t*
879 // Type *sel_type = StructType::get(m_module->getContext());
880 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
881 Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000882
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883 Type *type_array[1];
884
885 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
886
887 ArrayRef<Type *> srN_arg_types(type_array, 1);
888
889 llvm::Type *srN_type =
890 FunctionType::get(sel_ptr_type, srN_arg_types, false);
891
892 // Build the constant containing the pointer to the function
893 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
894 Constant *srN_addr_int =
895 ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
896 m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
897 }
898
899 Value *argument_array[1];
900
901 Constant *omvn_pointer = ConstantExpr::getBitCast(
902 _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
903
904 argument_array[0] = omvn_pointer;
905
906 ArrayRef<Value *> srN_arguments(argument_array, 1);
907
908 CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
909 "sel_registerName", selector_load);
910
911 // Replace the load with the call in all users
912
913 selector_load->replaceAllUsesWith(srN_call);
914
915 selector_load->eraseFromParent();
916
917 return true;
918}
919
920bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
921 lldb_private::Log *log(
922 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
923
924 BasicBlock::iterator ii;
925
926 typedef SmallVector<Instruction *, 2> InstrList;
927 typedef InstrList::iterator InstrIterator;
928
929 InstrList selector_loads;
930
931 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
932 Instruction &inst = *ii;
933
934 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
935 if (IsObjCSelectorRef(load->getPointerOperand()))
936 selector_loads.push_back(&inst);
937 }
938
939 InstrIterator iter;
940
941 for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
942 if (!RewriteObjCSelector(*iter)) {
943 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
944 "static reference to an Objective-C selector to a "
945 "dynamic reference\n");
946
947 if (log)
948 log->PutCString(
949 "Couldn't rewrite a reference to an Objective-C selector");
950
951 return false;
Sean Callananc70ed462011-10-25 18:36:40 +0000952 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000953 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000954
Kate Stoneb9c1b512016-09-06 20:57:50 +0000955 return true;
956}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000957
Sean Callananac900582016-09-29 00:45:33 +0000958static bool IsObjCClassReference(Value *value) {
959 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
960
961 if (!global_variable || !global_variable->hasName() ||
962 !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"))
963 return false;
964
965 return true;
966}
967
968// This function does not report errors; its callers are responsible.
969bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
970 lldb_private::Log *log(
971 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
972
973 LoadInst *load = dyn_cast<LoadInst>(class_load);
974
975 if (!load)
976 return false;
977
978 // Unpack the class name from the reference. In LLVM IR, a reference to an
979 // Objective-C class gets represented as
980 //
981 // %tmp = load %struct._objc_class*,
982 // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
983 //
984 // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
985 // @OBJC_CLASS_NAME_.
986 // @OBJC_CLASS_NAME contains the string.
987
988 // Find the pointer's initializer (a ConstantExpr with opcode BitCast)
989 // and get the string from its target
990
991 GlobalVariable *_objc_class_references_ =
992 dyn_cast<GlobalVariable>(load->getPointerOperand());
993
994 if (!_objc_class_references_ ||
995 !_objc_class_references_->hasInitializer())
996 return false;
997
998 Constant *ocr_initializer = _objc_class_references_->getInitializer();
999
1000 ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
1001
1002 if (!ocr_initializer_expr ||
1003 ocr_initializer_expr->getOpcode() != Instruction::BitCast)
1004 return false;
1005
1006 Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
1007
1008 if (!ocr_initializer_base)
1009 return false;
1010
1011 // Find the string's initializer (a ConstantArray) and get the string from it
1012
1013 GlobalVariable *_objc_class_name_ =
1014 dyn_cast<GlobalVariable>(ocr_initializer_base);
1015
1016 if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
1017 return false;
1018
1019 Constant *ocn_initializer = _objc_class_name_->getInitializer();
1020
1021 ConstantDataArray *ocn_initializer_array =
1022 dyn_cast<ConstantDataArray>(ocn_initializer);
1023
1024 if (!ocn_initializer_array->isString())
1025 return false;
1026
1027 std::string ocn_initializer_string = ocn_initializer_array->getAsString();
1028
1029 if (log)
1030 log->Printf("Found Objective-C class reference \"%s\"",
1031 ocn_initializer_string.c_str());
1032
1033 // Construct a call to objc_getClass
1034
1035 if (!m_objc_getClass) {
1036 lldb::addr_t objc_getClass_addr;
1037
1038 static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
1039 objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str);
1040 if (objc_getClass_addr == LLDB_INVALID_ADDRESS)
1041 return false;
1042
1043 if (log)
1044 log->Printf("Found objc_getClass at 0x%" PRIx64,
1045 objc_getClass_addr);
1046
1047 // Build the function type: %struct._objc_class *objc_getClass(i8*)
1048
1049 Type *class_type = load->getType();
1050 Type *type_array[1];
1051 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
1052
1053 ArrayRef<Type *> ogC_arg_types(type_array, 1);
1054
1055 llvm::Type *ogC_type =
1056 FunctionType::get(class_type, ogC_arg_types, false);
1057
1058 // Build the constant containing the pointer to the function
1059 PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
1060 Constant *ogC_addr_int =
1061 ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
1062 m_objc_getClass = ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty);
1063 }
1064
1065 Value *argument_array[1];
1066
1067 Constant *ocn_pointer = ConstantExpr::getBitCast(
1068 _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
1069
1070 argument_array[0] = ocn_pointer;
1071
1072 ArrayRef<Value *> ogC_arguments(argument_array, 1);
1073
1074 CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
1075 "objc_getClass", class_load);
1076
1077 // Replace the load with the call in all users
1078
1079 class_load->replaceAllUsesWith(ogC_call);
1080
1081 class_load->eraseFromParent();
1082
1083 return true;
1084}
1085
1086bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
1087 lldb_private::Log *log(
1088 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1089
1090 BasicBlock::iterator ii;
1091
1092 typedef SmallVector<Instruction *, 2> InstrList;
1093 typedef InstrList::iterator InstrIterator;
1094
1095 InstrList class_loads;
1096
1097 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1098 Instruction &inst = *ii;
1099
1100 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1101 if (IsObjCClassReference(load->getPointerOperand()))
1102 class_loads.push_back(&inst);
1103 }
1104
1105 InstrIterator iter;
1106
1107 for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) {
1108 if (!RewriteObjCClassReference(*iter)) {
1109 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
1110 "static reference to an Objective-C class to a "
1111 "dynamic reference\n");
1112
1113 if (log)
1114 log->PutCString(
1115 "Couldn't rewrite a reference to an Objective-C class");
1116
1117 return false;
1118 }
1119 }
1120
1121 return true;
1122}
1123
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124// This function does not report errors; its callers are responsible.
1125bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
1126 lldb_private::Log *log(
1127 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001128
Kate Stoneb9c1b512016-09-06 20:57:50 +00001129 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001130
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001132
Kate Stoneb9c1b512016-09-06 20:57:50 +00001133 if (!alloc_md || !alloc_md->getNumOperands())
1134 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 ConstantInt *constant_int =
1137 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001138
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139 if (!constant_int)
1140 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001141
Kate Stoneb9c1b512016-09-06 20:57:50 +00001142 // We attempt to register this as a new persistent variable with the DeclMap.
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001143
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001145
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001147
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148 lldb_private::TypeFromParser result_decl_type(
1149 decl->getType().getAsOpaquePtr(),
1150 lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001151
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 StringRef decl_name(decl->getName());
1153 lldb_private::ConstString persistent_variable_name(decl_name.data(),
1154 decl_name.size());
1155 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1156 result_decl_type, false, false))
1157 return false;
Sean Callanan6e6d4a62012-07-21 02:02:15 +00001158
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159 GlobalVariable *persistent_global = new GlobalVariable(
1160 (*m_module), alloc->getType(), false, /* not constant */
1161 GlobalValue::ExternalLinkage, NULL, /* no initializer */
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001162 alloc->getName().str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001163
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164 // What we're going to do here is make believe this was a regular old external
1165 // variable. That means we need to make the metadata valid.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001166
Kate Stoneb9c1b512016-09-06 20:57:50 +00001167 NamedMDNode *named_metadata =
1168 m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001169
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 llvm::Metadata *values[2];
1171 values[0] = ConstantAsMetadata::get(persistent_global);
1172 values[1] = ConstantAsMetadata::get(constant_int);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001173
Kate Stoneb9c1b512016-09-06 20:57:50 +00001174 ArrayRef<llvm::Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001175
Kate Stoneb9c1b512016-09-06 20:57:50 +00001176 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1177 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001178
Kate Stoneb9c1b512016-09-06 20:57:50 +00001179 // Now, since the variable is a pointer variable, we will drop in a load of
1180 // that
1181 // pointer variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001182
Kate Stoneb9c1b512016-09-06 20:57:50 +00001183 LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001184
Kate Stoneb9c1b512016-09-06 20:57:50 +00001185 if (log)
1186 log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
1187 PrintValue(persistent_load).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001188
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189 alloc->replaceAllUsesWith(persistent_load);
1190 alloc->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001191
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 return true;
1193}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001194
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1196 if (!m_resolve_vars)
1197 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001198
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199 lldb_private::Log *log(
1200 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001201
Kate Stoneb9c1b512016-09-06 20:57:50 +00001202 BasicBlock::iterator ii;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001203
Kate Stoneb9c1b512016-09-06 20:57:50 +00001204 typedef SmallVector<Instruction *, 2> InstrList;
1205 typedef InstrList::iterator InstrIterator;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001206
Kate Stoneb9c1b512016-09-06 20:57:50 +00001207 InstrList pvar_allocs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001208
Kate Stoneb9c1b512016-09-06 20:57:50 +00001209 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1210 Instruction &inst = *ii;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001211
Kate Stoneb9c1b512016-09-06 20:57:50 +00001212 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1213 llvm::StringRef alloc_name = alloc->getName();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001214
Kate Stoneb9c1b512016-09-06 20:57:50 +00001215 if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1216 if (alloc_name.find_first_of("0123456789") == 1) {
1217 if (log)
1218 log->Printf("Rejecting a numeric persistent variable.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001219
Kate Stoneb9c1b512016-09-06 20:57:50 +00001220 m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1221 "$1, ... are reserved for use as result "
1222 "names\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001223
Kate Stoneb9c1b512016-09-06 20:57:50 +00001224 return false;
Sean Callanan00294b32016-03-22 21:05:51 +00001225 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001226
Kate Stoneb9c1b512016-09-06 20:57:50 +00001227 pvar_allocs.push_back(alloc);
1228 }
Sean Callanan17827832010-12-13 22:46:15 +00001229 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001231
Kate Stoneb9c1b512016-09-06 20:57:50 +00001232 InstrIterator iter;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001233
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234 for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
1235 if (!RewritePersistentAlloc(*iter)) {
1236 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1237 "the creation of a persistent variable\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001238
Kate Stoneb9c1b512016-09-06 20:57:50 +00001239 if (log)
1240 log->PutCString(
1241 "Couldn't rewrite the creation of a persistent variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001242
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001244 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001245 }
1246
1247 return true;
1248}
1249
1250bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
1251 if (!initializer)
1252 return true;
1253
1254 lldb_private::Log *log(
1255 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1256
1257 if (log && log->GetVerbose())
1258 log->Printf(" MaterializeInitializer(%p, %s)", (void *)data,
1259 PrintValue(initializer).c_str());
1260
1261 Type *initializer_type = initializer->getType();
1262
1263 if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
1264 size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
1265 lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
1266 llvm::NextPowerOf2(constant_size) * 8);
1267
1268 lldb_private::Error get_data_error;
1269 if (!scalar.GetAsMemoryData(data, constant_size,
1270 lldb_private::endian::InlHostByteOrder(),
1271 get_data_error))
1272 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001273
1274 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001275 } else if (ConstantDataArray *array_initializer =
1276 dyn_cast<ConstantDataArray>(initializer)) {
1277 if (array_initializer->isString()) {
1278 std::string array_initializer_string = array_initializer->getAsString();
1279 memcpy(data, array_initializer_string.c_str(),
1280 m_target_data->getTypeStoreSize(initializer_type));
1281 } else {
1282 ArrayType *array_initializer_type = array_initializer->getType();
1283 Type *array_element_type = array_initializer_type->getElementType();
1284
1285 size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
1286
1287 for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
1288 Value *operand_value = array_initializer->getOperand(i);
1289 Constant *operand_constant = dyn_cast<Constant>(operand_value);
1290
1291 if (!operand_constant)
1292 return false;
1293
1294 if (!MaterializeInitializer(data + (i * element_size),
1295 operand_constant))
1296 return false;
1297 }
1298 }
1299 return true;
1300 } else if (ConstantStruct *struct_initializer =
1301 dyn_cast<ConstantStruct>(initializer)) {
1302 StructType *struct_initializer_type = struct_initializer->getType();
1303 const StructLayout *struct_layout =
1304 m_target_data->getStructLayout(struct_initializer_type);
1305
1306 for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
1307 if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
1308 struct_initializer->getOperand(i)))
1309 return false;
1310 }
1311 return true;
1312 } else if (isa<ConstantAggregateZero>(initializer)) {
1313 memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
1314 return true;
1315 }
1316 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001317}
1318
Kate Stoneb9c1b512016-09-06 20:57:50 +00001319// This function does not report errors; its callers are responsible.
1320bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1321 lldb_private::Log *log(
1322 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1323
1324 if (log)
1325 log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
1326
1327 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1328 switch (constant_expr->getOpcode()) {
1329 default:
1330 break;
1331 case Instruction::GetElementPtr:
1332 case Instruction::BitCast:
1333 Value *s = constant_expr->getOperand(0);
1334 if (!MaybeHandleVariable(s))
1335 return false;
1336 }
1337 } else if (GlobalVariable *global_variable =
1338 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1339 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1340 return true;
1341
1342 clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1343
1344 if (!named_decl) {
1345 if (IsObjCSelectorRef(llvm_value_ptr))
1346 return true;
1347
1348 if (!global_variable->hasExternalLinkage())
1349 return true;
1350
1351 if (log)
1352 log->Printf("Found global variable \"%s\" without metadata",
1353 global_variable->getName().str().c_str());
1354
1355 return false;
1356 }
1357
1358 std::string name(named_decl->getName().str());
1359
1360 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1361 if (value_decl == NULL)
1362 return false;
1363
1364 lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
1365 value_decl->getType());
1366
1367 const Type *value_type = NULL;
1368
1369 if (name[0] == '$') {
1370 // The $__lldb_expr_result name indicates the return value has allocated
1371 // as
1372 // a static variable. Per the comment at
1373 // ASTResultSynthesizer::SynthesizeBodyResult,
1374 // accesses to this static variable need to be redirected to the result of
1375 // dereferencing
1376 // a pointer that is passed in as one of the arguments.
1377 //
1378 // Consequently, when reporting the size of the type, we report a pointer
1379 // type pointing
1380 // to the type of $__lldb_expr_result, not the type itself.
1381 //
1382 // We also do this for any user-declared persistent variables.
1383 compiler_type = compiler_type.GetPointerType();
1384 value_type = PointerType::get(global_variable->getType(), 0);
1385 } else {
1386 value_type = global_variable->getType();
1387 }
1388
1389 const uint64_t value_size = compiler_type.GetByteSize(nullptr);
1390 lldb::offset_t value_alignment =
1391 (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
1392
1393 if (log) {
1394 log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
1395 ", align %" PRIu64 "]",
1396 name.c_str(),
1397 lldb_private::ClangUtil::GetQualType(compiler_type)
1398 .getAsString()
1399 .c_str(),
1400 PrintType(value_type).c_str(), value_size, value_alignment);
1401 }
1402
1403 if (named_decl &&
1404 !m_decl_map->AddValueToStruct(
1405 named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
1406 value_size, value_alignment)) {
1407 if (!global_variable->hasExternalLinkage())
1408 return true;
1409 else
1410 return true;
1411 }
1412 } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
1413 if (log)
1414 log->Printf("Function pointers aren't handled right now");
1415
1416 return false;
1417 }
1418
1419 return true;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001420}
1421
Kate Stoneb9c1b512016-09-06 20:57:50 +00001422// This function does not report errors; its callers are responsible.
1423bool IRForTarget::HandleSymbol(Value *symbol) {
1424 lldb_private::Log *log(
1425 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1426
1427 lldb_private::ConstString name(symbol->getName().str().c_str());
1428
1429 lldb::addr_t symbol_addr =
1430 m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1431
1432 if (symbol_addr == LLDB_INVALID_ADDRESS) {
1433 if (log)
1434 log->Printf("Symbol \"%s\" had no address", name.GetCString());
1435
1436 return false;
1437 }
1438
1439 if (log)
1440 log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
1441
1442 Type *symbol_type = symbol->getType();
1443
1444 Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1445
1446 Value *symbol_addr_ptr =
1447 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1448
1449 if (log)
1450 log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
1451 PrintValue(symbol_addr_ptr).c_str());
1452
1453 symbol->replaceAllUsesWith(symbol_addr_ptr);
1454
1455 return true;
1456}
1457
1458bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1459 lldb_private::Log *log(
1460 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1461
1462 if (log)
1463 log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
1464
1465 for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1466 op_index < num_ops; ++op_index)
1467 if (!MaybeHandleVariable(Old->getArgOperand(
1468 op_index))) // conservatively believe that this is a store
1469 {
1470 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1471 "one of the arguments of a function call.\n");
1472
1473 return false;
1474 }
1475
1476 return true;
1477}
1478
1479bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1480 lldb_private::Log *log(
1481 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1482
1483 GlobalVariable *global_variable =
1484 dyn_cast<GlobalVariable>(classlist_reference);
1485
1486 if (!global_variable)
1487 return false;
1488
1489 Constant *initializer = global_variable->getInitializer();
1490
1491 if (!initializer)
1492 return false;
1493
1494 if (!initializer->hasName())
1495 return false;
1496
1497 StringRef name(initializer->getName());
1498 lldb_private::ConstString name_cstr(name.str().c_str());
1499 lldb::addr_t class_ptr =
1500 m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1501
1502 if (log)
1503 log->Printf("Found reference to Objective-C class %s (0x%llx)",
1504 name_cstr.AsCString(), (unsigned long long)class_ptr);
1505
1506 if (class_ptr == LLDB_INVALID_ADDRESS)
1507 return false;
1508
1509 if (global_variable->use_empty())
1510 return false;
1511
1512 SmallVector<LoadInst *, 2> load_instructions;
1513
1514 for (llvm::User *u : global_variable->users()) {
1515 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1516 load_instructions.push_back(load_instruction);
1517 }
1518
1519 if (load_instructions.empty())
1520 return false;
1521
1522 Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1523
1524 for (LoadInst *load_instruction : load_instructions) {
1525 Constant *class_bitcast =
1526 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1527
1528 load_instruction->replaceAllUsesWith(class_bitcast);
1529
1530 load_instruction->eraseFromParent();
1531 }
1532
1533 return true;
1534}
1535
1536bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
1537 BasicBlock::iterator ii;
1538
1539 std::vector<CallInst *> calls_to_remove;
1540
1541 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1542 Instruction &inst = *ii;
1543
1544 CallInst *call = dyn_cast<CallInst>(&inst);
1545
1546 // MaybeHandleCallArguments handles error reporting; we are silent here
1547 if (!call)
1548 continue;
1549
1550 bool remove = false;
1551
1552 llvm::Function *func = call->getCalledFunction();
1553
1554 if (func && func->getName() == "__cxa_atexit")
1555 remove = true;
1556
1557 llvm::Value *val = call->getCalledValue();
1558
1559 if (val && val->getName() == "__cxa_atexit")
1560 remove = true;
1561
1562 if (remove)
1563 calls_to_remove.push_back(call);
1564 }
1565
1566 for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
1567 ce = calls_to_remove.end();
1568 ci != ce; ++ci) {
1569 (*ci)->eraseFromParent();
1570 }
1571
1572 return true;
1573}
1574
1575bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
1576 /////////////////////////////////////////////////////////////////////////
1577 // Prepare the current basic block for execution in the remote process
1578 //
1579
1580 BasicBlock::iterator ii;
1581
1582 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1583 Instruction &inst = *ii;
1584
1585 CallInst *call = dyn_cast<CallInst>(&inst);
1586
1587 // MaybeHandleCallArguments handles error reporting; we are silent here
1588 if (call && !MaybeHandleCallArguments(call))
1589 return false;
1590 }
1591
1592 return true;
1593}
1594
1595bool IRForTarget::ResolveExternals(Function &llvm_function) {
1596 lldb_private::Log *log(
1597 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1598
1599 for (GlobalVariable &global_var : m_module->globals()) {
1600 std::string global_name = global_var.getName().str();
1601
1602 if (log)
1603 log->Printf("Examining %s, DeclForGlobalValue returns %p",
1604 global_name.c_str(),
1605 static_cast<void *>(DeclForGlobal(&global_var)));
1606
1607 if (global_name.find("OBJC_IVAR") == 0) {
1608 if (!HandleSymbol(&global_var)) {
1609 m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
1610 "indirect ivar symbol %s\n",
1611 global_name.c_str());
1612
1613 return false;
1614 }
1615 } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
1616 global_name.npos) {
1617 if (!HandleObjCClass(&global_var)) {
1618 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1619 "for an Objective-C static method call\n");
1620
1621 return false;
1622 }
1623 } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
1624 global_name.npos) {
1625 if (!HandleObjCClass(&global_var)) {
1626 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1627 "for an Objective-C static method call\n");
1628
1629 return false;
1630 }
1631 } else if (DeclForGlobal(&global_var)) {
1632 if (!MaybeHandleVariable(&global_var)) {
1633 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1634 "external variable %s\n",
1635 global_name.c_str());
1636
1637 return false;
1638 }
1639 }
1640 }
1641
1642 return true;
1643}
1644
1645static bool isGuardVariableRef(Value *V) {
1646 Constant *Old = NULL;
1647
1648 if (!(Old = dyn_cast<Constant>(V)))
1649 return false;
1650
1651 ConstantExpr *CE = NULL;
1652
1653 if ((CE = dyn_cast<ConstantExpr>(V))) {
1654 if (CE->getOpcode() != Instruction::BitCast)
1655 return false;
1656
1657 Old = CE->getOperand(0);
1658 }
1659
1660 GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1661
1662 if (!GV || !GV->hasName() ||
1663 (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
1664 !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
1665 {
1666 return false;
1667 }
1668
1669 return true;
1670}
1671
1672void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1673 Constant *zero(Constant::getNullValue(guard_load->getType()));
1674 guard_load->replaceAllUsesWith(zero);
1675 guard_load->eraseFromParent();
1676}
1677
1678static void ExciseGuardStore(Instruction *guard_store) {
1679 guard_store->eraseFromParent();
1680}
1681
1682bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
1683 ///////////////////////////////////////////////////////
1684 // Eliminate any reference to guard variables found.
1685 //
1686
1687 BasicBlock::iterator ii;
1688
1689 typedef SmallVector<Instruction *, 2> InstrList;
1690 typedef InstrList::iterator InstrIterator;
1691
1692 InstrList guard_loads;
1693 InstrList guard_stores;
1694
1695 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1696 Instruction &inst = *ii;
1697
1698 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1699 if (isGuardVariableRef(load->getPointerOperand()))
1700 guard_loads.push_back(&inst);
1701
1702 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1703 if (isGuardVariableRef(store->getPointerOperand()))
1704 guard_stores.push_back(&inst);
1705 }
1706
1707 InstrIterator iter;
1708
1709 for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
1710 TurnGuardLoadIntoZero(*iter);
1711
1712 for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
1713 ExciseGuardStore(*iter);
1714
1715 return true;
1716}
1717
1718// This function does not report errors; its callers are responsible.
1719bool IRForTarget::UnfoldConstant(Constant *old_constant,
1720 llvm::Function *llvm_function,
1721 FunctionValueCache &value_maker,
1722 FunctionValueCache &entry_instruction_finder,
1723 lldb_private::Stream &error_stream) {
1724 SmallVector<User *, 16> users;
1725
1726 // We do this because the use list might change, invalidating our iterator.
1727 // Much better to keep a work list ourselves.
1728 for (llvm::User *u : old_constant->users())
1729 users.push_back(u);
1730
1731 for (size_t i = 0; i < users.size(); ++i) {
1732 User *user = users[i];
1733
1734 if (Constant *constant = dyn_cast<Constant>(user)) {
1735 // synthesize a new non-constant equivalent of the constant
1736
1737 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1738 switch (constant_expr->getOpcode()) {
1739 default:
1740 error_stream.Printf("error [IRForTarget internal]: Unhandled "
1741 "constant expression type: \"%s\"",
1742 PrintValue(constant_expr).c_str());
1743 return false;
1744 case Instruction::BitCast: {
1745 FunctionValueCache bit_cast_maker(
1746 [&value_maker, &entry_instruction_finder, old_constant,
1747 constant_expr](llvm::Function *function) -> llvm::Value * {
1748 // UnaryExpr
1749 // OperandList[0] is value
1750
1751 if (constant_expr->getOperand(0) != old_constant)
1752 return constant_expr;
1753
1754 return new BitCastInst(
1755 value_maker.GetValue(function), constant_expr->getType(),
1756 "", llvm::cast<Instruction>(
1757 entry_instruction_finder.GetValue(function)));
1758 });
1759
1760 if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1761 entry_instruction_finder, error_stream))
1762 return false;
1763 } break;
1764 case Instruction::GetElementPtr: {
1765 // GetElementPtrConstantExpr
1766 // OperandList[0] is base
1767 // OperandList[1]... are indices
1768
1769 FunctionValueCache get_element_pointer_maker(
1770 [&value_maker, &entry_instruction_finder, old_constant,
1771 constant_expr](llvm::Function *function) -> llvm::Value * {
1772 Value *ptr = constant_expr->getOperand(0);
1773
1774 if (ptr == old_constant)
1775 ptr = value_maker.GetValue(function);
1776
1777 std::vector<Value *> index_vector;
1778
1779 unsigned operand_index;
1780 unsigned num_operands = constant_expr->getNumOperands();
1781
1782 for (operand_index = 1; operand_index < num_operands;
1783 ++operand_index) {
1784 Value *operand = constant_expr->getOperand(operand_index);
1785
1786 if (operand == old_constant)
1787 operand = value_maker.GetValue(function);
1788
1789 index_vector.push_back(operand);
1790 }
1791
1792 ArrayRef<Value *> indices(index_vector);
1793
1794 return GetElementPtrInst::Create(
1795 nullptr, ptr, indices, "",
1796 llvm::cast<Instruction>(
1797 entry_instruction_finder.GetValue(function)));
1798 });
1799
1800 if (!UnfoldConstant(constant_expr, llvm_function,
1801 get_element_pointer_maker,
1802 entry_instruction_finder, error_stream))
1803 return false;
1804 } break;
1805 }
1806 } else {
1807 error_stream.Printf(
1808 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1809 PrintValue(constant).c_str());
1810 return false;
1811 }
1812 } else {
1813 if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1814 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1815 error_stream.PutCString("error: Capturing non-local variables in "
1816 "expressions is unsupported.\n");
1817 return false;
1818 }
1819 inst->replaceUsesOfWith(
1820 old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1821 } else {
1822 error_stream.Printf(
1823 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1824 PrintValue(user).c_str());
1825 return false;
1826 }
1827 }
1828 }
1829
1830 if (!isa<GlobalValue>(old_constant)) {
1831 old_constant->destroyConstant();
1832 }
1833
1834 return true;
1835}
1836
1837bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1838 if (!m_resolve_vars)
1839 return true;
1840
1841 lldb_private::Log *log(
1842 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1843
1844 m_decl_map->DoStructLayout();
1845
1846 if (log)
1847 log->Printf("Element arrangement:");
1848
1849 uint32_t num_elements;
1850 uint32_t element_index;
1851
1852 size_t size;
1853 lldb::offset_t alignment;
1854
1855 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1856 return false;
1857
1858 Function::arg_iterator iter(llvm_function.getArgumentList().begin());
1859
1860 if (iter == llvm_function.getArgumentList().end()) {
1861 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1862 "arguments (should take at least a struct pointer)");
1863
1864 return false;
1865 }
1866
1867 Argument *argument = &*iter;
1868
1869 if (argument->getName().equals("this")) {
1870 ++iter;
1871
1872 if (iter == llvm_function.getArgumentList().end()) {
1873 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1874 "'this' argument (should take a struct pointer "
1875 "too)");
1876
1877 return false;
1878 }
1879
1880 argument = &*iter;
1881 } else if (argument->getName().equals("self")) {
1882 ++iter;
1883
1884 if (iter == llvm_function.getArgumentList().end()) {
1885 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1886 "'self' argument (should take '_cmd' and a struct "
1887 "pointer too)");
1888
1889 return false;
1890 }
1891
1892 if (!iter->getName().equals("_cmd")) {
1893 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
1894 "after 'self' argument (should take '_cmd')",
1895 iter->getName().str().c_str());
1896
1897 return false;
1898 }
1899
1900 ++iter;
1901
1902 if (iter == llvm_function.getArgumentList().end()) {
1903 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1904 "'self' and '_cmd' arguments (should take a struct "
1905 "pointer too)");
1906
1907 return false;
1908 }
1909
1910 argument = &*iter;
1911 }
1912
1913 if (!argument->getName().equals("$__lldb_arg")) {
1914 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
1915 "argument named '%s' instead of the struct pointer",
1916 argument->getName().str().c_str());
1917
1918 return false;
1919 }
1920
1921 if (log)
1922 log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
1923
1924 BasicBlock &entry_block(llvm_function.getEntryBlock());
1925 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1926
1927 if (!FirstEntryInstruction) {
1928 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1929 "first instruction in the wrapper for use in "
1930 "rewriting");
1931
1932 return false;
1933 }
1934
1935 LLVMContext &context(m_module->getContext());
1936 IntegerType *offset_type(Type::getInt32Ty(context));
1937
1938 if (!offset_type) {
1939 m_error_stream.Printf(
1940 "Internal error [IRForTarget]: Couldn't produce an offset type");
1941
1942 return false;
1943 }
1944
1945 for (element_index = 0; element_index < num_elements; ++element_index) {
1946 const clang::NamedDecl *decl = NULL;
1947 Value *value = NULL;
1948 lldb::offset_t offset;
1949 lldb_private::ConstString name;
1950
1951 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1952 element_index)) {
1953 m_error_stream.Printf(
1954 "Internal error [IRForTarget]: Structure information is incomplete");
1955
1956 return false;
1957 }
1958
1959 if (log)
1960 log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
1961 decl->getNameAsString().c_str(), offset);
1962
1963 if (value) {
1964 if (log)
1965 log->Printf(" Replacing [%s]", PrintValue(value).c_str());
1966
1967 FunctionValueCache body_result_maker(
1968 [this, name, offset_type, offset, argument,
1969 value](llvm::Function *function) -> llvm::Value * {
1970 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in
1971 // cases where the result
1972 // variable is an rvalue, we have to synthesize a dereference of the
1973 // appropriate structure
1974 // entry in order to produce the static variable that the AST thinks
1975 // it is accessing.
1976
1977 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1978 m_entry_instruction_finder.GetValue(function));
1979
1980 ConstantInt *offset_int(
1981 ConstantInt::get(offset_type, offset, true));
1982 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1983 nullptr, argument, offset_int, "", entry_instruction);
1984
1985 if (name == m_result_name && !m_result_is_pointer) {
1986 BitCastInst *bit_cast = new BitCastInst(
1987 get_element_ptr, value->getType()->getPointerTo(), "",
1988 entry_instruction);
1989
1990 LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1991
1992 return load;
1993 } else {
1994 BitCastInst *bit_cast = new BitCastInst(
1995 get_element_ptr, value->getType(), "", entry_instruction);
1996
1997 return bit_cast;
1998 }
1999 });
2000
2001 if (Constant *constant = dyn_cast<Constant>(value)) {
2002 if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
2003 m_entry_instruction_finder, m_error_stream)) {
2004 return false;
2005 }
2006 } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
2007 if (instruction->getParent()->getParent() != &llvm_function) {
2008 m_error_stream.PutCString("error: Capturing non-local variables in "
2009 "expressions is unsupported.\n");
2010 return false;
2011 }
2012 value->replaceAllUsesWith(
2013 body_result_maker.GetValue(instruction->getParent()->getParent()));
2014 } else {
2015 if (log)
2016 log->Printf("Unhandled non-constant type: \"%s\"",
2017 PrintValue(value).c_str());
2018 return false;
2019 }
2020
2021 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
2022 var->eraseFromParent();
2023 }
2024 }
2025
2026 if (log)
2027 log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
2028 (int64_t)alignment, (uint64_t)size);
2029
2030 return true;
2031}
2032
2033llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
2034 uint64_t offset) {
2035 llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
2036
2037 llvm::Constant *offset_array[1];
2038
2039 offset_array[0] = offset_int;
2040
2041 llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
2042 llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
2043 llvm::Type *char_pointer_type = char_type->getPointerTo();
2044
2045 llvm::Constant *reloc_placeholder_bitcast =
2046 ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
2047 llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
2048 char_type, reloc_placeholder_bitcast, offsets);
2049 llvm::Constant *reloc_bitcast =
2050 ConstantExpr::getBitCast(reloc_getelementptr, type);
2051
2052 return reloc_bitcast;
2053}
2054
2055bool IRForTarget::runOnModule(Module &llvm_module) {
2056 lldb_private::Log *log(
2057 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
2058
2059 m_module = &llvm_module;
2060 m_target_data.reset(new DataLayout(m_module));
2061 m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
2062 m_target_data->getPointerSizeInBits());
2063
2064 if (log) {
2065 std::string s;
2066 raw_string_ostream oss(s);
2067
2068 m_module->print(oss, NULL);
2069
2070 oss.flush();
2071
2072 log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
2073 }
2074
2075 Function *const main_function =
2076 m_func_name.IsEmpty() ? nullptr
2077 : m_module->getFunction(m_func_name.GetStringRef());
2078
2079 if (!m_func_name.IsEmpty() && !main_function) {
2080 if (log)
2081 log->Printf("Couldn't find \"%s()\" in the module",
2082 m_func_name.AsCString());
2083
2084 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
2085 "'%s' in the module",
2086 m_func_name.AsCString());
2087
2088 return false;
2089 }
2090
2091 if (main_function) {
2092 if (!FixFunctionLinkage(*main_function)) {
2093 if (log)
2094 log->Printf("Couldn't fix the linkage for the function");
2095
2096 return false;
2097 }
2098 }
2099
2100 llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
2101
2102 m_reloc_placeholder = new llvm::GlobalVariable(
2103 (*m_module), int8_ty, false /* IsConstant */,
2104 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
2105 "reloc_placeholder", NULL /* InsertBefore */,
2106 GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
2107
2108 ////////////////////////////////////////////////////////////
2109 // Replace $__lldb_expr_result with a persistent variable
2110 //
2111
2112 if (main_function) {
2113 if (!CreateResultVariable(*main_function)) {
2114 if (log)
2115 log->Printf("CreateResultVariable() failed");
2116
2117 // CreateResultVariable() reports its own errors, so we don't do so here
2118
2119 return false;
2120 }
2121 }
2122
2123 if (log && log->GetVerbose()) {
2124 std::string s;
2125 raw_string_ostream oss(s);
2126
2127 m_module->print(oss, NULL);
2128
2129 oss.flush();
2130
2131 log->Printf("Module after creating the result variable: \n\"%s\"",
2132 s.c_str());
2133 }
2134
2135 for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2136 ++fi) {
2137 llvm::Function *function = &*fi;
2138
2139 if (function->begin() == function->end())
2140 continue;
2141
2142 Function::iterator bbi;
2143
2144 for (bbi = function->begin(); bbi != function->end(); ++bbi) {
2145 if (!RemoveGuards(*bbi)) {
2146 if (log)
2147 log->Printf("RemoveGuards() failed");
2148
2149 // RemoveGuards() reports its own errors, so we don't do so here
2150
2151 return false;
2152 }
2153
2154 if (!RewritePersistentAllocs(*bbi)) {
2155 if (log)
2156 log->Printf("RewritePersistentAllocs() failed");
2157
2158 // RewritePersistentAllocs() reports its own errors, so we don't do so
2159 // here
2160
2161 return false;
2162 }
2163
2164 if (!RemoveCXAAtExit(*bbi)) {
2165 if (log)
2166 log->Printf("RemoveCXAAtExit() failed");
2167
2168 // RemoveCXAAtExit() reports its own errors, so we don't do so here
2169
2170 return false;
2171 }
2172 }
2173 }
2174
2175 ///////////////////////////////////////////////////////////////////////////////
2176 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
2177 //
2178
2179 if (!RewriteObjCConstStrings()) {
2180 if (log)
2181 log->Printf("RewriteObjCConstStrings() failed");
2182
2183 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
2184
2185 return false;
2186 }
2187
2188 for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2189 ++fi) {
2190 llvm::Function *function = &*fi;
2191
2192 for (llvm::Function::iterator bbi = function->begin(),
2193 bbe = function->end();
2194 bbi != bbe; ++bbi) {
2195 if (!RewriteObjCSelectors(*bbi)) {
2196 if (log)
2197 log->Printf("RewriteObjCSelectors() failed");
2198
2199 // RewriteObjCSelectors() reports its own errors, so we don't do so here
2200
2201 return false;
2202 }
Sean Callananac900582016-09-29 00:45:33 +00002203
2204 if (!RewriteObjCClassReferences(*bbi)) {
2205 if (log)
2206 log->Printf("RewriteObjCClassReferences() failed");
2207
2208 // RewriteObjCClasses() reports its own errors, so we don't do so here
2209
2210 return false;
2211 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002212 }
2213 }
2214
2215 for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2216 ++fi) {
2217 llvm::Function *function = &*fi;
2218
2219 for (llvm::Function::iterator bbi = function->begin(),
2220 bbe = function->end();
2221 bbi != bbe; ++bbi) {
2222 if (!ResolveCalls(*bbi)) {
2223 if (log)
2224 log->Printf("ResolveCalls() failed");
2225
2226 // ResolveCalls() reports its own errors, so we don't do so here
2227
2228 return false;
2229 }
2230 }
2231 }
2232
2233 ////////////////////////////////////////////////////////////////////////
2234 // Run function-level passes that only make sense on the main function
2235 //
2236
2237 if (main_function) {
2238 if (!ResolveExternals(*main_function)) {
2239 if (log)
2240 log->Printf("ResolveExternals() failed");
2241
2242 // ResolveExternals() reports its own errors, so we don't do so here
2243
2244 return false;
2245 }
2246
2247 if (!ReplaceVariables(*main_function)) {
2248 if (log)
2249 log->Printf("ReplaceVariables() failed");
2250
2251 // ReplaceVariables() reports its own errors, so we don't do so here
2252
2253 return false;
2254 }
2255 }
2256
2257 if (log && log->GetVerbose()) {
2258 std::string s;
2259 raw_string_ostream oss(s);
2260
2261 m_module->print(oss, NULL);
2262
2263 oss.flush();
2264
2265 log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
2266 }
2267
2268 return true;
2269}
2270
2271void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2272 PassManagerType pass_mgr_type) {}
2273
2274PassManagerType IRForTarget::getPotentialPassManagerType() const {
2275 return PMT_ModulePassManager;
Sean Callanan2ab712f22010-07-03 01:35:46 +00002276}