blob: 4a34aa50c5f4b87ba8ff5ead0f3025857fb0a1d6 [file] [log] [blame]
Sean Callanan3bfdaa22011-09-15 02:13:07 +00001//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
Sean Callanan2ab712f22010-07-03 01:35:46 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Sean Callanan2ab712f22010-07-03 01:35:46 +00006//
7//===----------------------------------------------------------------------===//
8
Sean Callanan4dbb2712015-09-25 20:35:58 +00009#include "IRForTarget.h"
10
11#include "ClangExpressionDeclMap.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000012
Chandler Carruth1e157582013-01-02 12:20:07 +000013#include "llvm/IR/Constants.h"
14#include "llvm/IR/DataLayout.h"
15#include "llvm/IR/InstrTypes.h"
16#include "llvm/IR/Instructions.h"
17#include "llvm/IR/Intrinsics.h"
Ilia Kc9a475d2015-02-13 10:49:18 +000018#include "llvm/IR/LegacyPassManager.h"
Zachary Turner543afa12014-12-09 22:29:47 +000019#include "llvm/IR/Metadata.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000020#include "llvm/IR/Module.h"
Chandler Carruth1e157582013-01-02 12:20:07 +000021#include "llvm/IR/ValueSymbolTable.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000022#include "llvm/Support/raw_ostream.h"
23#include "llvm/Transforms/IPO.h"
Sean Callanan549c9f72010-07-13 21:41:46 +000024
25#include "clang/AST/ASTContext.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000026
Zachary Turnerd133f6a2016-03-28 22:53:41 +000027#include "lldb/Core/dwarf.h"
Sean Callanan8dfb68e2013-03-19 00:10:07 +000028#include "lldb/Expression/IRExecutionUnit.h"
Sean Callanan3bfdaa22011-09-15 02:13:07 +000029#include "lldb/Expression/IRInterpreter.h"
Sean Callanan63697e52011-05-07 01:06:41 +000030#include "lldb/Symbol/ClangASTContext.h"
Zachary Turnerd133f6a2016-03-28 22:53:41 +000031#include "lldb/Symbol/ClangUtil.h"
Greg Claytona1e5dc82015-08-11 22:53:00 +000032#include "lldb/Symbol/CompilerType.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000033#include "lldb/Utility/ConstString.h"
Zachary Turner666cc0b2017-03-04 01:30:05 +000034#include "lldb/Utility/DataBufferHeap.h"
Zachary Turner01c32432017-02-14 19:06:07 +000035#include "lldb/Utility/Endian.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000036#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000037#include "lldb/Utility/Scalar.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000038#include "lldb/Utility/StreamString.h"
Sean Callanan2ab712f22010-07-03 01:35:46 +000039
40#include <map>
41
42using namespace llvm;
43
Sean Callananeaacbc92010-08-18 18:50:51 +000044static char ID;
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
47 : m_maker(maker), m_values() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000048
Kate Stoneb9c1b512016-09-06 20:57:50 +000049IRForTarget::FunctionValueCache::~FunctionValueCache() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000050
Greg Clayton526ae042015-02-12 00:34:25 +000051llvm::Value *
Kate Stoneb9c1b512016-09-06 20:57:50 +000052IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
53 if (!m_values.count(function)) {
54 llvm::Value *ret = m_maker(function);
55 m_values[function] = ret;
56 return ret;
57 }
58 return m_values[function];
Sean Callanan1f9db3e2013-06-28 21:44:15 +000059}
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061static llvm::Value *FindEntryInstruction(llvm::Function *function) {
62 if (function->empty())
Konrad Kleine248a1302019-05-23 11:14:47 +000063 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 return function->getEntryBlock().getFirstNonPHIOrDbg();
Sean Callanan1f9db3e2013-06-28 21:44:15 +000066}
67
Kate Stoneb9c1b512016-09-06 20:57:50 +000068IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
69 bool resolve_vars,
70 lldb_private::IRExecutionUnit &execution_unit,
71 lldb_private::Stream &error_stream,
72 const char *func_name)
73 : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
Konrad Kleine248a1302019-05-23 11:14:47 +000074 m_module(nullptr), m_decl_map(decl_map),
75 m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
76 m_objc_getClass(nullptr), m_intptr_ty(nullptr),
77 m_error_stream(error_stream), m_execution_unit(execution_unit),
78 m_result_store(nullptr), m_result_is_pointer(false),
79 m_reloc_placeholder(nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 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)
Konrad Kleine248a1302019-05-23 11:14:47 +0000120 return nullptr;
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)
Konrad Kleine248a1302019-05-23 11:14:47 +0000129 return nullptr;
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)
Konrad Kleine248a1302019-05-23 11:14:47 +0000142 return nullptr;
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
Konrad Kleine248a1302019-05-23 11:14:47 +0000149 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000150}
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
Raphael Isemann50f7e942019-08-08 22:19:16 +0000167 llvm::StringRef result_name;
168 bool found_result = false;
Sean Callanan2235f322010-08-11 03:57:18 +0000169
Raphael Isemanndced4452019-08-09 07:59:18 +0000170 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
171 result_name = value_symbol.first();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000172
Raphael Isemann50f7e942019-08-08 22:19:16 +0000173 if (result_name.contains("$__lldb_expr_result_ptr") &&
174 !result_name.startswith("_ZGV")) {
175 found_result = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 m_result_is_pointer = true;
177 break;
178 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000179
Raphael Isemann50f7e942019-08-08 22:19:16 +0000180 if (result_name.contains("$__lldb_expr_result") &&
181 !result_name.startswith("_ZGV")) {
182 found_result = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000183 m_result_is_pointer = false;
184 break;
185 }
186 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000187
Raphael Isemann50f7e942019-08-08 22:19:16 +0000188 if (!found_result) {
Sean Callanane1175b72011-01-13 21:23:32 +0000189 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 log->PutCString("Couldn't find result variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000191
Sean Callanan2235f322010-08-11 03:57:18 +0000192 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 }
Sean Callanan2235f322010-08-11 03:57:18 +0000194
Raphael Isemann50f7e942019-08-08 22:19:16 +0000195 LLDB_LOG(log, "Result name: \"{0}\"", result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 Value *result_value = m_module->getNamedValue(result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199 if (!result_value) {
200 if (log)
201 log->PutCString("Result variable had no data");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000202
Raphael Isemann50f7e942019-08-08 22:19:16 +0000203 m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
204 "name ({0}) exists, but not its definition\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000205 result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000206
Sean Callananc70ed462011-10-25 18:36:40 +0000207 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208 }
Sean Callananc70ed462011-10-25 18:36:40 +0000209
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000210 LLDB_LOGF(log, "Found result in the IR: \"%s\"",
211 PrintValue(result_value, false).c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212
213 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
214
215 if (!result_global) {
216 if (log)
217 log->PutCString("Result variable isn't a GlobalVariable");
218
Raphael Isemann50f7e942019-08-08 22:19:16 +0000219 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 "is defined, but is not a global variable\n",
221 result_name);
222
223 return false;
224 }
225
226 clang::NamedDecl *result_decl = DeclForGlobal(result_global);
227 if (!result_decl) {
228 if (log)
229 log->PutCString("Result variable doesn't have a corresponding Decl");
230
Raphael Isemann50f7e942019-08-08 22:19:16 +0000231 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000232 "does not have a corresponding Clang entity\n",
233 result_name);
234
235 return false;
236 }
237
238 if (log) {
239 std::string decl_desc_str;
240 raw_string_ostream decl_desc_stream(decl_desc_str);
241 result_decl->print(decl_desc_stream);
242 decl_desc_stream.flush();
243
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000244 LLDB_LOGF(log, "Found result decl: \"%s\"", decl_desc_str.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245 }
246
247 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
248 if (!result_var) {
249 if (log)
250 log->PutCString("Result variable Decl isn't a VarDecl");
251
Raphael Isemann50f7e942019-08-08 22:19:16 +0000252 m_error_stream.Format("Internal error [IRForTarget]: Result variable "
253 "({0})'s corresponding Clang entity isn't a "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254 "variable\n",
255 result_name);
256
257 return false;
258 }
259
260 // Get the next available result name from m_decl_map and create the
Adrian Prantl05097242018-04-30 16:49:04 +0000261 // persistent variable for it
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262
263 // If the result is an Lvalue, it is emitted as a pointer; see
264 // ASTResultSynthesizer::SynthesizeBodyResult.
265 if (m_result_is_pointer) {
266 clang::QualType pointer_qual_type = result_var->getType();
267 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
268
269 const clang::PointerType *pointer_pointertype =
270 pointer_type->getAs<clang::PointerType>();
271 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
272 pointer_type->getAs<clang::ObjCObjectPointerType>();
273
274 if (pointer_pointertype) {
275 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
276
277 m_result_type = lldb_private::TypeFromParser(
278 element_qual_type.getAsOpaquePtr(),
279 lldb_private::ClangASTContext::GetASTContext(
280 &result_decl->getASTContext()));
281 } else if (pointer_objcobjpointertype) {
282 clang::QualType element_qual_type =
283 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
284
285 m_result_type = lldb_private::TypeFromParser(
286 element_qual_type.getAsOpaquePtr(),
287 lldb_private::ClangASTContext::GetASTContext(
288 &result_decl->getASTContext()));
289 } else {
290 if (log)
291 log->PutCString("Expected result to have pointer type, but it did not");
292
Raphael Isemann50f7e942019-08-08 22:19:16 +0000293 m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000294 "is not a pointer variable\n",
295 result_name);
296
297 return false;
298 }
299 } else {
300 m_result_type = lldb_private::TypeFromParser(
301 result_var->getType().getAsOpaquePtr(),
302 lldb_private::ClangASTContext::GetASTContext(
303 &result_decl->getASTContext()));
304 }
305
306 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
307 lldb_private::ExecutionContext exe_ctx(target_sp, true);
Adrian Prantld6a9bbf2019-01-15 20:33:58 +0000308 llvm::Optional<uint64_t> bit_size =
Adrian Prantld963a7c2019-01-15 18:07:52 +0000309 m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
310 if (!bit_size) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000311 lldb_private::StreamString type_desc_stream;
312 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000313
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000314 LLDB_LOGF(log, "Result type has unknown size");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000315
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316 m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
317 "couldn't be determined\n",
318 type_desc_stream.GetData());
319 return false;
320 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000321
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 if (log) {
323 lldb_private::StreamString type_desc_stream;
324 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000326 LLDB_LOGF(log, "Result decl type: \"%s\"", type_desc_stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000328
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329 m_result_name = lldb_private::ConstString("$RESULT_NAME");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000330
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000331 LLDB_LOGF(log, "Creating a new result global: \"%s\" with size 0x%" PRIx64,
332 m_result_name.GetCString(),
333 m_result_type.GetByteSize(nullptr).getValueOr(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000334
Kate Stoneb9c1b512016-09-06 20:57:50 +0000335 // Construct a new result global and set up its metadata
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000336
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 GlobalVariable *new_result_global = new GlobalVariable(
338 (*m_module), result_global->getType()->getElementType(),
Konrad Kleine248a1302019-05-23 11:14:47 +0000339 false, /* not constant */
340 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 m_result_name.GetCString());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Adrian Prantl05097242018-04-30 16:49:04 +0000343 // It's too late in compilation to create a new VarDecl for this, but we
344 // don't need to. We point the metadata at the old VarDecl. This creates an
345 // odd anomaly: a variable with a Value whose name is something like $0 and a
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 // Decl whose name is $__lldb_expr_result. This condition is handled in
347 // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
348 // fixed up.
Greg Clayton57ee3062013-07-11 22:46:58 +0000349
Kate Stoneb9c1b512016-09-06 20:57:50 +0000350 ConstantInt *new_constant_int =
351 ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
352 reinterpret_cast<uint64_t>(result_decl), false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000353
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 llvm::Metadata *values[2];
355 values[0] = ConstantAsMetadata::get(new_result_global);
356 values[1] = ConstantAsMetadata::get(new_constant_int);
Greg Clayton57ee3062013-07-11 22:46:58 +0000357
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 ArrayRef<Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000359
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
361 NamedMDNode *named_metadata =
362 m_module->getNamedMetadata("clang.global.decl.ptrs");
363 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000364
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000365 LLDB_LOGF(log, "Replacing \"%s\" with \"%s\"",
366 PrintValue(result_global).c_str(),
367 PrintValue(new_result_global).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 if (result_global->use_empty()) {
370 // We need to synthesize a store for this variable, because otherwise
371 // there's nothing to put into its equivalent persistent variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000372
Greg Clayton1b95a6f2010-11-19 01:05:25 +0000373 BasicBlock &entry_block(llvm_function.getEntryBlock());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374 Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000375
Kate Stoneb9c1b512016-09-06 20:57:50 +0000376 if (!first_entry_instruction)
377 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000378
Kate Stoneb9c1b512016-09-06 20:57:50 +0000379 if (!result_global->hasInitializer()) {
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000380 LLDB_LOGF(log, "Couldn't find initializer for unused variable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381
Raphael Isemann50f7e942019-08-08 22:19:16 +0000382 m_error_stream.Format("Internal error [IRForTarget]: Result variable "
383 "({0}) has no writes and no initializer\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000384 result_name);
385
386 return false;
Sean Callanan3989fb92011-01-27 01:07:04 +0000387 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000388
Kate Stoneb9c1b512016-09-06 20:57:50 +0000389 Constant *initializer = result_global->getInitializer();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000390
Kate Stoneb9c1b512016-09-06 20:57:50 +0000391 StoreInst *synthesized_store =
392 new StoreInst(initializer, new_result_global, first_entry_instruction);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000393
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000394 LLDB_LOGF(log, "Synthesized result store \"%s\"\n",
395 PrintValue(synthesized_store).c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396 } else {
397 result_global->replaceAllUsesWith(new_result_global);
398 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000399
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 if (!m_decl_map->AddPersistentVariable(
401 result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
402 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000403
Kate Stoneb9c1b512016-09-06 20:57:50 +0000404 result_global->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000405
Kate Stoneb9c1b512016-09-06 20:57:50 +0000406 return true;
407}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000408
Kate Stoneb9c1b512016-09-06 20:57:50 +0000409bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
410 llvm::GlobalVariable *cstr) {
411 lldb_private::Log *log(
412 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000413
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 Type *ns_str_ty = ns_str->getType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000415
Kate Stoneb9c1b512016-09-06 20:57:50 +0000416 Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
417 Type *i32_ty = Type::getInt32Ty(m_module->getContext());
418 Type *i8_ty = Type::getInt8Ty(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000419
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420 if (!m_CFStringCreateWithBytes) {
421 lldb::addr_t CFStringCreateWithBytes_addr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423 static lldb_private::ConstString g_CFStringCreateWithBytes_str(
424 "CFStringCreateWithBytes");
Sean Callanan1f9db3e2013-06-28 21:44:15 +0000425
Jim Inghamf2128b22019-06-28 21:40:05 +0000426 bool missing_weak = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427 CFStringCreateWithBytes_addr =
Jim Inghamf2128b22019-06-28 21:40:05 +0000428 m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
429 missing_weak);
430 if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000431 log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000432
Kate Stoneb9c1b512016-09-06 20:57:50 +0000433 m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
434 "constant string requires "
435 "CFStringCreateWithBytes\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000436
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 return false;
Sean Callanan549c9f72010-07-13 21:41:46 +0000438 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000439
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000440 LLDB_LOGF(log, "Found CFStringCreateWithBytes at 0x%" PRIx64,
441 CFStringCreateWithBytes_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 // Build the function type:
444 //
445 // CFStringRef CFStringCreateWithBytes (
446 // CFAllocatorRef alloc,
447 // const UInt8 *bytes,
448 // CFIndex numBytes,
449 // CFStringEncoding encoding,
450 // Boolean isExternalRepresentation
451 // );
452 //
453 // We make the following substitutions:
454 //
455 // CFStringRef -> i8*
456 // CFAllocatorRef -> i8*
457 // UInt8 * -> i8*
458 // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
Adrian Prantl05097242018-04-30 16:49:04 +0000459 // pointer size for now) CFStringEncoding -> i32 Boolean -> i8
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460
461 Type *arg_type_array[5];
462
463 arg_type_array[0] = i8_ptr_ty;
464 arg_type_array[1] = i8_ptr_ty;
465 arg_type_array[2] = m_intptr_ty;
466 arg_type_array[3] = i32_ty;
467 arg_type_array[4] = i8_ty;
468
469 ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
470
James Y Knightae2f9512019-02-08 19:30:46 +0000471 llvm::FunctionType *CFSCWB_ty =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472 FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
473
474 // Build the constant containing the pointer to the function
475 PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
476 Constant *CFSCWB_addr_int =
477 ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +0000478 m_CFStringCreateWithBytes = {
479 CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000480 }
481
Konrad Kleine248a1302019-05-23 11:14:47 +0000482 ConstantDataSequential *string_array = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000483
484 if (cstr)
485 string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
486
487 Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
488 Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
489 : Constant::getNullValue(i8_ptr_ty);
490 Constant *numBytes_arg = ConstantInt::get(
Sean Callanancd1eb722016-12-01 17:46:51 +0000491 m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
492 int encoding_flags = 0;
Sean Callanan01341522016-12-01 19:14:55 +0000493 switch (cstr ? string_array->getElementByteSize() : 1) {
Sean Callanancd1eb722016-12-01 17:46:51 +0000494 case 1:
495 encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
496 break;
497 case 2:
498 encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
499 break;
500 case 4:
501 encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
502 break;
503 default:
504 encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
Pavel Labath107d9bb2017-01-18 11:00:26 +0000505 LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
Luke Drummond63dea592016-12-22 19:15:07 +0000506 "element size {0}",
Pavel Labath107d9bb2017-01-18 11:00:26 +0000507 string_array->getElementByteSize());
Sean Callanancd1eb722016-12-01 17:46:51 +0000508 }
509 Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
510 Constant *isExternal_arg =
511 ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512
Sean Callanancd1eb722016-12-01 17:46:51 +0000513 Value *argument_array[5];
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514
Sean Callanancd1eb722016-12-01 17:46:51 +0000515 argument_array[0] = alloc_arg;
516 argument_array[1] = bytes_arg;
517 argument_array[2] = numBytes_arg;
518 argument_array[3] = encoding_arg;
519 argument_array[4] = isExternal_arg;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000520
Sean Callanancd1eb722016-12-01 17:46:51 +0000521 ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522
Sean Callanancd1eb722016-12-01 17:46:51 +0000523 FunctionValueCache CFSCWB_Caller(
524 [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
525 return CallInst::Create(
526 m_CFStringCreateWithBytes, CFSCWB_arguments,
527 "CFStringCreateWithBytes",
528 llvm::cast<Instruction>(
529 m_entry_instruction_finder.GetValue(function)));
530 });
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531
Sean Callanancd1eb722016-12-01 17:46:51 +0000532 if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
533 m_error_stream)) {
534 if (log)
535 log->PutCString(
536 "Couldn't replace the NSString with the result of the call");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537
Sean Callanancd1eb722016-12-01 17:46:51 +0000538 m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
539 "Objective-C constant string with a dynamic "
540 "string\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541
Sean Callanancd1eb722016-12-01 17:46:51 +0000542 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 }
544
545 ns_str->eraseFromParent();
546
547 return true;
Sean Callanan549c9f72010-07-13 21:41:46 +0000548}
549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550bool IRForTarget::RewriteObjCConstStrings() {
551 lldb_private::Log *log(
552 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000553
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000555
Raphael Isemanndced4452019-08-09 07:59:18 +0000556 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
557 std::string value_name = value_symbol.first().str();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000558 const char *value_name_cstr = value_name.c_str();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
Raphael Isemanndced4452019-08-09 07:59:18 +0000561 Value *nsstring_value = value_symbol.second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000562
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563 GlobalVariable *nsstring_global =
564 dyn_cast<GlobalVariable>(nsstring_value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000565
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 if (!nsstring_global) {
567 if (log)
568 log->PutCString("NSString variable is not a GlobalVariable");
569
570 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
571 "constant string is not a global variable\n");
572
573 return false;
574 }
575
576 if (!nsstring_global->hasInitializer()) {
577 if (log)
578 log->PutCString("NSString variable does not have an initializer");
579
580 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
581 "constant string does not have an initializer\n");
582
583 return false;
584 }
585
586 ConstantStruct *nsstring_struct =
587 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
588
589 if (!nsstring_struct) {
590 if (log)
591 log->PutCString(
592 "NSString variable's initializer is not a ConstantStruct");
593
594 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
595 "constant string is not a structure constant\n");
596
597 return false;
598 }
599
600 // We expect the following structure:
601 //
602 // struct {
603 // int *isa;
604 // int flags;
605 // char *str;
606 // long length;
607 // };
608
609 if (nsstring_struct->getNumOperands() != 4) {
610 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000611 LLDB_LOGF(log,
612 "NSString variable's initializer structure has an "
613 "unexpected number of members. Should be 4, is %d",
614 nsstring_struct->getNumOperands());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615
616 m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
617 "Objective-C constant string is not as "
618 "expected\n");
619
620 return false;
621 }
622
623 Constant *nsstring_member = nsstring_struct->getOperand(2);
624
625 if (!nsstring_member) {
626 if (log)
627 log->PutCString("NSString initializer's str element was empty");
628
629 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
630 "constant string does not have a string "
631 "initializer\n");
632
633 return false;
634 }
635
636 ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
637
638 if (!nsstring_expr) {
639 if (log)
640 log->PutCString(
641 "NSString initializer's str element is not a ConstantExpr");
642
643 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
644 "constant string's string initializer is not "
645 "constant\n");
646
647 return false;
648 }
649
Sean Callanancd1eb722016-12-01 17:46:51 +0000650 GlobalVariable *cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651
Sean Callanancd1eb722016-12-01 17:46:51 +0000652 if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
653 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
654 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
655 } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
656 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
657 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 }
659
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660 if (!cstr_global) {
661 if (log)
662 log->PutCString(
663 "NSString initializer's str element is not a GlobalVariable");
664
Sean Callanancd1eb722016-12-01 17:46:51 +0000665 m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
666 "constant string initializer\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667
668 return false;
669 }
670
671 if (!cstr_global->hasInitializer()) {
672 if (log)
673 log->PutCString("NSString initializer's str element does not have an "
674 "initializer");
675
676 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
677 "constant string's string initializer doesn't "
678 "point to initialized data\n");
679
680 return false;
681 }
682
683 /*
684 if (!cstr_array)
685 {
686 if (log)
687 log->PutCString("NSString initializer's str element is not a
688 ConstantArray");
689
690 if (m_error_stream)
691 m_error_stream.Printf("Internal error [IRForTarget]: An
692 Objective-C constant string's string initializer doesn't point to an
693 array\n");
694
695 return false;
696 }
697
698 if (!cstr_array->isCString())
699 {
700 if (log)
701 log->PutCString("NSString initializer's str element is not a C
702 string array");
703
704 if (m_error_stream)
705 m_error_stream.Printf("Internal error [IRForTarget]: An
706 Objective-C constant string's string initializer doesn't point to a C
707 string\n");
708
709 return false;
710 }
711 */
712
713 ConstantDataArray *cstr_array =
714 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
715
716 if (log) {
717 if (cstr_array)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000718 LLDB_LOGF(log, "Found NSString constant %s, which contains \"%s\"",
719 value_name_cstr, cstr_array->getAsString().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000720 else
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000721 LLDB_LOGF(log, "Found NSString constant %s, which contains \"\"",
722 value_name_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 }
724
725 if (!cstr_array)
Konrad Kleine248a1302019-05-23 11:14:47 +0000726 cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727
728 if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
729 if (log)
730 log->PutCString("Error rewriting the constant string");
731
732 // We don't print an error message here because RewriteObjCConstString
733 // has done so for us.
734
735 return false;
736 }
737 }
738 }
739
Raphael Isemanndced4452019-08-09 07:59:18 +0000740 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
741 std::string value_name = value_symbol.first().str();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 const char *value_name_cstr = value_name.c_str();
743
744 if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
Raphael Isemanndced4452019-08-09 07:59:18 +0000745 GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000746
747 if (!gv) {
748 if (log)
749 log->PutCString(
750 "__CFConstantStringClassReference is not a global variable");
751
752 m_error_stream.Printf("Internal error [IRForTarget]: Found a "
753 "CFConstantStringClassReference, but it is not a "
754 "global object\n");
755
756 return false;
757 }
758
759 gv->eraseFromParent();
760
761 break;
762 }
763 }
764
765 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000766}
767
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768static bool IsObjCSelectorRef(Value *value) {
769 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000770
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000771 return !(!global_variable || !global_variable->hasName() ||
772 !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773}
774
775// This function does not report errors; its callers are responsible.
776bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
777 lldb_private::Log *log(
778 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
779
780 LoadInst *load = dyn_cast<LoadInst>(selector_load);
781
782 if (!load)
783 return false;
784
785 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
786 // gets represented as
787 //
Adrian Prantl05097242018-04-30 16:49:04 +0000788 // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call = call
789 // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790 //
791 // where %obj is the object pointer and %tmp is the selector.
792 //
793 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
794 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
795 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
796
797 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
798 // and get the string from its target
799
800 GlobalVariable *_objc_selector_references_ =
801 dyn_cast<GlobalVariable>(load->getPointerOperand());
802
803 if (!_objc_selector_references_ ||
804 !_objc_selector_references_->hasInitializer())
805 return false;
806
807 Constant *osr_initializer = _objc_selector_references_->getInitializer();
808
809 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
810
811 if (!osr_initializer_expr ||
812 osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
813 return false;
814
815 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
816
817 if (!osr_initializer_base)
818 return false;
819
820 // Find the string's initializer (a ConstantArray) and get the string from it
821
822 GlobalVariable *_objc_meth_var_name_ =
823 dyn_cast<GlobalVariable>(osr_initializer_base);
824
825 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
826 return false;
827
828 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
829
830 ConstantDataArray *omvn_initializer_array =
831 dyn_cast<ConstantDataArray>(omvn_initializer);
832
833 if (!omvn_initializer_array->isString())
834 return false;
835
836 std::string omvn_initializer_string = omvn_initializer_array->getAsString();
837
838 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000839 LLDB_LOGF(log, "Found Objective-C selector reference \"%s\"",
840 omvn_initializer_string.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841
842 // Construct a call to sel_registerName
843
844 if (!m_sel_registerName) {
845 lldb::addr_t sel_registerName_addr;
846
Jim Inghamf2128b22019-06-28 21:40:05 +0000847 bool missing_weak = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000848 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
Jim Inghamf2128b22019-06-28 21:40:05 +0000849 sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str,
850 missing_weak);
851 if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000852 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000853
Sean Callananc70ed462011-10-25 18:36:40 +0000854 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +0000855 LLDB_LOGF(log, "Found sel_registerName at 0x%" PRIx64,
856 sel_registerName_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000857
Adrian Prantl05097242018-04-30 16:49:04 +0000858 // Build the function type: struct objc_selector
859 // *sel_registerName(uint8_t*)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000860
Kate Stoneb9c1b512016-09-06 20:57:50 +0000861 // The below code would be "more correct," but in actuality what's required
862 // is uint8_t*
863 // Type *sel_type = StructType::get(m_module->getContext());
864 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
865 Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000866
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 Type *type_array[1];
868
869 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
870
871 ArrayRef<Type *> srN_arg_types(type_array, 1);
872
James Y Knightae2f9512019-02-08 19:30:46 +0000873 llvm::FunctionType *srN_type =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000874 FunctionType::get(sel_ptr_type, srN_arg_types, false);
875
876 // Build the constant containing the pointer to the function
877 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
878 Constant *srN_addr_int =
879 ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +0000880 m_sel_registerName = {srN_type,
881 ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000882 }
883
884 Value *argument_array[1];
885
886 Constant *omvn_pointer = ConstantExpr::getBitCast(
887 _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
888
889 argument_array[0] = omvn_pointer;
890
891 ArrayRef<Value *> srN_arguments(argument_array, 1);
892
893 CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
894 "sel_registerName", selector_load);
895
896 // Replace the load with the call in all users
897
898 selector_load->replaceAllUsesWith(srN_call);
899
900 selector_load->eraseFromParent();
901
902 return true;
903}
904
905bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
906 lldb_private::Log *log(
907 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000908 typedef SmallVector<Instruction *, 2> InstrList;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909
910 InstrList selector_loads;
911
Raphael Isemanndced4452019-08-09 07:59:18 +0000912 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000913 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
914 if (IsObjCSelectorRef(load->getPointerOperand()))
915 selector_loads.push_back(&inst);
916 }
917
Raphael Isemanndced4452019-08-09 07:59:18 +0000918 for (Instruction *inst : selector_loads) {
919 if (!RewriteObjCSelector(inst)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
921 "static reference to an Objective-C selector to a "
922 "dynamic reference\n");
923
924 if (log)
925 log->PutCString(
926 "Couldn't rewrite a reference to an Objective-C selector");
927
928 return false;
Sean Callananc70ed462011-10-25 18:36:40 +0000929 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000930 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000931
Kate Stoneb9c1b512016-09-06 20:57:50 +0000932 return true;
933}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000934
Sean Callananac900582016-09-29 00:45:33 +0000935static bool IsObjCClassReference(Value *value) {
936 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
937
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000938 return !(!global_variable || !global_variable->hasName() ||
939 !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
Sean Callananac900582016-09-29 00:45:33 +0000940}
941
942// This function does not report errors; its callers are responsible.
943bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
944 lldb_private::Log *log(
945 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
946
947 LoadInst *load = dyn_cast<LoadInst>(class_load);
948
949 if (!load)
950 return false;
951
952 // Unpack the class name from the reference. In LLVM IR, a reference to an
953 // Objective-C class gets represented as
954 //
955 // %tmp = load %struct._objc_class*,
956 // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
957 //
958 // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
Adrian Prantl05097242018-04-30 16:49:04 +0000959 // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.
Sean Callananac900582016-09-29 00:45:33 +0000960
Adrian Prantl05097242018-04-30 16:49:04 +0000961 // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and
962 // get the string from its target
Sean Callananac900582016-09-29 00:45:33 +0000963
964 GlobalVariable *_objc_class_references_ =
965 dyn_cast<GlobalVariable>(load->getPointerOperand());
966
967 if (!_objc_class_references_ ||
968 !_objc_class_references_->hasInitializer())
969 return false;
970
971 Constant *ocr_initializer = _objc_class_references_->getInitializer();
972
973 ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
974
975 if (!ocr_initializer_expr ||
976 ocr_initializer_expr->getOpcode() != Instruction::BitCast)
977 return false;
978
979 Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
980
981 if (!ocr_initializer_base)
982 return false;
983
984 // Find the string's initializer (a ConstantArray) and get the string from it
985
986 GlobalVariable *_objc_class_name_ =
987 dyn_cast<GlobalVariable>(ocr_initializer_base);
988
989 if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
990 return false;
991
992 Constant *ocn_initializer = _objc_class_name_->getInitializer();
993
994 ConstantDataArray *ocn_initializer_array =
995 dyn_cast<ConstantDataArray>(ocn_initializer);
996
997 if (!ocn_initializer_array->isString())
998 return false;
999
1000 std::string ocn_initializer_string = ocn_initializer_array->getAsString();
1001
1002 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001003 LLDB_LOGF(log, "Found Objective-C class reference \"%s\"",
1004 ocn_initializer_string.c_str());
Sean Callananac900582016-09-29 00:45:33 +00001005
1006 // Construct a call to objc_getClass
1007
1008 if (!m_objc_getClass) {
1009 lldb::addr_t objc_getClass_addr;
1010
Jim Inghamf2128b22019-06-28 21:40:05 +00001011 bool missing_weak = false;
Sean Callananac900582016-09-29 00:45:33 +00001012 static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
Jim Inghamf2128b22019-06-28 21:40:05 +00001013 objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str,
1014 missing_weak);
1015 if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
Sean Callananac900582016-09-29 00:45:33 +00001016 return false;
1017
1018 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001019 LLDB_LOGF(log, "Found objc_getClass at 0x%" PRIx64, objc_getClass_addr);
Sean Callananac900582016-09-29 00:45:33 +00001020
1021 // Build the function type: %struct._objc_class *objc_getClass(i8*)
1022
1023 Type *class_type = load->getType();
1024 Type *type_array[1];
1025 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
1026
1027 ArrayRef<Type *> ogC_arg_types(type_array, 1);
1028
James Y Knightae2f9512019-02-08 19:30:46 +00001029 llvm::FunctionType *ogC_type =
Sean Callananac900582016-09-29 00:45:33 +00001030 FunctionType::get(class_type, ogC_arg_types, false);
1031
1032 // Build the constant containing the pointer to the function
1033 PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
1034 Constant *ogC_addr_int =
1035 ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +00001036 m_objc_getClass = {ogC_type,
1037 ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
Sean Callananac900582016-09-29 00:45:33 +00001038 }
1039
1040 Value *argument_array[1];
1041
1042 Constant *ocn_pointer = ConstantExpr::getBitCast(
1043 _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
1044
1045 argument_array[0] = ocn_pointer;
1046
1047 ArrayRef<Value *> ogC_arguments(argument_array, 1);
1048
1049 CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
1050 "objc_getClass", class_load);
1051
1052 // Replace the load with the call in all users
1053
1054 class_load->replaceAllUsesWith(ogC_call);
1055
1056 class_load->eraseFromParent();
1057
1058 return true;
1059}
1060
1061bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
1062 lldb_private::Log *log(
1063 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1064
Sean Callananac900582016-09-29 00:45:33 +00001065 typedef SmallVector<Instruction *, 2> InstrList;
Sean Callananac900582016-09-29 00:45:33 +00001066
1067 InstrList class_loads;
1068
Raphael Isemanndced4452019-08-09 07:59:18 +00001069 for (Instruction &inst : basic_block) {
Sean Callananac900582016-09-29 00:45:33 +00001070 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1071 if (IsObjCClassReference(load->getPointerOperand()))
1072 class_loads.push_back(&inst);
1073 }
1074
Raphael Isemanndced4452019-08-09 07:59:18 +00001075 for (Instruction *inst : class_loads) {
1076 if (!RewriteObjCClassReference(inst)) {
Sean Callananac900582016-09-29 00:45:33 +00001077 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
1078 "static reference to an Objective-C class to a "
1079 "dynamic reference\n");
1080
1081 if (log)
1082 log->PutCString(
1083 "Couldn't rewrite a reference to an Objective-C class");
1084
1085 return false;
1086 }
1087 }
1088
1089 return true;
1090}
1091
Kate Stoneb9c1b512016-09-06 20:57:50 +00001092// This function does not report errors; its callers are responsible.
1093bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
1094 lldb_private::Log *log(
1095 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001096
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001098
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 if (!alloc_md || !alloc_md->getNumOperands())
1102 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001103
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 ConstantInt *constant_int =
1105 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001106
Kate Stoneb9c1b512016-09-06 20:57:50 +00001107 if (!constant_int)
1108 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001109
Kate Stoneb9c1b512016-09-06 20:57:50 +00001110 // We attempt to register this as a new persistent variable with the DeclMap.
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001111
Kate Stoneb9c1b512016-09-06 20:57:50 +00001112 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001113
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001115
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 lldb_private::TypeFromParser result_decl_type(
1117 decl->getType().getAsOpaquePtr(),
1118 lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001119
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 StringRef decl_name(decl->getName());
1121 lldb_private::ConstString persistent_variable_name(decl_name.data(),
1122 decl_name.size());
1123 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1124 result_decl_type, false, false))
1125 return false;
Sean Callanan6e6d4a62012-07-21 02:02:15 +00001126
Kate Stoneb9c1b512016-09-06 20:57:50 +00001127 GlobalVariable *persistent_global = new GlobalVariable(
Konrad Kleine248a1302019-05-23 11:14:47 +00001128 (*m_module), alloc->getType(), false, /* not constant */
1129 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001130 alloc->getName().str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001131
Adrian Prantl05097242018-04-30 16:49:04 +00001132 // What we're going to do here is make believe this was a regular old
1133 // external variable. That means we need to make the metadata valid.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001134
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135 NamedMDNode *named_metadata =
1136 m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001137
Kate Stoneb9c1b512016-09-06 20:57:50 +00001138 llvm::Metadata *values[2];
1139 values[0] = ConstantAsMetadata::get(persistent_global);
1140 values[1] = ConstantAsMetadata::get(constant_int);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001141
Kate Stoneb9c1b512016-09-06 20:57:50 +00001142 ArrayRef<llvm::Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001143
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1145 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001146
Kate Stoneb9c1b512016-09-06 20:57:50 +00001147 // Now, since the variable is a pointer variable, we will drop in a load of
Adrian Prantl05097242018-04-30 16:49:04 +00001148 // that pointer variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150 LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001151
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001153 LLDB_LOGF(log, "Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
1154 PrintValue(persistent_load).c_str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001155
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 alloc->replaceAllUsesWith(persistent_load);
1157 alloc->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001158
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159 return true;
1160}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001161
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1163 if (!m_resolve_vars)
1164 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001165
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 lldb_private::Log *log(
1167 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001168
Kate Stoneb9c1b512016-09-06 20:57:50 +00001169 typedef SmallVector<Instruction *, 2> InstrList;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001170
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 InstrList pvar_allocs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001172
Raphael Isemanndced4452019-08-09 07:59:18 +00001173 for (Instruction &inst : basic_block) {
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001174
Kate Stoneb9c1b512016-09-06 20:57:50 +00001175 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1176 llvm::StringRef alloc_name = alloc->getName();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001177
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178 if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1179 if (alloc_name.find_first_of("0123456789") == 1) {
1180 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001181 LLDB_LOGF(log, "Rejecting a numeric persistent variable.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001182
Kate Stoneb9c1b512016-09-06 20:57:50 +00001183 m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1184 "$1, ... are reserved for use as result "
1185 "names\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001186
Kate Stoneb9c1b512016-09-06 20:57:50 +00001187 return false;
Sean Callanan00294b32016-03-22 21:05:51 +00001188 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001189
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190 pvar_allocs.push_back(alloc);
1191 }
Sean Callanan17827832010-12-13 22:46:15 +00001192 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001193 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001194
Raphael Isemanndced4452019-08-09 07:59:18 +00001195 for (Instruction *inst : pvar_allocs) {
1196 if (!RewritePersistentAlloc(inst)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001197 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1198 "the creation of a persistent variable\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001199
Kate Stoneb9c1b512016-09-06 20:57:50 +00001200 if (log)
1201 log->PutCString(
1202 "Couldn't rewrite the creation of a persistent variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001203
Kate Stoneb9c1b512016-09-06 20:57:50 +00001204 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001205 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001206 }
1207
1208 return true;
1209}
1210
1211bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
1212 if (!initializer)
1213 return true;
1214
1215 lldb_private::Log *log(
1216 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1217
1218 if (log && log->GetVerbose())
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001219 LLDB_LOGF(log, " MaterializeInitializer(%p, %s)", (void *)data,
1220 PrintValue(initializer).c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001221
1222 Type *initializer_type = initializer->getType();
1223
1224 if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
1225 size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
1226 lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
1227 llvm::NextPowerOf2(constant_size) * 8);
1228
Zachary Turner97206d52017-05-12 04:51:55 +00001229 lldb_private::Status get_data_error;
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001230 return scalar.GetAsMemoryData(data, constant_size,
1231 lldb_private::endian::InlHostByteOrder(),
1232 get_data_error) != 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001233 } else if (ConstantDataArray *array_initializer =
1234 dyn_cast<ConstantDataArray>(initializer)) {
1235 if (array_initializer->isString()) {
1236 std::string array_initializer_string = array_initializer->getAsString();
1237 memcpy(data, array_initializer_string.c_str(),
1238 m_target_data->getTypeStoreSize(initializer_type));
1239 } else {
1240 ArrayType *array_initializer_type = array_initializer->getType();
1241 Type *array_element_type = array_initializer_type->getElementType();
1242
1243 size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
1244
1245 for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
1246 Value *operand_value = array_initializer->getOperand(i);
1247 Constant *operand_constant = dyn_cast<Constant>(operand_value);
1248
1249 if (!operand_constant)
1250 return false;
1251
1252 if (!MaterializeInitializer(data + (i * element_size),
1253 operand_constant))
1254 return false;
1255 }
1256 }
1257 return true;
1258 } else if (ConstantStruct *struct_initializer =
1259 dyn_cast<ConstantStruct>(initializer)) {
1260 StructType *struct_initializer_type = struct_initializer->getType();
1261 const StructLayout *struct_layout =
1262 m_target_data->getStructLayout(struct_initializer_type);
1263
1264 for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
1265 if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
1266 struct_initializer->getOperand(i)))
1267 return false;
1268 }
1269 return true;
1270 } else if (isa<ConstantAggregateZero>(initializer)) {
1271 memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
1272 return true;
1273 }
1274 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001275}
1276
Kate Stoneb9c1b512016-09-06 20:57:50 +00001277// This function does not report errors; its callers are responsible.
1278bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1279 lldb_private::Log *log(
1280 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1281
1282 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001283 LLDB_LOGF(log, "MaybeHandleVariable (%s)",
1284 PrintValue(llvm_value_ptr).c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001285
1286 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1287 switch (constant_expr->getOpcode()) {
1288 default:
1289 break;
1290 case Instruction::GetElementPtr:
1291 case Instruction::BitCast:
1292 Value *s = constant_expr->getOperand(0);
1293 if (!MaybeHandleVariable(s))
1294 return false;
1295 }
1296 } else if (GlobalVariable *global_variable =
1297 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1298 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1299 return true;
1300
1301 clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1302
1303 if (!named_decl) {
1304 if (IsObjCSelectorRef(llvm_value_ptr))
1305 return true;
1306
1307 if (!global_variable->hasExternalLinkage())
1308 return true;
1309
1310 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001311 LLDB_LOGF(log, "Found global variable \"%s\" without metadata",
1312 global_variable->getName().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001313
1314 return false;
1315 }
1316
Raphael Isemann7491f362019-08-08 21:22:21 +00001317 llvm::StringRef name(named_decl->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001318
1319 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
Konrad Kleine248a1302019-05-23 11:14:47 +00001320 if (value_decl == nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321 return false;
1322
1323 lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
1324 value_decl->getType());
1325
Konrad Kleine248a1302019-05-23 11:14:47 +00001326 const Type *value_type = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001327
Raphael Isemann7491f362019-08-08 21:22:21 +00001328 if (name.startswith("$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329 // The $__lldb_expr_result name indicates the return value has allocated
Adrian Prantl05097242018-04-30 16:49:04 +00001330 // as a static variable. Per the comment at
1331 // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
1332 // variable need to be redirected to the result of dereferencing a
1333 // pointer that is passed in as one of the arguments.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001334 //
1335 // Consequently, when reporting the size of the type, we report a pointer
Adrian Prantl05097242018-04-30 16:49:04 +00001336 // type pointing to the type of $__lldb_expr_result, not the type itself.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001337 //
1338 // We also do this for any user-declared persistent variables.
1339 compiler_type = compiler_type.GetPointerType();
1340 value_type = PointerType::get(global_variable->getType(), 0);
1341 } else {
1342 value_type = global_variable->getType();
1343 }
1344
Adrian Prantld6a9bbf2019-01-15 20:33:58 +00001345 llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
Adrian Prantld963a7c2019-01-15 18:07:52 +00001346 if (!value_size)
1347 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001348 lldb::offset_t value_alignment =
1349 (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
1350
1351 if (log) {
Raphael Isemann7491f362019-08-08 21:22:21 +00001352 LLDB_LOG(
1353 log,
1354 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1355 "align {4}]",
1356 name,
1357 lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
1358 PrintType(value_type), *value_size, value_alignment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359 }
1360
Raphael Isemann0e5eef52019-08-08 16:41:32 +00001361 if (named_decl)
Raphael Isemann7491f362019-08-08 21:22:21 +00001362 m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
1363 llvm_value_ptr, *value_size,
1364 value_alignment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001365 } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
1366 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001367 LLDB_LOGF(log, "Function pointers aren't handled right now");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001368
1369 return false;
1370 }
1371
1372 return true;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001373}
1374
Kate Stoneb9c1b512016-09-06 20:57:50 +00001375// This function does not report errors; its callers are responsible.
1376bool IRForTarget::HandleSymbol(Value *symbol) {
1377 lldb_private::Log *log(
1378 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1379
1380 lldb_private::ConstString name(symbol->getName().str().c_str());
1381
1382 lldb::addr_t symbol_addr =
1383 m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1384
1385 if (symbol_addr == LLDB_INVALID_ADDRESS) {
1386 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001387 LLDB_LOGF(log, "Symbol \"%s\" had no address", name.GetCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001388
1389 return false;
1390 }
1391
1392 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001393 LLDB_LOGF(log, "Found \"%s\" at 0x%" PRIx64, name.GetCString(),
1394 symbol_addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001395
1396 Type *symbol_type = symbol->getType();
1397
1398 Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1399
1400 Value *symbol_addr_ptr =
1401 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1402
1403 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001404 LLDB_LOGF(log, "Replacing %s with %s", PrintValue(symbol).c_str(),
1405 PrintValue(symbol_addr_ptr).c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001406
1407 symbol->replaceAllUsesWith(symbol_addr_ptr);
1408
1409 return true;
1410}
1411
1412bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1413 lldb_private::Log *log(
1414 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1415
1416 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001417 LLDB_LOGF(log, "MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001418
1419 for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1420 op_index < num_ops; ++op_index)
Raphael Isemanndced4452019-08-09 07:59:18 +00001421 // conservatively believe that this is a store
1422 if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1424 "one of the arguments of a function call.\n");
1425
1426 return false;
1427 }
1428
1429 return true;
1430}
1431
1432bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1433 lldb_private::Log *log(
1434 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1435
1436 GlobalVariable *global_variable =
1437 dyn_cast<GlobalVariable>(classlist_reference);
1438
1439 if (!global_variable)
1440 return false;
1441
1442 Constant *initializer = global_variable->getInitializer();
1443
1444 if (!initializer)
1445 return false;
1446
1447 if (!initializer->hasName())
1448 return false;
1449
1450 StringRef name(initializer->getName());
1451 lldb_private::ConstString name_cstr(name.str().c_str());
1452 lldb::addr_t class_ptr =
1453 m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1454
1455 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001456 LLDB_LOGF(log, "Found reference to Objective-C class %s (0x%llx)",
1457 name_cstr.AsCString(), (unsigned long long)class_ptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001458
1459 if (class_ptr == LLDB_INVALID_ADDRESS)
1460 return false;
1461
1462 if (global_variable->use_empty())
1463 return false;
1464
1465 SmallVector<LoadInst *, 2> load_instructions;
1466
1467 for (llvm::User *u : global_variable->users()) {
1468 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1469 load_instructions.push_back(load_instruction);
1470 }
1471
1472 if (load_instructions.empty())
1473 return false;
1474
1475 Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1476
1477 for (LoadInst *load_instruction : load_instructions) {
1478 Constant *class_bitcast =
1479 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1480
1481 load_instruction->replaceAllUsesWith(class_bitcast);
1482
1483 load_instruction->eraseFromParent();
1484 }
1485
1486 return true;
1487}
1488
1489bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001490 std::vector<CallInst *> calls_to_remove;
1491
Raphael Isemanndced4452019-08-09 07:59:18 +00001492 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001493 CallInst *call = dyn_cast<CallInst>(&inst);
1494
1495 // MaybeHandleCallArguments handles error reporting; we are silent here
1496 if (!call)
1497 continue;
1498
1499 bool remove = false;
1500
1501 llvm::Function *func = call->getCalledFunction();
1502
1503 if (func && func->getName() == "__cxa_atexit")
1504 remove = true;
1505
1506 llvm::Value *val = call->getCalledValue();
1507
1508 if (val && val->getName() == "__cxa_atexit")
1509 remove = true;
1510
1511 if (remove)
1512 calls_to_remove.push_back(call);
1513 }
1514
Raphael Isemanndced4452019-08-09 07:59:18 +00001515 for (CallInst *ci : calls_to_remove)
1516 ci->eraseFromParent();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001517
1518 return true;
1519}
1520
1521bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522 // Prepare the current basic block for execution in the remote process
Kate Stoneb9c1b512016-09-06 20:57:50 +00001523
Raphael Isemanndced4452019-08-09 07:59:18 +00001524 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001525 CallInst *call = dyn_cast<CallInst>(&inst);
1526
1527 // MaybeHandleCallArguments handles error reporting; we are silent here
1528 if (call && !MaybeHandleCallArguments(call))
1529 return false;
1530 }
1531
1532 return true;
1533}
1534
1535bool IRForTarget::ResolveExternals(Function &llvm_function) {
1536 lldb_private::Log *log(
1537 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1538
1539 for (GlobalVariable &global_var : m_module->globals()) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001540 llvm::StringRef global_name = global_var.getName();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001541
1542 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00001543 LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}",
1544 global_name, static_cast<void *>(DeclForGlobal(&global_var)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545
Raphael Isemanna7040522019-08-08 21:43:21 +00001546 if (global_name.startswith("OBJC_IVAR")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001547 if (!HandleSymbol(&global_var)) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001548 m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
1549 "indirect ivar symbol {0}\n",
1550 global_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001551
1552 return false;
1553 }
Raphael Isemanna7040522019-08-08 21:43:21 +00001554 } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001555 if (!HandleObjCClass(&global_var)) {
1556 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1557 "for an Objective-C static method call\n");
1558
1559 return false;
1560 }
Raphael Isemanna7040522019-08-08 21:43:21 +00001561 } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001562 if (!HandleObjCClass(&global_var)) {
1563 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1564 "for an Objective-C static method call\n");
1565
1566 return false;
1567 }
1568 } else if (DeclForGlobal(&global_var)) {
1569 if (!MaybeHandleVariable(&global_var)) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001570 m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
1571 "external variable {0}\n",
1572 global_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001573
1574 return false;
1575 }
1576 }
1577 }
1578
1579 return true;
1580}
1581
1582static bool isGuardVariableRef(Value *V) {
Konrad Kleine248a1302019-05-23 11:14:47 +00001583 Constant *Old = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001584
1585 if (!(Old = dyn_cast<Constant>(V)))
1586 return false;
1587
Konrad Kleine248a1302019-05-23 11:14:47 +00001588 ConstantExpr *CE = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001589
1590 if ((CE = dyn_cast<ConstantExpr>(V))) {
1591 if (CE->getOpcode() != Instruction::BitCast)
1592 return false;
1593
1594 Old = CE->getOperand(0);
1595 }
1596
1597 GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1598
1599 if (!GV || !GV->hasName() ||
1600 (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
1601 !GV->getName().endswith("@4IA"))) // Microsoft ABI guard variable
1602 {
1603 return false;
1604 }
1605
1606 return true;
1607}
1608
1609void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1610 Constant *zero(Constant::getNullValue(guard_load->getType()));
1611 guard_load->replaceAllUsesWith(zero);
1612 guard_load->eraseFromParent();
1613}
1614
1615static void ExciseGuardStore(Instruction *guard_store) {
1616 guard_store->eraseFromParent();
1617}
1618
1619bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001620 // Eliminate any reference to guard variables found.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001621 typedef SmallVector<Instruction *, 2> InstrList;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001622
1623 InstrList guard_loads;
1624 InstrList guard_stores;
1625
Raphael Isemanndced4452019-08-09 07:59:18 +00001626 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001627
1628 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1629 if (isGuardVariableRef(load->getPointerOperand()))
1630 guard_loads.push_back(&inst);
1631
1632 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1633 if (isGuardVariableRef(store->getPointerOperand()))
1634 guard_stores.push_back(&inst);
1635 }
1636
Raphael Isemanndced4452019-08-09 07:59:18 +00001637 for (Instruction *inst : guard_loads)
1638 TurnGuardLoadIntoZero(inst);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001639
Raphael Isemanndced4452019-08-09 07:59:18 +00001640 for (Instruction *inst : guard_stores)
1641 ExciseGuardStore(inst);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001642
1643 return true;
1644}
1645
1646// This function does not report errors; its callers are responsible.
1647bool IRForTarget::UnfoldConstant(Constant *old_constant,
1648 llvm::Function *llvm_function,
1649 FunctionValueCache &value_maker,
1650 FunctionValueCache &entry_instruction_finder,
1651 lldb_private::Stream &error_stream) {
1652 SmallVector<User *, 16> users;
1653
1654 // We do this because the use list might change, invalidating our iterator.
1655 // Much better to keep a work list ourselves.
1656 for (llvm::User *u : old_constant->users())
1657 users.push_back(u);
1658
1659 for (size_t i = 0; i < users.size(); ++i) {
1660 User *user = users[i];
1661
1662 if (Constant *constant = dyn_cast<Constant>(user)) {
1663 // synthesize a new non-constant equivalent of the constant
1664
1665 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1666 switch (constant_expr->getOpcode()) {
1667 default:
1668 error_stream.Printf("error [IRForTarget internal]: Unhandled "
1669 "constant expression type: \"%s\"",
1670 PrintValue(constant_expr).c_str());
1671 return false;
1672 case Instruction::BitCast: {
1673 FunctionValueCache bit_cast_maker(
1674 [&value_maker, &entry_instruction_finder, old_constant,
1675 constant_expr](llvm::Function *function) -> llvm::Value * {
1676 // UnaryExpr
1677 // OperandList[0] is value
1678
1679 if (constant_expr->getOperand(0) != old_constant)
1680 return constant_expr;
1681
1682 return new BitCastInst(
1683 value_maker.GetValue(function), constant_expr->getType(),
1684 "", llvm::cast<Instruction>(
1685 entry_instruction_finder.GetValue(function)));
1686 });
1687
1688 if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1689 entry_instruction_finder, error_stream))
1690 return false;
1691 } break;
1692 case Instruction::GetElementPtr: {
1693 // GetElementPtrConstantExpr
1694 // OperandList[0] is base
1695 // OperandList[1]... are indices
1696
1697 FunctionValueCache get_element_pointer_maker(
1698 [&value_maker, &entry_instruction_finder, old_constant,
1699 constant_expr](llvm::Function *function) -> llvm::Value * {
1700 Value *ptr = constant_expr->getOperand(0);
1701
1702 if (ptr == old_constant)
1703 ptr = value_maker.GetValue(function);
1704
1705 std::vector<Value *> index_vector;
1706
1707 unsigned operand_index;
1708 unsigned num_operands = constant_expr->getNumOperands();
1709
1710 for (operand_index = 1; operand_index < num_operands;
1711 ++operand_index) {
1712 Value *operand = constant_expr->getOperand(operand_index);
1713
1714 if (operand == old_constant)
1715 operand = value_maker.GetValue(function);
1716
1717 index_vector.push_back(operand);
1718 }
1719
1720 ArrayRef<Value *> indices(index_vector);
1721
1722 return GetElementPtrInst::Create(
1723 nullptr, ptr, indices, "",
1724 llvm::cast<Instruction>(
1725 entry_instruction_finder.GetValue(function)));
1726 });
1727
1728 if (!UnfoldConstant(constant_expr, llvm_function,
1729 get_element_pointer_maker,
1730 entry_instruction_finder, error_stream))
1731 return false;
1732 } break;
1733 }
1734 } else {
1735 error_stream.Printf(
1736 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1737 PrintValue(constant).c_str());
1738 return false;
1739 }
1740 } else {
1741 if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1742 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1743 error_stream.PutCString("error: Capturing non-local variables in "
1744 "expressions is unsupported.\n");
1745 return false;
1746 }
1747 inst->replaceUsesOfWith(
1748 old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1749 } else {
1750 error_stream.Printf(
1751 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1752 PrintValue(user).c_str());
1753 return false;
1754 }
1755 }
1756 }
1757
1758 if (!isa<GlobalValue>(old_constant)) {
1759 old_constant->destroyConstant();
1760 }
1761
1762 return true;
1763}
1764
1765bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1766 if (!m_resolve_vars)
1767 return true;
1768
1769 lldb_private::Log *log(
1770 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1771
1772 m_decl_map->DoStructLayout();
1773
1774 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00001775 LLDB_LOGF(log, "Element arrangement:");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001776
1777 uint32_t num_elements;
1778 uint32_t element_index;
1779
1780 size_t size;
1781 lldb::offset_t alignment;
1782
1783 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1784 return false;
1785
Reid Kleckner20670ba2017-03-16 23:13:49 +00001786 Function::arg_iterator iter(llvm_function.arg_begin());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001787
Reid Kleckner20670ba2017-03-16 23:13:49 +00001788 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001789 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1790 "arguments (should take at least a struct pointer)");
1791
1792 return false;
1793 }
1794
1795 Argument *argument = &*iter;
1796
1797 if (argument->getName().equals("this")) {
1798 ++iter;
1799
Reid Kleckner20670ba2017-03-16 23:13:49 +00001800 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001801 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1802 "'this' argument (should take a struct pointer "
1803 "too)");
1804
1805 return false;
1806 }
1807
1808 argument = &*iter;
1809 } else if (argument->getName().equals("self")) {
1810 ++iter;
1811
Reid Kleckner20670ba2017-03-16 23:13:49 +00001812 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001813 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1814 "'self' argument (should take '_cmd' and a struct "
1815 "pointer too)");
1816
1817 return false;
1818 }
1819
1820 if (!iter->getName().equals("_cmd")) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001821 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
Kate Stoneb9c1b512016-09-06 20:57:50 +00001822 "after 'self' argument (should take '_cmd')",
Raphael Isemanna7040522019-08-08 21:43:21 +00001823 iter->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001824
1825 return false;
1826 }
1827
1828 ++iter;
1829
Reid Kleckner20670ba2017-03-16 23:13:49 +00001830 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001831 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1832 "'self' and '_cmd' arguments (should take a struct "
1833 "pointer too)");
1834
1835 return false;
1836 }
1837
1838 argument = &*iter;
1839 }
1840
1841 if (!argument->getName().equals("$__lldb_arg")) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001842 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
1843 "argument named '{0}' instead of the struct pointer",
1844 argument->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001845
1846 return false;
1847 }
1848
1849 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00001850 LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001851
1852 BasicBlock &entry_block(llvm_function.getEntryBlock());
1853 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1854
1855 if (!FirstEntryInstruction) {
1856 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1857 "first instruction in the wrapper for use in "
1858 "rewriting");
1859
1860 return false;
1861 }
1862
1863 LLVMContext &context(m_module->getContext());
1864 IntegerType *offset_type(Type::getInt32Ty(context));
1865
1866 if (!offset_type) {
1867 m_error_stream.Printf(
1868 "Internal error [IRForTarget]: Couldn't produce an offset type");
1869
1870 return false;
1871 }
1872
1873 for (element_index = 0; element_index < num_elements; ++element_index) {
Konrad Kleine248a1302019-05-23 11:14:47 +00001874 const clang::NamedDecl *decl = nullptr;
1875 Value *value = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001876 lldb::offset_t offset;
1877 lldb_private::ConstString name;
1878
1879 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1880 element_index)) {
1881 m_error_stream.Printf(
1882 "Internal error [IRForTarget]: Structure information is incomplete");
1883
1884 return false;
1885 }
1886
1887 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00001888 LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at %" PRIu64, name,
1889 decl->getNameAsString(), offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001890
1891 if (value) {
1892 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00001893 LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001894
1895 FunctionValueCache body_result_maker(
1896 [this, name, offset_type, offset, argument,
1897 value](llvm::Function *function) -> llvm::Value * {
Adrian Prantl05097242018-04-30 16:49:04 +00001898 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
1899 // in cases where the result variable is an rvalue, we have to
1900 // synthesize a dereference of the appropriate structure entry in
1901 // order to produce the static variable that the AST thinks it is
1902 // accessing.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001903
1904 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1905 m_entry_instruction_finder.GetValue(function));
1906
1907 ConstantInt *offset_int(
1908 ConstantInt::get(offset_type, offset, true));
1909 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1910 nullptr, argument, offset_int, "", entry_instruction);
1911
1912 if (name == m_result_name && !m_result_is_pointer) {
1913 BitCastInst *bit_cast = new BitCastInst(
1914 get_element_ptr, value->getType()->getPointerTo(), "",
1915 entry_instruction);
1916
1917 LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1918
1919 return load;
1920 } else {
1921 BitCastInst *bit_cast = new BitCastInst(
1922 get_element_ptr, value->getType(), "", entry_instruction);
1923
1924 return bit_cast;
1925 }
1926 });
1927
1928 if (Constant *constant = dyn_cast<Constant>(value)) {
1929 if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
1930 m_entry_instruction_finder, m_error_stream)) {
1931 return false;
1932 }
1933 } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1934 if (instruction->getParent()->getParent() != &llvm_function) {
1935 m_error_stream.PutCString("error: Capturing non-local variables in "
1936 "expressions is unsupported.\n");
1937 return false;
1938 }
1939 value->replaceAllUsesWith(
1940 body_result_maker.GetValue(instruction->getParent()->getParent()));
1941 } else {
1942 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00001943 LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
1944 PrintValue(value));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001945 return false;
1946 }
1947
1948 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1949 var->eraseFromParent();
1950 }
1951 }
1952
1953 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00001954 LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
1955 (uint64_t)size);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001956
1957 return true;
1958}
1959
1960llvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
1961 uint64_t offset) {
1962 llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
1963
1964 llvm::Constant *offset_array[1];
1965
1966 offset_array[0] = offset_int;
1967
1968 llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
1969 llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
1970 llvm::Type *char_pointer_type = char_type->getPointerTo();
1971
1972 llvm::Constant *reloc_placeholder_bitcast =
1973 ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
1974 llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
1975 char_type, reloc_placeholder_bitcast, offsets);
1976 llvm::Constant *reloc_bitcast =
1977 ConstantExpr::getBitCast(reloc_getelementptr, type);
1978
1979 return reloc_bitcast;
1980}
1981
1982bool IRForTarget::runOnModule(Module &llvm_module) {
1983 lldb_private::Log *log(
1984 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1985
1986 m_module = &llvm_module;
1987 m_target_data.reset(new DataLayout(m_module));
1988 m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
1989 m_target_data->getPointerSizeInBits());
1990
1991 if (log) {
1992 std::string s;
1993 raw_string_ostream oss(s);
1994
Konrad Kleine248a1302019-05-23 11:14:47 +00001995 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001996
1997 oss.flush();
1998
Raphael Isemanna7040522019-08-08 21:43:21 +00001999 LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002000 }
2001
2002 Function *const main_function =
2003 m_func_name.IsEmpty() ? nullptr
2004 : m_module->getFunction(m_func_name.GetStringRef());
2005
2006 if (!m_func_name.IsEmpty() && !main_function) {
2007 if (log)
Raphael Isemanna7040522019-08-08 21:43:21 +00002008 LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002009
Raphael Isemanna7040522019-08-08 21:43:21 +00002010 m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
2011 "'{0}' in the module",
2012 m_func_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002013
2014 return false;
2015 }
2016
2017 if (main_function) {
2018 if (!FixFunctionLinkage(*main_function)) {
2019 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002020 LLDB_LOGF(log, "Couldn't fix the linkage for the function");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002021
2022 return false;
2023 }
2024 }
2025
2026 llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
2027
2028 m_reloc_placeholder = new llvm::GlobalVariable(
2029 (*m_module), int8_ty, false /* IsConstant */,
2030 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
Konrad Kleine248a1302019-05-23 11:14:47 +00002031 "reloc_placeholder", nullptr /* InsertBefore */,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002032 GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
2033
2034 ////////////////////////////////////////////////////////////
2035 // Replace $__lldb_expr_result with a persistent variable
2036 //
2037
2038 if (main_function) {
2039 if (!CreateResultVariable(*main_function)) {
2040 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002041 LLDB_LOGF(log, "CreateResultVariable() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002042
2043 // CreateResultVariable() reports its own errors, so we don't do so here
2044
2045 return false;
2046 }
2047 }
2048
2049 if (log && log->GetVerbose()) {
2050 std::string s;
2051 raw_string_ostream oss(s);
2052
Konrad Kleine248a1302019-05-23 11:14:47 +00002053 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002054
2055 oss.flush();
2056
Raphael Isemanna7040522019-08-08 21:43:21 +00002057 LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002058 }
2059
Raphael Isemanndced4452019-08-09 07:59:18 +00002060 for (llvm::Function &function : *m_module) {
2061 for (BasicBlock &bb : function) {
2062 if (!RemoveGuards(bb)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002063 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002064 LLDB_LOGF(log, "RemoveGuards() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002065
2066 // RemoveGuards() reports its own errors, so we don't do so here
2067
2068 return false;
2069 }
2070
Raphael Isemanndced4452019-08-09 07:59:18 +00002071 if (!RewritePersistentAllocs(bb)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002072 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002073 LLDB_LOGF(log, "RewritePersistentAllocs() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002074
2075 // RewritePersistentAllocs() reports its own errors, so we don't do so
2076 // here
2077
2078 return false;
2079 }
2080
Raphael Isemanndced4452019-08-09 07:59:18 +00002081 if (!RemoveCXAAtExit(bb)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002082 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002083 LLDB_LOGF(log, "RemoveCXAAtExit() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084
2085 // RemoveCXAAtExit() reports its own errors, so we don't do so here
2086
2087 return false;
2088 }
2089 }
2090 }
2091
2092 ///////////////////////////////////////////////////////////////////////////////
2093 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
2094 //
2095
2096 if (!RewriteObjCConstStrings()) {
2097 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002098 LLDB_LOGF(log, "RewriteObjCConstStrings() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002099
2100 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
2101
2102 return false;
2103 }
2104
Raphael Isemanndced4452019-08-09 07:59:18 +00002105 for (llvm::Function &function : *m_module) {
2106 for (llvm::BasicBlock &bb : function) {
2107 if (!RewriteObjCSelectors(bb)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002108 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002109 LLDB_LOGF(log, "RewriteObjCSelectors() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002110
Adrian Prantl05097242018-04-30 16:49:04 +00002111 // RewriteObjCSelectors() reports its own errors, so we don't do so
2112 // here
Kate Stoneb9c1b512016-09-06 20:57:50 +00002113
2114 return false;
2115 }
Sean Callananac900582016-09-29 00:45:33 +00002116
Raphael Isemanndced4452019-08-09 07:59:18 +00002117 if (!RewriteObjCClassReferences(bb)) {
Sean Callananac900582016-09-29 00:45:33 +00002118 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002119 LLDB_LOGF(log, "RewriteObjCClassReferences() failed");
Sean Callananac900582016-09-29 00:45:33 +00002120
2121 // RewriteObjCClasses() reports its own errors, so we don't do so here
2122
2123 return false;
2124 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002125 }
2126 }
2127
Raphael Isemanndced4452019-08-09 07:59:18 +00002128 for (llvm::Function &function : *m_module) {
2129 for (BasicBlock &bb : function) {
2130 if (!ResolveCalls(bb)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002131 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002132 LLDB_LOGF(log, "ResolveCalls() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002133
2134 // ResolveCalls() reports its own errors, so we don't do so here
2135
2136 return false;
2137 }
2138 }
2139 }
2140
2141 ////////////////////////////////////////////////////////////////////////
2142 // Run function-level passes that only make sense on the main function
2143 //
2144
2145 if (main_function) {
2146 if (!ResolveExternals(*main_function)) {
2147 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002148 LLDB_LOGF(log, "ResolveExternals() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002149
2150 // ResolveExternals() reports its own errors, so we don't do so here
2151
2152 return false;
2153 }
2154
2155 if (!ReplaceVariables(*main_function)) {
2156 if (log)
Jonas Devlieghere63e5fb72019-07-24 17:56:10 +00002157 LLDB_LOGF(log, "ReplaceVariables() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002158
2159 // ReplaceVariables() reports its own errors, so we don't do so here
2160
2161 return false;
2162 }
2163 }
2164
2165 if (log && log->GetVerbose()) {
2166 std::string s;
2167 raw_string_ostream oss(s);
2168
Konrad Kleine248a1302019-05-23 11:14:47 +00002169 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002170
2171 oss.flush();
2172
Raphael Isemanna7040522019-08-08 21:43:21 +00002173 LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002174 }
2175
2176 return true;
2177}
2178
2179void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2180 PassManagerType pass_mgr_type) {}
2181
2182PassManagerType IRForTarget::getPotentialPassManagerType() const {
2183 return PMT_ModulePassManager;
Sean Callanan2ab712f22010-07-03 01:35:46 +00002184}