DebugServer2
Loading...
Searching...
No Matches
RegisterCopy.h
1//
2// Copyright (c) 2014-present, Facebook, Inc.
3// All rights reserved.
4//
5// This source code is licensed under the University of Illinois/NCSA Open
6// Source License found in the LICENSE file in the root directory of this
7// source tree. An additional grant of patent rights can be found in the
8// PATENTS file in the same directory.
9//
10
11// Yes, I just decided to write macro vomit.
12
13#pragma once
14
15#include "DebugServer2/Architecture/CPUState.h"
16
17namespace ds2 {
18namespace Architecture {
19namespace X86 {
20
21// Macros are shit.
22#define _PASTE(A, B) A##B
23#define PASTE(A, B) _PASTE(A, B)
24
25#define DO_EMPTY() \
26 do { \
27 } while (0)
28
29#define DO_COPY_GPR_32() \
30 do { \
31 DO_COPY_GP_REG(ax); \
32 DO_COPY_GP_REG(cx); \
33 DO_COPY_GP_REG(dx); \
34 DO_COPY_GP_REG(bx); \
35 DO_COPY_GP_REG(si); \
36 DO_COPY_GP_REG(di); \
37 DO_COPY_GP_REG(bp); \
38 DO_COPY_GP_REG(sp); \
39 DO_COPY_GP_REG(ip); \
40 DO_COPY_FLAGS(); \
41 } while (0)
42
43#define DO_COPY_GPR_64() \
44 do { \
45 DO_COPY_GPR_32(); \
46 DO_COPY_GP_REG(8); \
47 DO_COPY_GP_REG(9); \
48 DO_COPY_GP_REG(10); \
49 DO_COPY_GP_REG(11); \
50 DO_COPY_GP_REG(12); \
51 DO_COPY_GP_REG(13); \
52 DO_COPY_GP_REG(14); \
53 DO_COPY_GP_REG(15); \
54 } while (0)
55
56#if defined(OS_WIN32)
57#define DO_COPY_SS() \
58 do { \
59 DO_COPY_SS_REG(cs, Cs); \
60 DO_COPY_SS_REG(ss, Ss); \
61 DO_COPY_SS_REG(ds, Ds); \
62 DO_COPY_SS_REG(es, Es); \
63 DO_COPY_SS_REG(fs, Fs); \
64 DO_COPY_SS_REG(gs, Gs); \
65 } while (0)
66#else
67#define DO_COPY_SS() \
68 do { \
69 DO_COPY_SS_REG(cs, cs); \
70 DO_COPY_SS_REG(ss, ss); \
71 DO_COPY_SS_REG(ds, ds); \
72 DO_COPY_SS_REG(es, es); \
73 DO_COPY_SS_REG(fs, fs); \
74 DO_COPY_SS_REG(gs, gs); \
75 } while (0)
76#endif
77
78#if defined(OS_LINUX)
79#define DO_COPY_EXTRA_32() \
80 do { \
81 DO_COPY_REG(state.linux_gp.PASTE(orig_, STATE_GP_REG(ax)), \
82 user.PASTE(orig_, USER_GP_REG(ax)), 0); \
83 } while (0)
84#define DO_COPY_EXTRA_64() \
85 do { \
86 DO_COPY_EXTRA_32(); \
87 DO_COPY_REG(state.linux_gp.fs_base, user.fs_base, 0); \
88 DO_COPY_REG(state.linux_gp.gs_base, user.gs_base, 0); \
89 } while (0)
90#else
91#define DO_COPY_EXTRA_32() DO_EMPTY()
92#define DO_COPY_EXTRA_64() DO_EMPTY()
93#endif
94
95#if defined(OS_LINUX) && defined(ARCH_X86)
96#define USER_GP_REG(NAME) e##NAME
97#define USER_SS_REG(NAME) x##NAME
98#define USER_FLAGS_REG() eflags
99#elif defined(OS_LINUX) && defined(ARCH_X86_64)
100#define USER_GP_REG(NAME) r##NAME
101#define USER_SS_REG(NAME) NAME
102#define USER_FLAGS_REG() eflags
103#elif defined(OS_FREEBSD) && defined(ARCH_X86_64)
104#define USER_GP_REG(NAME) r_r##NAME
105#define USER_SS_REG(NAME) r_##NAME
106#define USER_FLAGS_REG() r_rflags
107#elif defined(OS_WIN32) && defined(ARCH_X86)
108#define USER_GP_REG(NAME) E##NAME
109#define USER_SS_REG(NAME) Seg##NAME
110#define USER_FLAGS_REG() EFlags
111#elif defined(OS_WIN32) && defined(ARCH_X86_64)
112#define USER_GP_REG(NAME) R##NAME
113#define USER_SS_REG(NAME) Seg##NAME
114#define USER_FLAGS_REG() EFlags
115#endif
116
117#define DO_COPY_GP_REG(NAME) \
118 DO_COPY_REG(state.gp.STATE_GP_REG(NAME), user.USER_GP_REG(NAME), 0)
119#define DO_COPY_SS_REG(S, U) \
120 DO_COPY_REG(state.gp.S, user.USER_SS_REG(U), 0xffff)
121#define DO_COPY_FLAGS() DO_COPY_REG(state.gp.eflags, user.USER_FLAGS_REG(), 0)
122
123#define STATE_GP_REG(NAME) e##NAME
124#define DO_COPY_REG(S, U, M) S = (M ? U & M : U)
125template <typename StateType, typename UserStructType>
126static inline void user_to_state32(StateType &state,
127 UserStructType const &user) {
128 DO_COPY_GPR_32();
129 DO_COPY_SS();
130 DO_COPY_EXTRA_32();
131}
132#undef DO_COPY_REG
133
134#define DO_COPY_REG(S, U, M) U = (M ? S & M : S)
135template <typename UserStructType, typename StateType>
136static inline void state32_to_user(UserStructType &user,
137 StateType const &state) {
138 DO_COPY_GPR_32();
139 DO_COPY_SS();
140 DO_COPY_EXTRA_32();
141}
142#undef DO_COPY_REG
143#undef STATE_GP_REG
144
145#define STATE_GP_REG(NAME) r##NAME
146#define DO_COPY_REG(S, U, M) S = (M ? U & M : U)
147template <typename StateType, typename UserStructType>
148static inline void user_to_state64(StateType &state,
149 UserStructType const &user) {
150 DO_COPY_GPR_64();
151 DO_COPY_SS();
152 DO_COPY_EXTRA_64();
153}
154#undef DO_COPY_REG
155
156#define DO_COPY_REG(S, U, M) U = (M ? S & M : S)
157template <typename UserStructType, typename StateType>
158static inline void state64_to_user(UserStructType &user,
159 StateType const &state) {
160 DO_COPY_GPR_64();
161 DO_COPY_SS();
162 DO_COPY_EXTRA_64();
163}
164#undef DO_COPY_REG
165#undef STATE_GP_REG
166} // namespace X86
167} // namespace Architecture
168} // namespace ds2