(root)/
strace-6.5/
src/
printsiginfo.c
       1  /*
       2   * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
       3   * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
       4   * Copyright (c) 1993-1996 Rick Sladkey <jrs@world.std.com>
       5   * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
       6   * Copyright (c) 2001 John Hughes <john@Calva.COM>
       7   * Copyright (c) 2013 Denys Vlasenko <vda.linux@googlemail.com>
       8   * Copyright (c) 2011-2015 Dmitry V. Levin <ldv@strace.io>
       9   * Copyright (c) 2015 Elvira Khabirova <lineprinter0@gmail.com>
      10   * Copyright (c) 2015-2023 The strace developers.
      11   * All rights reserved.
      12   *
      13   * SPDX-License-Identifier: LGPL-2.1-or-later
      14   */
      15  
      16  #include "defs.h"
      17  
      18  #include DEF_MPERS_TYPE(siginfo_t)
      19  
      20  #include <signal.h>
      21  #include <linux/audit.h>
      22  
      23  #include MPERS_DEFS
      24  
      25  #ifndef IN_MPERS
      26  # include "printsiginfo.h"
      27  #endif
      28  
      29  #define XLAT_MACROS_ONLY
      30  /* For xlat/audit_arch.h */
      31  # include "xlat/elf_em.h"
      32  #undef XLAT_MACROS_ONLY
      33  
      34  #include "xlat/audit_arch.h"
      35  #include "xlat/sigbus_codes.h"
      36  #include "xlat/sigchld_codes.h"
      37  #include "xlat/sigfpe_codes.h"
      38  #include "xlat/sigill_codes.h"
      39  #include "xlat/siginfo_codes.h"
      40  #include "xlat/sigpoll_codes.h"
      41  #include "xlat/sigprof_codes.h"
      42  #include "xlat/sigsegv_codes.h"
      43  #include "xlat/sigsys_codes.h"
      44  #include "xlat/sigtrap_codes.h"
      45  
      46  #ifdef ALPHA
      47  # include "xlat/alpha_trap_codes.h"
      48  #endif
      49  
      50  #ifdef SIGEMT
      51  # include "xlat/sigemt_codes.h"
      52  #endif
      53  
      54  #ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
      55  # include "xlat/sigtrap_perf_flags.h"
      56  #endif
      57  
      58  #ifndef SI_FROMUSER
      59  # define SI_FROMUSER(sip)	((sip)->si_code <= 0)
      60  #endif
      61  
      62  static void
      63  printsigsource(struct tcb *tcp, const siginfo_t *sip)
      64  {
      65  	tprint_struct_next();
      66  	PRINT_FIELD_TGID(*sip, si_pid, tcp);
      67  	tprint_struct_next();
      68  	PRINT_FIELD_ID(*sip, si_uid);
      69  }
      70  
      71  static void
      72  printsigval(const siginfo_t *sip)
      73  {
      74  	tprint_struct_next();
      75  	PRINT_FIELD_D(*sip, si_int);
      76  	tprint_struct_next();
      77  	PRINT_FIELD_PTR(*sip, si_ptr);
      78  }
      79  
      80  static void
      81  print_si_code(const unsigned int si_code, const int si_signo)
      82  {
      83  	static const struct xlat * const si_codes[] = {
      84  		[SIGTRAP] = sigtrap_codes,
      85  		[SIGCHLD] = sigchld_codes,
      86  		[SIGIO]   = sigpoll_codes, /* SIGPOLL */
      87  		[SIGPROF] = sigprof_codes,
      88  		[SIGILL]  = sigill_codes,
      89  #ifdef SIGEMT
      90  		[SIGEMT]  = sigemt_codes,
      91  #endif
      92  		[SIGFPE]  = sigfpe_codes,
      93  		[SIGSEGV] = sigsegv_codes,
      94  		[SIGBUS]  = sigbus_codes,
      95  		[SIGSYS]  = sigsys_codes,
      96  	};
      97  
      98  	const char *code = xlookup(siginfo_codes, si_code);
      99  
     100  	if (!code && (unsigned int) si_signo < ARRAY_SIZE(si_codes)
     101  	    && si_codes[si_signo])
     102  		code = xlookup(si_codes[si_signo], si_code);
     103  
     104  	print_xlat_ex(si_code, code, XLAT_STYLE_DEFAULT);
     105  }
     106  
     107  static void
     108  print_si_info(struct tcb *tcp, const siginfo_t *sip)
     109  {
     110  	if (sip->si_errno) {
     111  		tprint_struct_next();
     112  		PRINT_FIELD_ERR_U(*sip, si_errno);
     113  	}
     114  
     115  	if (SI_FROMUSER(sip)) {
     116  		switch (sip->si_code) {
     117  		case SI_USER:
     118  			printsigsource(tcp, sip);
     119  			break;
     120  		case SI_TKILL:
     121  			printsigsource(tcp, sip);
     122  			break;
     123  #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
     124  		case SI_TIMER:
     125  			tprint_struct_next();
     126  			PRINT_FIELD_X(*sip, si_timerid);
     127  			tprint_struct_next();
     128  			PRINT_FIELD_D(*sip, si_overrun);
     129  			printsigval(sip);
     130  			break;
     131  #endif
     132  		case SI_SIGIO:
     133  			tprint_struct_next();
     134  			PRINT_FIELD_D(*sip, si_band);
     135  			tprint_struct_next();
     136  			PRINT_FIELD_FD(*sip, si_fd, tcp);
     137  			break;
     138  		default:
     139  			printsigsource(tcp, sip);
     140  			if (sip->si_ptr)
     141  				printsigval(sip);
     142  			break;
     143  		}
     144  	} else {
     145  		switch (sip->si_signo) {
     146  		case SIGCHLD:
     147  			printsigsource(tcp, sip);
     148  			if (sip->si_code == CLD_EXITED) {
     149  				tprint_struct_next();
     150  				PRINT_FIELD_D(*sip, si_status);
     151  			} else {
     152  				tprint_struct_next();
     153  				PRINT_FIELD_OBJ_VAL(*sip, si_status, printsignal);
     154  			}
     155  			tprint_struct_next();
     156  			PRINT_FIELD_CLOCK_T(*sip, si_utime);
     157  			tprint_struct_next();
     158  			PRINT_FIELD_CLOCK_T(*sip, si_stime);
     159  			break;
     160  		case SIGILL:
     161  			tprint_struct_next();
     162  			PRINT_FIELD_PTR(*sip, si_addr);
     163  #if defined(SPARC) || defined(SPARC64)
     164  			tprint_struct_next();
     165  			PRINT_FIELD_D(*sip, si_trapno);
     166  #endif /* SPARC || SPARC64 */
     167  			break;
     168  		case SIGFPE:
     169  			tprint_struct_next();
     170  			PRINT_FIELD_PTR(*sip, si_addr);
     171  #if defined ALPHA && defined HAVE_SIGINFO_T_SI_TRAPNO
     172  			tprint_struct_next();
     173  			PRINT_FIELD_XVAL_D(*sip, si_trapno, alpha_trap_codes,
     174  					   "GEN_???");
     175  #endif /* ALPHA */
     176  			break;
     177  		case SIGBUS:
     178  			tprint_struct_next();
     179  			PRINT_FIELD_PTR(*sip, si_addr);
     180  #if !defined(BUS_OPFETCH) && defined(HAVE_SIGINFO_T_SI_ADDR_LSB)
     181  			switch (sip->si_code) {
     182  			case BUS_MCEERR_AR:
     183  			case BUS_MCEERR_AO:
     184  				tprint_struct_next();
     185  				PRINT_FIELD_X(*sip, si_addr_lsb);
     186  				break;
     187  			}
     188  #endif /* !BUS_OPFETCH && HAVE_SIGINFO_T_SI_ADDR_LSB */
     189  			break;
     190  		case SIGSEGV:
     191  			tprint_struct_next();
     192  			PRINT_FIELD_PTR(*sip, si_addr);
     193  #if (!defined(SEGV_STACKFLOW) && defined(HAVE_SIGINFO_T_SI_LOWER)) \
     194      || (!defined(__SEGV_PSTKOVF) && defined(HAVE_SIGINFO_T_SI_PKEY))
     195  			switch (sip->si_code) {
     196  # if !defined(SEGV_STACKFLOW) && defined(HAVE_SIGINFO_T_SI_LOWER)
     197  			case SEGV_BNDERR:
     198  				tprint_struct_next();
     199  				PRINT_FIELD_PTR(*sip, si_lower);
     200  				tprint_struct_next();
     201  				PRINT_FIELD_PTR(*sip, si_upper);
     202  				break;
     203  # endif /* !SEGV_STACKFLOW && HAVE_SIGINFO_T_SI_LOWER */
     204  # if !defined(__SEGV_PSTKOVF) && defined(HAVE_SIGINFO_T_SI_PKEY)
     205  			case SEGV_PKUERR:
     206  				tprint_struct_next();
     207  				PRINT_FIELD_U(*sip, si_pkey);
     208  				break;
     209  # endif /* !__SEGV_PSTKOVF && HAVE_SIGINFO_T_SI_PKEY */
     210  			}
     211  #endif /* !SEGV_STACKFLOW && HAVE_SIGINFO_T_SI_LOWER
     212  	* || !__SEGV_PSTKOVF && HAVE_SIGINFO_T_SI_PKEY */
     213  			break;
     214  		case SIGTRAP:
     215  			tprint_struct_next();
     216  			PRINT_FIELD_PTR(*sip, si_addr);
     217  #if (defined ALPHA && defined HAVE_SIGINFO_T_SI_TRAPNO) \
     218   || defined HAVE_SIGINFO_T_SI_PERF_DATA
     219  			switch (sip->si_code) {
     220  # if defined ALPHA && defined HAVE_SIGINFO_T_SI_TRAPNO
     221  			case TRAP_UNK:
     222  				tprint_struct_next();
     223  				PRINT_FIELD_XVAL_D(*sip, si_trapno,
     224  						   alpha_trap_codes, "GEN_???");
     225  				break;
     226  # endif /* ALPHA && HAVE_SIGINFO_T_SI_TRAPNO */
     227  # ifdef HAVE_SIGINFO_T_SI_PERF_DATA
     228  			case TRAP_PERF:
     229  				tprint_struct_next();
     230  				PRINT_FIELD_X(*sip, si_perf_data);
     231  #  ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
     232  				tprint_struct_next();
     233  				PRINT_FIELD_XVAL(*sip, si_perf_type,
     234  						 perf_type_id, "PERF_TYPE_???");
     235  #  endif /* HAVE_SIGINFO_T_SI_PERF_TYPE */
     236  #  ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
     237  				tprint_struct_next();
     238  				PRINT_FIELD_FLAGS(*sip, si_perf_flags,
     239  						  sigtrap_perf_flags,
     240  						  "TRAP_PERF_FLAG_???");
     241  #  endif /* HAVE_SIGINFO_T_SI_PERF_FLAGS */
     242  # endif /* HAVE_SIGINFO_T_SI_PERF_DATA */
     243  			}
     244  #endif /* ALPHA || HAVE_SIGINFO_T_SI_PERF_DATA */
     245  			break;
     246  #ifdef SIGEMT
     247  		case SIGEMT:
     248  			tprint_struct_next();
     249  			PRINT_FIELD_PTR(*sip, si_addr);
     250  			break;
     251  #endif
     252  		case SIGIO: /* SIGPOLL */
     253  			switch (sip->si_code) {
     254  			case POLL_IN:  case POLL_OUT: case POLL_MSG:
     255  			case POLL_ERR: case POLL_PRI: case POLL_HUP:
     256  				tprint_struct_next();
     257  				PRINT_FIELD_D(*sip, si_band);
     258  				tprint_struct_next();
     259  				PRINT_FIELD_FD(*sip, si_fd, tcp);
     260  				break;
     261  			}
     262  			break;
     263  #ifdef HAVE_SIGINFO_T_SI_SYSCALL
     264  		case SIGSYS:
     265  			tprint_struct_next();
     266  			PRINT_FIELD_PTR(*sip, si_call_addr);
     267  			tprint_struct_next();
     268  			PRINT_FIELD_SYSCALL_NAME(*sip, si_syscall,
     269  						 sip->si_arch);
     270  			tprint_struct_next();
     271  			PRINT_FIELD_XVAL(*sip, si_arch, audit_arch,
     272  					 "AUDIT_ARCH_???");
     273  			break;
     274  #endif
     275  		default:
     276  			if (sip->si_pid || sip->si_uid)
     277  				printsigsource(tcp, sip);
     278  			if (sip->si_ptr)
     279  				printsigval(sip);
     280  		}
     281  	}
     282  }
     283  
     284  #ifdef IN_MPERS
     285  static
     286  #endif
     287  void
     288  printsiginfo(struct tcb *tcp, const siginfo_t *sip)
     289  {
     290  	tprint_struct_begin();
     291  
     292  	if (sip->si_signo) {
     293  		PRINT_FIELD_OBJ_VAL(*sip, si_signo, printsignal);
     294  		tprint_struct_next();
     295  		PRINT_FIELD_OBJ_VAL(*sip, si_code, print_si_code,
     296  				    sip->si_signo);
     297  
     298  #ifdef SI_NOINFO
     299  		if (sip->si_code != SI_NOINFO)
     300  #endif
     301  			print_si_info(tcp, sip);
     302  	}
     303  
     304  	tprint_struct_end();
     305  }
     306  
     307  MPERS_PRINTER_DECL(void, printsiginfo_at,
     308  		   struct tcb *const tcp, const kernel_ulong_t addr)
     309  {
     310  	siginfo_t si;
     311  
     312  	if (!umove_or_printaddr(tcp, addr, &si))
     313  		printsiginfo(tcp, &si);
     314  }
     315  
     316  static bool
     317  print_siginfo_t(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
     318  {
     319  	printsiginfo(tcp, (const siginfo_t *) elem_buf);
     320  	return true;
     321  }
     322  
     323  MPERS_PRINTER_DECL(void, print_siginfo_array, struct tcb *const tcp,
     324  		   const kernel_ulong_t addr, const kernel_ulong_t len)
     325  {
     326  	siginfo_t si;
     327  
     328  	print_array(tcp, addr, len, &si, sizeof(si),
     329  		    tfetch_mem, print_siginfo_t, 0);
     330  }