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