blob: db3f1589fa5d974661f71d69705e8cba04a42d9f [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),
76 m_sel_registerName(NULL), m_intptr_ty(NULL), m_error_stream(error_stream),
77 m_execution_unit(execution_unit), m_result_store(NULL),
78 m_result_is_pointer(false), m_reloc_placeholder(NULL),
79 m_entry_instruction_finder(FindEntryInstruction) {}
Sean Callanan2ab712f22010-07-03 01:35:46 +000080
Sean Callanan038df5032010-09-30 21:18:25 +000081/* Handy utility functions used at several places in the code */
Sean Callanan2235f322010-08-11 03:57:18 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083static std::string PrintValue(const Value *value, bool truncate = false) {
84 std::string s;
85 if (value) {
Sean Callanan038df5032010-09-30 21:18:25 +000086 raw_string_ostream rso(s);
Kate Stoneb9c1b512016-09-06 20:57:50 +000087 value->print(rso);
Sean Callanan038df5032010-09-30 21:18:25 +000088 rso.flush();
89 if (truncate)
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 s.resize(s.length() - 1);
91 }
92 return s;
Sean Callanan038df5032010-09-30 21:18:25 +000093}
94
Kate Stoneb9c1b512016-09-06 20:57:50 +000095static std::string PrintType(const llvm::Type *type, bool truncate = false) {
96 std::string s;
97 raw_string_ostream rso(s);
98 type->print(rso);
99 rso.flush();
100 if (truncate)
101 s.resize(s.length() - 1);
102 return s;
Sean Callanan2ab712f22010-07-03 01:35:46 +0000103}
104
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105IRForTarget::~IRForTarget() {}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
108 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
109
110 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000111}
112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
114 Module *module) {
115 NamedMDNode *named_metadata =
116 module->getNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000117
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118 if (!named_metadata)
Sean Callanan63697e52011-05-07 01:06:41 +0000119 return NULL;
Sean Callanan63697e52011-05-07 01:06:41 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 unsigned num_nodes = named_metadata->getNumOperands();
122 unsigned node_index;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 for (node_index = 0; node_index < num_nodes; ++node_index) {
125 llvm::MDNode *metadata_node =
126 dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
127 if (!metadata_node)
128 return NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000129
Kate Stoneb9c1b512016-09-06 20:57:50 +0000130 if (metadata_node->getNumOperands() != 2)
131 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 if (mdconst::dyn_extract_or_null<GlobalValue>(
134 metadata_node->getOperand(0)) != global_val)
135 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 ConstantInt *constant_int =
138 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000139
Sean Callanan2235f322010-08-11 03:57:18 +0000140 if (!constant_int)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141 return NULL;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000142
Sean Callanan2235f322010-08-11 03:57:18 +0000143 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000144
Kate Stoneb9c1b512016-09-06 20:57:50 +0000145 return reinterpret_cast<clang::NamedDecl *>(ptr);
146 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 return NULL;
149}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000150
Kate Stoneb9c1b512016-09-06 20:57:50 +0000151clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
152 return DeclForGlobal(global_val, m_module);
153}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000154
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
156 lldb_private::Log *log(
157 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000158
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 if (!m_resolve_vars)
160 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 // Find the result variable. If it doesn't exist, we can give up right here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000165
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 std::string result_name_str;
167 const char *result_name = NULL;
Sean Callanan2235f322010-08-11 03:57:18 +0000168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
170 ve = value_symbol_table.end();
171 vi != ve; ++vi) {
172 result_name_str = vi->first().str();
173 const char *value_name = result_name_str.c_str();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 if (strstr(value_name, "$__lldb_expr_result_ptr") &&
176 strncmp(value_name, "_ZGV", 4)) {
177 result_name = value_name;
178 m_result_is_pointer = true;
179 break;
180 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 if (strstr(value_name, "$__lldb_expr_result") &&
183 strncmp(value_name, "_ZGV", 4)) {
184 result_name = value_name;
185 m_result_is_pointer = false;
186 break;
187 }
188 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 if (!result_name) {
Sean Callanane1175b72011-01-13 21:23:32 +0000191 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 log->PutCString("Couldn't find result variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000193
Sean Callanan2235f322010-08-11 03:57:18 +0000194 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 }
Sean Callanan2235f322010-08-11 03:57:18 +0000196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 if (log)
198 log->Printf("Result name: \"%s\"", result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 Value *result_value = m_module->getNamedValue(result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 if (!result_value) {
203 if (log)
204 log->PutCString("Result variable had no data");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
207 "name (%s) exists, but not its definition\n",
208 result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000209
Sean Callananc70ed462011-10-25 18:36:40 +0000210 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 }
Sean Callananc70ed462011-10-25 18:36:40 +0000212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 if (log)
214 log->Printf("Found result in the IR: \"%s\"",
215 PrintValue(result_value, false).c_str());
216
217 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
218
219 if (!result_global) {
220 if (log)
221 log->PutCString("Result variable isn't a GlobalVariable");
222
223 m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
224 "is defined, but is not a global variable\n",
225 result_name);
226
227 return false;
228 }
229
230 clang::NamedDecl *result_decl = DeclForGlobal(result_global);
231 if (!result_decl) {
232 if (log)
233 log->PutCString("Result variable doesn't have a corresponding Decl");
234
235 m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
236 "does not have a corresponding Clang entity\n",
237 result_name);
238
239 return false;
240 }
241
242 if (log) {
243 std::string decl_desc_str;
244 raw_string_ostream decl_desc_stream(decl_desc_str);
245 result_decl->print(decl_desc_stream);
246 decl_desc_stream.flush();
247
248 log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
249 }
250
251 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
252 if (!result_var) {
253 if (log)
254 log->PutCString("Result variable Decl isn't a VarDecl");
255
256 m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
257 "(%s)'s corresponding Clang entity isn't a "
258 "variable\n",
259 result_name);
260
261 return false;
262 }
263
264 // Get the next available result name from m_decl_map and create the
265 // persistent
266 // variable for it
267
268 // If the result is an Lvalue, it is emitted as a pointer; see
269 // ASTResultSynthesizer::SynthesizeBodyResult.
270 if (m_result_is_pointer) {
271 clang::QualType pointer_qual_type = result_var->getType();
272 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
273
274 const clang::PointerType *pointer_pointertype =
275 pointer_type->getAs<clang::PointerType>();
276 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
277 pointer_type->getAs<clang::ObjCObjectPointerType>();
278
279 if (pointer_pointertype) {
280 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
281
282 m_result_type = lldb_private::TypeFromParser(
283 element_qual_type.getAsOpaquePtr(),
284 lldb_private::ClangASTContext::GetASTContext(
285 &result_decl->getASTContext()));
286 } else if (pointer_objcobjpointertype) {
287 clang::QualType element_qual_type =
288 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
289
290 m_result_type = lldb_private::TypeFromParser(
291 element_qual_type.getAsOpaquePtr(),
292 lldb_private::ClangASTContext::GetASTContext(
293 &result_decl->getASTContext()));
294 } else {
295 if (log)
296 log->PutCString("Expected result to have pointer type, but it did not");
297
298 m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
299 "is not a pointer variable\n",
300 result_name);
301
302 return false;
303 }
304 } else {
305 m_result_type = lldb_private::TypeFromParser(
306 result_var->getType().getAsOpaquePtr(),
307 lldb_private::ClangASTContext::GetASTContext(
308 &result_decl->getASTContext()));
309 }
310
311 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
312 lldb_private::ExecutionContext exe_ctx(target_sp, true);
313 if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) {
314 lldb_private::StreamString type_desc_stream;
315 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000316
Sean Callanand7a1ca22010-12-02 19:47:57 +0000317 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 log->Printf("Result type has size 0");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000319
Kate Stoneb9c1b512016-09-06 20:57:50 +0000320 m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
321 "couldn't be determined\n",
322 type_desc_stream.GetData());
323 return false;
324 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325
Kate Stoneb9c1b512016-09-06 20:57:50 +0000326 if (log) {
327 lldb_private::StreamString type_desc_stream;
328 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000329
Kate Stoneb9c1b512016-09-06 20:57:50 +0000330 log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
331 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000332
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333 m_result_name = lldb_private::ConstString("$RESULT_NAME");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000334
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335 if (log)
336 log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
337 m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000338
Kate Stoneb9c1b512016-09-06 20:57:50 +0000339 // Construct a new result global and set up its metadata
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000340
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 GlobalVariable *new_result_global = new GlobalVariable(
342 (*m_module), result_global->getType()->getElementType(),
343 false, /* not constant */
344 GlobalValue::ExternalLinkage, NULL, /* no initializer */
345 m_result_name.GetCString());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000346
Kate Stoneb9c1b512016-09-06 20:57:50 +0000347 // It's too late in compilation to create a new VarDecl for this, but we don't
348 // need to. We point the metadata at the old VarDecl. This creates an odd
349 // anomaly: a variable with a Value whose name is something like $0 and a
350 // Decl whose name is $__lldb_expr_result. This condition is handled in
351 // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
352 // fixed up.
Greg Clayton57ee3062013-07-11 22:46:58 +0000353
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 ConstantInt *new_constant_int =
355 ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
356 reinterpret_cast<uint64_t>(result_decl), false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000357
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 llvm::Metadata *values[2];
359 values[0] = ConstantAsMetadata::get(new_result_global);
360 values[1] = ConstantAsMetadata::get(new_constant_int);
Greg Clayton57ee3062013-07-11 22:46:58 +0000361
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362 ArrayRef<Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000363
Kate Stoneb9c1b512016-09-06 20:57:50 +0000364 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
365 NamedMDNode *named_metadata =
366 m_module->getNamedMetadata("clang.global.decl.ptrs");
367 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 if (log)
370 log->Printf("Replacing \"%s\" with \"%s\"",
371 PrintValue(result_global).c_str(),
372 PrintValue(new_result_global).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000373
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374 if (result_global->use_empty()) {
375 // We need to synthesize a store for this variable, because otherwise
376 // there's nothing to put into its equivalent persistent variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000377
Greg Clayton1b95a6f2010-11-19 01:05:25 +0000378 BasicBlock &entry_block(llvm_function.getEntryBlock());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000380
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381 if (!first_entry_instruction)
382 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000383
Kate Stoneb9c1b512016-09-06 20:57:50 +0000384 if (!result_global->hasInitializer()) {
385 if (log)
386 log->Printf("Couldn't find initializer for unused variable");
387
388 m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
389 "(%s) has no writes and no initializer\n",
390 result_name);
391
392 return false;
Sean Callanan3989fb92011-01-27 01:07:04 +0000393 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000394
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 Constant *initializer = result_global->getInitializer();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000396
Kate Stoneb9c1b512016-09-06 20:57:50 +0000397 StoreInst *synthesized_store =
398 new StoreInst(initializer, new_result_global, first_entry_instruction);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 if (log)
401 log->Printf("Synthesized result store \"%s\"\n",
402 PrintValue(synthesized_store).c_str());
403 } else {
404 result_global->replaceAllUsesWith(new_result_global);
405 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000406
Kate Stoneb9c1b512016-09-06 20:57:50 +0000407 if (!m_decl_map->AddPersistentVariable(
408 result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
409 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000410
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411 result_global->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000412
Kate Stoneb9c1b512016-09-06 20:57:50 +0000413 return true;
414}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000415
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
417 llvm::GlobalVariable *cstr) {
418 lldb_private::Log *log(
419 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000420
Kate Stoneb9c1b512016-09-06 20:57:50 +0000421 Type *ns_str_ty = ns_str->getType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
424 Type *i32_ty = Type::getInt32Ty(m_module->getContext());
425 Type *i8_ty = Type::getInt8Ty(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 if (!m_CFStringCreateWithBytes) {
428 lldb::addr_t CFStringCreateWithBytes_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000429
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430 static lldb_private::ConstString g_CFStringCreateWithBytes_str(
431 "CFStringCreateWithBytes");
Sean Callanan1f9db3e2013-06-28 21:44:15 +0000432
Kate Stoneb9c1b512016-09-06 20:57:50 +0000433 CFStringCreateWithBytes_addr =
434 m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str);
435 if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) {
436 if (log)
437 log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000438
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
440 "constant string requires "
441 "CFStringCreateWithBytes\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 return false;
Sean Callanan549c9f72010-07-13 21:41:46 +0000444 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000445
Sean Callanan549c9f72010-07-13 21:41:46 +0000446 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
448 CFStringCreateWithBytes_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450 // Build the function type:
451 //
452 // CFStringRef CFStringCreateWithBytes (
453 // CFAllocatorRef alloc,
454 // const UInt8 *bytes,
455 // CFIndex numBytes,
456 // CFStringEncoding encoding,
457 // Boolean isExternalRepresentation
458 // );
459 //
460 // We make the following substitutions:
461 //
462 // CFStringRef -> i8*
463 // CFAllocatorRef -> i8*
464 // UInt8 * -> i8*
465 // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
466 // pointer size for now)
467 // CFStringEncoding -> i32
468 // Boolean -> i8
469
470 Type *arg_type_array[5];
471
472 arg_type_array[0] = i8_ptr_ty;
473 arg_type_array[1] = i8_ptr_ty;
474 arg_type_array[2] = m_intptr_ty;
475 arg_type_array[3] = i32_ty;
476 arg_type_array[4] = i8_ty;
477
478 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
479
480 llvm::Type *CFSCWB_ty =
481 FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
482
483 // Build the constant containing the pointer to the function
484 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
485 Constant *CFSCWB_addr_int =
486 ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
487 m_CFStringCreateWithBytes =
488 ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
489 }
490
491 ConstantDataSequential *string_array = NULL;
492
493 if (cstr)
494 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
495
496 Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
497 Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
498 : Constant::getNullValue(i8_ptr_ty);
499 Constant *numBytes_arg = ConstantInt::get(
500 m_intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
501 Constant *encoding_arg = ConstantInt::get(
502 i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
503 Constant *isExternal_arg =
504 ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
505
506 Value *argument_array[5];
507
508 argument_array[0] = alloc_arg;
509 argument_array[1] = bytes_arg;
510 argument_array[2] = numBytes_arg;
511 argument_array[3] = encoding_arg;
512 argument_array[4] = isExternal_arg;
513
514 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
515
516 FunctionValueCache CFSCWB_Caller(
517 [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
518 return CallInst::Create(
519 m_CFStringCreateWithBytes, CFSCWB_arguments,
520 "CFStringCreateWithBytes",
521 llvm::cast<Instruction>(
522 m_entry_instruction_finder.GetValue(function)));
523 });
524
525 if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller,
526 m_entry_instruction_finder, m_error_stream)) {
527 if (log)
528 log->PutCString(
529 "Couldn't replace the NSString with the result of the call");
530
531 m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
532 "Objective-C constant string with a dynamic "
533 "string\n");
534
535 return false;
536 }
537
538 ns_str->eraseFromParent();
539
540 return true;
Sean Callanan549c9f72010-07-13 21:41:46 +0000541}
542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543bool IRForTarget::RewriteObjCConstStrings() {
544 lldb_private::Log *log(
545 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
550 ve = value_symbol_table.end();
551 vi != ve; ++vi) {
552 std::string value_name = vi->first().str();
553 const char *value_name_cstr = value_name.c_str();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000554
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
556 Value *nsstring_value = vi->second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000557
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558 GlobalVariable *nsstring_global =
559 dyn_cast<GlobalVariable>(nsstring_value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000560
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561 if (!nsstring_global) {
562 if (log)
563 log->PutCString("NSString variable is not a GlobalVariable");
564
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()) {
572 if (log)
573 log->PutCString("NSString variable does not have an initializer");
574
575 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
576 "constant string does not have an initializer\n");
577
578 return false;
579 }
580
581 ConstantStruct *nsstring_struct =
582 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
583
584 if (!nsstring_struct) {
585 if (log)
586 log->PutCString(
587 "NSString variable's initializer is not a ConstantStruct");
588
589 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
590 "constant string is not a structure constant\n");
591
592 return false;
593 }
594
595 // We expect the following structure:
596 //
597 // struct {
598 // int *isa;
599 // int flags;
600 // char *str;
601 // long length;
602 // };
603
604 if (nsstring_struct->getNumOperands() != 4) {
605 if (log)
606 log->Printf("NSString variable's initializer structure has an "
607 "unexpected number of members. Should be 4, is %d",
608 nsstring_struct->getNumOperands());
609
610 m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
611 "Objective-C constant string is not as "
612 "expected\n");
613
614 return false;
615 }
616
617 Constant *nsstring_member = nsstring_struct->getOperand(2);
618
619 if (!nsstring_member) {
620 if (log)
621 log->PutCString("NSString initializer's str element was empty");
622
623 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
624 "constant string does not have a string "
625 "initializer\n");
626
627 return false;
628 }
629
630 ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
631
632 if (!nsstring_expr) {
633 if (log)
634 log->PutCString(
635 "NSString initializer's str element is not a ConstantExpr");
636
637 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
638 "constant string's string initializer is not "
639 "constant\n");
640
641 return false;
642 }
643
644 if (nsstring_expr->getOpcode() != Instruction::GetElementPtr) {
645 if (log)
646 log->Printf("NSString initializer's str element is not a "
647 "GetElementPtr expression, it's a %s",
648 nsstring_expr->getOpcodeName());
649
650 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
651 "constant string's string initializer is not an "
652 "array\n");
653
654 return false;
655 }
656
657 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
658
659 GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
660
661 if (!cstr_global) {
662 if (log)
663 log->PutCString(
664 "NSString initializer's str element is not a GlobalVariable");
665
666 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
667 "constant string's string initializer doesn't "
668 "point to a global\n");
669
670 return false;
671 }
672
673 if (!cstr_global->hasInitializer()) {
674 if (log)
675 log->PutCString("NSString initializer's str element does not have an "
676 "initializer");
677
678 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
679 "constant string's string initializer doesn't "
680 "point to initialized data\n");
681
682 return false;
683 }
684
685 /*
686 if (!cstr_array)
687 {
688 if (log)
689 log->PutCString("NSString initializer's str element is not a
690 ConstantArray");
691
692 if (m_error_stream)
693 m_error_stream.Printf("Internal error [IRForTarget]: An
694 Objective-C constant string's string initializer doesn't point to an
695 array\n");
696
697 return false;
698 }
699
700 if (!cstr_array->isCString())
701 {
702 if (log)
703 log->PutCString("NSString initializer's str element is not a C
704 string array");
705
706 if (m_error_stream)
707 m_error_stream.Printf("Internal error [IRForTarget]: An
708 Objective-C constant string's string initializer doesn't point to a C
709 string\n");
710
711 return false;
712 }
713 */
714
715 ConstantDataArray *cstr_array =
716 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
717
718 if (log) {
719 if (cstr_array)
720 log->Printf("Found NSString constant %s, which contains \"%s\"",
721 value_name_cstr, cstr_array->getAsString().str().c_str());
722 else
723 log->Printf("Found NSString constant %s, which contains \"\"",
724 value_name_cstr);
725 }
726
727 if (!cstr_array)
728 cstr_global = NULL;
729
730 if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
731 if (log)
732 log->PutCString("Error rewriting the constant string");
733
734 // We don't print an error message here because RewriteObjCConstString
735 // has done so for us.
736
737 return false;
738 }
739 }
740 }
741
742 for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
743 ve = value_symbol_table.end();
744 vi != ve; ++vi) {
745 std::string value_name = vi->first().str();
746 const char *value_name_cstr = value_name.c_str();
747
748 if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
749 GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
750
751 if (!gv) {
752 if (log)
753 log->PutCString(
754 "__CFConstantStringClassReference is not a global variable");
755
756 m_error_stream.Printf("Internal error [IRForTarget]: Found a "
757 "CFConstantStringClassReference, but it is not a "
758 "global object\n");
759
760 return false;
761 }
762
763 gv->eraseFromParent();
764
765 break;
766 }
767 }
768
769 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000770}
771
Kate Stoneb9c1b512016-09-06 20:57:50 +0000772static bool IsObjCSelectorRef(Value *value) {
773 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000774
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 if (!global_variable || !global_variable->hasName() ||
776 !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
777 return false;
778
779 return true;
780}
781
782// This function does not report errors; its callers are responsible.
783bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
784 lldb_private::Log *log(
785 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
786
787 LoadInst *load = dyn_cast<LoadInst>(selector_load);
788
789 if (!load)
790 return false;
791
792 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
793 // gets represented as
794 //
795 // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
796 // %call = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...)
797 // ; <i8*>
798 //
799 // where %obj is the object pointer and %tmp is the selector.
800 //
801 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
802 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
803 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
804
805 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
806 // and get the string from its target
807
808 GlobalVariable *_objc_selector_references_ =
809 dyn_cast<GlobalVariable>(load->getPointerOperand());
810
811 if (!_objc_selector_references_ ||
812 !_objc_selector_references_->hasInitializer())
813 return false;
814
815 Constant *osr_initializer = _objc_selector_references_->getInitializer();
816
817 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
818
819 if (!osr_initializer_expr ||
820 osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
821 return false;
822
823 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
824
825 if (!osr_initializer_base)
826 return false;
827
828 // Find the string's initializer (a ConstantArray) and get the string from it
829
830 GlobalVariable *_objc_meth_var_name_ =
831 dyn_cast<GlobalVariable>(osr_initializer_base);
832
833 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
834 return false;
835
836 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
837
838 ConstantDataArray *omvn_initializer_array =
839 dyn_cast<ConstantDataArray>(omvn_initializer);
840
841 if (!omvn_initializer_array->isString())
842 return false;
843
844 std::string omvn_initializer_string = omvn_initializer_array->getAsString();
845
846 if (log)
847 log->Printf("Found Objective-C selector reference \"%s\"",
848 omvn_initializer_string.c_str());
849
850 // Construct a call to sel_registerName
851
852 if (!m_sel_registerName) {
853 lldb::addr_t sel_registerName_addr;
854
855 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
856 sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str);
857 if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
858 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000859
Sean Callananc70ed462011-10-25 18:36:40 +0000860 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861 log->Printf("Found sel_registerName at 0x%" PRIx64,
862 sel_registerName_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000863
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864 // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000865
Kate Stoneb9c1b512016-09-06 20:57:50 +0000866 // The below code would be "more correct," but in actuality what's required
867 // is uint8_t*
868 // Type *sel_type = StructType::get(m_module->getContext());
869 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
870 Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000871
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 Type *type_array[1];
873
874 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
875
876 ArrayRef<Type *> srN_arg_types(type_array, 1);
877
878 llvm::Type *srN_type =
879 FunctionType::get(sel_ptr_type, srN_arg_types, false);
880
881 // Build the constant containing the pointer to the function
882 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
883 Constant *srN_addr_int =
884 ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
885 m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
886 }
887
888 Value *argument_array[1];
889
890 Constant *omvn_pointer = ConstantExpr::getBitCast(
891 _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
892
893 argument_array[0] = omvn_pointer;
894
895 ArrayRef<Value *> srN_arguments(argument_array, 1);
896
897 CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
898 "sel_registerName", selector_load);
899
900 // Replace the load with the call in all users
901
902 selector_load->replaceAllUsesWith(srN_call);
903
904 selector_load->eraseFromParent();
905
906 return true;
907}
908
909bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
910 lldb_private::Log *log(
911 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
912
913 BasicBlock::iterator ii;
914
915 typedef SmallVector<Instruction *, 2> InstrList;
916 typedef InstrList::iterator InstrIterator;
917
918 InstrList selector_loads;
919
920 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
921 Instruction &inst = *ii;
922
923 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
924 if (IsObjCSelectorRef(load->getPointerOperand()))
925 selector_loads.push_back(&inst);
926 }
927
928 InstrIterator iter;
929
930 for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
931 if (!RewriteObjCSelector(*iter)) {
932 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
933 "static reference to an Objective-C selector to a "
934 "dynamic reference\n");
935
936 if (log)
937 log->PutCString(
938 "Couldn't rewrite a reference to an Objective-C selector");
939
940 return false;
Sean Callananc70ed462011-10-25 18:36:40 +0000941 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000942 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000943
Kate Stoneb9c1b512016-09-06 20:57:50 +0000944 return true;
945}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000946
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947// This function does not report errors; its callers are responsible.
948bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
949 lldb_private::Log *log(
950 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000951
Kate Stoneb9c1b512016-09-06 20:57:50 +0000952 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
Sean Callanan1f9db3e2013-06-28 21:44:15 +0000953
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000955
Kate Stoneb9c1b512016-09-06 20:57:50 +0000956 if (!alloc_md || !alloc_md->getNumOperands())
957 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000958
Kate Stoneb9c1b512016-09-06 20:57:50 +0000959 ConstantInt *constant_int =
960 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000961
Kate Stoneb9c1b512016-09-06 20:57:50 +0000962 if (!constant_int)
963 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000964
Kate Stoneb9c1b512016-09-06 20:57:50 +0000965 // We attempt to register this as a new persistent variable with the DeclMap.
Sean Callanan1f9db3e2013-06-28 21:44:15 +0000966
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000968
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000970
Kate Stoneb9c1b512016-09-06 20:57:50 +0000971 lldb_private::TypeFromParser result_decl_type(
972 decl->getType().getAsOpaquePtr(),
973 lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000974
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975 StringRef decl_name(decl->getName());
976 lldb_private::ConstString persistent_variable_name(decl_name.data(),
977 decl_name.size());
978 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
979 result_decl_type, false, false))
980 return false;
Sean Callanan6e6d4a62012-07-21 02:02:15 +0000981
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 GlobalVariable *persistent_global = new GlobalVariable(
983 (*m_module), alloc->getType(), false, /* not constant */
984 GlobalValue::ExternalLinkage, NULL, /* no initializer */
985 alloc->getName().str().c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 // What we're going to do here is make believe this was a regular old external
988 // variable. That means we need to make the metadata valid.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000989
Kate Stoneb9c1b512016-09-06 20:57:50 +0000990 NamedMDNode *named_metadata =
991 m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000992
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993 llvm::Metadata *values[2];
994 values[0] = ConstantAsMetadata::get(persistent_global);
995 values[1] = ConstantAsMetadata::get(constant_int);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000996
Kate Stoneb9c1b512016-09-06 20:57:50 +0000997 ArrayRef<llvm::Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000998
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1000 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001001
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 // Now, since the variable is a pointer variable, we will drop in a load of
1003 // that
1004 // pointer variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001005
Kate Stoneb9c1b512016-09-06 20:57:50 +00001006 LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001007
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 if (log)
1009 log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
1010 PrintValue(persistent_load).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001011
Kate Stoneb9c1b512016-09-06 20:57:50 +00001012 alloc->replaceAllUsesWith(persistent_load);
1013 alloc->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001014
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 return true;
1016}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001017
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1019 if (!m_resolve_vars)
1020 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001021
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 lldb_private::Log *log(
1023 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001024
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 BasicBlock::iterator ii;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001026
Kate Stoneb9c1b512016-09-06 20:57:50 +00001027 typedef SmallVector<Instruction *, 2> InstrList;
1028 typedef InstrList::iterator InstrIterator;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001029
Kate Stoneb9c1b512016-09-06 20:57:50 +00001030 InstrList pvar_allocs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001031
Kate Stoneb9c1b512016-09-06 20:57:50 +00001032 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1033 Instruction &inst = *ii;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001034
Kate Stoneb9c1b512016-09-06 20:57:50 +00001035 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1036 llvm::StringRef alloc_name = alloc->getName();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001037
Kate Stoneb9c1b512016-09-06 20:57:50 +00001038 if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1039 if (alloc_name.find_first_of("0123456789") == 1) {
1040 if (log)
1041 log->Printf("Rejecting a numeric persistent variable.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001042
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1044 "$1, ... are reserved for use as result "
1045 "names\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001046
Kate Stoneb9c1b512016-09-06 20:57:50 +00001047 return false;
Sean Callanan00294b32016-03-22 21:05:51 +00001048 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001049
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 pvar_allocs.push_back(alloc);
1051 }
Sean Callanan17827832010-12-13 22:46:15 +00001052 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001053 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001054
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055 InstrIterator iter;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001056
Kate Stoneb9c1b512016-09-06 20:57:50 +00001057 for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
1058 if (!RewritePersistentAlloc(*iter)) {
1059 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1060 "the creation of a persistent variable\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001061
Kate Stoneb9c1b512016-09-06 20:57:50 +00001062 if (log)
1063 log->PutCString(
1064 "Couldn't rewrite the creation of a persistent variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001065
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001067 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068 }
1069
1070 return true;
1071}
1072
1073bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
1074 if (!initializer)
1075 return true;
1076
1077 lldb_private::Log *log(
1078 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1079
1080 if (log && log->GetVerbose())
1081 log->Printf(" MaterializeInitializer(%p, %s)", (void *)data,
1082 PrintValue(initializer).c_str());
1083
1084 Type *initializer_type = initializer->getType();
1085
1086 if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
1087 size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
1088 lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
1089 llvm::NextPowerOf2(constant_size) * 8);
1090
1091 lldb_private::Error get_data_error;
1092 if (!scalar.GetAsMemoryData(data, constant_size,
1093 lldb_private::endian::InlHostByteOrder(),
1094 get_data_error))
1095 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001096
1097 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098 } else if (ConstantDataArray *array_initializer =
1099 dyn_cast<ConstantDataArray>(initializer)) {
1100 if (array_initializer->isString()) {
1101 std::string array_initializer_string = array_initializer->getAsString();
1102 memcpy(data, array_initializer_string.c_str(),
1103 m_target_data->getTypeStoreSize(initializer_type));
1104 } else {
1105 ArrayType *array_initializer_type = array_initializer->getType();
1106 Type *array_element_type = array_initializer_type->getElementType();
1107
1108 size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
1109
1110 for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
1111 Value *operand_value = array_initializer->getOperand(i);
1112 Constant *operand_constant = dyn_cast<Constant>(operand_value);
1113
1114 if (!operand_constant)
1115 return false;
1116
1117 if (!MaterializeInitializer(data + (i * element_size),
1118 operand_constant))
1119 return false;
1120 }
1121 }
1122 return true;
1123 } else if (ConstantStruct *struct_initializer =
1124 dyn_cast<ConstantStruct>(initializer)) {
1125 StructType *struct_initializer_type = struct_initializer->getType();
1126 const StructLayout *struct_layout =
1127 m_target_data->getStructLayout(struct_initializer_type);
1128
1129 for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
1130 if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
1131 struct_initializer->getOperand(i)))
1132 return false;
1133 }
1134 return true;
1135 } else if (isa<ConstantAggregateZero>(initializer)) {
1136 memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
1137 return true;
1138 }
1139 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001140}
1141
Kate Stoneb9c1b512016-09-06 20:57:50 +00001142// This function does not report errors; its callers are responsible.
1143bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1144 lldb_private::Log *log(
1145 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1146
1147 if (log)
1148 log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
1149
1150 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1151 switch (constant_expr->getOpcode()) {
1152 default:
1153 break;
1154 case Instruction::GetElementPtr:
1155 case Instruction::BitCast:
1156 Value *s = constant_expr->getOperand(0);
1157 if (!MaybeHandleVariable(s))
1158 return false;
1159 }
1160 } else if (GlobalVariable *global_variable =
1161 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1162 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1163 return true;
1164
1165 clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1166
1167 if (!named_decl) {
1168 if (IsObjCSelectorRef(llvm_value_ptr))
1169 return true;
1170
1171 if (!global_variable->hasExternalLinkage())
1172 return true;
1173
1174 if (log)
1175 log->Printf("Found global variable \"%s\" without metadata",
1176 global_variable->getName().str().c_str());
1177
1178 return false;
1179 }
1180
1181 std::string name(named_decl->getName().str());
1182
1183 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1184 if (value_decl == NULL)
1185 return false;
1186
1187 lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
1188 value_decl->getType());
1189
1190 const Type *value_type = NULL;
1191
1192 if (name[0] == '$') {
1193 // The $__lldb_expr_result name indicates the return value has allocated
1194 // as
1195 // a static variable. Per the comment at
1196 // ASTResultSynthesizer::SynthesizeBodyResult,
1197 // accesses to this static variable need to be redirected to the result of
1198 // dereferencing
1199 // a pointer that is passed in as one of the arguments.
1200 //
1201 // Consequently, when reporting the size of the type, we report a pointer
1202 // type pointing
1203 // to the type of $__lldb_expr_result, not the type itself.
1204 //
1205 // We also do this for any user-declared persistent variables.
1206 compiler_type = compiler_type.GetPointerType();
1207 value_type = PointerType::get(global_variable->getType(), 0);
1208 } else {
1209 value_type = global_variable->getType();
1210 }
1211
1212 const uint64_t value_size = compiler_type.GetByteSize(nullptr);
1213 lldb::offset_t value_alignment =
1214 (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
1215
1216 if (log) {
1217 log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
1218 ", align %" PRIu64 "]",
1219 name.c_str(),
1220 lldb_private::ClangUtil::GetQualType(compiler_type)
1221 .getAsString()
1222 .c_str(),
1223 PrintType(value_type).c_str(), value_size, value_alignment);
1224 }
1225
1226 if (named_decl &&
1227 !m_decl_map->AddValueToStruct(
1228 named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
1229 value_size, value_alignment)) {
1230 if (!global_variable->hasExternalLinkage())
1231 return true;
1232 else
1233 return true;
1234 }
1235 } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
1236 if (log)
1237 log->Printf("Function pointers aren't handled right now");
1238
1239 return false;
1240 }
1241
1242 return true;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001243}
1244
Kate Stoneb9c1b512016-09-06 20:57:50 +00001245// This function does not report errors; its callers are responsible.
1246bool IRForTarget::HandleSymbol(Value *symbol) {
1247 lldb_private::Log *log(
1248 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1249
1250 lldb_private::ConstString name(symbol->getName().str().c_str());
1251
1252 lldb::addr_t symbol_addr =
1253 m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1254
1255 if (symbol_addr == LLDB_INVALID_ADDRESS) {
1256 if (log)
1257 log->Printf("Symbol \"%s\" had no address", name.GetCString());
1258
1259 return false;
1260 }
1261
1262 if (log)
1263 log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
1264
1265 Type *symbol_type = symbol->getType();
1266
1267 Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1268
1269 Value *symbol_addr_ptr =
1270 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1271
1272 if (log)
1273 log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
1274 PrintValue(symbol_addr_ptr).c_str());
1275
1276 symbol->replaceAllUsesWith(symbol_addr_ptr);
1277
1278 return true;
1279}
1280
1281bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1282 lldb_private::Log *log(
1283 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1284
1285 if (log)
1286 log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
1287
1288 for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1289 op_index < num_ops; ++op_index)
1290 if (!MaybeHandleVariable(Old->getArgOperand(
1291 op_index))) // conservatively believe that this is a store
1292 {
1293 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1294 "one of the arguments of a function call.\n");
1295
1296 return false;
1297 }
1298
1299 return true;
1300}
1301
1302bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1303 lldb_private::Log *log(
1304 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1305
1306 GlobalVariable *global_variable =
1307 dyn_cast<GlobalVariable>(classlist_reference);
1308
1309 if (!global_variable)
1310 return false;
1311
1312 Constant *initializer = global_variable->getInitializer();
1313
1314 if (!initializer)
1315 return false;
1316
1317 if (!initializer->hasName())
1318 return false;
1319
1320 StringRef name(initializer->getName());
1321 lldb_private::ConstString name_cstr(name.str().c_str());
1322 lldb::addr_t class_ptr =
1323 m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1324
1325 if (log)
1326 log->Printf("Found reference to Objective-C class %s (0x%llx)",
1327 name_cstr.AsCString(), (unsigned long long)class_ptr);
1328
1329 if (class_ptr == LLDB_INVALID_ADDRESS)
1330 return false;
1331
1332 if (global_variable->use_empty())
1333 return false;
1334
1335 SmallVector<LoadInst *, 2> load_instructions;
1336
1337 for (llvm::User *u : global_variable->users()) {
1338 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1339 load_instructions.push_back(load_instruction);
1340 }
1341
1342 if (load_instructions.empty())
1343 return false;
1344
1345 Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1346
1347 for (LoadInst *load_instruction : load_instructions) {
1348 Constant *class_bitcast =
1349 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1350
1351 load_instruction->replaceAllUsesWith(class_bitcast);
1352
1353 load_instruction->eraseFromParent();
1354 }
1355
1356 return true;
1357}
1358
1359bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
1360 BasicBlock::iterator ii;
1361
1362 std::vector<CallInst *> calls_to_remove;
1363
1364 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1365 Instruction &inst = *ii;
1366
1367 CallInst *call = dyn_cast<CallInst>(&inst);
1368
1369 // MaybeHandleCallArguments handles error reporting; we are silent here
1370 if (!call)
1371 continue;
1372
1373 bool remove = false;
1374
1375 llvm::Function *func = call->getCalledFunction();
1376
1377 if (func && func->getName() == "__cxa_atexit")
1378 remove = true;
1379
1380 llvm::Value *val = call->getCalledValue();
1381
1382 if (val && val->getName() == "__cxa_atexit")
1383 remove = true;
1384
1385 if (remove)
1386 calls_to_remove.push_back(call);
1387 }
1388
1389 for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
1390 ce = calls_to_remove.end();
1391 ci != ce; ++ci) {
1392 (*ci)->eraseFromParent();
1393 }
1394
1395 return true;
1396}
1397
1398bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
1399 /////////////////////////////////////////////////////////////////////////
1400 // Prepare the current basic block for execution in the remote process
1401 //
1402
1403 BasicBlock::iterator ii;
1404
1405 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1406 Instruction &inst = *ii;
1407
1408 CallInst *call = dyn_cast<CallInst>(&inst);
1409
1410 // MaybeHandleCallArguments handles error reporting; we are silent here
1411 if (call && !MaybeHandleCallArguments(call))
1412 return false;
1413 }
1414
1415 return true;
1416}
1417
1418bool IRForTarget::ResolveExternals(Function &llvm_function) {
1419 lldb_private::Log *log(
1420 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1421
1422 for (GlobalVariable &global_var : m_module->globals()) {
1423 std::string global_name = global_var.getName().str();
1424
1425 if (log)
1426 log->Printf("Examining %s, DeclForGlobalValue returns %p",
1427 global_name.c_str(),
1428 static_cast<void *>(DeclForGlobal(&global_var)));
1429
1430 if (global_name.find("OBJC_IVAR") == 0) {
1431 if (!HandleSymbol(&global_var)) {
1432 m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
1433 "indirect ivar symbol %s\n",
1434 global_name.c_str());
1435
1436 return false;
1437 }
1438 } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
1439 global_name.npos) {
1440 if (!HandleObjCClass(&global_var)) {
1441 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1442 "for an Objective-C static method call\n");
1443
1444 return false;
1445 }
1446 } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
1447 global_name.npos) {
1448 if (!HandleObjCClass(&global_var)) {
1449 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1450 "for an Objective-C static method call\n");
1451
1452 return false;
1453 }
1454 } else if (DeclForGlobal(&global_var)) {
1455 if (!MaybeHandleVariable(&global_var)) {
1456 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1457 "external variable %s\n",
1458 global_name.c_str());
1459
1460 return false;
1461 }
1462 }
1463 }
1464
1465 return true;
1466}
1467
1468static bool isGuardVariableRef(Value *V) {
1469 Constant *Old = NULL;
1470
1471 if (!(Old = dyn_cast<Constant>(V)))
1472 return false;
1473
1474 ConstantExpr *CE = NULL;
1475
1476 if ((CE = dyn_cast<ConstantExpr>(V))) {
1477 if (CE->getOpcode() != Instruction::BitCast)
1478 return false;
1479
1480 Old = CE->getOperand(0);
1481 }
1482
1483 GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1484
1485 if (!GV || !GV->hasName() ||
1486 (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
1487 !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
1488 {
1489 return false;
1490 }
1491
1492 return true;
1493}
1494
1495void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1496 Constant *zero(Constant::getNullValue(guard_load->getType()));
1497 guard_load->replaceAllUsesWith(zero);
1498 guard_load->eraseFromParent();
1499}
1500
1501static void ExciseGuardStore(Instruction *guard_store) {
1502 guard_store->eraseFromParent();
1503}
1504
1505bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
1506 ///////////////////////////////////////////////////////
1507 // Eliminate any reference to guard variables found.
1508 //
1509
1510 BasicBlock::iterator ii;
1511
1512 typedef SmallVector<Instruction *, 2> InstrList;
1513 typedef InstrList::iterator InstrIterator;
1514
1515 InstrList guard_loads;
1516 InstrList guard_stores;
1517
1518 for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1519 Instruction &inst = *ii;
1520
1521 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1522 if (isGuardVariableRef(load->getPointerOperand()))
1523 guard_loads.push_back(&inst);
1524
1525 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1526 if (isGuardVariableRef(store->getPointerOperand()))
1527 guard_stores.push_back(&inst);
1528 }
1529
1530 InstrIterator iter;
1531
1532 for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
1533 TurnGuardLoadIntoZero(*iter);
1534
1535 for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
1536 ExciseGuardStore(*iter);
1537
1538 return true;
1539}
1540
1541// This function does not report errors; its callers are responsible.
1542bool IRForTarget::UnfoldConstant(Constant *old_constant,
1543 llvm::Function *llvm_function,
1544 FunctionValueCache &value_maker,
1545 FunctionValueCache &entry_instruction_finder,
1546 lldb_private::Stream &error_stream) {
1547 SmallVector<User *, 16> users;
1548
1549 // We do this because the use list might change, invalidating our iterator.
1550 // Much better to keep a work list ourselves.
1551 for (llvm::User *u : old_constant->users())
1552 users.push_back(u);
1553
1554 for (size_t i = 0; i < users.size(); ++i) {
1555 User *user = users[i];
1556
1557 if (Constant *constant = dyn_cast<Constant>(user)) {
1558 // synthesize a new non-constant equivalent of the constant
1559
1560 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1561 switch (constant_expr->getOpcode()) {
1562 default:
1563 error_stream.Printf("error [IRForTarget internal]: Unhandled "
1564 "constant expression type: \"%s\"",
1565 PrintValue(constant_expr).c_str());
1566 return false;
1567 case Instruction::BitCast: {
1568 FunctionValueCache bit_cast_maker(
1569 [&value_maker, &entry_instruction_finder, old_constant,
1570 constant_expr](llvm::Function *function) -> llvm::Value * {
1571 // UnaryExpr
1572 // OperandList[0] is value
1573
1574 if (constant_expr->getOperand(0) != old_constant)
1575 return constant_expr;
1576
1577 return new BitCastInst(
1578 value_maker.GetValue(function), constant_expr->getType(),
1579 "", llvm::cast<Instruction>(
1580 entry_instruction_finder.GetValue(function)));
1581 });
1582
1583 if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1584 entry_instruction_finder, error_stream))
1585 return false;
1586 } break;
1587 case Instruction::GetElementPtr: {
1588 // GetElementPtrConstantExpr
1589 // OperandList[0] is base
1590 // OperandList[1]... are indices
1591
1592 FunctionValueCache get_element_pointer_maker(
1593 [&value_maker, &entry_instruction_finder, old_constant,
1594 constant_expr](llvm::Function *function) -> llvm::Value * {
1595 Value *ptr = constant_expr->getOperand(0);
1596
1597 if (ptr == old_constant)
1598 ptr = value_maker.GetValue(function);
1599
1600 std::vector<Value *> index_vector;
1601
1602 unsigned operand_index;
1603 unsigned num_operands = constant_expr->getNumOperands();
1604
1605 for (operand_index = 1; operand_index < num_operands;
1606 ++operand_index) {
1607 Value *operand = constant_expr->getOperand(operand_index);
1608
1609 if (operand == old_constant)
1610 operand = value_maker.GetValue(function);
1611
1612 index_vector.push_back(operand);
1613 }
1614
1615 ArrayRef<Value *> indices(index_vector);
1616
1617 return GetElementPtrInst::Create(
1618 nullptr, ptr, indices, "",
1619 llvm::cast<Instruction>(
1620 entry_instruction_finder.GetValue(function)));
1621 });
1622
1623 if (!UnfoldConstant(constant_expr, llvm_function,
1624 get_element_pointer_maker,
1625 entry_instruction_finder, error_stream))
1626 return false;
1627 } break;
1628 }
1629 } else {
1630 error_stream.Printf(
1631 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1632 PrintValue(constant).c_str());
1633 return false;
1634 }
1635 } else {
1636 if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1637 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1638 error_stream.PutCString("error: Capturing non-local variables in "
1639 "expressions is unsupported.\n");
1640 return false;
1641 }
1642 inst->replaceUsesOfWith(
1643 old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1644 } else {
1645 error_stream.Printf(
1646 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1647 PrintValue(user).c_str());
1648 return false;
1649 }
1650 }
1651 }
1652
1653 if (!isa<GlobalValue>(old_constant)) {
1654 old_constant->destroyConstant();
1655 }
1656
1657 return true;
1658}
1659
1660bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1661 if (!m_resolve_vars)
1662 return true;
1663
1664 lldb_private::Log *log(
1665 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1666
1667 m_decl_map->DoStructLayout();
1668
1669 if (log)
1670 log->Printf("Element arrangement:");
1671
1672 uint32_t num_elements;
1673 uint32_t element_index;
1674
1675 size_t size;
1676 lldb::offset_t alignment;
1677
1678 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1679 return false;
1680
1681 Function::arg_iterator iter(llvm_function.getArgumentList().begin());
1682
1683 if (iter == llvm_function.getArgumentList().end()) {
1684 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1685 "arguments (should take at least a struct pointer)");
1686
1687 return false;
1688 }
1689
1690 Argument *argument = &*iter;
1691
1692 if (argument->getName().equals("this")) {
1693 ++iter;
1694
1695 if (iter == llvm_function.getArgumentList().end()) {
1696 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1697 "'this' argument (should take a struct pointer "
1698 "too)");
1699
1700 return false;
1701 }
1702
1703 argument = &*iter;
1704 } else if (argument->getName().equals("self")) {
1705 ++iter;
1706
1707 if (iter == llvm_function.getArgumentList().end()) {
1708 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1709 "'self' argument (should take '_cmd' and a struct "
1710 "pointer too)");
1711
1712 return false;
1713 }
1714
1715 if (!iter->getName().equals("_cmd")) {
1716 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
1717 "after 'self' argument (should take '_cmd')",
1718 iter->getName().str().c_str());
1719
1720 return false;
1721 }
1722
1723 ++iter;
1724
1725 if (iter == llvm_function.getArgumentList().end()) {
1726 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1727 "'self' and '_cmd' arguments (should take a struct "
1728 "pointer too)");
1729
1730 return false;
1731 }
1732
1733 argument = &*iter;
1734 }
1735
1736 if (!argument->getName().equals("$__lldb_arg")) {
1737 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
1738 "argument named '%s' instead of the struct pointer",
1739 argument->getName().str().c_str());
1740
1741 return false;
1742 }
1743
1744 if (log)
1745 log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
1746
1747 BasicBlock &entry_block(llvm_function.getEntryBlock());
1748 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1749
1750 if (!FirstEntryInstruction) {
1751 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1752 "first instruction in the wrapper for use in "
1753 "rewriting");
1754
1755 return false;
1756 }
1757
1758 LLVMContext &context(m_module->getContext());
1759 IntegerType *offset_type(Type::getInt32Ty(context));
1760
1761 if (!offset_type) {
1762 m_error_stream.Printf(
1763 "Internal error [IRForTarget]: Couldn't produce an offset type");
1764
1765 return false;
1766 }
1767
1768 for (element_index = 0; element_index < num_elements; ++element_index) {
1769 const clang::NamedDecl *decl = NULL;
1770 Value *value = NULL;
1771 lldb::offset_t offset;
1772 lldb_private::ConstString name;
1773
1774 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1775 element_index)) {
1776 m_error_stream.Printf(
1777 "Internal error [IRForTarget]: Structure information is incomplete");
1778
1779 return false;
1780 }
1781
1782 if (log)
1783 log->Printf(" \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
1784 decl->getNameAsString().c_str(), offset);
1785
1786 if (value) {
1787 if (log)
1788 log->Printf(" Replacing [%s]", PrintValue(value).c_str());
1789
1790 FunctionValueCache body_result_maker(
1791 [this, name, offset_type, offset, argument,
1792 value](llvm::Function *function) -> llvm::Value * {
1793 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in
1794 // cases where the result
1795 // variable is an rvalue, we have to synthesize a dereference of the
1796 // appropriate structure
1797 // entry in order to produce the static variable that the AST thinks
1798 // it is accessing.
1799
1800 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1801 m_entry_instruction_finder.GetValue(function));
1802
1803 ConstantInt *offset_int(
1804 ConstantInt::get(offset_type, offset, true));
1805 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1806 nullptr, argument, offset_int, "", entry_instruction);
1807
1808 if (name == m_result_name && !m_result_is_pointer) {
1809 BitCastInst *bit_cast = new BitCastInst(
1810 get_element_ptr, value->getType()->getPointerTo(), "",
1811 entry_instruction);
1812
1813 LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1814
1815 return load;
1816 } else {
1817 BitCastInst *bit_cast = new BitCastInst(
1818 get_element_ptr, value->getType(), "", entry_instruction);
1819
1820 return bit_cast;
1821 }
1822 });
1823
1824 if (Constant *constant = dyn_cast<Constant>(value)) {
1825 if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
1826 m_entry_instruction_finder, m_error_stream)) {
1827 return false;
1828 }
1829 } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1830 if (instruction->getParent()->getParent() != &llvm_function) {
1831 m_error_stream.PutCString("error: Capturing non-local variables in "
1832 "expressions is unsupported.\n");
1833 return false;
1834 }
1835 value->replaceAllUsesWith(
1836 body_result_maker.GetValue(instruction->getParent()->getParent()));
1837 } else {
1838 if (log)
1839 log->Printf("Unhandled non-constant type: \"%s\"",
1840 PrintValue(value).c_str());
1841 return false;
1842 }
1843
1844 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1845 var->eraseFromParent();
1846 }
1847 }
1848
1849 if (log)
1850 log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
1851 (int64_t)alignment, (uint64_t)size);
1852
1853 return true;
1854}
1855
1856llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
1857 uint64_t offset) {
1858 llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
1859
1860 llvm::Constant *offset_array[1];
1861
1862 offset_array[0] = offset_int;
1863
1864 llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
1865 llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
1866 llvm::Type *char_pointer_type = char_type->getPointerTo();
1867
1868 llvm::Constant *reloc_placeholder_bitcast =
1869 ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
1870 llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
1871 char_type, reloc_placeholder_bitcast, offsets);
1872 llvm::Constant *reloc_bitcast =
1873 ConstantExpr::getBitCast(reloc_getelementptr, type);
1874
1875 return reloc_bitcast;
1876}
1877
1878bool IRForTarget::runOnModule(Module &llvm_module) {
1879 lldb_private::Log *log(
1880 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1881
1882 m_module = &llvm_module;
1883 m_target_data.reset(new DataLayout(m_module));
1884 m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
1885 m_target_data->getPointerSizeInBits());
1886
1887 if (log) {
1888 std::string s;
1889 raw_string_ostream oss(s);
1890
1891 m_module->print(oss, NULL);
1892
1893 oss.flush();
1894
1895 log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
1896 }
1897
1898 Function *const main_function =
1899 m_func_name.IsEmpty() ? nullptr
1900 : m_module->getFunction(m_func_name.GetStringRef());
1901
1902 if (!m_func_name.IsEmpty() && !main_function) {
1903 if (log)
1904 log->Printf("Couldn't find \"%s()\" in the module",
1905 m_func_name.AsCString());
1906
1907 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
1908 "'%s' in the module",
1909 m_func_name.AsCString());
1910
1911 return false;
1912 }
1913
1914 if (main_function) {
1915 if (!FixFunctionLinkage(*main_function)) {
1916 if (log)
1917 log->Printf("Couldn't fix the linkage for the function");
1918
1919 return false;
1920 }
1921 }
1922
1923 llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
1924
1925 m_reloc_placeholder = new llvm::GlobalVariable(
1926 (*m_module), int8_ty, false /* IsConstant */,
1927 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
1928 "reloc_placeholder", NULL /* InsertBefore */,
1929 GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
1930
1931 ////////////////////////////////////////////////////////////
1932 // Replace $__lldb_expr_result with a persistent variable
1933 //
1934
1935 if (main_function) {
1936 if (!CreateResultVariable(*main_function)) {
1937 if (log)
1938 log->Printf("CreateResultVariable() failed");
1939
1940 // CreateResultVariable() reports its own errors, so we don't do so here
1941
1942 return false;
1943 }
1944 }
1945
1946 if (log && log->GetVerbose()) {
1947 std::string s;
1948 raw_string_ostream oss(s);
1949
1950 m_module->print(oss, NULL);
1951
1952 oss.flush();
1953
1954 log->Printf("Module after creating the result variable: \n\"%s\"",
1955 s.c_str());
1956 }
1957
1958 for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
1959 ++fi) {
1960 llvm::Function *function = &*fi;
1961
1962 if (function->begin() == function->end())
1963 continue;
1964
1965 Function::iterator bbi;
1966
1967 for (bbi = function->begin(); bbi != function->end(); ++bbi) {
1968 if (!RemoveGuards(*bbi)) {
1969 if (log)
1970 log->Printf("RemoveGuards() failed");
1971
1972 // RemoveGuards() reports its own errors, so we don't do so here
1973
1974 return false;
1975 }
1976
1977 if (!RewritePersistentAllocs(*bbi)) {
1978 if (log)
1979 log->Printf("RewritePersistentAllocs() failed");
1980
1981 // RewritePersistentAllocs() reports its own errors, so we don't do so
1982 // here
1983
1984 return false;
1985 }
1986
1987 if (!RemoveCXAAtExit(*bbi)) {
1988 if (log)
1989 log->Printf("RemoveCXAAtExit() failed");
1990
1991 // RemoveCXAAtExit() reports its own errors, so we don't do so here
1992
1993 return false;
1994 }
1995 }
1996 }
1997
1998 ///////////////////////////////////////////////////////////////////////////////
1999 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
2000 //
2001
2002 if (!RewriteObjCConstStrings()) {
2003 if (log)
2004 log->Printf("RewriteObjCConstStrings() failed");
2005
2006 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
2007
2008 return false;
2009 }
2010
2011 for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2012 ++fi) {
2013 llvm::Function *function = &*fi;
2014
2015 for (llvm::Function::iterator bbi = function->begin(),
2016 bbe = function->end();
2017 bbi != bbe; ++bbi) {
2018 if (!RewriteObjCSelectors(*bbi)) {
2019 if (log)
2020 log->Printf("RewriteObjCSelectors() failed");
2021
2022 // RewriteObjCSelectors() reports its own errors, so we don't do so here
2023
2024 return false;
2025 }
2026 }
2027 }
2028
2029 for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2030 ++fi) {
2031 llvm::Function *function = &*fi;
2032
2033 for (llvm::Function::iterator bbi = function->begin(),
2034 bbe = function->end();
2035 bbi != bbe; ++bbi) {
2036 if (!ResolveCalls(*bbi)) {
2037 if (log)
2038 log->Printf("ResolveCalls() failed");
2039
2040 // ResolveCalls() reports its own errors, so we don't do so here
2041
2042 return false;
2043 }
2044 }
2045 }
2046
2047 ////////////////////////////////////////////////////////////////////////
2048 // Run function-level passes that only make sense on the main function
2049 //
2050
2051 if (main_function) {
2052 if (!ResolveExternals(*main_function)) {
2053 if (log)
2054 log->Printf("ResolveExternals() failed");
2055
2056 // ResolveExternals() reports its own errors, so we don't do so here
2057
2058 return false;
2059 }
2060
2061 if (!ReplaceVariables(*main_function)) {
2062 if (log)
2063 log->Printf("ReplaceVariables() failed");
2064
2065 // ReplaceVariables() reports its own errors, so we don't do so here
2066
2067 return false;
2068 }
2069 }
2070
2071 if (log && log->GetVerbose()) {
2072 std::string s;
2073 raw_string_ostream oss(s);
2074
2075 m_module->print(oss, NULL);
2076
2077 oss.flush();
2078
2079 log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
2080 }
2081
2082 return true;
2083}
2084
2085void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2086 PassManagerType pass_mgr_type) {}
2087
2088PassManagerType IRForTarget::getPotentialPassManagerType() const {
2089 return PMT_ModulePassManager;
Sean Callanan2ab712f22010-07-03 01:35:46 +00002090}