Commit | Line | Data |
---|---|---|
93813b37 WT |
1 | /* Low-level siginfo manipulation for amd64. |
2 | ||
e2882c85 | 3 | Copyright (C) 2002-2018 Free Software Foundation, Inc. |
93813b37 WT |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include <signal.h> | |
21 | #include "common-defs.h" | |
22 | #include "amd64-linux-siginfo.h" | |
23 | ||
9cf12d57 PA |
24 | #define GDB_SI_SIZE 128 |
25 | ||
26 | /* The types below define the most complete kernel siginfo types known | |
27 | for the architecture, independent of the system/libc headers. They | |
28 | are named from a 64-bit kernel's perspective: | |
29 | ||
30 | | layout | type | | |
31 | |--------+----------------------| | |
32 | | 64-bit | nat_siginfo_t | | |
33 | | 32-bit | compat_siginfo_t | | |
34 | | x32 | compat_x32_siginfo_t | | |
35 | */ | |
36 | ||
37 | #ifndef __ILP32__ | |
3f2f6cb5 WT |
38 | |
39 | typedef int nat_int_t; | |
9cf12d57 | 40 | typedef unsigned long nat_uptr_t; |
3f2f6cb5 WT |
41 | |
42 | typedef int nat_time_t; | |
43 | typedef int nat_timer_t; | |
44 | ||
9cf12d57 PA |
45 | /* For native 64-bit, clock_t in _sigchld is 64-bit. */ |
46 | typedef long nat_clock_t; | |
3f2f6cb5 WT |
47 | |
48 | typedef union nat_sigval | |
49 | { | |
50 | nat_int_t sival_int; | |
51 | nat_uptr_t sival_ptr; | |
52 | } nat_sigval_t; | |
53 | ||
54 | typedef struct nat_siginfo | |
55 | { | |
56 | int si_signo; | |
57 | int si_errno; | |
58 | int si_code; | |
59 | ||
60 | union | |
61 | { | |
62 | int _pad[((128 / sizeof (int)) - 4)]; | |
63 | /* kill() */ | |
64 | struct | |
65 | { | |
66 | unsigned int _pid; | |
67 | unsigned int _uid; | |
68 | } _kill; | |
69 | ||
70 | /* POSIX.1b timers */ | |
71 | struct | |
72 | { | |
73 | nat_timer_t _tid; | |
74 | int _overrun; | |
75 | nat_sigval_t _sigval; | |
76 | } _timer; | |
77 | ||
78 | /* POSIX.1b signals */ | |
79 | struct | |
80 | { | |
81 | unsigned int _pid; | |
82 | unsigned int _uid; | |
83 | nat_sigval_t _sigval; | |
84 | } _rt; | |
85 | ||
86 | /* SIGCHLD */ | |
87 | struct | |
88 | { | |
89 | unsigned int _pid; | |
90 | unsigned int _uid; | |
91 | int _status; | |
92 | nat_clock_t _utime; | |
93 | nat_clock_t _stime; | |
94 | } _sigchld; | |
95 | ||
96 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
97 | struct | |
98 | { | |
99 | nat_uptr_t _addr; | |
100 | short int _addr_lsb; | |
101 | struct | |
102 | { | |
103 | nat_uptr_t _lower; | |
104 | nat_uptr_t _upper; | |
105 | } si_addr_bnd; | |
106 | } _sigfault; | |
107 | ||
108 | /* SIGPOLL */ | |
109 | struct | |
110 | { | |
111 | int _band; | |
112 | int _fd; | |
113 | } _sigpoll; | |
114 | } _sifields; | |
9cf12d57 | 115 | } nat_siginfo_t; |
3f2f6cb5 | 116 | |
9cf12d57 | 117 | #endif /* __ILP32__ */ |
3f2f6cb5 | 118 | |
93813b37 WT |
119 | /* These types below (compat_*) define a siginfo type that is layout |
120 | compatible with the siginfo type exported by the 32-bit userspace | |
121 | support. */ | |
122 | ||
123 | typedef int compat_int_t; | |
124 | typedef unsigned int compat_uptr_t; | |
125 | ||
126 | typedef int compat_time_t; | |
127 | typedef int compat_timer_t; | |
128 | typedef int compat_clock_t; | |
129 | ||
130 | struct compat_timeval | |
131 | { | |
132 | compat_time_t tv_sec; | |
133 | int tv_usec; | |
134 | }; | |
135 | ||
136 | typedef union compat_sigval | |
137 | { | |
138 | compat_int_t sival_int; | |
139 | compat_uptr_t sival_ptr; | |
140 | } compat_sigval_t; | |
141 | ||
142 | typedef struct compat_siginfo | |
143 | { | |
144 | int si_signo; | |
145 | int si_errno; | |
146 | int si_code; | |
147 | ||
148 | union | |
149 | { | |
150 | int _pad[((128 / sizeof (int)) - 3)]; | |
151 | ||
152 | /* kill() */ | |
153 | struct | |
154 | { | |
155 | unsigned int _pid; | |
156 | unsigned int _uid; | |
157 | } _kill; | |
158 | ||
159 | /* POSIX.1b timers */ | |
160 | struct | |
161 | { | |
162 | compat_timer_t _tid; | |
163 | int _overrun; | |
164 | compat_sigval_t _sigval; | |
165 | } _timer; | |
166 | ||
167 | /* POSIX.1b signals */ | |
168 | struct | |
169 | { | |
170 | unsigned int _pid; | |
171 | unsigned int _uid; | |
172 | compat_sigval_t _sigval; | |
173 | } _rt; | |
174 | ||
175 | /* SIGCHLD */ | |
176 | struct | |
177 | { | |
178 | unsigned int _pid; | |
179 | unsigned int _uid; | |
180 | int _status; | |
181 | compat_clock_t _utime; | |
182 | compat_clock_t _stime; | |
183 | } _sigchld; | |
184 | ||
185 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
186 | struct | |
187 | { | |
188 | unsigned int _addr; | |
3f2f6cb5 WT |
189 | short int _addr_lsb; |
190 | struct | |
191 | { | |
192 | unsigned int _lower; | |
193 | unsigned int _upper; | |
194 | } si_addr_bnd; | |
93813b37 WT |
195 | } _sigfault; |
196 | ||
197 | /* SIGPOLL */ | |
198 | struct | |
199 | { | |
200 | int _band; | |
201 | int _fd; | |
202 | } _sigpoll; | |
203 | } _sifields; | |
204 | } compat_siginfo_t; | |
205 | ||
206 | /* For x32, clock_t in _sigchld is 64bit aligned at 4 bytes. */ | |
207 | typedef long __attribute__ ((__aligned__ (4))) compat_x32_clock_t; | |
208 | ||
209 | typedef struct compat_x32_siginfo | |
210 | { | |
211 | int si_signo; | |
212 | int si_errno; | |
213 | int si_code; | |
214 | ||
215 | union | |
216 | { | |
217 | int _pad[((128 / sizeof (int)) - 3)]; | |
218 | ||
219 | /* kill() */ | |
220 | struct | |
221 | { | |
222 | unsigned int _pid; | |
223 | unsigned int _uid; | |
224 | } _kill; | |
225 | ||
226 | /* POSIX.1b timers */ | |
227 | struct | |
228 | { | |
229 | compat_timer_t _tid; | |
230 | int _overrun; | |
231 | compat_sigval_t _sigval; | |
232 | } _timer; | |
233 | ||
234 | /* POSIX.1b signals */ | |
235 | struct | |
236 | { | |
237 | unsigned int _pid; | |
238 | unsigned int _uid; | |
239 | compat_sigval_t _sigval; | |
240 | } _rt; | |
241 | ||
242 | /* SIGCHLD */ | |
243 | struct | |
244 | { | |
245 | unsigned int _pid; | |
246 | unsigned int _uid; | |
247 | int _status; | |
248 | compat_x32_clock_t _utime; | |
249 | compat_x32_clock_t _stime; | |
250 | } _sigchld; | |
251 | ||
252 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | |
253 | struct | |
254 | { | |
255 | unsigned int _addr; | |
3f2f6cb5 | 256 | unsigned int _addr_lsb; |
93813b37 WT |
257 | } _sigfault; |
258 | ||
259 | /* SIGPOLL */ | |
260 | struct | |
261 | { | |
262 | int _band; | |
263 | int _fd; | |
264 | } _sigpoll; | |
265 | } _sifields; | |
266 | } compat_x32_siginfo_t __attribute__ ((__aligned__ (8))); | |
267 | ||
268 | /* To simplify usage of siginfo fields. */ | |
269 | ||
270 | #define cpt_si_pid _sifields._kill._pid | |
271 | #define cpt_si_uid _sifields._kill._uid | |
272 | #define cpt_si_timerid _sifields._timer._tid | |
273 | #define cpt_si_overrun _sifields._timer._overrun | |
274 | #define cpt_si_status _sifields._sigchld._status | |
275 | #define cpt_si_utime _sifields._sigchld._utime | |
276 | #define cpt_si_stime _sifields._sigchld._stime | |
277 | #define cpt_si_ptr _sifields._rt._sigval.sival_ptr | |
278 | #define cpt_si_addr _sifields._sigfault._addr | |
3f2f6cb5 | 279 | #define cpt_si_addr_lsb _sifields._sigfault._addr_lsb |
93813b37 WT |
280 | #define cpt_si_band _sifields._sigpoll._band |
281 | #define cpt_si_fd _sifields._sigpoll._fd | |
282 | ||
283 | /* glibc at least up to 2.3.2 doesn't have si_timerid, si_overrun. | |
284 | In their place is si_timer1,si_timer2. */ | |
285 | ||
286 | #ifndef si_timerid | |
287 | #define si_timerid si_timer1 | |
288 | #endif | |
289 | #ifndef si_overrun | |
290 | #define si_overrun si_timer2 | |
291 | #endif | |
292 | ||
9cf12d57 PA |
293 | /* The type of the siginfo object the kernel returns in |
294 | PTRACE_GETSIGINFO. If gdb is built as a x32 program, we get a x32 | |
295 | siginfo. */ | |
296 | #ifdef __ILP32__ | |
297 | typedef compat_x32_siginfo_t ptrace_siginfo_t; | |
298 | #else | |
299 | typedef nat_siginfo_t ptrace_siginfo_t; | |
300 | #endif | |
301 | ||
93813b37 WT |
302 | /* Convert the system provided siginfo into compatible siginfo. */ |
303 | ||
304 | static void | |
9cf12d57 | 305 | compat_siginfo_from_siginfo (compat_siginfo_t *to, const siginfo_t *from) |
93813b37 | 306 | { |
9cf12d57 | 307 | ptrace_siginfo_t from_ptrace; |
3f2f6cb5 | 308 | |
9cf12d57 | 309 | memcpy (&from_ptrace, from, sizeof (from_ptrace)); |
93813b37 WT |
310 | memset (to, 0, sizeof (*to)); |
311 | ||
9cf12d57 PA |
312 | to->si_signo = from_ptrace.si_signo; |
313 | to->si_errno = from_ptrace.si_errno; | |
314 | to->si_code = from_ptrace.si_code; | |
93813b37 WT |
315 | |
316 | if (to->si_code == SI_TIMER) | |
317 | { | |
9cf12d57 PA |
318 | to->cpt_si_timerid = from_ptrace.cpt_si_timerid; |
319 | to->cpt_si_overrun = from_ptrace.cpt_si_overrun; | |
320 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
321 | } |
322 | else if (to->si_code == SI_USER) | |
323 | { | |
9cf12d57 PA |
324 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
325 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
93813b37 WT |
326 | } |
327 | else if (to->si_code < 0) | |
328 | { | |
9cf12d57 PA |
329 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
330 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
331 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
332 | } |
333 | else | |
334 | { | |
335 | switch (to->si_signo) | |
336 | { | |
337 | case SIGCHLD: | |
9cf12d57 PA |
338 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
339 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
340 | to->cpt_si_status = from_ptrace.cpt_si_status; | |
341 | to->cpt_si_utime = from_ptrace.cpt_si_utime; | |
342 | to->cpt_si_stime = from_ptrace.cpt_si_stime; | |
93813b37 WT |
343 | break; |
344 | case SIGILL: | |
345 | case SIGFPE: | |
346 | case SIGSEGV: | |
347 | case SIGBUS: | |
9cf12d57 | 348 | to->cpt_si_addr = from_ptrace.cpt_si_addr; |
93813b37 WT |
349 | break; |
350 | case SIGPOLL: | |
9cf12d57 PA |
351 | to->cpt_si_band = from_ptrace.cpt_si_band; |
352 | to->cpt_si_fd = from_ptrace.cpt_si_fd; | |
93813b37 WT |
353 | break; |
354 | default: | |
9cf12d57 PA |
355 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
356 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
357 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
358 | break; |
359 | } | |
360 | } | |
361 | } | |
362 | ||
363 | /* Convert the compatible siginfo into system siginfo. */ | |
364 | ||
365 | static void | |
9cf12d57 | 366 | siginfo_from_compat_siginfo (siginfo_t *to, const compat_siginfo_t *from) |
93813b37 | 367 | { |
9cf12d57 | 368 | ptrace_siginfo_t to_ptrace; |
93813b37 | 369 | |
9cf12d57 | 370 | memset (&to_ptrace, 0, sizeof (to_ptrace)); |
93813b37 | 371 | |
9cf12d57 PA |
372 | to_ptrace.si_signo = from->si_signo; |
373 | to_ptrace.si_errno = from->si_errno; | |
374 | to_ptrace.si_code = from->si_code; | |
3f2f6cb5 | 375 | |
9cf12d57 | 376 | if (to_ptrace.si_code == SI_TIMER) |
93813b37 | 377 | { |
9cf12d57 PA |
378 | to_ptrace.cpt_si_timerid = from->cpt_si_timerid; |
379 | to_ptrace.cpt_si_overrun = from->cpt_si_overrun; | |
380 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 | 381 | } |
9cf12d57 | 382 | else if (to_ptrace.si_code == SI_USER) |
93813b37 | 383 | { |
9cf12d57 PA |
384 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
385 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
93813b37 | 386 | } |
9cf12d57 | 387 | if (to_ptrace.si_code < 0) |
93813b37 | 388 | { |
9cf12d57 PA |
389 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
390 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
391 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
392 | } |
393 | else | |
394 | { | |
9cf12d57 | 395 | switch (to_ptrace.si_signo) |
93813b37 WT |
396 | { |
397 | case SIGCHLD: | |
9cf12d57 PA |
398 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
399 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
400 | to_ptrace.cpt_si_status = from->cpt_si_status; | |
401 | to_ptrace.cpt_si_utime = from->cpt_si_utime; | |
402 | to_ptrace.cpt_si_stime = from->cpt_si_stime; | |
93813b37 WT |
403 | break; |
404 | case SIGILL: | |
405 | case SIGFPE: | |
406 | case SIGSEGV: | |
407 | case SIGBUS: | |
9cf12d57 PA |
408 | to_ptrace.cpt_si_addr = from->cpt_si_addr; |
409 | to_ptrace.cpt_si_addr_lsb = from->cpt_si_addr_lsb; | |
93813b37 WT |
410 | break; |
411 | case SIGPOLL: | |
9cf12d57 PA |
412 | to_ptrace.cpt_si_band = from->cpt_si_band; |
413 | to_ptrace.cpt_si_fd = from->cpt_si_fd; | |
93813b37 WT |
414 | break; |
415 | default: | |
9cf12d57 PA |
416 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
417 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
418 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
419 | break; |
420 | } | |
421 | } | |
9cf12d57 | 422 | memcpy (to, &to_ptrace, sizeof (to_ptrace)); |
93813b37 WT |
423 | } |
424 | ||
425 | /* Convert the system provided siginfo into compatible x32 siginfo. */ | |
426 | ||
427 | static void | |
428 | compat_x32_siginfo_from_siginfo (compat_x32_siginfo_t *to, | |
9cf12d57 | 429 | const siginfo_t *from) |
93813b37 | 430 | { |
9cf12d57 | 431 | ptrace_siginfo_t from_ptrace; |
3f2f6cb5 | 432 | |
9cf12d57 | 433 | memcpy (&from_ptrace, from, sizeof (from_ptrace)); |
93813b37 WT |
434 | memset (to, 0, sizeof (*to)); |
435 | ||
9cf12d57 PA |
436 | to->si_signo = from_ptrace.si_signo; |
437 | to->si_errno = from_ptrace.si_errno; | |
438 | to->si_code = from_ptrace.si_code; | |
93813b37 WT |
439 | |
440 | if (to->si_code == SI_TIMER) | |
441 | { | |
9cf12d57 PA |
442 | to->cpt_si_timerid = from_ptrace.cpt_si_timerid; |
443 | to->cpt_si_overrun = from_ptrace.cpt_si_overrun; | |
444 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
445 | } |
446 | else if (to->si_code == SI_USER) | |
447 | { | |
9cf12d57 PA |
448 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
449 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
93813b37 WT |
450 | } |
451 | else if (to->si_code < 0) | |
452 | { | |
9cf12d57 PA |
453 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
454 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
455 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
456 | } |
457 | else | |
458 | { | |
459 | switch (to->si_signo) | |
460 | { | |
461 | case SIGCHLD: | |
9cf12d57 PA |
462 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
463 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
464 | to->cpt_si_status = from_ptrace.cpt_si_status; | |
465 | memcpy (&to->cpt_si_utime, &from_ptrace.cpt_si_utime, | |
93813b37 | 466 | sizeof (to->cpt_si_utime)); |
9cf12d57 | 467 | memcpy (&to->cpt_si_stime, &from_ptrace.cpt_si_stime, |
93813b37 WT |
468 | sizeof (to->cpt_si_stime)); |
469 | break; | |
470 | case SIGILL: | |
471 | case SIGFPE: | |
472 | case SIGSEGV: | |
473 | case SIGBUS: | |
9cf12d57 | 474 | to->cpt_si_addr = from_ptrace.cpt_si_addr; |
93813b37 WT |
475 | break; |
476 | case SIGPOLL: | |
9cf12d57 PA |
477 | to->cpt_si_band = from_ptrace.cpt_si_band; |
478 | to->cpt_si_fd = from_ptrace.cpt_si_fd; | |
93813b37 WT |
479 | break; |
480 | default: | |
9cf12d57 PA |
481 | to->cpt_si_pid = from_ptrace.cpt_si_pid; |
482 | to->cpt_si_uid = from_ptrace.cpt_si_uid; | |
483 | to->cpt_si_ptr = from_ptrace.cpt_si_ptr; | |
93813b37 WT |
484 | break; |
485 | } | |
486 | } | |
487 | } | |
488 | ||
3f2f6cb5 WT |
489 | |
490 | ||
491 | ||
93813b37 WT |
492 | /* Convert the compatible x32 siginfo into system siginfo. */ |
493 | static void | |
494 | siginfo_from_compat_x32_siginfo (siginfo_t *to, | |
9cf12d57 | 495 | const compat_x32_siginfo_t *from) |
93813b37 | 496 | { |
9cf12d57 | 497 | ptrace_siginfo_t to_ptrace; |
93813b37 | 498 | |
9cf12d57 PA |
499 | memset (&to_ptrace, 0, sizeof (to_ptrace)); |
500 | to_ptrace.si_signo = from->si_signo; | |
501 | to_ptrace.si_errno = from->si_errno; | |
502 | to_ptrace.si_code = from->si_code; | |
93813b37 | 503 | |
9cf12d57 | 504 | if (to_ptrace.si_code == SI_TIMER) |
93813b37 | 505 | { |
9cf12d57 PA |
506 | to_ptrace.cpt_si_timerid = from->cpt_si_timerid; |
507 | to_ptrace.cpt_si_overrun = from->cpt_si_overrun; | |
508 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 | 509 | } |
9cf12d57 | 510 | else if (to_ptrace.si_code == SI_USER) |
93813b37 | 511 | { |
9cf12d57 PA |
512 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
513 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
93813b37 | 514 | } |
9cf12d57 | 515 | if (to_ptrace.si_code < 0) |
93813b37 | 516 | { |
9cf12d57 PA |
517 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
518 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
519 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
520 | } |
521 | else | |
522 | { | |
9cf12d57 | 523 | switch (to_ptrace.si_signo) |
93813b37 WT |
524 | { |
525 | case SIGCHLD: | |
9cf12d57 PA |
526 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
527 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
528 | to_ptrace.cpt_si_status = from->cpt_si_status; | |
529 | memcpy (&to_ptrace.cpt_si_utime, &from->cpt_si_utime, | |
530 | sizeof (to_ptrace.cpt_si_utime)); | |
531 | memcpy (&to_ptrace.cpt_si_stime, &from->cpt_si_stime, | |
532 | sizeof (to_ptrace.cpt_si_stime)); | |
93813b37 WT |
533 | break; |
534 | case SIGILL: | |
535 | case SIGFPE: | |
536 | case SIGSEGV: | |
537 | case SIGBUS: | |
9cf12d57 | 538 | to_ptrace.cpt_si_addr = from->cpt_si_addr; |
93813b37 WT |
539 | break; |
540 | case SIGPOLL: | |
9cf12d57 PA |
541 | to_ptrace.cpt_si_band = from->cpt_si_band; |
542 | to_ptrace.cpt_si_fd = from->cpt_si_fd; | |
93813b37 WT |
543 | break; |
544 | default: | |
9cf12d57 PA |
545 | to_ptrace.cpt_si_pid = from->cpt_si_pid; |
546 | to_ptrace.cpt_si_uid = from->cpt_si_uid; | |
547 | to_ptrace.cpt_si_ptr = from->cpt_si_ptr; | |
93813b37 WT |
548 | break; |
549 | } | |
550 | } | |
9cf12d57 | 551 | memcpy (to, &to_ptrace, sizeof (to_ptrace)); |
93813b37 WT |
552 | } |
553 | ||
9cf12d57 | 554 | /* Convert a ptrace siginfo object, into/from the siginfo in the |
93813b37 WT |
555 | layout of the inferiors' architecture. Returns true if any |
556 | conversion was done; false otherwise. If DIRECTION is 1, then copy | |
9cf12d57 PA |
557 | from INF to PTRACE. If DIRECTION is 0, then copy from NATIVE to |
558 | INF. */ | |
93813b37 WT |
559 | |
560 | int | |
9cf12d57 | 561 | amd64_linux_siginfo_fixup_common (siginfo_t *ptrace, gdb_byte *inf, |
93813b37 WT |
562 | int direction, |
563 | enum amd64_siginfo_fixup_mode mode) | |
564 | { | |
565 | if (mode == FIXUP_32) | |
566 | { | |
93813b37 | 567 | if (direction == 0) |
9cf12d57 | 568 | compat_siginfo_from_siginfo ((struct compat_siginfo *) inf, ptrace); |
93813b37 | 569 | else |
9cf12d57 | 570 | siginfo_from_compat_siginfo (ptrace, (struct compat_siginfo *) inf); |
93813b37 WT |
571 | |
572 | return 1; | |
573 | } | |
574 | else if (mode == FIXUP_X32) | |
575 | { | |
93813b37 WT |
576 | if (direction == 0) |
577 | compat_x32_siginfo_from_siginfo ((struct compat_x32_siginfo *) inf, | |
9cf12d57 | 578 | ptrace); |
93813b37 | 579 | else |
9cf12d57 | 580 | siginfo_from_compat_x32_siginfo (ptrace, |
93813b37 WT |
581 | (struct compat_x32_siginfo *) inf); |
582 | ||
583 | return 1; | |
584 | } | |
585 | return 0; | |
586 | } | |
9cf12d57 PA |
587 | |
588 | /* Sanity check for the siginfo structure sizes. */ | |
589 | ||
590 | gdb_static_assert (sizeof (siginfo_t) == GDB_SI_SIZE); | |
591 | #ifndef __ILP32__ | |
592 | gdb_static_assert (sizeof (nat_siginfo_t) == GDB_SI_SIZE); | |
593 | #endif | |
594 | gdb_static_assert (sizeof (compat_x32_siginfo_t) == GDB_SI_SIZE); | |
595 | gdb_static_assert (sizeof (compat_siginfo_t) == GDB_SI_SIZE); | |
596 | gdb_static_assert (sizeof (ptrace_siginfo_t) == GDB_SI_SIZE); |