1830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//===-- ClangUserExpression.cpp -------------------------------------*- C++ -*-===// 2830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// 3830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// The LLVM Compiler Infrastructure 4830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// 5830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// This file is distributed under the University of Illinois Open Source 6830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// License. See LICENSE.TXT for details. 7830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// 8830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//===----------------------------------------------------------------------===// 9830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 10830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// C Includes 11830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include <stdio.h> 12830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#if HAVE_SYS_TYPES_H 13830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan# include <sys/types.h> 14830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#endif 15830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 16830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan// C++ Includes 17830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 18830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Core/ConstString.h" 19c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan#include "lldb/Core/Log.h" 20830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Core/Stream.h" 21c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#include "lldb/Core/StreamFile.h" 22e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h" 23830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Expression/ClangExpressionParser.h" 24830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Expression/ClangUtilityFunction.h" 258459ba986e7ddd1539b046648680f2283fde8304Greg Clayton#include "lldb/Expression/ExpressionSourceCode.h" 2681a96aa6242f7b559770f5dc62316253cb8cb0d4Greg Clayton#include "lldb/Expression/IRExecutionUnit.h" 27830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Host/Host.h" 28830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Target/ExecutionContext.h" 29830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan#include "lldb/Target/Target.h" 30830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 31830a903fd7cd4595cf52e1630b6491930ada0400Sean Callananusing namespace lldb_private; 32830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 33830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------ 34830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// Constructor 35830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// 36830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] text 37830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// The text of the function. Must be a full translation unit. 38830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// 39830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] name 40830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// The name of the function, as used in the text. 41830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------ 42830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUtilityFunction::ClangUtilityFunction (const char *text, 43830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan const char *name) : 44d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton ClangExpression (), 458459ba986e7ddd1539b046648680f2283fde8304Greg Clayton m_function_text (ExpressionSourceCode::g_expression_prefix), 46d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton m_function_name (name) 47830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan{ 48ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton if (text && text[0]) 49ce490e3161b17c3f2904d6e797bb5e5517d651c2Greg Clayton m_function_text.append (text); 50830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan} 51830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 526a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg ClaytonClangUtilityFunction::~ClangUtilityFunction () 536a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Clayton{ 546a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Clayton} 556a5aa8ab240a13f397e3e09f2ca1ea3f16b451c2Greg Clayton 56830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------ 57830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// Install the utility function into a process 58830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// 59830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] error_stream 60830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// A stream to print parse errors and warnings to. 61830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// 62830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @param[in] exe_ctx 63830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// The execution context to install the utility function to. 64830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// 65830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// @return 66830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan/// True on success (no errors); false otherwise. 67830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan//------------------------------------------------------------------ 68830a903fd7cd4595cf52e1630b6491930ada0400Sean Callananbool 69830a903fd7cd4595cf52e1630b6491930ada0400Sean CallananClangUtilityFunction::Install (Stream &error_stream, 70830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan ExecutionContext &exe_ctx) 71f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan{ 72d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton if (m_jit_start_addr != LLDB_INVALID_ADDRESS) 73f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan { 74f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan error_stream.PutCString("error: already installed\n"); 75f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan return false; 76f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan } 77f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan 78830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan //////////////////////////////////// 79830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan // Set up the target and compiler 80830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan // 81830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 82567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 83830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 84830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan if (!target) 85830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan { 86830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan error_stream.PutCString ("error: invalid target\n"); 87830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan return false; 88830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan } 89c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 90567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 91c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 92c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan if (!process) 93c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan { 94c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan error_stream.PutCString ("error: invalid process\n"); 95c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan return false; 96c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan } 97395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton 98830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan ////////////////////////// 99830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan // Parse the expression 100830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan // 101e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 1026a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan bool keep_result_in_memory = false; 1036a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan 10473b520f4f60dca58e58e446c9504d45384ee677bSean Callanan m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx)); 105aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan 1063b16eb9d424068446fea9cd0e0fe5e7d435f5b6eSean Callanan if (!m_expr_decl_map->WillParse(exe_ctx, NULL)) 107166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan { 108166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n"); 109166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan return false; 110166ba106f9d8c377f2fda72112c821550d2e82d1Sean Callanan } 111830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 112395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton ClangExpressionParser parser(exe_ctx.GetBestExecutionContextScope(), *this); 113830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 114830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan unsigned num_errors = parser.Parse (error_stream); 115830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 116830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan if (num_errors) 117830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan { 118830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan error_stream.Printf ("error: %d errors parsing expression\n", num_errors); 119e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 120e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan m_expr_decl_map.reset(); 121e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 122830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan return false; 123830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan } 124830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 125830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan ////////////////////////////////// 126830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan // JIT the output of the parser 127830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan // 1280f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan 1290f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan bool can_interpret = false; // should stay that way 13047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan 1311cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan Error jit_error = parser.PrepareForExecution (m_jit_start_addr, 1329e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan m_jit_end_addr, 1339e6f6a6f394bb570c5f1f9a850ec0befe4a59fefSean Callanan m_execution_unit_ap, 13447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan exe_ctx, 1350f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan can_interpret, 13647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan eExecutionPolicyAlways); 137c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan 138567e7f3ba16eb48cb9fd6a2f26f2f7269eb6983cGreg Clayton if (m_jit_start_addr != LLDB_INVALID_ADDRESS) 1397adfcfdb46018d16393995276699a04505727808Enrico Granata m_jit_process_wp = lldb::ProcessWP(process->shared_from_this()); 140830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 141c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#if 0 142c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton // jingham: look here 143c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton StreamFile logfile ("/tmp/exprs.txt", "a"); 1445f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea logfile.Printf ("0x%16.16" PRIx64 ": func = %s, source =\n%s\n", 145d0882d062a09effb7a22ce81cb327e9b9fa108bdGreg Clayton m_jit_start_addr, 146c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton m_function_name.c_str(), 147c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton m_function_text.c_str()); 148c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton#endif 149c71899ef308e6134d1b0ca5f30cbc64414855e1aGreg Clayton 150aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan m_expr_decl_map->DidParse(); 151aa301c49e8b31f01c551cffbaa74c8ba82851a79Sean Callanan 152e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan m_expr_decl_map.reset(); 153e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan 154830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan if (jit_error.Success()) 155830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan { 156830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan return true; 157830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan } 158830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan else 159830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan { 1603058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton const char *error_cstr = jit_error.AsCString(); 1613058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton if (error_cstr && error_cstr[0]) 1623058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton error_stream.Printf ("error: %s\n", error_cstr); 1633058197753e56a7ea9f4c5784e460a3b977d7bd0Greg Clayton else 1647e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda error_stream.Printf ("error: expression can't be interpreted or run\n"); 165830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan return false; 166830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan } 167830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan} 168830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 169830a903fd7cd4595cf52e1630b6491930ada0400Sean Callanan 170