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