blob: 29d2bbf43eb0c40939e91e0b204c67af1e41a972 [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
Raphael Isemannac42e742019-08-09 10:01:51 +000046typedef SmallVector<Instruction *, 2> InstrList;
47
Kate Stoneb9c1b512016-09-06 20:57:50 +000048IRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
49 : m_maker(maker), m_values() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051IRForTarget::FunctionValueCache::~FunctionValueCache() {}
Sean Callanan1f9db3e2013-06-28 21:44:15 +000052
Greg Clayton526ae042015-02-12 00:34:25 +000053llvm::Value *
Kate Stoneb9c1b512016-09-06 20:57:50 +000054IRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
55 if (!m_values.count(function)) {
56 llvm::Value *ret = m_maker(function);
57 m_values[function] = ret;
58 return ret;
59 }
60 return m_values[function];
Sean Callanan1f9db3e2013-06-28 21:44:15 +000061}
62
Kate Stoneb9c1b512016-09-06 20:57:50 +000063static llvm::Value *FindEntryInstruction(llvm::Function *function) {
64 if (function->empty())
Konrad Kleine248a1302019-05-23 11:14:47 +000065 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 return function->getEntryBlock().getFirstNonPHIOrDbg();
Sean Callanan1f9db3e2013-06-28 21:44:15 +000068}
69
Kate Stoneb9c1b512016-09-06 20:57:50 +000070IRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
71 bool resolve_vars,
72 lldb_private::IRExecutionUnit &execution_unit,
73 lldb_private::Stream &error_stream,
74 const char *func_name)
75 : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
Konrad Kleine248a1302019-05-23 11:14:47 +000076 m_module(nullptr), m_decl_map(decl_map),
77 m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
78 m_objc_getClass(nullptr), m_intptr_ty(nullptr),
79 m_error_stream(error_stream), m_execution_unit(execution_unit),
80 m_result_store(nullptr), m_result_is_pointer(false),
81 m_reloc_placeholder(nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 m_entry_instruction_finder(FindEntryInstruction) {}
Sean Callanan2ab712f22010-07-03 01:35:46 +000083
Sean Callanan038df5032010-09-30 21:18:25 +000084/* Handy utility functions used at several places in the code */
Sean Callanan2235f322010-08-11 03:57:18 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086static std::string PrintValue(const Value *value, bool truncate = false) {
87 std::string s;
88 if (value) {
Sean Callanan038df5032010-09-30 21:18:25 +000089 raw_string_ostream rso(s);
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 value->print(rso);
Sean Callanan038df5032010-09-30 21:18:25 +000091 rso.flush();
92 if (truncate)
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 s.resize(s.length() - 1);
94 }
95 return s;
Sean Callanan038df5032010-09-30 21:18:25 +000096}
97
Kate Stoneb9c1b512016-09-06 20:57:50 +000098static std::string PrintType(const llvm::Type *type, bool truncate = false) {
99 std::string s;
100 raw_string_ostream rso(s);
101 type->print(rso);
102 rso.flush();
103 if (truncate)
104 s.resize(s.length() - 1);
105 return s;
Sean Callanan2ab712f22010-07-03 01:35:46 +0000106}
107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108IRForTarget::~IRForTarget() {}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110bool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
111 llvm_function.setLinkage(GlobalValue::ExternalLinkage);
112
113 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000114}
115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116clang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
117 Module *module) {
118 NamedMDNode *named_metadata =
119 module->getNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 if (!named_metadata)
Konrad Kleine248a1302019-05-23 11:14:47 +0000122 return nullptr;
Sean Callanan63697e52011-05-07 01:06:41 +0000123
Kate Stoneb9c1b512016-09-06 20:57:50 +0000124 unsigned num_nodes = named_metadata->getNumOperands();
125 unsigned node_index;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000126
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 for (node_index = 0; node_index < num_nodes; ++node_index) {
128 llvm::MDNode *metadata_node =
129 dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
130 if (!metadata_node)
Konrad Kleine248a1302019-05-23 11:14:47 +0000131 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000132
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 if (metadata_node->getNumOperands() != 2)
134 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000135
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 if (mdconst::dyn_extract_or_null<GlobalValue>(
137 metadata_node->getOperand(0)) != global_val)
138 continue;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000139
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 ConstantInt *constant_int =
141 mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000142
Sean Callanan2235f322010-08-11 03:57:18 +0000143 if (!constant_int)
Konrad Kleine248a1302019-05-23 11:14:47 +0000144 return nullptr;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000145
Sean Callanan2235f322010-08-11 03:57:18 +0000146 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 return reinterpret_cast<clang::NamedDecl *>(ptr);
149 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000150
Konrad Kleine248a1302019-05-23 11:14:47 +0000151 return nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000152}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000153
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154clang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
155 return DeclForGlobal(global_val, m_module);
156}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000157
Raphael Isemann94fbbf72019-08-09 09:27:04 +0000158/// Returns true iff the mangled symbol is for a static guard variable.
159static bool isGuardVariableSymbol(llvm::StringRef mangled_symbol) {
160 return mangled_symbol.startswith("_ZGV") || // Itanium ABI guard variable
161 mangled_symbol.startswith("@4IA"); // Microsoft ABI guard variable
162}
163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
165 lldb_private::Log *log(
166 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 if (!m_resolve_vars)
169 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000170
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 // Find the result variable. If it doesn't exist, we can give up right here.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000172
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000174
Raphael Isemann50f7e942019-08-08 22:19:16 +0000175 llvm::StringRef result_name;
176 bool found_result = false;
Sean Callanan2235f322010-08-11 03:57:18 +0000177
Raphael Isemanndced4452019-08-09 07:59:18 +0000178 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
179 result_name = value_symbol.first();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000180
Raphael Isemann50f7e942019-08-08 22:19:16 +0000181 if (result_name.contains("$__lldb_expr_result_ptr") &&
Raphael Isemann94fbbf72019-08-09 09:27:04 +0000182 !isGuardVariableSymbol(result_name)) {
Raphael Isemann50f7e942019-08-08 22:19:16 +0000183 found_result = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184 m_result_is_pointer = true;
185 break;
186 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000187
Raphael Isemann50f7e942019-08-08 22:19:16 +0000188 if (result_name.contains("$__lldb_expr_result") &&
Raphael Isemann94fbbf72019-08-09 09:27:04 +0000189 !isGuardVariableSymbol(result_name)) {
Raphael Isemann50f7e942019-08-08 22:19:16 +0000190 found_result = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 m_result_is_pointer = false;
192 break;
193 }
194 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000195
Raphael Isemann50f7e942019-08-08 22:19:16 +0000196 if (!found_result) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000197 LLDB_LOG(log, "Couldn't find result variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000198
Sean Callanan2235f322010-08-11 03:57:18 +0000199 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 }
Sean Callanan2235f322010-08-11 03:57:18 +0000201
Raphael Isemann50f7e942019-08-08 22:19:16 +0000202 LLDB_LOG(log, "Result name: \"{0}\"", result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000203
Kate Stoneb9c1b512016-09-06 20:57:50 +0000204 Value *result_value = m_module->getNamedValue(result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206 if (!result_value) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000207 LLDB_LOG(log, "Result variable had no data");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000208
Raphael Isemann50f7e942019-08-08 22:19:16 +0000209 m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
210 "name ({0}) exists, but not its definition\n",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 result_name);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000212
Sean Callananc70ed462011-10-25 18:36:40 +0000213 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 }
Sean Callananc70ed462011-10-25 18:36:40 +0000215
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000216 LLDB_LOG(log, "Found result in the IR: \"{0}\"",
217 PrintValue(result_value, false));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218
219 GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
220
221 if (!result_global) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000222 LLDB_LOG(log, "Result variable isn't a GlobalVariable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223
Raphael Isemann50f7e942019-08-08 22:19:16 +0000224 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225 "is defined, but is not a global variable\n",
226 result_name);
227
228 return false;
229 }
230
231 clang::NamedDecl *result_decl = DeclForGlobal(result_global);
232 if (!result_decl) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000233 LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000234
Raphael Isemann50f7e942019-08-08 22:19:16 +0000235 m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 "does not have a corresponding Clang entity\n",
237 result_name);
238
239 return false;
240 }
241
242 if (log) {
243 std::string decl_desc_str;
244 raw_string_ostream decl_desc_stream(decl_desc_str);
245 result_decl->print(decl_desc_stream);
246 decl_desc_stream.flush();
247
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000248 LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000249 }
250
251 clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
252 if (!result_var) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000253 LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000254
Raphael Isemann50f7e942019-08-08 22:19:16 +0000255 m_error_stream.Format("Internal error [IRForTarget]: Result variable "
256 "({0})'s corresponding Clang entity isn't a "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000257 "variable\n",
258 result_name);
259
260 return false;
261 }
262
263 // Get the next available result name from m_decl_map and create the
Adrian Prantl05097242018-04-30 16:49:04 +0000264 // persistent variable for it
Kate Stoneb9c1b512016-09-06 20:57:50 +0000265
266 // If the result is an Lvalue, it is emitted as a pointer; see
267 // ASTResultSynthesizer::SynthesizeBodyResult.
268 if (m_result_is_pointer) {
269 clang::QualType pointer_qual_type = result_var->getType();
270 const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
271
272 const clang::PointerType *pointer_pointertype =
273 pointer_type->getAs<clang::PointerType>();
274 const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
275 pointer_type->getAs<clang::ObjCObjectPointerType>();
276
277 if (pointer_pointertype) {
278 clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
279
280 m_result_type = lldb_private::TypeFromParser(
281 element_qual_type.getAsOpaquePtr(),
282 lldb_private::ClangASTContext::GetASTContext(
283 &result_decl->getASTContext()));
284 } else if (pointer_objcobjpointertype) {
285 clang::QualType element_qual_type =
286 clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
287
288 m_result_type = lldb_private::TypeFromParser(
289 element_qual_type.getAsOpaquePtr(),
290 lldb_private::ClangASTContext::GetASTContext(
291 &result_decl->getASTContext()));
292 } else {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000293 LLDB_LOG(log, "Expected result to have pointer type, but it did not");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000294
Raphael Isemann50f7e942019-08-08 22:19:16 +0000295 m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 "is not a pointer variable\n",
297 result_name);
298
299 return false;
300 }
301 } else {
302 m_result_type = lldb_private::TypeFromParser(
303 result_var->getType().getAsOpaquePtr(),
304 lldb_private::ClangASTContext::GetASTContext(
305 &result_decl->getASTContext()));
306 }
307
308 lldb::TargetSP target_sp(m_execution_unit.GetTarget());
309 lldb_private::ExecutionContext exe_ctx(target_sp, true);
Adrian Prantld6a9bbf2019-01-15 20:33:58 +0000310 llvm::Optional<uint64_t> bit_size =
Adrian Prantld963a7c2019-01-15 18:07:52 +0000311 m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
312 if (!bit_size) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313 lldb_private::StreamString type_desc_stream;
314 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000315
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000316 LLDB_LOG(log, "Result type has unknown size");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000317
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
319 "couldn't be determined\n",
320 type_desc_stream.GetData());
321 return false;
322 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000323
Kate Stoneb9c1b512016-09-06 20:57:50 +0000324 if (log) {
325 lldb_private::StreamString type_desc_stream;
326 m_result_type.DumpTypeDescription(&type_desc_stream);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000327
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000328 LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000329 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000330
Kate Stoneb9c1b512016-09-06 20:57:50 +0000331 m_result_name = lldb_private::ConstString("$RESULT_NAME");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000332
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000333 LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
334 m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336 // Construct a new result global and set up its metadata
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000337
Kate Stoneb9c1b512016-09-06 20:57:50 +0000338 GlobalVariable *new_result_global = new GlobalVariable(
339 (*m_module), result_global->getType()->getElementType(),
Konrad Kleine248a1302019-05-23 11:14:47 +0000340 false, /* not constant */
341 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342 m_result_name.GetCString());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000343
Adrian Prantl05097242018-04-30 16:49:04 +0000344 // It's too late in compilation to create a new VarDecl for this, but we
345 // don't need to. We point the metadata at the old VarDecl. This creates an
346 // odd anomaly: a variable with a Value whose name is something like $0 and a
Kate Stoneb9c1b512016-09-06 20:57:50 +0000347 // Decl whose name is $__lldb_expr_result. This condition is handled in
348 // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
349 // fixed up.
Greg Clayton57ee3062013-07-11 22:46:58 +0000350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 ConstantInt *new_constant_int =
352 ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
353 reinterpret_cast<uint64_t>(result_decl), false);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000354
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 llvm::Metadata *values[2];
356 values[0] = ConstantAsMetadata::get(new_result_global);
357 values[1] = ConstantAsMetadata::get(new_constant_int);
Greg Clayton57ee3062013-07-11 22:46:58 +0000358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 ArrayRef<Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
362 NamedMDNode *named_metadata =
363 m_module->getNamedMetadata("clang.global.decl.ptrs");
364 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000365
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000366 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
367 PrintValue(new_result_global));
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()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000380 LLDB_LOG(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
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000394 LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
395 PrintValue(synthesized_store));
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
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000440 LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
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)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000534 LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535
Sean Callanancd1eb722016-12-01 17:46:51 +0000536 m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
537 "Objective-C constant string with a dynamic "
538 "string\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539
Sean Callanancd1eb722016-12-01 17:46:51 +0000540 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 }
542
543 ns_str->eraseFromParent();
544
545 return true;
Sean Callanan549c9f72010-07-13 21:41:46 +0000546}
547
Kate Stoneb9c1b512016-09-06 20:57:50 +0000548bool IRForTarget::RewriteObjCConstStrings() {
549 lldb_private::Log *log(
550 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000551
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552 ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000553
Raphael Isemanndced4452019-08-09 07:59:18 +0000554 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
Raphael Isemann474d70b2019-08-09 08:10:02 +0000555 llvm::StringRef value_name = value_symbol.first();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000556
Raphael Isemann474d70b2019-08-09 08:10:02 +0000557 if (value_name.contains("_unnamed_cfstring_")) {
Raphael Isemanndced4452019-08-09 07:59:18 +0000558 Value *nsstring_value = value_symbol.second;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 GlobalVariable *nsstring_global =
561 dyn_cast<GlobalVariable>(nsstring_value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000562
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563 if (!nsstring_global) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000564 LLDB_LOG(log, "NSString variable is not a GlobalVariable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000565
566 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
567 "constant string is not a global variable\n");
568
569 return false;
570 }
571
572 if (!nsstring_global->hasInitializer()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000573 LLDB_LOG(log, "NSString variable does not have an initializer");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574
575 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
576 "constant string does not have an initializer\n");
577
578 return false;
579 }
580
581 ConstantStruct *nsstring_struct =
582 dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
583
584 if (!nsstring_struct) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000585 LLDB_LOG(log,
586 "NSString variable's initializer is not a ConstantStruct");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000587
588 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
589 "constant string is not a structure constant\n");
590
591 return false;
592 }
593
594 // We expect the following structure:
595 //
596 // struct {
597 // int *isa;
598 // int flags;
599 // char *str;
600 // long length;
601 // };
602
603 if (nsstring_struct->getNumOperands() != 4) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000604
605 LLDB_LOG(log,
606 "NSString variable's initializer structure has an "
607 "unexpected number of members. Should be 4, is {0}",
608 nsstring_struct->getNumOperands());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609
610 m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
611 "Objective-C constant string is not as "
612 "expected\n");
613
614 return false;
615 }
616
617 Constant *nsstring_member = nsstring_struct->getOperand(2);
618
619 if (!nsstring_member) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000620 LLDB_LOG(log, "NSString initializer's str element was empty");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000621
622 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
623 "constant string does not have a string "
624 "initializer\n");
625
626 return false;
627 }
628
629 ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
630
631 if (!nsstring_expr) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000632 LLDB_LOG(log,
633 "NSString initializer's str element is not a ConstantExpr");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634
635 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
636 "constant string's string initializer is not "
637 "constant\n");
638
639 return false;
640 }
641
Sean Callanancd1eb722016-12-01 17:46:51 +0000642 GlobalVariable *cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643
Sean Callanancd1eb722016-12-01 17:46:51 +0000644 if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
645 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
646 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
647 } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
648 Constant *nsstring_cstr = nsstring_expr->getOperand(0);
649 cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000650 }
651
Kate Stoneb9c1b512016-09-06 20:57:50 +0000652 if (!cstr_global) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000653 LLDB_LOG(log,
654 "NSString initializer's str element is not a GlobalVariable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655
Sean Callanancd1eb722016-12-01 17:46:51 +0000656 m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
657 "constant string initializer\n");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658
659 return false;
660 }
661
662 if (!cstr_global->hasInitializer()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000663 LLDB_LOG(log, "NSString initializer's str element does not have an "
664 "initializer");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000665
666 m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
667 "constant string's string initializer doesn't "
668 "point to initialized data\n");
669
670 return false;
671 }
672
673 /*
674 if (!cstr_array)
675 {
676 if (log)
677 log->PutCString("NSString initializer's str element is not a
678 ConstantArray");
679
680 if (m_error_stream)
681 m_error_stream.Printf("Internal error [IRForTarget]: An
682 Objective-C constant string's string initializer doesn't point to an
683 array\n");
684
685 return false;
686 }
687
688 if (!cstr_array->isCString())
689 {
690 if (log)
691 log->PutCString("NSString initializer's str element is not a C
692 string array");
693
694 if (m_error_stream)
695 m_error_stream.Printf("Internal error [IRForTarget]: An
696 Objective-C constant string's string initializer doesn't point to a C
697 string\n");
698
699 return false;
700 }
701 */
702
703 ConstantDataArray *cstr_array =
704 dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
705
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000706 if (cstr_array)
707 LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
708 value_name, cstr_array->getAsString());
709 else
710 LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
711 value_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000712
713 if (!cstr_array)
Konrad Kleine248a1302019-05-23 11:14:47 +0000714 cstr_global = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000715
716 if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000717 LLDB_LOG(log, "Error rewriting the constant string");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000718
719 // We don't print an error message here because RewriteObjCConstString
720 // has done so for us.
721
722 return false;
723 }
724 }
725 }
726
Raphael Isemanndced4452019-08-09 07:59:18 +0000727 for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
Raphael Isemann474d70b2019-08-09 08:10:02 +0000728 llvm::StringRef value_name = value_symbol.first();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000729
Raphael Isemann474d70b2019-08-09 08:10:02 +0000730 if (value_name == "__CFConstantStringClassReference") {
Raphael Isemanndced4452019-08-09 07:59:18 +0000731 GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732
733 if (!gv) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000734 LLDB_LOG(log,
735 "__CFConstantStringClassReference is not a global variable");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000736
737 m_error_stream.Printf("Internal error [IRForTarget]: Found a "
738 "CFConstantStringClassReference, but it is not a "
739 "global object\n");
740
741 return false;
742 }
743
744 gv->eraseFromParent();
745
746 break;
747 }
748 }
749
750 return true;
Sean Callanan79763a42011-05-23 21:40:23 +0000751}
752
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753static bool IsObjCSelectorRef(Value *value) {
754 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000755
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000756 return !(!global_variable || !global_variable->hasName() ||
757 !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758}
759
760// This function does not report errors; its callers are responsible.
761bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
762 lldb_private::Log *log(
763 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
764
765 LoadInst *load = dyn_cast<LoadInst>(selector_load);
766
767 if (!load)
768 return false;
769
770 // Unpack the message name from the selector. In LLVM IR, an objc_msgSend
771 // gets represented as
772 //
Adrian Prantl05097242018-04-30 16:49:04 +0000773 // %tmp = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call = call
774 // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 //
776 // where %obj is the object pointer and %tmp is the selector.
777 //
778 // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
779 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
780 // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
781
782 // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
783 // and get the string from its target
784
785 GlobalVariable *_objc_selector_references_ =
786 dyn_cast<GlobalVariable>(load->getPointerOperand());
787
788 if (!_objc_selector_references_ ||
789 !_objc_selector_references_->hasInitializer())
790 return false;
791
792 Constant *osr_initializer = _objc_selector_references_->getInitializer();
793
794 ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
795
796 if (!osr_initializer_expr ||
797 osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
798 return false;
799
800 Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
801
802 if (!osr_initializer_base)
803 return false;
804
805 // Find the string's initializer (a ConstantArray) and get the string from it
806
807 GlobalVariable *_objc_meth_var_name_ =
808 dyn_cast<GlobalVariable>(osr_initializer_base);
809
810 if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
811 return false;
812
813 Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
814
815 ConstantDataArray *omvn_initializer_array =
816 dyn_cast<ConstantDataArray>(omvn_initializer);
817
818 if (!omvn_initializer_array->isString())
819 return false;
820
821 std::string omvn_initializer_string = omvn_initializer_array->getAsString();
822
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000823 LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
824 omvn_initializer_string);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825
826 // Construct a call to sel_registerName
827
828 if (!m_sel_registerName) {
829 lldb::addr_t sel_registerName_addr;
830
Jim Inghamf2128b22019-06-28 21:40:05 +0000831 bool missing_weak = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000832 static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
Jim Inghamf2128b22019-06-28 21:40:05 +0000833 sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str,
834 missing_weak);
835 if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000836 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000837
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000838 LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000839
Adrian Prantl05097242018-04-30 16:49:04 +0000840 // Build the function type: struct objc_selector
841 // *sel_registerName(uint8_t*)
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000842
Kate Stoneb9c1b512016-09-06 20:57:50 +0000843 // The below code would be "more correct," but in actuality what's required
844 // is uint8_t*
845 // Type *sel_type = StructType::get(m_module->getContext());
846 // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
847 Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000848
Kate Stoneb9c1b512016-09-06 20:57:50 +0000849 Type *type_array[1];
850
851 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
852
853 ArrayRef<Type *> srN_arg_types(type_array, 1);
854
James Y Knightae2f9512019-02-08 19:30:46 +0000855 llvm::FunctionType *srN_type =
Kate Stoneb9c1b512016-09-06 20:57:50 +0000856 FunctionType::get(sel_ptr_type, srN_arg_types, false);
857
858 // Build the constant containing the pointer to the function
859 PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
860 Constant *srN_addr_int =
861 ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +0000862 m_sel_registerName = {srN_type,
863 ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864 }
865
866 Value *argument_array[1];
867
868 Constant *omvn_pointer = ConstantExpr::getBitCast(
869 _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
870
871 argument_array[0] = omvn_pointer;
872
873 ArrayRef<Value *> srN_arguments(argument_array, 1);
874
875 CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
876 "sel_registerName", selector_load);
877
878 // Replace the load with the call in all users
879
880 selector_load->replaceAllUsesWith(srN_call);
881
882 selector_load->eraseFromParent();
883
884 return true;
885}
886
887bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
888 lldb_private::Log *log(
889 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000890
891 InstrList selector_loads;
892
Raphael Isemanndced4452019-08-09 07:59:18 +0000893 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000894 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
895 if (IsObjCSelectorRef(load->getPointerOperand()))
896 selector_loads.push_back(&inst);
897 }
898
Raphael Isemanndced4452019-08-09 07:59:18 +0000899 for (Instruction *inst : selector_loads) {
900 if (!RewriteObjCSelector(inst)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
902 "static reference to an Objective-C selector to a "
903 "dynamic reference\n");
904
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000905 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000906
907 return false;
Sean Callananc70ed462011-10-25 18:36:40 +0000908 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000909 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000910
Kate Stoneb9c1b512016-09-06 20:57:50 +0000911 return true;
912}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000913
Sean Callananac900582016-09-29 00:45:33 +0000914static bool IsObjCClassReference(Value *value) {
915 GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
916
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000917 return !(!global_variable || !global_variable->hasName() ||
918 !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
Sean Callananac900582016-09-29 00:45:33 +0000919}
920
921// This function does not report errors; its callers are responsible.
922bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
923 lldb_private::Log *log(
924 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
925
926 LoadInst *load = dyn_cast<LoadInst>(class_load);
927
928 if (!load)
929 return false;
930
931 // Unpack the class name from the reference. In LLVM IR, a reference to an
932 // Objective-C class gets represented as
933 //
934 // %tmp = load %struct._objc_class*,
935 // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
936 //
937 // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
Adrian Prantl05097242018-04-30 16:49:04 +0000938 // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.
Sean Callananac900582016-09-29 00:45:33 +0000939
Adrian Prantl05097242018-04-30 16:49:04 +0000940 // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and
941 // get the string from its target
Sean Callananac900582016-09-29 00:45:33 +0000942
943 GlobalVariable *_objc_class_references_ =
944 dyn_cast<GlobalVariable>(load->getPointerOperand());
945
946 if (!_objc_class_references_ ||
947 !_objc_class_references_->hasInitializer())
948 return false;
949
950 Constant *ocr_initializer = _objc_class_references_->getInitializer();
951
952 ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
953
954 if (!ocr_initializer_expr ||
955 ocr_initializer_expr->getOpcode() != Instruction::BitCast)
956 return false;
957
958 Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
959
960 if (!ocr_initializer_base)
961 return false;
962
963 // Find the string's initializer (a ConstantArray) and get the string from it
964
965 GlobalVariable *_objc_class_name_ =
966 dyn_cast<GlobalVariable>(ocr_initializer_base);
967
968 if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
969 return false;
970
971 Constant *ocn_initializer = _objc_class_name_->getInitializer();
972
973 ConstantDataArray *ocn_initializer_array =
974 dyn_cast<ConstantDataArray>(ocn_initializer);
975
976 if (!ocn_initializer_array->isString())
977 return false;
978
979 std::string ocn_initializer_string = ocn_initializer_array->getAsString();
980
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000981 LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
982 ocn_initializer_string);
Sean Callananac900582016-09-29 00:45:33 +0000983
984 // Construct a call to objc_getClass
985
986 if (!m_objc_getClass) {
987 lldb::addr_t objc_getClass_addr;
988
Jim Inghamf2128b22019-06-28 21:40:05 +0000989 bool missing_weak = false;
Sean Callananac900582016-09-29 00:45:33 +0000990 static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
Jim Inghamf2128b22019-06-28 21:40:05 +0000991 objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str,
992 missing_weak);
993 if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
Sean Callananac900582016-09-29 00:45:33 +0000994 return false;
995
Raphael Isemann4ef50a32019-08-09 08:54:01 +0000996 LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);
Sean Callananac900582016-09-29 00:45:33 +0000997
998 // Build the function type: %struct._objc_class *objc_getClass(i8*)
999
1000 Type *class_type = load->getType();
1001 Type *type_array[1];
1002 type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
1003
1004 ArrayRef<Type *> ogC_arg_types(type_array, 1);
1005
James Y Knightae2f9512019-02-08 19:30:46 +00001006 llvm::FunctionType *ogC_type =
Sean Callananac900582016-09-29 00:45:33 +00001007 FunctionType::get(class_type, ogC_arg_types, false);
1008
1009 // Build the constant containing the pointer to the function
1010 PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
1011 Constant *ogC_addr_int =
1012 ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
James Y Knightae2f9512019-02-08 19:30:46 +00001013 m_objc_getClass = {ogC_type,
1014 ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
Sean Callananac900582016-09-29 00:45:33 +00001015 }
1016
1017 Value *argument_array[1];
1018
1019 Constant *ocn_pointer = ConstantExpr::getBitCast(
1020 _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
1021
1022 argument_array[0] = ocn_pointer;
1023
1024 ArrayRef<Value *> ogC_arguments(argument_array, 1);
1025
1026 CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
1027 "objc_getClass", class_load);
1028
1029 // Replace the load with the call in all users
1030
1031 class_load->replaceAllUsesWith(ogC_call);
1032
1033 class_load->eraseFromParent();
1034
1035 return true;
1036}
1037
1038bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
1039 lldb_private::Log *log(
1040 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1041
Sean Callananac900582016-09-29 00:45:33 +00001042 InstrList class_loads;
1043
Raphael Isemanndced4452019-08-09 07:59:18 +00001044 for (Instruction &inst : basic_block) {
Sean Callananac900582016-09-29 00:45:33 +00001045 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1046 if (IsObjCClassReference(load->getPointerOperand()))
1047 class_loads.push_back(&inst);
1048 }
1049
Raphael Isemanndced4452019-08-09 07:59:18 +00001050 for (Instruction *inst : class_loads) {
1051 if (!RewriteObjCClassReference(inst)) {
Sean Callananac900582016-09-29 00:45:33 +00001052 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
1053 "static reference to an Objective-C class to a "
1054 "dynamic reference\n");
1055
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001056 LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");
Sean Callananac900582016-09-29 00:45:33 +00001057
1058 return false;
1059 }
1060 }
1061
1062 return true;
1063}
1064
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065// This function does not report errors; its callers are responsible.
1066bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
1067 lldb_private::Log *log(
1068 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001069
Kate Stoneb9c1b512016-09-06 20:57:50 +00001070 AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001071
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072 MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001073
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074 if (!alloc_md || !alloc_md->getNumOperands())
1075 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001076
Kate Stoneb9c1b512016-09-06 20:57:50 +00001077 ConstantInt *constant_int =
1078 mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001079
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 if (!constant_int)
1081 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001082
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 // We attempt to register this as a new persistent variable with the DeclMap.
Sean Callanan1f9db3e2013-06-28 21:44:15 +00001084
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085 uintptr_t ptr = constant_int->getZExtValue();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001086
Kate Stoneb9c1b512016-09-06 20:57:50 +00001087 clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001088
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 lldb_private::TypeFromParser result_decl_type(
1090 decl->getType().getAsOpaquePtr(),
1091 lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001092
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 StringRef decl_name(decl->getName());
1094 lldb_private::ConstString persistent_variable_name(decl_name.data(),
1095 decl_name.size());
1096 if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1097 result_decl_type, false, false))
1098 return false;
Sean Callanan6e6d4a62012-07-21 02:02:15 +00001099
Kate Stoneb9c1b512016-09-06 20:57:50 +00001100 GlobalVariable *persistent_global = new GlobalVariable(
Konrad Kleine248a1302019-05-23 11:14:47 +00001101 (*m_module), alloc->getType(), false, /* not constant */
1102 GlobalValue::ExternalLinkage, nullptr, /* no initializer */
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001103 alloc->getName().str());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001104
Adrian Prantl05097242018-04-30 16:49:04 +00001105 // What we're going to do here is make believe this was a regular old
1106 // external variable. That means we need to make the metadata valid.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001107
Kate Stoneb9c1b512016-09-06 20:57:50 +00001108 NamedMDNode *named_metadata =
1109 m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001110
Kate Stoneb9c1b512016-09-06 20:57:50 +00001111 llvm::Metadata *values[2];
1112 values[0] = ConstantAsMetadata::get(persistent_global);
1113 values[1] = ConstantAsMetadata::get(constant_int);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001114
Kate Stoneb9c1b512016-09-06 20:57:50 +00001115 ArrayRef<llvm::Metadata *> value_ref(values, 2);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001116
Kate Stoneb9c1b512016-09-06 20:57:50 +00001117 MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1118 named_metadata->addOperand(persistent_global_md);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001119
Kate Stoneb9c1b512016-09-06 20:57:50 +00001120 // Now, since the variable is a pointer variable, we will drop in a load of
Adrian Prantl05097242018-04-30 16:49:04 +00001121 // that pointer variable.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001122
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123 LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001124
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001125 LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
1126 PrintValue(persistent_load));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001127
Kate Stoneb9c1b512016-09-06 20:57:50 +00001128 alloc->replaceAllUsesWith(persistent_load);
1129 alloc->eraseFromParent();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001130
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131 return true;
1132}
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001133
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134bool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1135 if (!m_resolve_vars)
1136 return true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001137
Kate Stoneb9c1b512016-09-06 20:57:50 +00001138 lldb_private::Log *log(
1139 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001140
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 InstrList pvar_allocs;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001142
Raphael Isemanndced4452019-08-09 07:59:18 +00001143 for (Instruction &inst : basic_block) {
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001144
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1146 llvm::StringRef alloc_name = alloc->getName();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001147
Kate Stoneb9c1b512016-09-06 20:57:50 +00001148 if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1149 if (alloc_name.find_first_of("0123456789") == 1) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001150 LLDB_LOG(log, "Rejecting a numeric persistent variable.");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001151
Kate Stoneb9c1b512016-09-06 20:57:50 +00001152 m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1153 "$1, ... are reserved for use as result "
1154 "names\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001155
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 return false;
Sean Callanan00294b32016-03-22 21:05:51 +00001157 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001158
Kate Stoneb9c1b512016-09-06 20:57:50 +00001159 pvar_allocs.push_back(alloc);
1160 }
Sean Callanan17827832010-12-13 22:46:15 +00001161 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001163
Raphael Isemanndced4452019-08-09 07:59:18 +00001164 for (Instruction *inst : pvar_allocs) {
1165 if (!RewritePersistentAlloc(inst)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1167 "the creation of a persistent variable\n");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001168
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001169 LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001170
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001172 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001173 }
1174
1175 return true;
1176}
1177
1178bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
1179 if (!initializer)
1180 return true;
1181
1182 lldb_private::Log *log(
1183 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1184
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001185 LLDB_LOGV(log, " MaterializeInitializer({0}, {1})", (void *)data,
1186 PrintValue(initializer));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001187
1188 Type *initializer_type = initializer->getType();
1189
1190 if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
1191 size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
1192 lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
1193 llvm::NextPowerOf2(constant_size) * 8);
1194
Zachary Turner97206d52017-05-12 04:51:55 +00001195 lldb_private::Status get_data_error;
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001196 return scalar.GetAsMemoryData(data, constant_size,
1197 lldb_private::endian::InlHostByteOrder(),
1198 get_data_error) != 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001199 } else if (ConstantDataArray *array_initializer =
1200 dyn_cast<ConstantDataArray>(initializer)) {
1201 if (array_initializer->isString()) {
1202 std::string array_initializer_string = array_initializer->getAsString();
1203 memcpy(data, array_initializer_string.c_str(),
1204 m_target_data->getTypeStoreSize(initializer_type));
1205 } else {
1206 ArrayType *array_initializer_type = array_initializer->getType();
1207 Type *array_element_type = array_initializer_type->getElementType();
1208
1209 size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
1210
1211 for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
1212 Value *operand_value = array_initializer->getOperand(i);
1213 Constant *operand_constant = dyn_cast<Constant>(operand_value);
1214
1215 if (!operand_constant)
1216 return false;
1217
1218 if (!MaterializeInitializer(data + (i * element_size),
1219 operand_constant))
1220 return false;
1221 }
1222 }
1223 return true;
1224 } else if (ConstantStruct *struct_initializer =
1225 dyn_cast<ConstantStruct>(initializer)) {
1226 StructType *struct_initializer_type = struct_initializer->getType();
1227 const StructLayout *struct_layout =
1228 m_target_data->getStructLayout(struct_initializer_type);
1229
1230 for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
1231 if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
1232 struct_initializer->getOperand(i)))
1233 return false;
1234 }
1235 return true;
1236 } else if (isa<ConstantAggregateZero>(initializer)) {
1237 memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
1238 return true;
1239 }
1240 return false;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001241}
1242
Kate Stoneb9c1b512016-09-06 20:57:50 +00001243// This function does not report errors; its callers are responsible.
1244bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1245 lldb_private::Log *log(
1246 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1247
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001248 LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001249
1250 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1251 switch (constant_expr->getOpcode()) {
1252 default:
1253 break;
1254 case Instruction::GetElementPtr:
1255 case Instruction::BitCast:
1256 Value *s = constant_expr->getOperand(0);
1257 if (!MaybeHandleVariable(s))
1258 return false;
1259 }
1260 } else if (GlobalVariable *global_variable =
1261 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1262 if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1263 return true;
1264
1265 clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1266
1267 if (!named_decl) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001268 LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
1269 global_variable->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001270
Raphael Isemannb448d1b2019-08-10 10:56:17 +00001271 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001272 }
1273
Raphael Isemann7491f362019-08-08 21:22:21 +00001274 llvm::StringRef name(named_decl->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001275
1276 clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
Konrad Kleine248a1302019-05-23 11:14:47 +00001277 if (value_decl == nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001278 return false;
1279
1280 lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
1281 value_decl->getType());
1282
Konrad Kleine248a1302019-05-23 11:14:47 +00001283 const Type *value_type = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001284
Raphael Isemann7491f362019-08-08 21:22:21 +00001285 if (name.startswith("$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001286 // The $__lldb_expr_result name indicates the return value has allocated
Adrian Prantl05097242018-04-30 16:49:04 +00001287 // as a static variable. Per the comment at
1288 // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
1289 // variable need to be redirected to the result of dereferencing a
1290 // pointer that is passed in as one of the arguments.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001291 //
1292 // Consequently, when reporting the size of the type, we report a pointer
Adrian Prantl05097242018-04-30 16:49:04 +00001293 // type pointing to the type of $__lldb_expr_result, not the type itself.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001294 //
1295 // We also do this for any user-declared persistent variables.
1296 compiler_type = compiler_type.GetPointerType();
1297 value_type = PointerType::get(global_variable->getType(), 0);
1298 } else {
1299 value_type = global_variable->getType();
1300 }
1301
Adrian Prantld6a9bbf2019-01-15 20:33:58 +00001302 llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
Adrian Prantld963a7c2019-01-15 18:07:52 +00001303 if (!value_size)
1304 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001305 lldb::offset_t value_alignment =
1306 (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
1307
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001308 LLDB_LOG(log,
1309 "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1310 "align {4}]",
1311 name,
1312 lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
1313 PrintType(value_type), *value_size, value_alignment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001314
Raphael Isemann0e5eef52019-08-08 16:41:32 +00001315 if (named_decl)
Raphael Isemann7491f362019-08-08 21:22:21 +00001316 m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
1317 llvm_value_ptr, *value_size,
1318 value_alignment);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001319 } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001320 LLDB_LOG(log, "Function pointers aren't handled right now");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321
1322 return false;
1323 }
1324
1325 return true;
Sean Callanan2ab712f22010-07-03 01:35:46 +00001326}
1327
Kate Stoneb9c1b512016-09-06 20:57:50 +00001328// This function does not report errors; its callers are responsible.
1329bool IRForTarget::HandleSymbol(Value *symbol) {
1330 lldb_private::Log *log(
1331 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1332
1333 lldb_private::ConstString name(symbol->getName().str().c_str());
1334
1335 lldb::addr_t symbol_addr =
1336 m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1337
1338 if (symbol_addr == LLDB_INVALID_ADDRESS) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001339 LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001340
1341 return false;
1342 }
1343
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001344 LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001345
1346 Type *symbol_type = symbol->getType();
1347
1348 Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1349
1350 Value *symbol_addr_ptr =
1351 ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1352
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001353 LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
1354 PrintValue(symbol_addr_ptr));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001355
1356 symbol->replaceAllUsesWith(symbol_addr_ptr);
1357
1358 return true;
1359}
1360
1361bool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1362 lldb_private::Log *log(
1363 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1364
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001365 LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001366
1367 for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1368 op_index < num_ops; ++op_index)
Raphael Isemanndced4452019-08-09 07:59:18 +00001369 // conservatively believe that this is a store
1370 if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001371 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1372 "one of the arguments of a function call.\n");
1373
1374 return false;
1375 }
1376
1377 return true;
1378}
1379
1380bool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1381 lldb_private::Log *log(
1382 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1383
1384 GlobalVariable *global_variable =
1385 dyn_cast<GlobalVariable>(classlist_reference);
1386
1387 if (!global_variable)
1388 return false;
1389
1390 Constant *initializer = global_variable->getInitializer();
1391
1392 if (!initializer)
1393 return false;
1394
1395 if (!initializer->hasName())
1396 return false;
1397
1398 StringRef name(initializer->getName());
1399 lldb_private::ConstString name_cstr(name.str().c_str());
1400 lldb::addr_t class_ptr =
1401 m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1402
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001403 LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
1404 (unsigned long long)class_ptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001405
1406 if (class_ptr == LLDB_INVALID_ADDRESS)
1407 return false;
1408
1409 if (global_variable->use_empty())
1410 return false;
1411
1412 SmallVector<LoadInst *, 2> load_instructions;
1413
1414 for (llvm::User *u : global_variable->users()) {
1415 if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1416 load_instructions.push_back(load_instruction);
1417 }
1418
1419 if (load_instructions.empty())
1420 return false;
1421
1422 Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1423
1424 for (LoadInst *load_instruction : load_instructions) {
1425 Constant *class_bitcast =
1426 ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1427
1428 load_instruction->replaceAllUsesWith(class_bitcast);
1429
1430 load_instruction->eraseFromParent();
1431 }
1432
1433 return true;
1434}
1435
1436bool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001437 std::vector<CallInst *> calls_to_remove;
1438
Raphael Isemanndced4452019-08-09 07:59:18 +00001439 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001440 CallInst *call = dyn_cast<CallInst>(&inst);
1441
1442 // MaybeHandleCallArguments handles error reporting; we are silent here
1443 if (!call)
1444 continue;
1445
1446 bool remove = false;
1447
1448 llvm::Function *func = call->getCalledFunction();
1449
1450 if (func && func->getName() == "__cxa_atexit")
1451 remove = true;
1452
1453 llvm::Value *val = call->getCalledValue();
1454
1455 if (val && val->getName() == "__cxa_atexit")
1456 remove = true;
1457
1458 if (remove)
1459 calls_to_remove.push_back(call);
1460 }
1461
Raphael Isemanndced4452019-08-09 07:59:18 +00001462 for (CallInst *ci : calls_to_remove)
1463 ci->eraseFromParent();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001464
1465 return true;
1466}
1467
1468bool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001469 // Prepare the current basic block for execution in the remote process
Kate Stoneb9c1b512016-09-06 20:57:50 +00001470
Raphael Isemanndced4452019-08-09 07:59:18 +00001471 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001472 CallInst *call = dyn_cast<CallInst>(&inst);
1473
1474 // MaybeHandleCallArguments handles error reporting; we are silent here
1475 if (call && !MaybeHandleCallArguments(call))
1476 return false;
1477 }
1478
1479 return true;
1480}
1481
1482bool IRForTarget::ResolveExternals(Function &llvm_function) {
1483 lldb_private::Log *log(
1484 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1485
1486 for (GlobalVariable &global_var : m_module->globals()) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001487 llvm::StringRef global_name = global_var.getName();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001488
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001489 LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
1490 static_cast<void *>(DeclForGlobal(&global_var)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001491
Raphael Isemanna7040522019-08-08 21:43:21 +00001492 if (global_name.startswith("OBJC_IVAR")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001493 if (!HandleSymbol(&global_var)) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001494 m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
1495 "indirect ivar symbol {0}\n",
1496 global_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001497
1498 return false;
1499 }
Raphael Isemanna7040522019-08-08 21:43:21 +00001500 } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001501 if (!HandleObjCClass(&global_var)) {
1502 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1503 "for an Objective-C static method call\n");
1504
1505 return false;
1506 }
Raphael Isemanna7040522019-08-08 21:43:21 +00001507 } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001508 if (!HandleObjCClass(&global_var)) {
1509 m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1510 "for an Objective-C static method call\n");
1511
1512 return false;
1513 }
1514 } else if (DeclForGlobal(&global_var)) {
1515 if (!MaybeHandleVariable(&global_var)) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001516 m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
1517 "external variable {0}\n",
1518 global_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001519
1520 return false;
1521 }
1522 }
1523 }
1524
1525 return true;
1526}
1527
1528static bool isGuardVariableRef(Value *V) {
Raphael Isemann94fbbf72019-08-09 09:27:04 +00001529 Constant *Old = dyn_cast<Constant>(V);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001530
Raphael Isemann94fbbf72019-08-09 09:27:04 +00001531 if (!Old)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001532 return false;
1533
Raphael Isemann94fbbf72019-08-09 09:27:04 +00001534 if (auto CE = dyn_cast<ConstantExpr>(V)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001535 if (CE->getOpcode() != Instruction::BitCast)
1536 return false;
1537
1538 Old = CE->getOperand(0);
1539 }
1540
1541 GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1542
Raphael Isemann94fbbf72019-08-09 09:27:04 +00001543 if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001544 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001545
1546 return true;
1547}
1548
1549void IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1550 Constant *zero(Constant::getNullValue(guard_load->getType()));
1551 guard_load->replaceAllUsesWith(zero);
1552 guard_load->eraseFromParent();
1553}
1554
1555static void ExciseGuardStore(Instruction *guard_store) {
1556 guard_store->eraseFromParent();
1557}
1558
1559bool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001560 // Eliminate any reference to guard variables found.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001561
1562 InstrList guard_loads;
1563 InstrList guard_stores;
1564
Raphael Isemanndced4452019-08-09 07:59:18 +00001565 for (Instruction &inst : basic_block) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001566
1567 if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1568 if (isGuardVariableRef(load->getPointerOperand()))
1569 guard_loads.push_back(&inst);
1570
1571 if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1572 if (isGuardVariableRef(store->getPointerOperand()))
1573 guard_stores.push_back(&inst);
1574 }
1575
Raphael Isemanndced4452019-08-09 07:59:18 +00001576 for (Instruction *inst : guard_loads)
1577 TurnGuardLoadIntoZero(inst);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001578
Raphael Isemanndced4452019-08-09 07:59:18 +00001579 for (Instruction *inst : guard_stores)
1580 ExciseGuardStore(inst);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001581
1582 return true;
1583}
1584
1585// This function does not report errors; its callers are responsible.
1586bool IRForTarget::UnfoldConstant(Constant *old_constant,
1587 llvm::Function *llvm_function,
1588 FunctionValueCache &value_maker,
1589 FunctionValueCache &entry_instruction_finder,
1590 lldb_private::Stream &error_stream) {
1591 SmallVector<User *, 16> users;
1592
1593 // We do this because the use list might change, invalidating our iterator.
1594 // Much better to keep a work list ourselves.
1595 for (llvm::User *u : old_constant->users())
1596 users.push_back(u);
1597
1598 for (size_t i = 0; i < users.size(); ++i) {
1599 User *user = users[i];
1600
1601 if (Constant *constant = dyn_cast<Constant>(user)) {
1602 // synthesize a new non-constant equivalent of the constant
1603
1604 if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1605 switch (constant_expr->getOpcode()) {
1606 default:
1607 error_stream.Printf("error [IRForTarget internal]: Unhandled "
1608 "constant expression type: \"%s\"",
1609 PrintValue(constant_expr).c_str());
1610 return false;
1611 case Instruction::BitCast: {
1612 FunctionValueCache bit_cast_maker(
1613 [&value_maker, &entry_instruction_finder, old_constant,
1614 constant_expr](llvm::Function *function) -> llvm::Value * {
1615 // UnaryExpr
1616 // OperandList[0] is value
1617
1618 if (constant_expr->getOperand(0) != old_constant)
1619 return constant_expr;
1620
1621 return new BitCastInst(
1622 value_maker.GetValue(function), constant_expr->getType(),
1623 "", llvm::cast<Instruction>(
1624 entry_instruction_finder.GetValue(function)));
1625 });
1626
1627 if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1628 entry_instruction_finder, error_stream))
1629 return false;
1630 } break;
1631 case Instruction::GetElementPtr: {
1632 // GetElementPtrConstantExpr
1633 // OperandList[0] is base
1634 // OperandList[1]... are indices
1635
1636 FunctionValueCache get_element_pointer_maker(
1637 [&value_maker, &entry_instruction_finder, old_constant,
1638 constant_expr](llvm::Function *function) -> llvm::Value * {
1639 Value *ptr = constant_expr->getOperand(0);
1640
1641 if (ptr == old_constant)
1642 ptr = value_maker.GetValue(function);
1643
1644 std::vector<Value *> index_vector;
1645
1646 unsigned operand_index;
1647 unsigned num_operands = constant_expr->getNumOperands();
1648
1649 for (operand_index = 1; operand_index < num_operands;
1650 ++operand_index) {
1651 Value *operand = constant_expr->getOperand(operand_index);
1652
1653 if (operand == old_constant)
1654 operand = value_maker.GetValue(function);
1655
1656 index_vector.push_back(operand);
1657 }
1658
1659 ArrayRef<Value *> indices(index_vector);
1660
1661 return GetElementPtrInst::Create(
1662 nullptr, ptr, indices, "",
1663 llvm::cast<Instruction>(
1664 entry_instruction_finder.GetValue(function)));
1665 });
1666
1667 if (!UnfoldConstant(constant_expr, llvm_function,
1668 get_element_pointer_maker,
1669 entry_instruction_finder, error_stream))
1670 return false;
1671 } break;
1672 }
1673 } else {
1674 error_stream.Printf(
1675 "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1676 PrintValue(constant).c_str());
1677 return false;
1678 }
1679 } else {
1680 if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1681 if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1682 error_stream.PutCString("error: Capturing non-local variables in "
1683 "expressions is unsupported.\n");
1684 return false;
1685 }
1686 inst->replaceUsesOfWith(
1687 old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1688 } else {
1689 error_stream.Printf(
1690 "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1691 PrintValue(user).c_str());
1692 return false;
1693 }
1694 }
1695 }
1696
1697 if (!isa<GlobalValue>(old_constant)) {
1698 old_constant->destroyConstant();
1699 }
1700
1701 return true;
1702}
1703
1704bool IRForTarget::ReplaceVariables(Function &llvm_function) {
1705 if (!m_resolve_vars)
1706 return true;
1707
1708 lldb_private::Log *log(
1709 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1710
1711 m_decl_map->DoStructLayout();
1712
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001713 LLDB_LOG(log, "Element arrangement:");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001714
1715 uint32_t num_elements;
1716 uint32_t element_index;
1717
1718 size_t size;
1719 lldb::offset_t alignment;
1720
1721 if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1722 return false;
1723
Reid Kleckner20670ba2017-03-16 23:13:49 +00001724 Function::arg_iterator iter(llvm_function.arg_begin());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001725
Reid Kleckner20670ba2017-03-16 23:13:49 +00001726 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001727 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1728 "arguments (should take at least a struct pointer)");
1729
1730 return false;
1731 }
1732
1733 Argument *argument = &*iter;
1734
1735 if (argument->getName().equals("this")) {
1736 ++iter;
1737
Reid Kleckner20670ba2017-03-16 23:13:49 +00001738 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001739 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1740 "'this' argument (should take a struct pointer "
1741 "too)");
1742
1743 return false;
1744 }
1745
1746 argument = &*iter;
1747 } else if (argument->getName().equals("self")) {
1748 ++iter;
1749
Reid Kleckner20670ba2017-03-16 23:13:49 +00001750 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001751 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1752 "'self' argument (should take '_cmd' and a struct "
1753 "pointer too)");
1754
1755 return false;
1756 }
1757
1758 if (!iter->getName().equals("_cmd")) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001759 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
Kate Stoneb9c1b512016-09-06 20:57:50 +00001760 "after 'self' argument (should take '_cmd')",
Raphael Isemanna7040522019-08-08 21:43:21 +00001761 iter->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762
1763 return false;
1764 }
1765
1766 ++iter;
1767
Reid Kleckner20670ba2017-03-16 23:13:49 +00001768 if (iter == llvm_function.arg_end()) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001769 m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1770 "'self' and '_cmd' arguments (should take a struct "
1771 "pointer too)");
1772
1773 return false;
1774 }
1775
1776 argument = &*iter;
1777 }
1778
1779 if (!argument->getName().equals("$__lldb_arg")) {
Raphael Isemanna7040522019-08-08 21:43:21 +00001780 m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
1781 "argument named '{0}' instead of the struct pointer",
1782 argument->getName());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001783
1784 return false;
1785 }
1786
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001787 LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001788
1789 BasicBlock &entry_block(llvm_function.getEntryBlock());
1790 Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1791
1792 if (!FirstEntryInstruction) {
1793 m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1794 "first instruction in the wrapper for use in "
1795 "rewriting");
1796
1797 return false;
1798 }
1799
1800 LLVMContext &context(m_module->getContext());
1801 IntegerType *offset_type(Type::getInt32Ty(context));
1802
1803 if (!offset_type) {
1804 m_error_stream.Printf(
1805 "Internal error [IRForTarget]: Couldn't produce an offset type");
1806
1807 return false;
1808 }
1809
1810 for (element_index = 0; element_index < num_elements; ++element_index) {
Konrad Kleine248a1302019-05-23 11:14:47 +00001811 const clang::NamedDecl *decl = nullptr;
1812 Value *value = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001813 lldb::offset_t offset;
1814 lldb_private::ConstString name;
1815
1816 if (!m_decl_map->GetStructElement(decl, value, offset, name,
1817 element_index)) {
1818 m_error_stream.Printf(
1819 "Internal error [IRForTarget]: Structure information is incomplete");
1820
1821 return false;
1822 }
1823
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001824 LLDB_LOG(log, " \"{0}\" (\"{1}\") placed at {2}", name,
1825 decl->getNameAsString(), offset);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001826
1827 if (value) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001828 LLDB_LOG(log, " Replacing [{0}]", PrintValue(value));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001829
1830 FunctionValueCache body_result_maker(
1831 [this, name, offset_type, offset, argument,
1832 value](llvm::Function *function) -> llvm::Value * {
Adrian Prantl05097242018-04-30 16:49:04 +00001833 // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
1834 // in cases where the result variable is an rvalue, we have to
1835 // synthesize a dereference of the appropriate structure entry in
1836 // order to produce the static variable that the AST thinks it is
1837 // accessing.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001838
1839 llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1840 m_entry_instruction_finder.GetValue(function));
1841
1842 ConstantInt *offset_int(
1843 ConstantInt::get(offset_type, offset, true));
1844 GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1845 nullptr, argument, offset_int, "", entry_instruction);
1846
1847 if (name == m_result_name && !m_result_is_pointer) {
1848 BitCastInst *bit_cast = new BitCastInst(
1849 get_element_ptr, value->getType()->getPointerTo(), "",
1850 entry_instruction);
1851
1852 LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1853
1854 return load;
1855 } else {
1856 BitCastInst *bit_cast = new BitCastInst(
1857 get_element_ptr, value->getType(), "", entry_instruction);
1858
1859 return bit_cast;
1860 }
1861 });
1862
1863 if (Constant *constant = dyn_cast<Constant>(value)) {
1864 if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
1865 m_entry_instruction_finder, m_error_stream)) {
1866 return false;
1867 }
1868 } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1869 if (instruction->getParent()->getParent() != &llvm_function) {
1870 m_error_stream.PutCString("error: Capturing non-local variables in "
1871 "expressions is unsupported.\n");
1872 return false;
1873 }
1874 value->replaceAllUsesWith(
1875 body_result_maker.GetValue(instruction->getParent()->getParent()));
1876 } else {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001877 LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
1878 PrintValue(value));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001879 return false;
1880 }
1881
1882 if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1883 var->eraseFromParent();
1884 }
1885 }
1886
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001887 LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
1888 (uint64_t)size);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001889
1890 return true;
1891}
1892
Kate Stoneb9c1b512016-09-06 20:57:50 +00001893bool IRForTarget::runOnModule(Module &llvm_module) {
1894 lldb_private::Log *log(
1895 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1896
1897 m_module = &llvm_module;
1898 m_target_data.reset(new DataLayout(m_module));
1899 m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
1900 m_target_data->getPointerSizeInBits());
1901
1902 if (log) {
1903 std::string s;
1904 raw_string_ostream oss(s);
1905
Konrad Kleine248a1302019-05-23 11:14:47 +00001906 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001907
1908 oss.flush();
1909
Raphael Isemanna7040522019-08-08 21:43:21 +00001910 LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001911 }
1912
1913 Function *const main_function =
1914 m_func_name.IsEmpty() ? nullptr
1915 : m_module->getFunction(m_func_name.GetStringRef());
1916
1917 if (!m_func_name.IsEmpty() && !main_function) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001918 LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001919
Raphael Isemanna7040522019-08-08 21:43:21 +00001920 m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
1921 "'{0}' in the module",
1922 m_func_name);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001923
1924 return false;
1925 }
1926
1927 if (main_function) {
1928 if (!FixFunctionLinkage(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001929 LLDB_LOG(log, "Couldn't fix the linkage for the function");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001930
1931 return false;
1932 }
1933 }
1934
1935 llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
1936
1937 m_reloc_placeholder = new llvm::GlobalVariable(
1938 (*m_module), int8_ty, false /* IsConstant */,
1939 GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
Konrad Kleine248a1302019-05-23 11:14:47 +00001940 "reloc_placeholder", nullptr /* InsertBefore */,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001941 GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
1942
1943 ////////////////////////////////////////////////////////////
1944 // Replace $__lldb_expr_result with a persistent variable
1945 //
1946
1947 if (main_function) {
1948 if (!CreateResultVariable(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001949 LLDB_LOG(log, "CreateResultVariable() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001950
1951 // CreateResultVariable() reports its own errors, so we don't do so here
1952
1953 return false;
1954 }
1955 }
1956
1957 if (log && log->GetVerbose()) {
1958 std::string s;
1959 raw_string_ostream oss(s);
1960
Konrad Kleine248a1302019-05-23 11:14:47 +00001961 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001962
1963 oss.flush();
1964
Raphael Isemanna7040522019-08-08 21:43:21 +00001965 LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001966 }
1967
Raphael Isemanndced4452019-08-09 07:59:18 +00001968 for (llvm::Function &function : *m_module) {
1969 for (BasicBlock &bb : function) {
1970 if (!RemoveGuards(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001971 LLDB_LOG(log, "RemoveGuards() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001972
1973 // RemoveGuards() reports its own errors, so we don't do so here
1974
1975 return false;
1976 }
1977
Raphael Isemanndced4452019-08-09 07:59:18 +00001978 if (!RewritePersistentAllocs(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001979 LLDB_LOG(log, "RewritePersistentAllocs() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001980
1981 // RewritePersistentAllocs() reports its own errors, so we don't do so
1982 // here
1983
1984 return false;
1985 }
1986
Raphael Isemanndced4452019-08-09 07:59:18 +00001987 if (!RemoveCXAAtExit(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00001988 LLDB_LOG(log, "RemoveCXAAtExit() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001989
1990 // RemoveCXAAtExit() reports its own errors, so we don't do so here
1991
1992 return false;
1993 }
1994 }
1995 }
1996
1997 ///////////////////////////////////////////////////////////////////////////////
1998 // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
1999 //
2000
2001 if (!RewriteObjCConstStrings()) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00002002 LLDB_LOG(log, "RewriteObjCConstStrings() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002003
2004 // RewriteObjCConstStrings() reports its own errors, so we don't do so here
2005
2006 return false;
2007 }
2008
Raphael Isemanndced4452019-08-09 07:59:18 +00002009 for (llvm::Function &function : *m_module) {
2010 for (llvm::BasicBlock &bb : function) {
2011 if (!RewriteObjCSelectors(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00002012 LLDB_LOG(log, "RewriteObjCSelectors() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002013
Adrian Prantl05097242018-04-30 16:49:04 +00002014 // RewriteObjCSelectors() reports its own errors, so we don't do so
2015 // here
Kate Stoneb9c1b512016-09-06 20:57:50 +00002016
2017 return false;
2018 }
Sean Callananac900582016-09-29 00:45:33 +00002019
Raphael Isemanndced4452019-08-09 07:59:18 +00002020 if (!RewriteObjCClassReferences(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00002021 LLDB_LOG(log, "RewriteObjCClassReferences() failed");
Sean Callananac900582016-09-29 00:45:33 +00002022
2023 // RewriteObjCClasses() reports its own errors, so we don't do so here
2024
2025 return false;
2026 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002027 }
2028 }
2029
Raphael Isemanndced4452019-08-09 07:59:18 +00002030 for (llvm::Function &function : *m_module) {
2031 for (BasicBlock &bb : function) {
2032 if (!ResolveCalls(bb)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00002033 LLDB_LOG(log, "ResolveCalls() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002034
2035 // ResolveCalls() reports its own errors, so we don't do so here
2036
2037 return false;
2038 }
2039 }
2040 }
2041
2042 ////////////////////////////////////////////////////////////////////////
2043 // Run function-level passes that only make sense on the main function
2044 //
2045
2046 if (main_function) {
2047 if (!ResolveExternals(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00002048 LLDB_LOG(log, "ResolveExternals() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002049
2050 // ResolveExternals() reports its own errors, so we don't do so here
2051
2052 return false;
2053 }
2054
2055 if (!ReplaceVariables(*main_function)) {
Raphael Isemann4ef50a32019-08-09 08:54:01 +00002056 LLDB_LOG(log, "ReplaceVariables() failed");
Kate Stoneb9c1b512016-09-06 20:57:50 +00002057
2058 // ReplaceVariables() reports its own errors, so we don't do so here
2059
2060 return false;
2061 }
2062 }
2063
2064 if (log && log->GetVerbose()) {
2065 std::string s;
2066 raw_string_ostream oss(s);
2067
Konrad Kleine248a1302019-05-23 11:14:47 +00002068 m_module->print(oss, nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002069
2070 oss.flush();
2071
Raphael Isemanna7040522019-08-08 21:43:21 +00002072 LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002073 }
2074
2075 return true;
2076}
2077
2078void IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2079 PassManagerType pass_mgr_type) {}
2080
2081PassManagerType IRForTarget::getPotentialPassManagerType() const {
2082 return PMT_ModulePassManager;
Sean Callanan2ab712f22010-07-03 01:35:46 +00002083}