Skip to content
IRInterpreter.cpp 64.9 KiB
Newer Older
//===-- IRInterpreter.cpp ---------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/DataEncoder.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/ClangExpressionVariable.h"
#include "lldb/Expression/IRForTarget.h"
#include "lldb/Expression/IRInterpreter.h"

#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/DataLayout.h"

#include <map>

using namespace llvm;

IRInterpreter::IRInterpreter(lldb_private::ClangExpressionDeclMap &decl_map,
                                           lldb_private::Stream *error_stream) :
    m_decl_map(decl_map),
    m_error_stream(error_stream)
{
    
}

IRInterpreter::~IRInterpreter()
{
    
}

static std::string 
PrintValue(const Value *value, bool truncate = false)
{
    std::string s;
    raw_string_ostream rso(s);
    value->print(rso);
    rso.flush();
    if (truncate)
        s.resize(s.length() - 1);
    
    size_t offset;
    while ((offset = s.find('\n')) != s.npos)
        s.erase(offset, 1);
    while (s[0] == ' ' || s[0] == '\t')
        s.erase(0, 1);
        
    return s;
}

static std::string
PrintType(const Type *type, bool truncate = false)
{
    std::string s;
    raw_string_ostream rso(s);
    type->print(rso);
    rso.flush();
    if (truncate)
        s.resize(s.length() - 1);
    return s;
}

Greg Clayton's avatar
Greg Clayton committed
typedef STD_SHARED_PTR(lldb_private::DataEncoder) DataEncoderSP;
typedef STD_SHARED_PTR(lldb_private::DataExtractor) DataExtractorSP;

class Memory
{
public:
    typedef uint32_t                    index_t;
    
    struct Allocation
    {
        // m_virtual_address is always the address of the variable in the virtual memory
        // space provided by Memory.
        //
        // m_origin is always non-NULL and describes the source of the data (possibly
        // m_data if this allocation is the authoritative source).
        //
        // Possible value configurations:
        //
        // Allocation type  getValueType()          getContextType()            m_origin->GetScalar()       m_data
        // =========================================================================================================================
        // FileAddress      eValueTypeFileAddress   eContextTypeInvalid         A location in a binary      NULL
        //                                                                      image
        //                                                      
        // LoadAddress      eValueTypeLoadAddress   eContextTypeInvalid         A location in the target's  NULL
        //                                                                      virtual memory
        //
        // Alloca           eValueTypeHostAddress   eContextTypeInvalid         == m_data->GetBytes()       Deleted at end of 
        //                                                                                                  execution
        //
        // PersistentVar    eValueTypeHostAddress   eContextTypeClangType       A persistent variable's     NULL
        //                                                                      location in LLDB's memory
        //
        // Register         [ignored]               eContextTypeRegister        [ignored]                   Flushed to the register
        //                                                                                                  at the end of execution
        
        lldb::addr_t        m_virtual_address;
        size_t              m_extent;
        lldb_private::Value m_origin;
        lldb::DataBufferSP  m_data;
        
        Allocation (lldb::addr_t virtual_address,
                    size_t extent,
                    lldb::DataBufferSP data) :
            m_virtual_address(virtual_address),
            m_extent(extent),
            m_data(data)
        {
        }
        
        Allocation (const Allocation &allocation) :
            m_virtual_address(allocation.m_virtual_address),
            m_extent(allocation.m_extent),
            m_origin(allocation.m_origin),
            m_data(allocation.m_data)
        {
        }
    };
    
Greg Clayton's avatar
Greg Clayton committed
    typedef STD_SHARED_PTR(Allocation)  AllocationSP;
    
    struct Region
    {
        AllocationSP m_allocation;
        uint64_t m_base;
        uint64_t m_extent;
        
        Region () :
            m_allocation(),
            m_base(0),
            m_extent(0)
        {
        }
        
        Region (AllocationSP allocation, uint64_t base, uint64_t extent) :
            m_allocation(allocation),
            m_base(base),
            m_extent(extent)
        {
        }
        
        Region (const Region &region) :
            m_allocation(region.m_allocation),
            m_base(region.m_base),
            m_extent(region.m_extent)
        {
        }
        
        bool IsValid ()
        {
            return !m_allocation;
        }
    };
    
    typedef std::vector <AllocationSP>          MemoryMap;

private:
    lldb::addr_t        m_addr_base;
    lldb::addr_t        m_addr_max;
    MemoryMap           m_memory;
    lldb::ByteOrder     m_byte_order;
    lldb::addr_t        m_addr_byte_size;
    DataLayout         &m_target_data;
    
    lldb_private::ClangExpressionDeclMap   &m_decl_map;
    
    MemoryMap::iterator LookupInternal (lldb::addr_t addr)
    {
        for (MemoryMap::iterator i = m_memory.begin(), e = m_memory.end();
             i != e;
             ++i)
        {
            if ((*i)->m_virtual_address <= addr &&
                (*i)->m_virtual_address + (*i)->m_extent > addr)
                return i;
        }
        
        return m_memory.end();
    }
    
public:
    Memory (DataLayout &target_data,
            lldb_private::ClangExpressionDeclMap &decl_map,
            lldb::addr_t alloc_start,
Loading
Loading full blame...