1 //===-- RegisterContextFreeBSD_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 "RegisterContextFreeBSD_x86_64.h"
11 #include <vector>
12
13 using 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) \
21 do { \
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) \
27 do { \
28 GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg); \
29 } while(false);
30
31 typedef 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.
GetRegisterContext()62 static std::vector<RegisterInfo> & GetRegisterContext () {
63 static std::vector<RegisterInfo> g_register_infos;
64 return g_register_infos;
65 }
66
67
RegisterContextFreeBSD_x86_64(Thread & thread,uint32_t concrete_frame_idx)68 RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(Thread &thread, uint32_t concrete_frame_idx):
69 RegisterContext_x86_64(thread, concrete_frame_idx)
70 {
71 }
72
73 size_t
GetGPRSize()74 RegisterContextFreeBSD_x86_64::GetGPRSize()
75 {
76 return sizeof(GPR);
77 }
78
79 const RegisterInfo *
GetRegisterInfo()80 RegisterContextFreeBSD_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
97 void
UpdateRegisterInfo()98 RegisterContextFreeBSD_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