Home | History | Annotate | Download | only in POSIX
      1 //===-- RegisterContextLinux_x86_64.h --------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===---------------------------------------------------------------------===//
      9 
     10 #include "llvm/Support/Compiler.h"
     11 #include "RegisterContextLinux_x86_64.h"
     12 #include <vector>
     13 
     14 using namespace lldb_private;
     15 
     16 // Computes the offset of the given GPR in the user data area.
     17 #define GPR_OFFSET(regname)                                                 \
     18     (offsetof(GPR, regname))
     19 
     20 // Update the Linux specific information (offset and size).
     21 #define UPDATE_GPR_INFO(reg)                                                \
     22 do {                                                                        \
     23     GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg);               \
     24     GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
     25 } while(false);
     26 
     27 #define UPDATE_I386_GPR_INFO(i386_reg, reg)                                 \
     28 do {                                                                        \
     29     GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
     30 } while(false);
     31 
     32 #define DR_OFFSET(reg_index)                                                \
     33     (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
     34 
     35 #define UPDATE_DR_INFO(reg_index)                                                \
     36 do {                                                                             \
     37     GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \
     38     GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index);          \
     39 } while(false);
     40 
     41 typedef struct _GPR
     42 {
     43     uint64_t r15;
     44     uint64_t r14;
     45     uint64_t r13;
     46     uint64_t r12;
     47     uint64_t rbp;
     48     uint64_t rbx;
     49     uint64_t r11;
     50     uint64_t r10;
     51     uint64_t r9;
     52     uint64_t r8;
     53     uint64_t rax;
     54     uint64_t rcx;
     55     uint64_t rdx;
     56     uint64_t rsi;
     57     uint64_t rdi;
     58     uint64_t orig_ax;
     59     uint64_t rip;
     60     uint64_t cs;
     61     uint64_t rflags;
     62     uint64_t rsp;
     63     uint64_t ss;
     64     uint64_t fs_base;
     65     uint64_t gs_base;
     66     uint64_t ds;
     67     uint64_t es;
     68     uint64_t fs;
     69     uint64_t gs;
     70 } GPR;
     71 
     72 typedef RegisterContext_x86_64::FXSAVE FXSAVE;
     73 
     74 struct UserArea
     75 {
     76     GPR      gpr;           // General purpose registers.
     77     int32_t  fpvalid;       // True if FPU is being used.
     78     int32_t  pad0;
     79     FXSAVE   i387;          // General purpose floating point registers (see FPR for extended register sets).
     80     uint64_t tsize;         // Text segment size.
     81     uint64_t dsize;         // Data segment size.
     82     uint64_t ssize;         // Stack segment size.
     83     uint64_t start_code;    // VM address of text.
     84     uint64_t start_stack;   // VM address of stack bottom (top in rsp).
     85     int64_t  signal;        // Signal causing core dump.
     86     int32_t  reserved;      // Unused.
     87     int32_t  pad1;
     88     uint64_t ar0;           // Location of GPR's.
     89     FXSAVE*  fpstate;       // Location of FPR's.
     90     uint64_t magic;         // Identifier for core dumps.
     91     char     u_comm[32];    // Command causing core dump.
     92     uint64_t u_debugreg[8]; // Debug registers (DR0 - DR7).
     93     uint64_t error_code;    // CPU error code.
     94     uint64_t fault_address; // Control register CR3.
     95 };
     96 
     97 // Use a singleton function to avoid global constructors in shared libraries.
     98 static std::vector<RegisterInfo> & GetRegisterContext () {
     99     static std::vector<RegisterInfo> g_register_infos;
    100     return g_register_infos;
    101 }
    102 
    103 RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx):
    104     RegisterContext_x86_64(thread, concrete_frame_idx)
    105 {
    106 }
    107 
    108 size_t
    109 RegisterContextLinux_x86_64::GetGPRSize()
    110 {
    111     return sizeof(GPR);
    112 }
    113 
    114 const RegisterInfo *
    115 RegisterContextLinux_x86_64::GetRegisterInfo()
    116 {
    117     // Allocate RegisterInfo only once
    118     if (GetRegisterContext().empty())
    119     {
    120         // Copy the register information from base class
    121         const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
    122         if (base_info)
    123         {
    124             GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
    125             // Update the Linux specific register information (offset and size).
    126             UpdateRegisterInfo();
    127         }
    128     }
    129     return &GetRegisterContext()[0];
    130 }
    131 
    132 void
    133 RegisterContextLinux_x86_64::UpdateRegisterInfo()
    134 {
    135     UPDATE_GPR_INFO(rax);
    136     UPDATE_GPR_INFO(rbx);
    137     UPDATE_GPR_INFO(rcx);
    138     UPDATE_GPR_INFO(rdx);
    139     UPDATE_GPR_INFO(rdi);
    140     UPDATE_GPR_INFO(rsi);
    141     UPDATE_GPR_INFO(rbp);
    142     UPDATE_GPR_INFO(rsp);
    143     UPDATE_GPR_INFO(r8);
    144     UPDATE_GPR_INFO(r9);
    145     UPDATE_GPR_INFO(r10);
    146     UPDATE_GPR_INFO(r11);
    147     UPDATE_GPR_INFO(r12);
    148     UPDATE_GPR_INFO(r13);
    149     UPDATE_GPR_INFO(r14);
    150     UPDATE_GPR_INFO(r15);
    151     UPDATE_GPR_INFO(rip);
    152     UPDATE_GPR_INFO(rflags);
    153     UPDATE_GPR_INFO(cs);
    154     UPDATE_GPR_INFO(fs);
    155     UPDATE_GPR_INFO(gs);
    156     UPDATE_GPR_INFO(ss);
    157     UPDATE_GPR_INFO(ds);
    158     UPDATE_GPR_INFO(es);
    159 
    160     UPDATE_I386_GPR_INFO(eax, rax);
    161     UPDATE_I386_GPR_INFO(ebx, rbx);
    162     UPDATE_I386_GPR_INFO(ecx, rcx);
    163     UPDATE_I386_GPR_INFO(edx, rdx);
    164     UPDATE_I386_GPR_INFO(edi, rdi);
    165     UPDATE_I386_GPR_INFO(esi, rsi);
    166     UPDATE_I386_GPR_INFO(ebp, rbp);
    167     UPDATE_I386_GPR_INFO(esp, rsp);
    168     UPDATE_I386_GPR_INFO(eip, rip);
    169     UPDATE_I386_GPR_INFO(eflags, rflags);
    170 
    171     UPDATE_DR_INFO(0);
    172     UPDATE_DR_INFO(1);
    173     UPDATE_DR_INFO(2);
    174     UPDATE_DR_INFO(3);
    175     UPDATE_DR_INFO(4);
    176     UPDATE_DR_INFO(5);
    177     UPDATE_DR_INFO(6);
    178     UPDATE_DR_INFO(7);
    179 }
    180 
    181