1254721Semaste//===-- ABI.cpp -------------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Target/ABI.h"
11254721Semaste#include "lldb/Core/PluginManager.h"
12254721Semaste#include "lldb/Core/Value.h"
13254721Semaste#include "lldb/Core/ValueObjectConstResult.h"
14254721Semaste#include "lldb/Symbol/ClangASTType.h"
15254721Semaste#include "lldb/Target/Target.h"
16254721Semaste#include "lldb/Target/Thread.h"
17254721Semaste
18254721Semasteusing namespace lldb;
19254721Semasteusing namespace lldb_private;
20254721Semaste
21254721SemasteABISP
22254721SemasteABI::FindPlugin (const ArchSpec &arch)
23254721Semaste{
24254721Semaste    ABISP abi_sp;
25254721Semaste    ABICreateInstance create_callback;
26254721Semaste
27254721Semaste    for (uint32_t idx = 0;
28254721Semaste         (create_callback = PluginManager::GetABICreateCallbackAtIndex(idx)) != NULL;
29254721Semaste         ++idx)
30254721Semaste    {
31254721Semaste        abi_sp = create_callback(arch);
32254721Semaste
33254721Semaste        if (abi_sp)
34254721Semaste            return abi_sp;
35254721Semaste    }
36254721Semaste    abi_sp.reset();
37254721Semaste    return abi_sp;
38254721Semaste}
39254721Semaste
40254721Semaste//----------------------------------------------------------------------
41254721Semaste// Constructor
42254721Semaste//----------------------------------------------------------------------
43254721SemasteABI::ABI()
44254721Semaste{
45254721Semaste}
46254721Semaste
47254721Semaste//----------------------------------------------------------------------
48254721Semaste// Destructor
49254721Semaste//----------------------------------------------------------------------
50254721SemasteABI::~ABI()
51254721Semaste{
52254721Semaste}
53254721Semaste
54254721Semaste
55254721Semastebool
56254721SemasteABI::GetRegisterInfoByName (const ConstString &name, RegisterInfo &info)
57254721Semaste{
58254721Semaste    uint32_t count = 0;
59254721Semaste    const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
60254721Semaste    if (register_info_array)
61254721Semaste    {
62254721Semaste        const char *unique_name_cstr = name.GetCString();
63254721Semaste        uint32_t i;
64254721Semaste        for (i=0; i<count; ++i)
65254721Semaste        {
66254721Semaste            if (register_info_array[i].name == unique_name_cstr)
67254721Semaste            {
68254721Semaste                info = register_info_array[i];
69254721Semaste                return true;
70254721Semaste            }
71254721Semaste        }
72254721Semaste        for (i=0; i<count; ++i)
73254721Semaste        {
74254721Semaste            if (register_info_array[i].alt_name == unique_name_cstr)
75254721Semaste            {
76254721Semaste                info = register_info_array[i];
77254721Semaste                return true;
78254721Semaste            }
79254721Semaste        }
80254721Semaste    }
81254721Semaste    return false;
82254721Semaste}
83254721Semaste
84254721Semastebool
85254721SemasteABI::GetRegisterInfoByKind (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo &info)
86254721Semaste{
87254721Semaste    if (reg_kind < eRegisterKindGCC || reg_kind >= kNumRegisterKinds)
88254721Semaste        return false;
89254721Semaste
90254721Semaste    uint32_t count = 0;
91254721Semaste    const RegisterInfo *register_info_array = GetRegisterInfoArray (count);
92254721Semaste    if (register_info_array)
93254721Semaste    {
94254721Semaste        for (uint32_t i=0; i<count; ++i)
95254721Semaste        {
96254721Semaste            if (register_info_array[i].kinds[reg_kind] == reg_num)
97254721Semaste            {
98254721Semaste                info = register_info_array[i];
99254721Semaste                return true;
100254721Semaste            }
101254721Semaste        }
102254721Semaste    }
103254721Semaste    return false;
104254721Semaste}
105254721Semaste
106254721SemasteValueObjectSP
107254721SemasteABI::GetReturnValueObject (Thread &thread,
108254721Semaste                           ClangASTType &ast_type,
109254721Semaste                           bool persistent) const
110254721Semaste{
111254721Semaste    if (!ast_type.IsValid())
112254721Semaste        return ValueObjectSP();
113254721Semaste
114254721Semaste    ValueObjectSP return_valobj_sp;
115254721Semaste
116254721Semaste    return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
117254721Semaste    if (!return_valobj_sp)
118254721Semaste        return return_valobj_sp;
119254721Semaste
120254721Semaste    // Now turn this into a persistent variable.
121254721Semaste    // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple
122254721Semaste    // of other places.  Figure out the correct Create function to do all this work.
123254721Semaste
124254721Semaste    if (persistent)
125254721Semaste    {
126254721Semaste        ClangPersistentVariables& persistent_variables = thread.CalculateTarget()->GetPersistentVariables();
127254721Semaste        ConstString persistent_variable_name (persistent_variables.GetNextPersistentVariableName());
128254721Semaste
129254721Semaste        lldb::ValueObjectSP const_valobj_sp;
130254721Semaste
131254721Semaste        // Check in case our value is already a constant value
132254721Semaste        if (return_valobj_sp->GetIsConstant())
133254721Semaste        {
134254721Semaste            const_valobj_sp = return_valobj_sp;
135254721Semaste            const_valobj_sp->SetName (persistent_variable_name);
136254721Semaste        }
137254721Semaste        else
138254721Semaste            const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name);
139254721Semaste
140254721Semaste        lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;
141254721Semaste
142254721Semaste        return_valobj_sp = const_valobj_sp;
143254721Semaste
144254721Semaste        ClangExpressionVariableSP clang_expr_variable_sp(persistent_variables.CreatePersistentVariable(return_valobj_sp));
145254721Semaste
146254721Semaste        assert (clang_expr_variable_sp.get());
147254721Semaste
148254721Semaste        // Set flags and live data as appropriate
149254721Semaste
150254721Semaste        const Value &result_value = live_valobj_sp->GetValue();
151254721Semaste
152254721Semaste        switch (result_value.GetValueType())
153254721Semaste        {
154254721Semaste        case Value::eValueTypeHostAddress:
155254721Semaste        case Value::eValueTypeFileAddress:
156254721Semaste            // we don't do anything with these for now
157254721Semaste            break;
158254721Semaste        case Value::eValueTypeScalar:
159254721Semaste        case Value::eValueTypeVector:
160254721Semaste            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
161254721Semaste            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
162254721Semaste            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
163254721Semaste            break;
164254721Semaste        case Value::eValueTypeLoadAddress:
165254721Semaste            clang_expr_variable_sp->m_live_sp = live_valobj_sp;
166254721Semaste            clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
167254721Semaste            break;
168254721Semaste        }
169254721Semaste
170254721Semaste        return_valobj_sp = clang_expr_variable_sp->GetValueObject();
171254721Semaste    }
172254721Semaste    return return_valobj_sp;
173254721Semaste}
174254721Semaste
175254721Semaste
176