1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3d9bc86a97fd..4a68189b4340 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1548,6 +1548,7 @@ HFILES_NO_SRCDIR = \
moxie-tdep.h \
namespace.h \
nat/aarch64-fpmr-linux.h \
+ nat/aarch64-gcs-linux.h \
nat/aarch64-hw-point.h \
nat/aarch64-linux.h \
nat/aarch64-linux-hw-point.h \
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 4b86ae9ebe16..52ace4aab411 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -33,6 +33,7 @@
#include "aarch32-tdep.h"
#include "arch/arm.h"
#include "nat/aarch64-fpmr-linux.h"
+#include "nat/aarch64-gcs-linux.h"
#include "nat/aarch64-linux.h"
#include "nat/aarch64-linux-hw-point.h"
#include "nat/aarch64-mte-linux-ptrace.h"
@@ -54,8 +55,6 @@
#include "gdb_proc_service.h"
#include "arch-utils.h"
-#include "arch/aarch64-gcs-linux.h"
-
#include <string.h>
#ifndef TRAP_HWBKPT
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 4ca05fba771d..d136b0f2145e 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -1736,8 +1736,9 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
gcs_regmap, regcache_supply_regset, regcache_collect_regset
};
- cb (".reg-aarch-gcs", sizeof (user_gcs), sizeof (user_gcs),
- &aarch64_linux_gcs_regset, "GCS registers", cb_data);
+ cb (".reg-aarch-gcs", AARCH64_LINUX_SIZEOF_GCS_REGSET,
+ AARCH64_LINUX_SIZEOF_GCS_REGSET, &aarch64_linux_gcs_regset,
+ "GCS registers", cb_data);
}
}
@@ -1763,7 +1764,7 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
length. */
features.vq = aarch64_linux_core_read_vq_from_sections (gdbarch, abfd);
features.pauth = hwcap & AARCH64_HWCAP_PACA;
- features.gcs = features.gcs_linux = hwcap & HWCAP_GCS;
+ features.gcs = features.gcs_linux = hwcap & AARCH64_HWCAP_GCS;
features.mte = hwcap2 & AARCH64_HWCAP2_MTE;
features.fpmr = hwcap2 & AARCH64_HWCAP2_FPMR;
@@ -2612,7 +2613,7 @@ aarch64_linux_get_shadow_stack_pointer (gdbarch *gdbarch, regcache *regcache,
if (status != REG_VALID)
error (_("Can't read $gcspr."));
- shadow_stack_enabled = features_enabled & PR_SHADOW_STACK_ENABLE;
+ shadow_stack_enabled = features_enabled & AARCH64_PR_SHADOW_STACK_ENABLE;
return gcspr;
}
@@ -2700,7 +2701,7 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
if (si_code == AARCH64_SEGV_MTEAERR || si_code == AARCH64_SEGV_MTESERR)
meaning = _("Memory tag violation");
- else if (si_code == SEGV_CPERR && si_errno == 0)
+ else if (si_code == AARCH64_SEGV_CPERR && si_errno == 0)
meaning = _("Guarded Control Stack error");
else
return;
@@ -2733,7 +2734,7 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
uiout->field_string ("logical-tag", hex_string (ltag));
}
}
- else if (si_code != SEGV_CPERR)
+ else if (si_code != AARCH64_SEGV_CPERR)
{
uiout->text ("\n");
uiout->text (_("Fault address unavailable"));
diff --git a/gdb/arch/aarch64-gcs-linux.h b/gdb/arch/aarch64-gcs-linux.h
index b31fc32daa03..4aa0cbd4def8 100644
--- a/gdb/arch/aarch64-gcs-linux.h
+++ b/gdb/arch/aarch64-gcs-linux.h
@@ -20,25 +20,17 @@
#ifndef GDB_ARCH_AARCH64_GCS_LINUX_H
#define GDB_ARCH_AARCH64_GCS_LINUX_H
-#include <stdint.h>
-
/* Feature check for Guarded Control Stack. */
-#ifndef HWCAP_GCS
-#define HWCAP_GCS (1ULL << 32)
-#endif
-
-/* Make sure we only define these if the kernel header doesn't. */
-#ifndef GCS_MAGIC
+#define AARCH64_HWCAP_GCS (1ULL << 32)
-/* GCS state (NT_ARM_GCS). */
+#define AARCH64_SEGV_CPERR 10 /* Control protection error. */
-struct user_gcs
-{
- uint64_t features_enabled;
- uint64_t features_locked;
- uint64_t gcspr_el0;
-};
+/* Flag which enables shadow stack in PR_SET_SHADOW_STACK_STATUS prctl. */
+#define AARCH64_PR_SHADOW_STACK_ENABLE (1UL << 0)
+#define AARCH64_PR_SHADOW_STACK_WRITE (1UL << 1)
+#define AARCH64_PR_SHADOW_STACK_PUSH (1UL << 2)
-#endif /* GCS_MAGIC */
+/* The GCS regset consists of 3 64-bit registers. */
+#define AARCH64_LINUX_SIZEOF_GCS_REGSET (3 * 8)
#endif /* GDB_ARCH_AARCH64_GCS_LINUX_H */
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 73d4832069f4..aee52eae0f4a 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -27,17 +27,6 @@
struct inferior;
struct regcache;
-#ifndef SEGV_CPERR
-#define SEGV_CPERR 10 /* Control protection error. */
-#endif
-
-/* Flag which enables shadow stack in PR_SET_SHADOW_STACK_STATUS prctl. */
-#ifndef PR_SHADOW_STACK_ENABLE
-#define PR_SHADOW_STACK_ENABLE (1UL << 0)
-#define PR_SHADOW_STACK_WRITE (1UL << 1)
-#define PR_SHADOW_STACK_PUSH (1UL << 2)
-#endif
-
/* Enum used to define the extra fields of the siginfo type used by an
architecture. */
enum linux_siginfo_extra_field_values
diff --git a/gdb/nat/aarch64-gcs-linux.h b/gdb/nat/aarch64-gcs-linux.h
new file mode 100644
index 000000000000..ddf8342a4284
--- /dev/null
+++ b/gdb/nat/aarch64-gcs-linux.h
@@ -0,0 +1,45 @@
+/* Common native Linux definitions for AArch64 Guarded Control Stack.
+
+ Copyright (C) 2025-2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_NAT_AARCH64_GCS_LINUX_H
+#define GDB_NAT_AARCH64_GCS_LINUX_H
+
+#include <stdint.h>
+#include <asm/ptrace.h>
+
+/* Feature check for Guarded Control Stack. */
+#ifndef HWCAP_GCS
+#define HWCAP_GCS (1ULL << 32)
+#endif
+
+/* Make sure we only define these if the kernel header doesn't. */
+#ifndef GCS_MAGIC
+
+/* GCS state (NT_ARM_GCS). */
+
+struct user_gcs
+{
+ uint64_t features_enabled;
+ uint64_t features_locked;
+ uint64_t gcspr_el0;
+};
+
+#endif /* GCS_MAGIC */
+
+#endif /* GDB_NAT_AARCH64_GCS_LINUX_H */
diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
index c44f75167141..a2588a6e2a9c 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -40,12 +40,12 @@
#include "gdb_proc_service.h"
#include "arch/aarch64.h"
-#include "arch/aarch64-gcs-linux.h"
#include "arch/aarch64-mte-linux.h"
#include "arch/aarch64-pauth-linux.h"
#include "linux-aarch32-tdesc.h"
#include "linux-aarch64-tdesc.h"
#include "nat/aarch64-fpmr-linux.h"
+#include "nat/aarch64-gcs-linux.h"
#include "nat/aarch64-mte-linux-ptrace.h"
#include "nat/aarch64-scalable-linux-ptrace.h"
#include "tdesc.h"
|