1169689Skan//===-- RegisterContextFreeBSD_x86_64.h ------------------------*- C++ -*-===//
2169689Skan//
3169689Skan//                     The LLVM Compiler Infrastructure
4169689Skan//
5169689Skan// This file is distributed under the University of Illinois Open Source
6169689Skan// License. See LICENSE.TXT for details.
7169689Skan//
8//===---------------------------------------------------------------------===//
9
10#include "RegisterContextFreeBSD_x86_64.h"
11#include <vector>
12
13using namespace lldb_private;
14
15// Computes the offset of the given GPR in the user data area.
16#define GPR_OFFSET(regname)                                                 \
17    (offsetof(GPR, regname))
18
19// Update the FreeBSD specific information (offset and size).
20#define UPDATE_GPR_INFO(reg)                                                \
21do {                                                                        \
22    GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg);               \
23    GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg);              \
24} while(false);
25
26#define UPDATE_I386_GPR_INFO(i386_reg, reg)                                 \
27do {                                                                        \
28    GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg);         \
29} while(false);
30
31typedef struct _GPR
32{
33    uint64_t r15;
34    uint64_t r14;
35    uint64_t r13;
36    uint64_t r12;
37    uint64_t r11;
38    uint64_t r10;
39    uint64_t r9;
40    uint64_t r8;
41    uint64_t rdi;
42    uint64_t rsi;
43    uint64_t rbp;
44    uint64_t rbx;
45    uint64_t rdx;
46    uint64_t rcx;
47    uint64_t rax;
48    uint32_t trapno;
49    uint16_t fs;
50    uint16_t gs;
51    uint32_t err;
52    uint16_t es;
53    uint16_t ds;
54    uint64_t rip;
55    uint64_t cs;
56    uint64_t rflags;
57    uint64_t rsp;
58    uint64_t ss;
59} GPR;
60
61// Use a singleton function to avoid global constructors in shared libraries.
62static std::vector<RegisterInfo> & GetRegisterContext () {
63    static std::vector<RegisterInfo> g_register_infos;
64    return g_register_infos;
65}
66
67
68RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(Thread &thread, uint32_t concrete_frame_idx):
69    RegisterContext_x86_64(thread, concrete_frame_idx)
70{
71}
72
73size_t
74RegisterContextFreeBSD_x86_64::GetGPRSize()
75{
76    return sizeof(GPR);
77}
78
79const RegisterInfo *
80RegisterContextFreeBSD_x86_64::GetRegisterInfo()
81{
82    // Allocate RegisterInfo only once
83    if (GetRegisterContext().empty())
84    {
85        // Copy the register information from base class
86        const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
87        if (base_info)
88        {
89            GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
90            // Update the FreeBSD specific register information (offset and size).
91            UpdateRegisterInfo();
92        }
93    }
94    return &GetRegisterContext()[0];
95}
96
97void
98RegisterContextFreeBSD_x86_64::UpdateRegisterInfo()
99{
100    UPDATE_GPR_INFO(rax);
101    UPDATE_GPR_INFO(rbx);
102    UPDATE_GPR_INFO(rcx);
103    UPDATE_GPR_INFO(rdx);
104    UPDATE_GPR_INFO(rdi);
105    UPDATE_GPR_INFO(rsi);
106    UPDATE_GPR_INFO(rbp);
107    UPDATE_GPR_INFO(rsp);
108    UPDATE_GPR_INFO(r8);
109    UPDATE_GPR_INFO(r9);
110    UPDATE_GPR_INFO(r10);
111    UPDATE_GPR_INFO(r11);
112    UPDATE_GPR_INFO(r12);
113    UPDATE_GPR_INFO(r13);
114    UPDATE_GPR_INFO(r14);
115    UPDATE_GPR_INFO(r15);
116    UPDATE_GPR_INFO(rip);
117    UPDATE_GPR_INFO(rflags);
118    UPDATE_GPR_INFO(cs);
119    UPDATE_GPR_INFO(fs);
120    UPDATE_GPR_INFO(gs);
121    UPDATE_GPR_INFO(ss);
122    UPDATE_GPR_INFO(ds);
123    UPDATE_GPR_INFO(es);
124
125    UPDATE_I386_GPR_INFO(eax, rax);
126    UPDATE_I386_GPR_INFO(ebx, rbx);
127    UPDATE_I386_GPR_INFO(ecx, rcx);
128    UPDATE_I386_GPR_INFO(edx, rdx);
129    UPDATE_I386_GPR_INFO(edi, rdi);
130    UPDATE_I386_GPR_INFO(esi, rsi);
131    UPDATE_I386_GPR_INFO(ebp, rbp);
132    UPDATE_I386_GPR_INFO(esp, rsp);
133    UPDATE_I386_GPR_INFO(eip, rip);
134    UPDATE_I386_GPR_INFO(eflags, rflags);
135}
136
137