147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//===-- IRInterpreter.cpp ---------------------------------------*- C++ -*-===//
247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//
347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//                     The LLVM Compiler Infrastructure
447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//
547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan// This file is distributed under the University of Illinois Open Source
647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan// License. See LICENSE.TXT for details.
747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//
847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//===----------------------------------------------------------------------===//
947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
107f27bcc0624ba4a43e87b4d9803c9aa1bbd0e2d9Sean Callanan#include "lldb/Core/DataExtractor.h"
117f27bcc0624ba4a43e87b4d9803c9aa1bbd0e2d9Sean Callanan#include "lldb/Core/Error.h"
1247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include "lldb/Core/Log.h"
137f27bcc0624ba4a43e87b4d9803c9aa1bbd0e2d9Sean Callanan#include "lldb/Core/Scalar.h"
147f27bcc0624ba4a43e87b4d9803c9aa1bbd0e2d9Sean Callanan#include "lldb/Core/StreamString.h"
157f27bcc0624ba4a43e87b4d9803c9aa1bbd0e2d9Sean Callanan#include "lldb/Expression/IRMemoryMap.h"
1647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include "lldb/Expression/IRInterpreter.h"
1747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
18a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Constants.h"
197f27bcc0624ba4a43e87b4d9803c9aa1bbd0e2d9Sean Callanan#include "llvm/IR/DataLayout.h"
20a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Function.h"
21a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Instructions.h"
22a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Module.h"
2347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include "llvm/Support/raw_ostream.h"
2447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
2547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include <map>
2647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
2747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callananusing namespace llvm;
2847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
2947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callananstatic std::string
3047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananPrintValue(const Value *value, bool truncate = false)
3147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan{
3247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    std::string s;
3347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    raw_string_ostream rso(s);
3447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    value->print(rso);
3547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    rso.flush();
3647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    if (truncate)
3747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        s.resize(s.length() - 1);
3847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
3947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    size_t offset;
4047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    while ((offset = s.find('\n')) != s.npos)
4147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        s.erase(offset, 1);
4247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    while (s[0] == ' ' || s[0] == '\t')
4347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        s.erase(0, 1);
4447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
4547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    return s;
4647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan}
4747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
4847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callananstatic std::string
4947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananPrintType(const Type *type, bool truncate = false)
5047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan{
5147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    std::string s;
5247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    raw_string_ostream rso(s);
5347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    type->print(rso);
5447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    rso.flush();
5547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    if (truncate)
5647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        s.resize(s.length() - 1);
5747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    return s;
5847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan}
5947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
6013615cfef0435af28ccc1e93e13c6161e94585edSean Callananclass InterpreterStackFrame
6147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan{
6247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callananpublic:
6313615cfef0435af28ccc1e93e13c6161e94585edSean Callanan    typedef std::map <const Value*, lldb::addr_t> ValueMap;
6447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
6547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    ValueMap                                m_values;
663051ed73a487e92f12f8b6062f8415781453da21Micah Villmow    DataLayout                             &m_target_data;
6786d6ac2a3d920622c1ee7a68b5ca28b09dc18142Sean Callanan    lldb_private::IRMemoryMap              &m_memory_map;
6847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    const BasicBlock                       *m_bb;
6947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    BasicBlock::const_iterator              m_ii;
7047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    BasicBlock::const_iterator              m_ie;
7147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
720f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    lldb::addr_t                            m_frame_process_address;
730f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    size_t                                  m_frame_size;
740f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    lldb::addr_t                            m_stack_pointer;
750f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
7647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    lldb::ByteOrder                         m_byte_order;
7747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    size_t                                  m_addr_byte_size;
7847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
793051ed73a487e92f12f8b6062f8415781453da21Micah Villmow    InterpreterStackFrame (DataLayout &target_data,
80cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                           lldb_private::IRMemoryMap &memory_map,
81cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                           lldb::addr_t stack_frame_bottom,
82cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan                           lldb::addr_t stack_frame_top) :
8397c8957257a3e0b3ce6f46f8e5a28c965e30f357Daniel Dunbar        m_target_data (target_data),
8486d6ac2a3d920622c1ee7a68b5ca28b09dc18142Sean Callanan        m_memory_map (memory_map)
8547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    {
8647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        m_byte_order = (target_data.isLittleEndian() ? lldb::eByteOrderLittle : lldb::eByteOrderBig);
874fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan        m_addr_byte_size = (target_data.getPointerSize(0));
88cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan
89cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        m_frame_process_address = stack_frame_bottom;
90cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        m_frame_size = stack_frame_top - stack_frame_bottom;
91cdc3ea5398f251d3eca482595f103b1874e51538Sean Callanan        m_stack_pointer = stack_frame_top;
920f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    }
930f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
940f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    ~InterpreterStackFrame ()
950f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    {
9647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    }
9747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
9847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    void Jump (const BasicBlock *bb)
9947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    {
10047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        m_bb = bb;
10147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        m_ii = m_bb->begin();
10247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        m_ie = m_bb->end();
10347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    }
10447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
10547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    std::string SummarizeValue (const Value *value)
10647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    {
10747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        lldb_private::StreamString ss;
10847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
10947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        ss.Printf("%s", PrintValue(value).c_str());
11047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
11147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        ValueMap::iterator i = m_values.find(value);
11247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
11347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        if (i != m_values.end())
11447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        {
11513615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            lldb::addr_t addr = i->second;
11647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
11713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            ss.Printf(" 0x%llx", (unsigned long long)addr);
11847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        }
11947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
12047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        return ss.GetString();
12147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    }
12247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
12347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    bool AssignToMatchType (lldb_private::Scalar &scalar, uint64_t u64value, Type *type)
12447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    {
12547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        size_t type_size = m_target_data.getTypeStoreSize(type);
12647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
12747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        switch (type_size)
12847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        {
12947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        case 1:
13047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            scalar = (uint8_t)u64value;
13147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            break;
13247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        case 2:
13347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            scalar = (uint16_t)u64value;
13447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            break;
13547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        case 4:
13647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            scalar = (uint32_t)u64value;
13747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            break;
13847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        case 8:
13947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            scalar = (uint64_t)u64value;
14047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            break;
14147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        default:
14247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan            return false;
14347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        }
14447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
14547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        return true;
14647dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    }
14747dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
14847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    bool EvaluateValue (lldb_private::Scalar &scalar, const Value *value, Module &module)
14947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    {
15047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        const Constant *constant = dyn_cast<Constant>(value);
15147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
15247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        if (constant)
15347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        {
154a45d2e2806cfa1e5b0189df96f069c137278fd46Sean Callanan            APInt value_apint;
155a45d2e2806cfa1e5b0189df96f069c137278fd46Sean Callanan
156a45d2e2806cfa1e5b0189df96f069c137278fd46Sean Callanan            if (!ResolveConstantValue(value_apint, constant))
157a45d2e2806cfa1e5b0189df96f069c137278fd46Sean Callanan                return false;
158a45d2e2806cfa1e5b0189df96f069c137278fd46Sean Callanan
159a45d2e2806cfa1e5b0189df96f069c137278fd46Sean Callanan            return AssignToMatchType(scalar, value_apint.getLimitedValue(), value->getType());
16047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        }
16147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        else
16247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        {
16313615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            lldb::addr_t process_address = ResolveValue(value, module);
16413615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            size_t value_size = m_target_data.getTypeStoreSize(value->getType());
16513615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
16613615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            lldb_private::DataExtractor value_extractor;
16713615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            lldb_private::Error extract_error;
16847dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
16913615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            m_memory_map.GetMemoryData(value_extractor, process_address, value_size, extract_error);
17013615cfef0435af28ccc1e93e13c6161e94585edSean Callanan
17113615cfef0435af28ccc1e93e13c6161e94585edSean Callanan            if (!extract_error.Success())
17247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan                return false;
17347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
17436da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton            lldb::offset_t offset = 0;
175d39de039f8beb6496ab3a7a485d0dcf1ce19f2baSean Callanan            if (value_size == 1 || value_size == 2 || value_size == 4 || value_size == 8)
176cd3ba2dd2757fa3de8aba0ba9ba4614055eb0ec3Greg Clayton            {
177cd3ba2dd2757fa3de8aba0ba9ba4614055eb0ec3Greg Clayton                uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size);
178cd3ba2dd2757fa3de8aba0ba9ba4614055eb0ec3Greg Clayton                return AssignToMatchType(scalar, u64value, value->getType());
179cd3ba2dd2757fa3de8aba0ba9ba4614055eb0ec3Greg Clayton            }
18047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        }
18147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
18247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        return false;
18347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    }
18447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
18547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    bool AssignValue (const Value *value, lldb_private::Scalar &scalar, Module &