ABISysV_x86_64.cpp revision 75906e4ec98af3717e415727a8d663a4e246bb4f
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"
157a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan#include "lldb/Core/Log.h"
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Module.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/PluginManager.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Value.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Symbol/ClangASTContext.h"
2075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton#include "lldb/Symbol/UnwindPlan.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Target.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Process.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/RegisterContext.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/StackFrame.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Target/Thread.h"
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/ADT/Triple.h"
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char *pluginName = "ABISysV_x86_64";
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char *pluginDesc = "System V ABI for x86_64 targets";
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic const char *pluginShort = "abi.sysv-x86_64";
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
3775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnersize_t
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetRedZoneSize () const
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 128;
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Static Functions
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
4775906e4ec98af3717e415727a8d663a4e246bb4fGreg ClaytonABISP
48395fc33dc4b06c048ed35047ec461bc092ef2df3Greg ClaytonABISysV_x86_64::CreateInstance (const ArchSpec &arch)
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    static ABISP g_abi_sp;
51395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton    if (arch.GetTriple().getArch() == llvm::Triple::x86_64)
5275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    {
5375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        if (!g_abi_sp)
5475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            g_abi_sp.reset (new ABISysV_x86_64);
5575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        return g_abi_sp;
5675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    }
5775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    return ABISP();
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::PrepareTrivialCall (Thread &thread,
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    lldb::addr_t sp,
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    lldb::addr_t functionAddress,
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                    lldb::addr_t returnAddress,
653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan                                    lldb::addr_t arg,
663aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    lldb::addr_t *this_arg,
673aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                                    lldb::addr_t *cmd_arg) const
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
69e005f2ce03c489ebde9110678a29cbfe8488d5b4Greg Clayton    LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
707a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
717a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan    if (log)
723aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n  thread = %p\n  sp = 0x%llx\n  functionAddress = 0x%llx\n  returnAddress = 0x%llx\n  arg = 0x%llx\n  this_arg = %p(0x%llx)\n  cmd_arg = %p(0x%llx)\n)",
737a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan                    (void*)&thread,
747a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan                    (uint64_t)sp,
757a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan                    (uint64_t)functionAddress,
767a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan                    (uint64_t)returnAddress,
777a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan                    (void*)arg,
783aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                    this_arg,
793aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                    this_arg ? (uint64_t)*this_arg : (uint64_t)0,
803aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                    cmd_arg,
813aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan                    cmd_arg ? (uint64_t)*cmd_arg : (uint64_t)0);
827a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
8308d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx)
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
873a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    uint32_t rdiID = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];
88059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#define CHAIN_RBP
89059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan
90059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#ifndef CHAIN_RBP
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t rbpID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP);
92059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#endif
93059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t ripID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC);
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t rspID = reg_ctx->ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP);
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The argument is in %rdi, and not on the stack.
983c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
993aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    if (cmd_arg)
1003aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
1013aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
1023aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->PutCString("The trivial call has a self and a _cmd pointer");
1033aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1043aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        uint32_t rsiID = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB];
1053aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        uint32_t rdxID = reg_ctx->GetRegisterInfoByName("rdx", 0)->kinds[eRegisterKindLLDB];
1063aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1073aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
1083aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("About to write 'self' (0x%llx) into RDI", (uint64_t)*this_arg);
1093aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1103aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, *this_arg))
1113aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            return false;
1123aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1133aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
1143aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("About to write '_cmd' (0x%llx) into RSI", (uint64_t)*cmd_arg);
1153aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
116047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rsiID, *cmd_arg))
1173aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            return false;
1183aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1193aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
1203aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("About to write the argument (0x%llx) into RDX", (uint64_t)arg);
1213aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1223aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rdxID, arg))
123047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan            return false;
124047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan    }
125047923c7bc90275f29c2e179d2385df26b8d81a1Sean Callanan    else if (this_arg)
1263c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
1277a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        if (log)
1287a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan            log->PutCString("The trivial call has a this pointer");
1297a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1303c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        uint32_t rsiID = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB];
1313c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1327a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        if (log)
1337a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan            log->Printf("About to write 'this' (0x%llx) into RDI", (uint64_t)*this_arg);
1347a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1353c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, *this_arg))
1363c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
1373c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
1387a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        if (log)
1397a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan            log->Printf("About to write the argument (0x%llx) into RSI", (uint64_t)arg);
1407a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rsiID, arg))
1423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
1433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
1443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    else
1453c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
1467a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        if (log)
1477a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan            log->PutCString("The trivial call does not have a this pointer");
1487a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1497a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        if (log)
1507a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan            log->Printf("About to write the argument (0x%llx) into RDI", (uint64_t)arg);
1517a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1523c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (!reg_ctx->WriteRegisterFromUnsigned(rdiID, arg))
1533c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
1543c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // First, align the SP
1577a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1587a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan    if (log)
1597a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        log->Printf("16-byte aligning SP: 0x%llx to 0x%llx", (uint64_t)sp, (uint64_t)(sp & ~0xfull));
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    sp &= ~(0xfull); // 16-byte alignment
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // The return address is pushed onto the stack.
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    sp -= 8;
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t returnAddressU64 = returnAddress;
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Error error;
1687a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1697a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan    if (log)
1707a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        log->Printf("Pushing the return address onto the stack: new SP 0x%llx, return address 0x%llx", (uint64_t)sp, (uint64_t)returnAddressU64);
1717a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (thread.GetProcess().WriteMemory (sp, &returnAddressU64, sizeof(returnAddressU64), error) != sizeof(returnAddressU64))
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // %rsp is set to the actual stack value.
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1777a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan    if (log)
1787a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        log->Printf("Writing SP (0x%llx) down", (uint64_t)sp);
1797a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx->WriteRegisterFromUnsigned(rspID, sp))
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
183059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#ifndef CHAIN_RBP
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // %rbp is set to a fake value, in our case 0x0000000000000000.
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx->WriteRegisterFromUnsigned(rbpID, 0x000000000000000))
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
188059ce9b34bce8bfa47e40edffc504103dfe07465Sean Callanan#endif
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // %rip is set to the address of the called function.
1917a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan
1927a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan    if (log)
1937a60b9403bb7c24f907f3269d246fb04971ecb8bSean Callanan        log->Printf("Writing new IP (0x%llx) down", (uint64_t)functionAddress);
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx->WriteRegisterFromUnsigned(ripID, functionAddress))
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::PrepareNormalCall (Thread &thread,
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   lldb::addr_t sp,
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   lldb::addr_t functionAddress,
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   lldb::addr_t returnAddress,
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   ValueList &args) const
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool ReadIntegerArgument(Scalar           &scalar,
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                unsigned int     bit_width,
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                bool             is_signed,
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                Thread           &thread,
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                uint32_t         *argument_register_ids,
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                unsigned int     &current_argument_register,
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                addr_t           &current_stack_argument)
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (bit_width > 64)
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false; // Scalar can't hold large integer arguments
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint64_t arg_contents;
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (current_argument_register < 6)
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        arg_contents = thread.GetRegisterContext()->ReadRegisterAsUnsigned(argument_register_ids[current_argument_register], 0);
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        current_argument_register++;
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint8_t arg_data[sizeof(arg_contents)];
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Error error;
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        thread.GetProcess().ReadMemory(current_stack_argument, arg_data, sizeof(arg_contents), error);
234395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton        DataExtractor arg_data_extractor (arg_data, sizeof(arg_contents),
235395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton                                          thread.GetProcess().GetTarget().GetArchitecture().GetByteOrder(),
236395fc33dc4b06c048ed35047ec461bc092ef2df3Greg Clayton                                          thread.GetProcess().GetTarget().GetArchitecture().GetAddressByteSize());
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t offset = 0;
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        arg_contents = arg_data_extractor.GetMaxU64(&offset, bit_width / 8);
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!offset)
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        current_stack_argument += (bit_width / 8);
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (is_signed)
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (bit_width)
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 8:
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int8_t)(arg_contents & 0xff);
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 16:
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int16_t)(arg_contents & 0xffff);
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 32:
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int32_t)(arg_contents & 0xffffffff);
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 64:
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (int64_t)arg_contents;
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (bit_width)
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 8:
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint8_t)(arg_contents & 0xff);
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 16:
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint16_t)(arg_contents & 0xffff);
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 32:
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint32_t)(arg_contents & 0xffffffff);
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        case 64:
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            scalar = (uint64_t)arg_contents;
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetArgumentValues (Thread &thread,
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   ValueList &values) const
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    unsigned int num_values = values.GetSize();
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    unsigned int value_index;
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // For now, assume that the types in the AST values come from the Target's
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // scratch AST.
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Extract the register context so we can read arguments from registers
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30208d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton    RegisterContext *reg_ctx = thread.GetRegisterContext().get();
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!reg_ctx)
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Get the pointer to the first stack argument so we have a place to start
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // when reading data
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    addr_t sp = reg_ctx->GetSP(0);
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (!sp)
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    addr_t current_stack_argument = sp + 8; // jump over return address
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t argument_register_ids[6];
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3193a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[0] = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];
3203a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[1] = reg_ctx->GetRegisterInfoByName("rsi", 0)->kinds[eRegisterKindLLDB];
3213a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[2] = reg_ctx->GetRegisterInfoByName("rdx", 0)->kinds[eRegisterKindLLDB];
3223a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[3] = reg_ctx->GetRegisterInfoByName("rcx", 0)->kinds[eRegisterKindLLDB];
3233a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[4] = reg_ctx->GetRegisterInfoByName("r8", 0)->kinds[eRegisterKindLLDB];
3243a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda    argument_register_ids[5] = reg_ctx->GetRegisterInfoByName("r9", 0)->kinds[eRegisterKindLLDB];
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    unsigned int current_argument_register = 0;
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (value_index = 0;
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner         value_index < num_values;
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner         ++value_index)
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Value *value = values.GetValueAtIndex(value_index);
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (!value)
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // We currently only support extracting values with Clang QualTypes.
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Do we care about others?
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        switch (value->GetContextType())
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
3436916e358c9725b75ed91f31236c147f26c9af10eGreg Clayton        case Value::eContextTypeClangType:
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
345462d4147f3bb9141bf62d904f58a623db00669dfGreg Clayton                void *value_type = value->GetClangType();
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                bool is_signed;
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                if (ClangASTContext::IsIntegerType (value_type, is_signed))
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
350960d6a40711f05effe6fcc5b66f0952450f79ea2Greg Clayton                    size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    ReadIntegerArgument(value->GetScalar(),
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        bit_width,
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        is_signed,
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        thread,
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        argument_register_ids,
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_argument_register,
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_stack_argument);
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                else if (ClangASTContext::IsPointerType (value_type))
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    ReadIntegerArgument(value->GetScalar(),
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        64,
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        false,
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        thread,
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        argument_register_ids,
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_argument_register,
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                        current_stack_argument);
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetReturnValue (Thread &thread,
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                Value &value) const
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    switch (value.GetContextType())
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        default:
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
3866916e358c9725b75ed91f31236c147f26c9af10eGreg Clayton        case Value::eContextTypeClangType:
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
388462d4147f3bb9141bf62d904f58a623db00669dfGreg Clayton            void *value_type = value.GetClangType();
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            bool is_signed;
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39108d7d3ae16110aa68ed40c161eac8571aeb94cd9Greg Clayton            RegisterContext *reg_ctx = thread.GetRegisterContext().get();
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (!reg_ctx)
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return false;
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (ClangASTContext::IsIntegerType (value_type, is_signed))
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // For now, assume that the types in the AST values come from the Target's
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // scratch AST.
40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
40224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // Extract the register context so we can read arguments from registers
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
405960d6a40711f05effe6fcc5b66f0952450f79ea2Greg Clayton                size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
4063a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
40724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                switch (bit_width)
40924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                {
41024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                default:
41124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 128:
41224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    // Scalar can't hold 128-bit literals, so we don't handle this
41324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    return false;
41424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 64:
41524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
41624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
41724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
41824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint64_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0));
41924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
42024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 32:
42124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
42224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
42324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
42424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint32_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffffffff);
42524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
42624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 16:
42724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
42824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
42924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
43024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint16_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xffff);
43124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
43224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                case 8:
43324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    if (is_signed)
43424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (int8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    else
43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                        value.GetScalar() = (uint8_t)(thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0) & 0xff);
43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    break;
43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                }
43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else if (ClangASTContext::IsPointerType (value_type))
44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
4423a4ea24572fad1e22525f8efb718d49d41e30398Jason Molenda                unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
44324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            else
44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                // not handled yet
44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return false;
44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        break;
45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
45775906e4ec98af3717e415727a8d663a4e246bb4fGreg Claytonbool
45875906e4ec98af3717e415727a8d663a4e246bb4fGreg ClaytonABISysV_x86_64::CreateFunctionEntryUnwindPlan (UnwindPlan &unwind_plan)
45975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton{
46075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t reg_kind = unwind_plan.GetRegisterKind();
46175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
46275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
46375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
46475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    switch (reg_kind)
46575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    {
46675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    case eRegisterKindDWARF:
46775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    case eRegisterKindGCC:
46875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        sp_reg_num = gcc_dwarf_rsp;
46975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        pc_reg_num = gcc_dwarf_rip;
47075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        break;
47175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
47275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    case eRegisterKindGDB:
47375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        sp_reg_num = gdb_rsp;
47475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        pc_reg_num = gdb_rip;
47575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        break;
47675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
47775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    case eRegisterKindGeneric:
47875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        sp_reg_num = LLDB_REGNUM_GENERIC_SP;
47975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        pc_reg_num = LLDB_REGNUM_GENERIC_PC;
48075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        break;
48175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    }
48275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
48375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    if (sp_reg_num == LLDB_INVALID_REGNUM ||
48475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        pc_reg_num == LLDB_INVALID_REGNUM)
48575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        return false;
48675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
48775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    UnwindPlan::Row row;
48875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetCFARegister (sp_reg_num);
48975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetCFAOffset (8);
49075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -8, false);
49175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    unwind_plan.AppendRow (row);
49275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    unwind_plan.SetSourceName (pluginName);
49375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    return true;
49475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton}
49575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
49675906e4ec98af3717e415727a8d663a4e246bb4fGreg Claytonbool
49775906e4ec98af3717e415727a8d663a4e246bb4fGreg ClaytonABISysV_x86_64::CreateDefaultUnwindPlan (UnwindPlan &unwind_plan)
49875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton{
49975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t reg_kind = unwind_plan.GetRegisterKind();
50075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t fp_reg_num = LLDB_INVALID_REGNUM;
50175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t sp_reg_num = LLDB_INVALID_REGNUM;
50275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    uint32_t pc_reg_num = LLDB_INVALID_REGNUM;
50375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
50475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    switch (reg_kind)
50575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    {
50675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        case eRegisterKindDWARF:
50775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        case eRegisterKindGCC:
50875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            fp_reg_num = gcc_dwarf_rbp;
50975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            sp_reg_num = gcc_dwarf_rsp;
51075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            pc_reg_num = gcc_dwarf_rip;
51175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            break;
51275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
51375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        case eRegisterKindGDB:
51475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            fp_reg_num = gdb_rbp;
51575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            sp_reg_num = gdb_rsp;
51675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            pc_reg_num = gdb_rip;
51775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            break;
51875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
51975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        case eRegisterKindGeneric:
52075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            fp_reg_num = LLDB_REGNUM_GENERIC_FP;
52175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            sp_reg_num = LLDB_REGNUM_GENERIC_SP;
52275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            pc_reg_num = LLDB_REGNUM_GENERIC_PC;
52375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            break;
52475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    }
52575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
52675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    if (fp_reg_num == LLDB_INVALID_REGNUM ||
52775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        sp_reg_num == LLDB_INVALID_REGNUM ||
52875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        pc_reg_num == LLDB_INVALID_REGNUM)
52975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        return false;
53075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
53175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    UnwindPlan::Row row;
53275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
53375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    const int32_t ptr_size = 8;
53475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetCFARegister (LLDB_REGNUM_GENERIC_FP);
53575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetCFAOffset (2 * ptr_size);
53675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetOffset (0);
53775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
53875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetRegisterLocationToAtCFAPlusOffset(fp_reg_num, ptr_size * -2, true);
53975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, ptr_size * -1, true);
54075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    row.SetRegisterLocationToAtCFAPlusOffset(sp_reg_num, ptr_size *  0, true);
54175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
54275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    unwind_plan.AppendRow (row);
54375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    unwind_plan.SetSourceName ("x86_64 default unwind plan");
54475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    return true;
54575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton}
54675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
54775906e4ec98af3717e415727a8d663a4e246bb4fGreg Claytonbool
54875906e4ec98af3717e415727a8d663a4e246bb4fGreg ClaytonABISysV_x86_64::RegisterIsVolatile (const RegisterInfo *reg_info)
54975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton{
55075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    return !RegisterIsCalleeSaved (reg_info);
55175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton}
55275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
55375906e4ec98af3717e415727a8d663a4e246bb4fGreg Claytonbool
55475906e4ec98af3717e415727a8d663a4e246bb4fGreg ClaytonABISysV_x86_64::RegisterIsCalleeSaved (const RegisterInfo *reg_info)
55575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton{
55675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    if (reg_info)
55775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    {
55875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        // Volatile registers include: rbx, rbp, rsp, r12, r13, r14, r15, rip
55975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        const char *name = reg_info->name;
56075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        if (name[0] == 'r')
56175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        {
56275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            switch (name[1])
56375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            {
56475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            case '1': // r12, r13, r14, r15
56575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                if (name[2] >= '2' && name[2] <= '5')
56675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                    return name[3] == '\0';
56775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                break;
56875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
56975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            case 'b': // rbp, rbx
57075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                if (name[2] == 'p' || name[2] == 'x')
57175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                    return name[3] == '\0';
57275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                break;
57375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
57475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            case 'i': // rip
57575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                if (name[2] == 'p')
57675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                    return name[3] == '\0';
57775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                break;
57875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
57975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            case 's': // rsp
58075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                if (name[2] == 'p')
58175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                    return name[3] == '\0';
58275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                break;
58375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
58475906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            default:
58575906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton                break;
58675906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton            }
58775906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton        }
58875906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    }
58975906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton    return false;
59075906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton}
59175906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
59275906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
59375906e4ec98af3717e415727a8d663a4e246bb4fGreg Clayton
59424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
59524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::Initialize()
59624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
59724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PluginManager::RegisterPlugin (pluginName,
59824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   pluginDesc,
59924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                                   CreateInstance);
60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
60124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
60224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
60324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::Terminate()
60424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    PluginManager::UnregisterPlugin (CreateInstance);
60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
60724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
60824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
60924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// PluginInterface protocol
61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//------------------------------------------------------------------
61124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetPluginName()
61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
61424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return pluginName;
61524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
61624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
61724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst char *
61824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetShortPluginName()
61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
62024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return pluginShort;
62124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
62224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
62324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattneruint32_t
62424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerABISysV_x86_64::GetPluginVersion()
62524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
62624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return 1;
62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
629