1 /* 2 * Copyright (c) 2016-2017 Dmitry V. Levin <ldv@altlinux.org> 3 * Copyright (c) 2017-2018 The strace developers. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef STRACE_PRINT_FIELDS_H 30 #define STRACE_PRINT_FIELDS_H 31 32 /* 33 * The printf-like function to use in header files 34 * shared between strace and its tests. 35 */ 36 #ifndef STRACE_PRINTF 37 # define STRACE_PRINTF tprintf 38 #endif 39 40 #define PRINT_FIELD_D(prefix_, where_, field_) \ 41 STRACE_PRINTF("%s%s=%lld", (prefix_), #field_, \ 42 sign_extend_unsigned_to_ll((where_).field_)) 43 44 #define PRINT_FIELD_U(prefix_, where_, field_) \ 45 STRACE_PRINTF("%s%s=%llu", (prefix_), #field_, \ 46 zero_extend_signed_to_ull((where_).field_)) 47 48 #define PRINT_FIELD_U_CAST(prefix_, where_, field_, type_) \ 49 STRACE_PRINTF("%s%s=%llu", (prefix_), #field_, \ 50 zero_extend_signed_to_ull((type_) (where_).field_)) 51 52 #define PRINT_FIELD_X(prefix_, where_, field_) \ 53 STRACE_PRINTF("%s%s=%#llx", (prefix_), #field_, \ 54 zero_extend_signed_to_ull((where_).field_)) 55 56 #define PRINT_FIELD_ADDR(prefix_, where_, field_) \ 57 do { \ 58 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 59 printaddr((where_).field_); \ 60 } while (0) 61 62 #define PRINT_FIELD_ADDR64(prefix_, where_, field_) \ 63 do { \ 64 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 65 printaddr64((where_).field_); \ 66 } while (0) 67 68 #define PRINT_FIELD_0X(prefix_, where_, field_) \ 69 STRACE_PRINTF("%s%s=%#0*llx", (prefix_), #field_, \ 70 (int) sizeof((where_).field_) * 2, \ 71 zero_extend_signed_to_ull((where_).field_)) 72 73 #define PRINT_FIELD_COOKIE(prefix_, where_, field_) \ 74 STRACE_PRINTF("%s%s=[%llu, %llu]", (prefix_), #field_, \ 75 zero_extend_signed_to_ull((where_).field_[0]), \ 76 zero_extend_signed_to_ull((where_).field_[1])) 77 78 #define PRINT_FIELD_FLAGS(prefix_, where_, field_, xlat_, dflt_) \ 79 do { \ 80 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 81 printflags64((xlat_), \ 82 zero_extend_signed_to_ull((where_).field_),\ 83 (dflt_)); \ 84 } while (0) 85 86 #define PRINT_FIELD_XVAL(prefix_, where_, field_, xlat_, dflt_) \ 87 do { \ 88 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 89 printxval64((xlat_), \ 90 zero_extend_signed_to_ull((where_).field_), \ 91 (dflt_)); \ 92 } while (0) 93 94 #define PRINT_FIELD_XVAL_U(prefix_, where_, field_, xlat_, dflt_) \ 95 do { \ 96 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 97 printxvals_ex(zero_extend_signed_to_ull((where_).field_), \ 98 (dflt_), XLAT_STYLE_FMT_U, \ 99 (xlat_), NULL); \ 100 } while (0) 101 102 #define PRINT_FIELD_XVAL_SORTED_SIZED(prefix_, where_, field_, xlat_, \ 103 xlat_size_, dflt_) \ 104 do { \ 105 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 106 printxval_searchn((xlat_), (xlat_size_), \ 107 zero_extend_signed_to_ull((where_).field_), \ 108 (dflt_)); \ 109 } while (0) 110 111 #define PRINT_FIELD_XVAL_INDEX(prefix_, where_, field_, xlat_, dflt_) \ 112 do { \ 113 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 114 printxval_index((xlat_), \ 115 zero_extend_signed_to_ull((where_).field_), \ 116 (dflt_)); \ 117 } while (0) 118 119 /* 120 * Generic "ID" printing. ID is considered unsigned except for the special value 121 * of -1. 122 */ 123 #define PRINT_FIELD_ID(prefix_, where_, field_) \ 124 do { \ 125 if (sign_extend_unsigned_to_ll((where_).field_) == -1LL) \ 126 STRACE_PRINTF("%s%s=-1", (prefix_), #field_); \ 127 else \ 128 STRACE_PRINTF("%s%s=%llu", (prefix_), #field_, \ 129 zero_extend_signed_to_ull((where_).field_)); \ 130 } while (0) 131 132 #define PRINT_FIELD_UID PRINT_FIELD_ID 133 134 #define PRINT_FIELD_U64(prefix_, where_, field_) \ 135 do { \ 136 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 137 if (zero_extend_signed_to_ull((where_).field_) == UINT64_MAX) \ 138 print_xlat_u(UINT64_MAX); \ 139 else \ 140 STRACE_PRINTF("%llu", \ 141 zero_extend_signed_to_ull((where_).field_)); \ 142 } while (0) 143 144 #define PRINT_FIELD_STRING(prefix_, where_, field_, len_, style_) \ 145 do { \ 146 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 147 print_quoted_string((const char *)(where_).field_, \ 148 (len_), (style_)); \ 149 } while (0) 150 151 #define PRINT_FIELD_CSTRING(prefix_, where_, field_) \ 152 do { \ 153 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 154 print_quoted_cstring((const char *) (where_).field_, \ 155 sizeof((where_).field_) + \ 156 MUST_BE_ARRAY((where_).field_)); \ 157 } while (0) 158 159 #define PRINT_FIELD_CSTRING_SZ(prefix_, where_, field_, size_) \ 160 do { \ 161 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 162 print_quoted_cstring((const char *) (where_).field_, \ 163 (size_)); \ 164 } while (0) 165 166 #define PRINT_FIELD_HEX_ARRAY(prefix_, where_, field_) \ 167 do { \ 168 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 169 print_quoted_string((const char *)(where_).field_, \ 170 sizeof((where_).field_) + \ 171 MUST_BE_ARRAY((where_).field_), \ 172 QUOTE_FORCE_HEX); \ 173 } while (0) 174 175 #define PRINT_FIELD_INET_ADDR(prefix_, where_, field_, af_) \ 176 do { \ 177 STRACE_PRINTF(prefix_); \ 178 print_inet_addr((af_), &(where_).field_, \ 179 sizeof((where_).field_), #field_); \ 180 } while (0) 181 182 #define PRINT_FIELD_INET4_ADDR(prefix_, where_, field_) \ 183 STRACE_PRINTF("%s%s=inet_addr(\"%s\")", (prefix_), #field_, \ 184 inet_ntoa((where_).field_)) 185 186 #define PRINT_FIELD_AX25_ADDR(prefix_, where_, field_) \ 187 do { \ 188 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 189 print_ax25_addr(&(where_).field_); \ 190 } while (0) 191 192 #define PRINT_FIELD_X25_ADDR(prefix_, where_, field_) \ 193 do { \ 194 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 195 print_x25_addr(&(where_).field_); \ 196 } while (0) 197 198 #define PRINT_FIELD_NET_PORT(prefix_, where_, field_) \ 199 STRACE_PRINTF("%s%s=htons(%u)", (prefix_), #field_, \ 200 ntohs((where_).field_)) 201 202 #define PRINT_FIELD_IFINDEX(prefix_, where_, field_) \ 203 do { \ 204 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 205 print_ifindex((where_).field_); \ 206 } while (0) 207 208 #define PRINT_FIELD_SOCKADDR(prefix_, where_, field_) \ 209 do { \ 210 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 211 print_sockaddr(&(where_).field_, \ 212 sizeof((where_).field_)); \ 213 } while (0) 214 215 #define PRINT_FIELD_DEV(prefix_, where_, field_) \ 216 do { \ 217 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 218 print_dev_t((where_).field_); \ 219 } while (0) 220 221 #define PRINT_FIELD_PTR(prefix_, where_, field_) \ 222 do { \ 223 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 224 printaddr((mpers_ptr_t) (where_).field_); \ 225 } while (0) 226 227 #define PRINT_FIELD_FD(prefix_, where_, field_, tcp_) \ 228 do { \ 229 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 230 printfd((tcp_), (where_).field_); \ 231 } while (0) 232 233 #define PRINT_FIELD_STRN(prefix_, where_, field_, len_, tcp_) \ 234 do { \ 235 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 236 printstrn((tcp_), (where_).field_, (len_)); \ 237 } while (0) 238 239 240 #define PRINT_FIELD_STR(prefix_, where_, field_, tcp_) \ 241 do { \ 242 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 243 printstr((tcp_), (where_).field_); \ 244 } while (0) 245 246 #define PRINT_FIELD_PATH(prefix_, where_, field_, tcp_) \ 247 do { \ 248 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 249 printpath((tcp_), (where_).field_); \ 250 } while (0) 251 252 #define PRINT_FIELD_MAC(prefix_, where_, field_) \ 253 PRINT_FIELD_MAC_SZ((prefix_), (where_), field_, \ 254 ARRAY_SIZE((where_).field_)) 255 256 #define PRINT_FIELD_MAC_SZ(prefix_, where_, field_, size_) \ 257 do { \ 258 static_assert(sizeof(((where_).field_)[0]) == 1, \ 259 "MAC address is not a byte array"); \ 260 STRACE_PRINTF("%s%s=", (prefix_), #field_); \ 261 print_mac_addr("", (const uint8_t *) ((where_).field_), \ 262 (size_)); \ 263 } while (0) 264 265 #endif /* !STRACE_PRINT_FIELDS_H */ 266