ABISysV_x86_64.cpp revision 3c9c5eb466869ede185e879d14a47335fb43194d
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- ABISysV_x86_64.cpp --------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "ABISysV_x86_64.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/ConstString.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataExtractor.h"
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Error.h"
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Module.h"
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/PluginManager.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Value.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/ClangASTContext.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Target.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/StackFrame.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/ADT/Triple.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char *pluginName = "ABISysV_x86_64";
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char *pluginDesc = "System V ABI for x86_64 targets";
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char *pluginShort = "abi.sysv-x86_64";
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetRedZoneSize () const
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 128;
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Static Functions
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerlldb_private::ABI *
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::CreateInstance (const ConstString &triple)
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    llvm::StringRef tripleStr(triple.GetCString());
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    llvm::Triple llvmTriple(tripleStr);
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (llvmTriple.getArch() != llvm::Triple::x86_64)
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return NULL;
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return new ABISysV_x86_64;
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::PrepareTrivialCall (Thread &thread,
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    lldb::addr_t sp,
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    lldb::addr_t functionAddress,
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    lldb::addr_t returnAddress,
603c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    lldb::addr_t arg,
613c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    lldb::addr_t *this_arg) const
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    RegisterContext *reg_ctx = thread.GetRegisterContext();
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx)
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
673a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint32_t rdiID = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];
68059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#define CHAIN_RBP
69059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan
70059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#ifndef CHAIN_RBP
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t rbpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
72059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#endif
73059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t ripID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t rspID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The argument is in %rdi, and not on the stack.
783c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
793c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (this_arg)
803c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        uint32_t rsiID = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB];
823c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
833c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, *this_arg))
843c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
853c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
863c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rsiID, arg))
873c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
883c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
893c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else
903c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
913c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, arg))
923c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
933c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // First, align the SP
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    sp &= ~(0xfull); // 16-byte alignment
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The return address is pushed onto the stack.
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    sp -= 8;
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t returnAddressU64 = returnAddress;
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Error error;
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (thread.GetProcess().WriteMemory (sp, &returnAddressU64, sizeof(returnAddressU64), error) != sizeof(returnAddressU64))
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // %rsp is set to the actual stack value.
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx->WriteRegisterFromUnsigned(rspID, sp))
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
112059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#ifndef CHAIN_RBP
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // %rbp is set to a fake value, in our case 0x0000000000000000.
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx->WriteRegisterFromUnsigned(rbpID, 0x000000000000000))
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
117059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#endif
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // %rip is set to the address of the called function.
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx->WriteRegisterFromUnsigned(ripID, functionAddress))
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::PrepareNormalCall (Thread &thread,
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   lldb::addr_t sp,
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   lldb::addr_t functionAddress,
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   lldb::addr_t returnAddress,
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   ValueList &args) const
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool ReadIntegerArgument(Scalar           &scalar,
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                unsigned int     bit_width,
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                bool             is_signed,
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                Thread           &thread,
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                uint32_t         *argument_register_ids,
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                unsigned int     &current_argument_register,
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                addr_t           &current_stack_argument)
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (bit_width > 64)
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false; // Scalar can't hold large integer arguments
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t arg_contents;
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (current_argument_register < 6)
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        arg_contents = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        current_argument_register++;
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint8_t arg_data[sizeof(arg_contents)];
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Error error;
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        thread.GetProcess().ReadMemory(current_stack_argument, arg_data, sizeof(arg_contents), error);
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DataExtractor arg_data_extractor(arg_data, sizeof(arg_contents), thread.GetProcess().GetByteOrder(), thread.GetProcess().GetAddressByteSize());
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t offset = 0;
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        arg_contents = arg_data_extractor.GetMaxU64(&offset, bit_width / 8);
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!offset)
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        current_stack_argument += (bit_width / 8);
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (is_signed)
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (bit_width)
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 8:
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int8_t)(arg_contents & 0xff);
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 16:
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int16_t)(arg_contents & 0xffff);
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 32:
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int32_t)(arg_contents & 0xffffffff);
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 64:
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int64_t)arg_contents;
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (bit_width)
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 8:
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint8_t)(arg_contents & 0xff);
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 16:
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint16_t)(arg_contents & 0xffff);
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 32:
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint32_t)(arg_contents & 0xffffffff);
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 64:
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint64_t)arg_contents;
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetArgumentValues (Thread &thread,
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   ValueList &values) const
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    unsigned int num_values = values.GetSize();
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    unsigned int value_index;
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // For now, assume that the types in the AST values come from the Target's
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // scratch AST.
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Extract the register context so we can read arguments from registers
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    RegisterContext *reg_ctx = thread.GetRegisterContext();
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx)
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Get the pointer to the first stack argument so we have a place to start
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // when reading data
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    addr_t sp = reg_ctx->GetSP(0);
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!sp)
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    addr_t current_stack_argument = sp + 8; // jump over return address
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t argument_register_ids[6];
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2433a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[0] = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];
2443a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[1] = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB];
2453a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[2] = reg_ctx->GetRegisterInfoByName("rdx", 0)->kinds[eRegisterKindLLDB];
2463a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[3] = reg_ctx->GetRegisterInfoByName("rcx", 0)->kinds[eRegisterKindLLDB];
2473a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[4] = reg_ctx->GetRegisterInfoByName("r8", 0)->kinds[eRegisterKindLLDB];
2483a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[5] = reg_ctx->GetRegisterInfoByName("r9", 0)->kinds[eRegisterKindLLDB];
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    unsigned int current_argument_register = 0;
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (value_index = 0;
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner         value_index < num_values;
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner         ++value_index)
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Value *value = values.GetValueAtIndex(value_index);
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!value)
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We currently only support extracting values with Clang QualTypes.
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Do we care about others?
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (value->GetContextType())
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case Value::eContextTypeOpaqueClangQualType:
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                void *value_type = value->GetOpaqueClangQualType();
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                bool is_signed;
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (ClangASTContext::IsIntegerType (value_type, is_signed))
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
274960d6a40711f05effe6fcc5b66f0952450f79ea2Greg Clayton                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    ReadIntegerArgument(value->GetScalar(),
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        bit_width,
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        is_signed,
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        thread,
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        argument_register_ids,
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_argument_register,
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_stack_argument);
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else if (ClangASTContext::IsPointerType (value_type))
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    ReadIntegerArgument(value->GetScalar(),
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        64,
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        false,
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        thread,
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        argument_register_ids,
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_argument_register,
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_stack_argument);
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetReturnValue (Thread &thread,
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                Value &value) const
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (value.GetContextType())
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case Value::eContextTypeOpaqueClangQualType:
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            void *value_type = value.GetOpaqueClangQualType();
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            bool is_signed;
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            RegisterContext *reg_ctx = thread.GetRegisterContext();
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (!reg_ctx)
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return false;
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (ClangASTContext::IsIntegerType (value_type, is_signed))
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // For now, assume that the types in the AST values come from the Target's
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // scratch AST.
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Extract the register context so we can read arguments from registers
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
329960d6a40711f05effe6fcc5b66f0952450f79ea2Greg Clayton                size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
3303a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                switch (bit_width)
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                default:
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 128:
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // Scalar can't hold 128-bit literals, so we don't handle this
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return false;
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 64:
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 32:
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 16:
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 8:
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else if (ClangASTContext::IsPointerType (value_type))
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
3663a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // not handled yet
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return false;
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::Initialize()
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PluginManager::RegisterPlugin (pluginName,
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   pluginDesc,
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   CreateInstance);
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
38824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::Terminate()
39124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PluginManager::UnregisterPlugin (CreateInstance);
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// PluginInterface protocol
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetPluginName()
40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return pluginName;
40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetShortPluginName()
40624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return pluginShort;
40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetPluginVersion()
41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 1;
41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetPluginCommandHelp (const char *command, Stream *strm)
41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerError
42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::ExecutePluginCommand (Args &command, Stream *strm)
42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Error error;
42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    error.SetErrorString("No plug-in command are currently supported.");
42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return error;
42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerLog *
43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::EnablePluginLogging (Stream *strm, Args &command)
43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
434