diff options
-rw-r--r-- | meta/recipes-devtools/gdb/gdb-cross-canadian_13.2.bb (renamed from meta/recipes-devtools/gdb/gdb-cross-canadian_13.1.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gdb/gdb-cross_13.2.bb (renamed from meta/recipes-devtools/gdb/gdb-cross_13.1.bb) | 0 | ||||
-rw-r--r-- | meta/recipes-devtools/gdb/gdb.inc | 4 | ||||
-rw-r--r-- | meta/recipes-devtools/gdb/gdb/0001-aarch64-Check-for-valid-inferior-thread-regcache-bef.patch | 286 | ||||
-rw-r--r-- | meta/recipes-devtools/gdb/gdb/0009-gdbserver-linux-low.cc-Fix-a-typo-in-ternary-operato.patch | 24 | ||||
-rw-r--r-- | meta/recipes-devtools/gdb/gdb_13.2.bb (renamed from meta/recipes-devtools/gdb/gdb_13.1.bb) | 0 |
6 files changed, 1 insertions, 313 deletions
diff --git a/meta/recipes-devtools/gdb/gdb-cross-canadian_13.1.bb b/meta/recipes-devtools/gdb/gdb-cross-canadian_13.2.bb index 4ab2b7156d..4ab2b7156d 100644 --- a/meta/recipes-devtools/gdb/gdb-cross-canadian_13.1.bb +++ b/meta/recipes-devtools/gdb/gdb-cross-canadian_13.2.bb | |||
diff --git a/meta/recipes-devtools/gdb/gdb-cross_13.1.bb b/meta/recipes-devtools/gdb/gdb-cross_13.2.bb index 3b654a2f0d..3b654a2f0d 100644 --- a/meta/recipes-devtools/gdb/gdb-cross_13.1.bb +++ b/meta/recipes-devtools/gdb/gdb-cross_13.2.bb | |||
diff --git a/meta/recipes-devtools/gdb/gdb.inc b/meta/recipes-devtools/gdb/gdb.inc index 8589de62ff..e986b1a1f9 100644 --- a/meta/recipes-devtools/gdb/gdb.inc +++ b/meta/recipes-devtools/gdb/gdb.inc | |||
@@ -13,10 +13,8 @@ SRC_URI = "${GNU_MIRROR}/gdb/gdb-${PV}.tar.xz \ | |||
13 | file://0006-resolve-restrict-keyword-conflict.patch \ | 13 | file://0006-resolve-restrict-keyword-conflict.patch \ |
14 | file://0007-Fix-invalid-sigprocmask-call.patch \ | 14 | file://0007-Fix-invalid-sigprocmask-call.patch \ |
15 | file://0008-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch \ | 15 | file://0008-Define-alignof-using-_Alignof-when-using-C11-or-newe.patch \ |
16 | file://0009-gdbserver-linux-low.cc-Fix-a-typo-in-ternary-operato.patch \ | ||
17 | file://add-missing-ldflags.patch \ | 16 | file://add-missing-ldflags.patch \ |
18 | file://0001-aarch64-Check-for-valid-inferior-thread-regcache-bef.patch \ | ||
19 | " | 17 | " |
20 | SRC_URI[sha256sum] = "115ad5c18d69a6be2ab15882d365dda2a2211c14f480b3502c6eba576e2e95a0" | 18 | SRC_URI[sha256sum] = "fd5bebb7be1833abdb6e023c2f498a354498281df9d05523d8915babeb893f0a" |
21 | 19 | ||
22 | TOOLCHAIN = "gcc" | 20 | TOOLCHAIN = "gcc" |
diff --git a/meta/recipes-devtools/gdb/gdb/0001-aarch64-Check-for-valid-inferior-thread-regcache-bef.patch b/meta/recipes-devtools/gdb/gdb/0001-aarch64-Check-for-valid-inferior-thread-regcache-bef.patch deleted file mode 100644 index 9adf4a4db5..0000000000 --- a/meta/recipes-devtools/gdb/gdb/0001-aarch64-Check-for-valid-inferior-thread-regcache-bef.patch +++ /dev/null | |||
@@ -1,286 +0,0 @@ | |||
1 | From b3eff3e15576229af9bae026c5c23ee694b90389 Mon Sep 17 00:00:00 2001 | ||
2 | From: Luis Machado <luis.machado@arm.com> | ||
3 | Date: Fri, 24 Mar 2023 07:58:38 +0000 | ||
4 | Subject: [PATCH] aarch64: Check for valid inferior thread/regcache before | ||
5 | reading pauth registers | ||
6 | |||
7 | Upstream-Status: Backport | ||
8 | Signed-off-by: Ross Burton <ross.burton@arm.com> | ||
9 | |||
10 | There were reports of gdb throwing internal errors when calling | ||
11 | inferior_thread ()/get_current_regcache () on a system with | ||
12 | Pointer Authentication enabled. | ||
13 | |||
14 | In such cases, gdb produces the following backtrace, or a variation | ||
15 | of it (for gdb's with the non-address removal implemented only in | ||
16 | the aarch64-linux-tdep.c file). | ||
17 | |||
18 | ../../../repos/binutils-gdb/gdb/thread.c:86: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed. | ||
19 | A problem internal to GDB has been detected, | ||
20 | further debugging may prove unreliable. | ||
21 | ----- Backtrace ----- | ||
22 | 0xaaaae04a571f gdb_internal_backtrace_1 | ||
23 | ../../../repos/binutils-gdb/gdb/bt-utils.c:122 | ||
24 | 0xaaaae04a57f3 _Z22gdb_internal_backtracev | ||
25 | ../../../repos/binutils-gdb/gdb/bt-utils.c:168 | ||
26 | 0xaaaae0b52ccf internal_vproblem | ||
27 | ../../../repos/binutils-gdb/gdb/utils.c:401 | ||
28 | 0xaaaae0b5310b _Z15internal_verrorPKciS0_St9__va_list | ||
29 | ../../../repos/binutils-gdb/gdb/utils.c:481 | ||
30 | 0xaaaae0e24b8f _Z18internal_error_locPKciS0_z | ||
31 | ../../../repos/binutils-gdb/gdbsupport/errors.cc:58 | ||
32 | 0xaaaae0a88983 _Z15inferior_threadv | ||
33 | ../../../repos/binutils-gdb/gdb/thread.c:86 | ||
34 | 0xaaaae0956c87 _Z20get_current_regcachev | ||
35 | ../../../repos/binutils-gdb/gdb/regcache.c:428 | ||
36 | 0xaaaae035223f aarch64_remove_non_address_bits | ||
37 | ../../../repos/binutils-gdb/gdb/aarch64-tdep.c:3572 | ||
38 | 0xaaaae03e8abb _Z31gdbarch_remove_non_address_bitsP7gdbarchm | ||
39 | ../../../repos/binutils-gdb/gdb/gdbarch.c:3109 | ||
40 | 0xaaaae0a692d7 memory_xfer_partial | ||
41 | ../../../repos/binutils-gdb/gdb/target.c:1620 | ||
42 | 0xaaaae0a695e3 _Z19target_xfer_partialP10target_ops13target_objectPKcPhPKhmmPm | ||
43 | ../../../repos/binutils-gdb/gdb/target.c:1684 | ||
44 | 0xaaaae0a69e9f target_read_partial | ||
45 | ../../../repos/binutils-gdb/gdb/target.c:1937 | ||
46 | 0xaaaae0a69fdf _Z11target_readP10target_ops13target_objectPKcPhml | ||
47 | ../../../repos/binutils-gdb/gdb/target.c:1977 | ||
48 | 0xaaaae0a69937 _Z18target_read_memorymPhl | ||
49 | ../../../repos/binutils-gdb/gdb/target.c:1773 | ||
50 | 0xaaaae08be523 ps_xfer_memory | ||
51 | ../../../repos/binutils-gdb/gdb/proc-service.c:90 | ||
52 | 0xaaaae08be6db ps_pdread | ||
53 | ../../../repos/binutils-gdb/gdb/proc-service.c:124 | ||
54 | 0x40001ed7c3b3 _td_fetch_value | ||
55 | /build/glibc-RIFKjK/glibc-2.31/nptl_db/fetch-value.c:115 | ||
56 | 0x40001ed791ef td_ta_map_lwp2thr | ||
57 | /build/glibc-RIFKjK/glibc-2.31/nptl_db/td_ta_map_lwp2thr.c:194 | ||
58 | 0xaaaae07f4473 thread_from_lwp | ||
59 | ../../../repos/binutils-gdb/gdb/linux-thread-db.c:413 | ||
60 | 0xaaaae07f6d6f _ZN16thread_db_target4waitE6ptid_tP17target_waitstatus10enum_flagsI16target_wait_flagE | ||
61 | ../../../repos/binutils-gdb/gdb/linux-thread-db.c:1420 | ||
62 | 0xaaaae0a6b33b _Z11target_wait6ptid_tP17target_waitstatus10enum_flagsI16target_wait_flagE | ||
63 | ../../../repos/binutils-gdb/gdb/target.c:2586 | ||
64 | 0xaaaae0789cf7 do_target_wait_1 | ||
65 | ../../../repos/binutils-gdb/gdb/infrun.c:3825 | ||
66 | 0xaaaae0789e6f operator() | ||
67 | ../../../repos/binutils-gdb/gdb/infrun.c:3884 | ||
68 | 0xaaaae078a167 do_target_wait | ||
69 | ../../../repos/binutils-gdb/gdb/infrun.c:3903 | ||
70 | 0xaaaae078b0af _Z20fetch_inferior_eventv | ||
71 | ../../../repos/binutils-gdb/gdb/infrun.c:4314 | ||
72 | 0xaaaae076652f _Z22inferior_event_handler19inferior_event_type | ||
73 | ../../../repos/binutils-gdb/gdb/inf-loop.c:41 | ||
74 | 0xaaaae07dc68b handle_target_event | ||
75 | ../../../repos/binutils-gdb/gdb/linux-nat.c:4206 | ||
76 | 0xaaaae0e25fbb handle_file_event | ||
77 | ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:573 | ||
78 | 0xaaaae0e264f3 gdb_wait_for_event | ||
79 | ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:694 | ||
80 | 0xaaaae0e24f9b _Z16gdb_do_one_eventi | ||
81 | ../../../repos/binutils-gdb/gdbsupport/event-loop.cc:217 | ||
82 | 0xaaaae080f033 start_event_loop | ||
83 | ../../../repos/binutils-gdb/gdb/main.c:411 | ||
84 | 0xaaaae080f1b7 captured_command_loop | ||
85 | ../../../repos/binutils-gdb/gdb/main.c:475 | ||
86 | 0xaaaae0810b97 captured_main | ||
87 | ../../../repos/binutils-gdb/gdb/main.c:1318 | ||
88 | 0xaaaae0810c1b _Z8gdb_mainP18captured_main_args | ||
89 | ../../../repos/binutils-gdb/gdb/main.c:1337 | ||
90 | 0xaaaae0338453 main | ||
91 | ../../../repos/binutils-gdb/gdb/gdb.c:32 | ||
92 | --------------------- | ||
93 | ../../../repos/binutils-gdb/gdb/thread.c:86: internal-error: inferior_thread: Assertion `current_thread_ != nullptr' failed. | ||
94 | A problem internal to GDB has been detected, | ||
95 | further debugging may prove unreliable. | ||
96 | Quit this debugging session? (y or n) | ||
97 | |||
98 | We also see failures across the testsuite if the tests get executed on a target | ||
99 | that has native support for the pointer authentication feature. But | ||
100 | gdb.base/break.exp and gdb.base/access-mem-running.exp are two examples of | ||
101 | tests that run into errors and internal errors. | ||
102 | |||
103 | This issue started after commit d88cb738e6a7a7179dfaff8af78d69250c852af1, which | ||
104 | enabled more broad use of pointer authentication masks to remove non-address | ||
105 | bits of pointers, but wasn't immediately detected because systems with native | ||
106 | support for pointer authentication are not that common yet. | ||
107 | |||
108 | The above crash happens because gdb is in the middle of handling an event, | ||
109 | and do_target_wait_1 calls switch_to_inferior_no_thread, nullifying the | ||
110 | current thread. This means a call to inferior_thread () will assert, and | ||
111 | attempting to call get_current_regcache () will also call inferior_thread (), | ||
112 | resulting in an assertion as well. | ||
113 | |||
114 | target_has_registers was one function that seemed useful for detecting these | ||
115 | types of situation where we don't have a register cache. The problem with that | ||
116 | is the inconsistent state of inferior_ptid, which is used by | ||
117 | target_has_registers. | ||
118 | |||
119 | Despite the call to switch_to_no_thread in switch_to_inferior_no_thread from | ||
120 | do_target_wait_1 in the backtrace above clearing inferior_ptid, the call to | ||
121 | ps_xfer_memory sets inferior_ptid momentarily before reading memory: | ||
122 | |||
123 | static ps_err_e | ||
124 | ps_xfer_memory (const struct ps_prochandle *ph, psaddr_t addr, | ||
125 | gdb_byte *buf, size_t len, int write) | ||
126 | { | ||
127 | scoped_restore_current_inferior restore_inferior; | ||
128 | set_current_inferior (ph->thread->inf); | ||
129 | |||
130 | scoped_restore_current_program_space restore_current_progspace; | ||
131 | set_current_program_space (ph->thread->inf->pspace); | ||
132 | |||
133 | scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid); | ||
134 | inferior_ptid = ph->thread->ptid; | ||
135 | |||
136 | CORE_ADDR core_addr = ps_addr_to_core_addr (addr); | ||
137 | |||
138 | int ret; | ||
139 | if (write) | ||
140 | ret = target_write_memory (core_addr, buf, len); | ||
141 | else | ||
142 | ret = target_read_memory (core_addr, buf, len); | ||
143 | return (ret == 0 ? PS_OK : PS_ERR); | ||
144 | } | ||
145 | |||
146 | Maybe this shouldn't happen, or maybe it is just an unfortunate state to be | ||
147 | in. But this prevents the use of target_has_registers to guard against the | ||
148 | lack of registers, since, although current_thread_ is still nullptr, | ||
149 | inferior_ptid is valid and is not null_ptid. | ||
150 | |||
151 | There is another crash scenario after we kill a previously active inferior, in | ||
152 | which case the gdbarch will still say we support pointer authentication but we | ||
153 | will also have no current thread (inferior_thread () will assert etc). | ||
154 | |||
155 | If the target has support for pointer authentication, gdb needs to use | ||
156 | a couple (or 4, for bare-metal) mask registers to mask off some bits of | ||
157 | pointers, and for that it needs to access the registers. | ||
158 | |||
159 | At some points, like the one from the backtrace above, there is no active | ||
160 | thread/current regcache because gdb is in the middle of doing event handling | ||
161 | and switching between threads. | ||
162 | |||
163 | Simon suggested the use of inferior_ptid to fetch the register cache, as | ||
164 | opposed to relying on the current register cache. Though we need to make sure | ||
165 | inferior_ptid is valid (not null_ptid), I think this works nicely. | ||
166 | |||
167 | With inferior_ptid, we can do safety checks along the way, making sure we have | ||
168 | a thread to fetch a register cache from and checking if the thread is actually | ||
169 | stopped or running. | ||
170 | |||
171 | The following patch implements this idea with safety checks to make sure we | ||
172 | don't run into assertions or errors. If any of the checks fail, we fallback to | ||
173 | using a default mask to remove non-address bits of a pointer. | ||
174 | |||
175 | I discussed with Pedro the possibility of caching the mask register values | ||
176 | (which are per-process and can change mid-execution), but there isn't a good | ||
177 | spot to cache those values. Besides, the mask registers can change constantly | ||
178 | for bare-metal debugging when switching between exception levels. | ||
179 | |||
180 | In some cases, it is just not possible to get access to these mask registers, | ||
181 | like the case where threads are running. In those cases, using a default mask | ||
182 | to remove the non-address bits should be enough. | ||
183 | |||
184 | This can happen when we let threads run in the background and then we attempt | ||
185 | to access a memory address (now that gdb is capable of reading memory even | ||
186 | with threads running). Thus gdb will attempt to remove non-address bits | ||
187 | of that memory access, will attempt to access registers, running into errors. | ||
188 | |||
189 | Regression-tested on aarch64-linux Ubuntu 20.04. | ||
190 | --- | ||
191 | gdb/aarch64-linux-tdep.c | 64 ++++++++++++++++++++++++++++++---------- | ||
192 | 1 file changed, 49 insertions(+), 15 deletions(-) | ||
193 | |||
194 | diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c | ||
195 | index 20a041c599e..4b2915b8e99 100644 | ||
196 | --- a/gdb/aarch64-linux-tdep.c | ||
197 | +++ b/gdb/aarch64-linux-tdep.c | ||
198 | @@ -57,6 +57,9 @@ | ||
199 | #include "elf/common.h" | ||
200 | #include "elf/aarch64.h" | ||
201 | |||
202 | +/* For inferior_ptid and current_inferior (). */ | ||
203 | +#include "inferior.h" | ||
204 | + | ||
205 | /* Signal frame handling. | ||
206 | |||
207 | +------------+ ^ | ||
208 | @@ -1986,29 +1989,60 @@ aarch64_linux_decode_memtag_section (struct gdbarch *gdbarch, | ||
209 | static CORE_ADDR | ||
210 | aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer) | ||
211 | { | ||
212 | - aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_gdbarch_tdep> (gdbarch); | ||
213 | - | ||
214 | /* By default, we assume TBI and discard the top 8 bits plus the VA range | ||
215 | - select bit (55). */ | ||
216 | + select bit (55). Below we try to fetch information about pointer | ||
217 | + authentication masks in order to make non-address removal more | ||
218 | + precise. */ | ||
219 | CORE_ADDR mask = AARCH64_TOP_BITS_MASK; | ||
220 | |||
221 | - if (tdep->has_pauth ()) | ||
222 | + /* Check if we have an inferior first. If not, just use the default | ||
223 | + mask. | ||
224 | + | ||
225 | + We use the inferior_ptid here because the pointer authentication masks | ||
226 | + should be the same across threads of a process. Since we may not have | ||
227 | + access to the current thread (gdb may have switched to no inferiors | ||
228 | + momentarily), we use the inferior ptid. */ | ||
229 | + if (inferior_ptid != null_ptid) | ||
230 | { | ||
231 | - /* Fetch the PAC masks. These masks are per-process, so we can just | ||
232 | - fetch data from whatever thread we have at the moment. | ||
233 | + /* If we do have an inferior, attempt to fetch its thread's thread_info | ||
234 | + struct. */ | ||
235 | + thread_info *thread | ||
236 | + = find_thread_ptid (current_inferior ()->process_target (), | ||
237 | + inferior_ptid); | ||
238 | |||
239 | - Also, we have both a code mask and a data mask. For now they are the | ||
240 | - same, but this may change in the future. */ | ||
241 | - struct regcache *regs = get_current_regcache (); | ||
242 | - CORE_ADDR cmask, dmask; | ||
243 | + /* If the thread is running, we will not be able to fetch the mask | ||
244 | + registers. */ | ||
245 | + if (thread != nullptr && thread->state != THREAD_RUNNING) | ||
246 | + { | ||
247 | + /* Otherwise, fetch the register cache and the masks. */ | ||
248 | + struct regcache *regs | ||
249 | + = get_thread_regcache (current_inferior ()->process_target (), | ||
250 | + inferior_ptid); | ||
251 | + | ||
252 | + /* Use the gdbarch from the register cache to check for pointer | ||
253 | + authentication support, as it matches the features found in | ||
254 | + that particular thread. */ | ||
255 | + aarch64_gdbarch_tdep *tdep | ||
256 | + = gdbarch_tdep<aarch64_gdbarch_tdep> (regs->arch ()); | ||
257 | + | ||
258 | + /* Is there pointer authentication support? */ | ||
259 | + if (tdep->has_pauth ()) | ||
260 | + { | ||
261 | + /* We have both a code mask and a data mask. For now they are | ||
262 | + the same, but this may change in the future. */ | ||
263 | + CORE_ADDR cmask, dmask; | ||
264 | |||
265 | - if (regs->cooked_read (tdep->pauth_reg_base, &dmask) != REG_VALID) | ||
266 | - dmask = mask; | ||
267 | + if (regs->cooked_read (tdep->pauth_reg_base, &dmask) | ||
268 | + != REG_VALID) | ||
269 | + dmask = mask; | ||
270 | |||
271 | - if (regs->cooked_read (tdep->pauth_reg_base + 1, &cmask) != REG_VALID) | ||
272 | - cmask = mask; | ||
273 | + if (regs->cooked_read (tdep->pauth_reg_base + 1, &cmask) | ||
274 | + != REG_VALID) | ||
275 | + cmask = mask; | ||
276 | |||
277 | - mask |= aarch64_mask_from_pac_registers (cmask, dmask); | ||
278 | + mask |= aarch64_mask_from_pac_registers (cmask, dmask); | ||
279 | + } | ||
280 | + } | ||
281 | } | ||
282 | |||
283 | return aarch64_remove_top_bits (pointer, mask); | ||
284 | -- | ||
285 | 2.34.1 | ||
286 | |||
diff --git a/meta/recipes-devtools/gdb/gdb/0009-gdbserver-linux-low.cc-Fix-a-typo-in-ternary-operato.patch b/meta/recipes-devtools/gdb/gdb/0009-gdbserver-linux-low.cc-Fix-a-typo-in-ternary-operato.patch deleted file mode 100644 index 32eba089bc..0000000000 --- a/meta/recipes-devtools/gdb/gdb/0009-gdbserver-linux-low.cc-Fix-a-typo-in-ternary-operato.patch +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | From 9a85132c4ba7d37a5df146239b3ab1a5854ce478 Mon Sep 17 00:00:00 2001 | ||
2 | From: Khem Raj <raj.khem@gmail.com> | ||
3 | Date: Wed, 22 Feb 2023 16:24:07 -0800 | ||
4 | Subject: [PATCH] gdbserver/linux-low.cc: Fix a typo in ternary operator | ||
5 | |||
6 | Upstream-Status: Submitted [https://sourceware.org/pipermail/gdb-patches/2023-February/197298.html] | ||
7 | Signed-off-by: Khem Raj <raj.khem@gmail.com> | ||
8 | --- | ||
9 | gdbserver/linux-low.cc | 2 +- | ||
10 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
11 | |||
12 | diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc | ||
13 | index 7e1de397893..95ec871d436 100644 | ||
14 | --- a/gdbserver/linux-low.cc | ||
15 | +++ b/gdbserver/linux-low.cc | ||
16 | @@ -5390,7 +5390,7 @@ proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf, | ||
17 | if (lseek (fd, memaddr, SEEK_SET) != -1) | ||
18 | bytes = (readbuf != nullptr | ||
19 | ? read (fd, readbuf, len) | ||
20 | - ? write (fd, writebuf, len)); | ||
21 | + : write (fd, writebuf, len)); | ||
22 | #endif | ||
23 | |||
24 | if (bytes < 0) | ||
diff --git a/meta/recipes-devtools/gdb/gdb_13.1.bb b/meta/recipes-devtools/gdb/gdb_13.2.bb index 9c6db4ca2c..9c6db4ca2c 100644 --- a/meta/recipes-devtools/gdb/gdb_13.1.bb +++ b/meta/recipes-devtools/gdb/gdb_13.2.bb | |||