1 #include "defs.h" 2 3 #include "xlat/sigbus_codes.h" 4 #include "xlat/sigchld_codes.h" 5 #include "xlat/sigfpe_codes.h" 6 #include "xlat/sigill_codes.h" 7 #include "xlat/siginfo_codes.h" 8 #include "xlat/sigpoll_codes.h" 9 #include "xlat/sigprof_codes.h" 10 #include "xlat/sigsegv_codes.h" 11 #include "xlat/sigsys_codes.h" 12 #include "xlat/sigtrap_codes.h" 13 14 #ifdef SIGEMT 15 # include "xlat/sigemt_codes.h" 16 #endif 17 18 #ifndef SI_FROMUSER 19 # define SI_FROMUSER(sip) ((sip)->si_code <= 0) 20 #endif 21 22 static void 23 printsigsource(const siginfo_t *sip) 24 { 25 tprintf(", si_pid=%lu, si_uid=%lu", 26 (unsigned long) sip->si_pid, 27 (unsigned long) sip->si_uid); 28 } 29 30 static void 31 printsigval(const siginfo_t *sip, bool verbose) 32 { 33 if (!verbose) 34 tprints(", ..."); 35 else 36 tprintf(", si_value={int=%u, ptr=%#lx}", 37 sip->si_int, 38 (unsigned long) sip->si_ptr); 39 } 40 41 static void 42 print_si_code(int si_signo, int si_code) 43 { 44 const char *code = xlookup(siginfo_codes, si_code); 45 46 if (!code) { 47 switch (si_signo) { 48 case SIGTRAP: 49 code = xlookup(sigtrap_codes, si_code); 50 break; 51 case SIGCHLD: 52 code = xlookup(sigchld_codes, si_code); 53 break; 54 case SIGPOLL: 55 code = xlookup(sigpoll_codes, si_code); 56 break; 57 case SIGPROF: 58 code = xlookup(sigprof_codes, si_code); 59 break; 60 case SIGILL: 61 code = xlookup(sigill_codes, si_code); 62 break; 63 #ifdef SIGEMT 64 case SIGEMT: 65 code = xlookup(sigemt_codes, si_code); 66 break; 67 #endif 68 case SIGFPE: 69 code = xlookup(sigfpe_codes, si_code); 70 break; 71 case SIGSEGV: 72 code = xlookup(sigsegv_codes, si_code); 73 break; 74 case SIGBUS: 75 code = xlookup(sigbus_codes, si_code); 76 break; 77 case SIGSYS: 78 code = xlookup(sigsys_codes, si_code); 79 break; 80 } 81 } 82 83 if (code) 84 tprints(code); 85 else 86 tprintf("%#x", si_code); 87 } 88 89 static void 90 print_si_info(const siginfo_t *sip, bool verbose) 91 { 92 if (sip->si_errno) { 93 tprints(", si_errno="); 94 if ((unsigned) sip->si_errno < nerrnos 95 && errnoent[sip->si_errno]) 96 tprints(errnoent[sip->si_errno]); 97 else 98 tprintf("%d", sip->si_errno); 99 } 100 101 if (SI_FROMUSER(sip)) { 102 switch (sip->si_code) { 103 case SI_USER: 104 printsigsource(sip); 105 break; 106 case SI_TKILL: 107 printsigsource(sip); 108 break; 109 #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN 110 case SI_TIMER: 111 tprintf(", si_timerid=%#x, si_overrun=%d", 112 sip->si_timerid, sip->si_overrun); 113 printsigval(sip, verbose); 114 break; 115 #endif 116 default: 117 printsigsource(sip); 118 if (sip->si_ptr) 119 printsigval(sip, verbose); 120 break; 121 } 122 } else { 123 switch (sip->si_signo) { 124 case SIGCHLD: 125 printsigsource(sip); 126 tprints(", si_status="); 127 if (sip->si_code == CLD_EXITED) 128 tprintf("%d", sip->si_status); 129 else 130 printsignal(sip->si_status); 131 if (!verbose) 132 tprints(", ..."); 133 else 134 tprintf(", si_utime=%llu, si_stime=%llu", 135 (unsigned long long) sip->si_utime, 136 (unsigned long long) sip->si_stime); 137 break; 138 case SIGILL: case SIGFPE: 139 case SIGSEGV: case SIGBUS: 140 tprintf(", si_addr=%#lx", 141 (unsigned long) sip->si_addr); 142 break; 143 case SIGPOLL: 144 switch (sip->si_code) { 145 case POLL_IN: case POLL_OUT: case POLL_MSG: 146 tprintf(", si_band=%ld", 147 (long) sip->si_band); 148 break; 149 } 150 break; 151 #ifdef HAVE_SIGINFO_T_SI_SYSCALL 152 case SIGSYS: 153 tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u", 154 (unsigned long) sip->si_call_addr, 155 sip->si_syscall, sip->si_arch); 156 break; 157 #endif 158 default: 159 if (sip->si_pid || sip->si_uid) 160 printsigsource(sip); 161 if (sip->si_ptr) 162 printsigval(sip, verbose); 163 } 164 } 165 } 166 167 void 168 printsiginfo(const siginfo_t *sip, bool verbose) 169 { 170 if (sip->si_signo == 0) { 171 tprints("{}"); 172 return; 173 } 174 tprints("{si_signo="); 175 printsignal(sip->si_signo); 176 177 tprints(", si_code="); 178 print_si_code(sip->si_signo, sip->si_code); 179 180 #ifdef SI_NOINFO 181 if (sip->si_code != SI_NOINFO) 182 #endif 183 print_si_info(sip, verbose); 184 185 tprints("}"); 186 } 187 188 void 189 printsiginfo_at(struct tcb *tcp, long addr) 190 { 191 siginfo_t si; 192 if (!addr) { 193 tprints("NULL"); 194 return; 195 } 196 if (syserror(tcp) || umove(tcp, addr, &si) < 0) { 197 tprintf("%#lx", addr); 198 return; 199 } 200 printsiginfo(&si, verbose(tcp)); 201 } 202