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 ¤t_argument_register, 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner addr_t ¤t_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