brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 63c034a Raw
185 lines · cpp
1//===-- RegisterContextLinux_x86_64.cpp -----------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===---------------------------------------------------------------------===//8 9#include "RegisterContextLinux_x86_64.h"10#include "RegisterContextLinux_i386.h"11#include "RegisterContextPOSIX_x86.h"12#include <vector>13 14using namespace lldb_private;15using namespace lldb;16 17typedef struct _GPR {18  uint64_t r15;19  uint64_t r14;20  uint64_t r13;21  uint64_t r12;22  uint64_t rbp;23  uint64_t rbx;24  uint64_t r11;25  uint64_t r10;26  uint64_t r9;27  uint64_t r8;28  uint64_t rax;29  uint64_t rcx;30  uint64_t rdx;31  uint64_t rsi;32  uint64_t rdi;33  uint64_t orig_rax;34  uint64_t rip;35  uint64_t cs;36  uint64_t rflags;37  uint64_t rsp;38  uint64_t ss;39  uint64_t fs_base;40  uint64_t gs_base;41  uint64_t ds;42  uint64_t es;43  uint64_t fs;44  uint64_t gs;45} GPR;46 47struct DBG {48  uint64_t dr[8];49};50 51struct UserArea {52  GPR gpr;         // General purpose registers.53  int32_t fpvalid; // True if FPU is being used.54  int32_t pad0;55  FXSAVE fpr; // General purpose floating point registers (see FPR for extended56              // register sets).57  uint64_t tsize;       // Text segment size.58  uint64_t dsize;       // Data segment size.59  uint64_t ssize;       // Stack segment size.60  uint64_t start_code;  // VM address of text.61  uint64_t start_stack; // VM address of stack bottom (top in rsp).62  int64_t signal;       // Signal causing core dump.63  int32_t reserved;     // Unused.64  int32_t pad1;65  uint64_t ar0;           // Location of GPR's.66  FXSAVE *fpstate;        // Location of FPR's.67  uint64_t magic;         // Identifier for core dumps.68  char u_comm[32];        // Command causing core dump.69  DBG dbg;                // Debug registers.70  uint64_t error_code;    // CPU error code.71  uint64_t fault_address; // Control register CR3.72};73 74#define DR_OFFSET(reg_index)                                                   \75  (LLVM_EXTENSION offsetof(UserArea, dbg) +                                    \76   LLVM_EXTENSION offsetof(DBG, dr[reg_index]))77 78// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64_with_base79// structure.80#define DECLARE_REGISTER_INFOS_X86_64_STRUCT81#include "RegisterInfos_x86_64_with_base.h"82#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT83 84static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() {85  static std::vector<lldb_private::RegisterInfo> g_register_infos;86  return g_register_infos;87}88 89static const RegisterInfo *90GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) {91  std::vector<lldb_private::RegisterInfo> &g_register_infos =92      GetPrivateRegisterInfoVector();93 94  // Allocate RegisterInfo only once95  if (g_register_infos.empty()) {96    // Copy the register information from base class97    std::unique_ptr<RegisterContextLinux_i386> reg_interface(98        new RegisterContextLinux_i386(arch));99    const RegisterInfo *base_info = reg_interface->GetRegisterInfo();100    g_register_infos.insert(g_register_infos.end(), &base_info[0],101                            &base_info[k_num_registers_i386]);102 103// Include RegisterInfos_x86_64 to update the g_register_infos structure104//  with x86_64 offsets.105#define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS106#include "RegisterInfos_x86_64_with_base.h"107#undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS108  }109 110  return &g_register_infos[0];111}112 113static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {114  switch (target_arch.GetMachine()) {115  case llvm::Triple::x86:116    return GetRegisterInfo_i386(target_arch);117  case llvm::Triple::x86_64:118    return g_register_infos_x86_64_with_base;119  default:120    assert(false && "Unhandled target architecture.");121    return nullptr;122  }123}124 125static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {126  switch (target_arch.GetMachine()) {127  case llvm::Triple::x86: {128    assert(!GetPrivateRegisterInfoVector().empty() &&129           "i386 register info not yet filled.");130    return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size());131  }132  case llvm::Triple::x86_64:133    return static_cast<uint32_t>(sizeof(g_register_infos_x86_64_with_base) /134                                 sizeof(g_register_infos_x86_64_with_base[0]));135  default:136    assert(false && "Unhandled target architecture.");137    return 0;138  }139}140 141static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) {142  switch (target_arch.GetMachine()) {143  case llvm::Triple::x86:144    return static_cast<uint32_t>(k_num_user_registers_i386);145  case llvm::Triple::x86_64:146    return static_cast<uint32_t>(x86_64_with_base::k_num_user_registers);147  default:148    assert(false && "Unhandled target architecture.");149    return 0;150  }151}152 153RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(154    const ArchSpec &target_arch)155    : lldb_private::RegisterContextLinux_x86(156          target_arch,157          {"orig_rax",158           nullptr,159           sizeof(((GPR *)nullptr)->orig_rax),160           (LLVM_EXTENSION offsetof(GPR, orig_rax)),161           eEncodingUint,162           eFormatHex,163           {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,164            LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM},165           nullptr,166           nullptr,167           nullptr}),168      m_register_info_p(GetRegisterInfoPtr(target_arch)),169      m_register_info_count(GetRegisterInfoCount(target_arch)),170      m_user_register_count(GetUserRegisterInfoCount(target_arch)) {}171 172size_t RegisterContextLinux_x86_64::GetGPRSizeStatic() { return sizeof(GPR); }173 174const RegisterInfo *RegisterContextLinux_x86_64::GetRegisterInfo() const {175  return m_register_info_p;176}177 178uint32_t RegisterContextLinux_x86_64::GetRegisterCount() const {179  return m_register_info_count;180}181 182uint32_t RegisterContextLinux_x86_64::GetUserRegisterCount() const {183  return m_user_register_count;184}185