aboutsummaryrefslogtreecommitdiff
path: root/include/lldb/Target/ABI.h
blob: 8809c0047fa0cbc02f1b6dd64d0d448bb9a5c868 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//===-- ABI.h ---------------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef liblldb_ABI_h_
#define liblldb_ABI_h_

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/lldb-private.h"

#include "llvm/ADT/ArrayRef.h"

// forward define the llvm::Type class
namespace llvm { class Type; }

namespace lldb_private {

class ABI :
    public PluginInterface
{
public:
    
    struct CallArgument
    {
        enum eType
        {
            HostPointer = 0,        /* pointer to host data */
            TargetValue ,           /* value is on the target or literal */
        };
        eType  type;                /* value of eType */
        size_t size;                /* size in bytes of this argument */
        union {
            lldb::addr_t  value;    /* literal value */
            uint8_t      *data;     /* host data pointer */
        };
    };

    virtual
    ~ABI();

    virtual size_t
    GetRedZoneSize () const = 0;
    
    virtual bool
    PrepareTrivialCall ( lldb_private::Thread &thread, 
                         lldb::addr_t sp,
                         lldb::addr_t functionAddress,
                         lldb::addr_t returnAddress, 
                         llvm::ArrayRef<lldb::addr_t> args) const = 0;

    // Prepare trivial call used from ThreadPlanFunctionCallGDB
    // AD:
    //  . Because i don't want to change other ABI's this is not declared pure virtual.
    //    The dummy implementation will simply fail.  Only HexagonABI will currently
    //    use this method.
    //  . Two PrepareTrivialCall's is not good design so perhaps this should be combined.
    //
    virtual bool
    PrepareTrivialCall ( lldb_private::Thread &thread, 
                         lldb::addr_t sp,
                         lldb::addr_t functionAddress,
                         lldb::addr_t returnAddress,
                         llvm::Type &prototype,
                         llvm::ArrayRef<CallArgument> args) const;

    virtual bool
    GetArgumentValues (Thread &thread,
                       ValueList &values) const = 0;
    
    lldb::ValueObjectSP
    GetReturnValueObject (Thread &thread,
                          ClangASTType &type,
                          bool persistent = true) const;
    
    // specialized to work with llvm IR types
    lldb::ValueObjectSP
    GetReturnValueObject (Thread &thread,
                          llvm::Type &type,
                          bool persistent = true) const;
    
    // Set the Return value object in the current frame as though a function with 
    virtual Error
    SetReturnValueObject(lldb::StackFrameSP &frame_sp, lldb::ValueObjectSP &new_value) = 0;

protected:    
    // This is the method the ABI will call to actually calculate the return value.
    // Don't put it in a persistent value object, that will be done by the ABI::GetReturnValueObject.
    virtual lldb::ValueObjectSP
    GetReturnValueObjectImpl (Thread &thread, ClangASTType &ast_type) const = 0;
    
    // specialized to work with llvm IR types
    virtual lldb::ValueObjectSP
    GetReturnValueObjectImpl( Thread &thread, llvm::Type &ir_type ) const;

public:
    virtual bool
    CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan) = 0;

    virtual bool
    CreateDefaultUnwindPlan (UnwindPlan &unwind_plan) = 0;

    virtual bool
    RegisterIsVolatile (const RegisterInfo *reg_info) = 0;

    // Should return true if your ABI uses frames when doing stack backtraces. This
    // means a frame pointer is used that points to the previous stack frame in some
    // way or another.
    virtual bool
    StackUsesFrames () = 0;

    // Should take a look at a call frame address (CFA) which is just the stack
    // pointer value upon entry to a function. ABIs usually impose alignment
    // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed.
    // This function should return true if "cfa" is valid call frame address for
    // the ABI, and false otherwise. This is used by the generic stack frame unwinding
    // code to help determine when a stack ends.
    virtual bool
    CallFrameAddressIsValid (lldb::addr_t cfa) = 0;

    // Validates a possible PC value and returns true if an opcode can be at "pc".
    virtual bool
    CodeAddressIsValid (lldb::addr_t pc) = 0;    

    virtual lldb::addr_t
    FixCodeAddress (lldb::addr_t pc)
    {
        // Some targets might use bits in a code address to indicate
        // a mode switch. ARM uses bit zero to signify a code address is
        // thumb, so any ARM ABI plug-ins would strip those bits.
        return pc;
    }

    virtual const RegisterInfo *
    GetRegisterInfoArray (uint32_t &count) = 0;

    // Some architectures (e.g. x86) will push the return address on the stack and decrement
    // the stack pointer when making a function call.  This means that every stack frame will
    // have a unique CFA.
    // Other architectures (e.g. arm) pass the return address in a register so it is possible
    // to have a frame on a backtrace that does not push anything on the stack or change the 
    // CFA.
    virtual bool
    FunctionCallsChangeCFA () = 0;

    bool
    GetRegisterInfoByName (const ConstString &name, RegisterInfo &info);

    bool
    GetRegisterInfoByKind (lldb::RegisterKind reg_kind, 
                           uint32_t reg_num, 
                           RegisterInfo &info);

    static lldb::ABISP
    FindPlugin (const ArchSpec &arch);
    
protected:
    //------------------------------------------------------------------
    // Classes that inherit from ABI can see and modify these
    //------------------------------------------------------------------
    ABI();
private:
    DISALLOW_COPY_AND_ASSIGN (ABI);
};

} // namespace lldb_private

#endif  // liblldb_ABI_h_