diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-05-12 15:20:49 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2008-05-23 14:54:55 -0400 |
| commit | 5e3ca0ec76fce92daa4eed0d02de9c79b1fe3920 (patch) | |
| tree | 684aee668cc10d63fd47c28cd7c804a61fbf2aed /kernel | |
| parent | 2e0f57618529a2739a5e1570e6c445c9c966b595 (diff) | |
ftrace: introduce the "hex" output method
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/trace/trace.c | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 71b25b79b3de..6974b212e938 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -103,7 +103,8 @@ enum trace_iterator_flags { | |||
| 103 | TRACE_ITER_SYM_ADDR = 0x04, | 103 | TRACE_ITER_SYM_ADDR = 0x04, |
| 104 | TRACE_ITER_VERBOSE = 0x08, | 104 | TRACE_ITER_VERBOSE = 0x08, |
| 105 | TRACE_ITER_RAW = 0x10, | 105 | TRACE_ITER_RAW = 0x10, |
| 106 | TRACE_ITER_BIN = 0x20, | 106 | TRACE_ITER_HEX = 0x20, |
| 107 | TRACE_ITER_BIN = 0x40, | ||
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | #define TRACE_ITER_SYM_MASK \ | 110 | #define TRACE_ITER_SYM_MASK \ |
| @@ -116,6 +117,7 @@ static const char *trace_options[] = { | |||
| 116 | "sym-addr", | 117 | "sym-addr", |
| 117 | "verbose", | 118 | "verbose", |
| 118 | "raw", | 119 | "raw", |
| 120 | "hex", | ||
| 119 | "bin", | 121 | "bin", |
| 120 | NULL | 122 | NULL |
| 121 | }; | 123 | }; |
| @@ -238,6 +240,47 @@ trace_seq_putmem(struct trace_seq *s, void *mem, size_t len) | |||
| 238 | return len; | 240 | return len; |
| 239 | } | 241 | } |
| 240 | 242 | ||
| 243 | #define HEX_CHARS 17 | ||
| 244 | |||
| 245 | static notrace int | ||
| 246 | trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len) | ||
| 247 | { | ||
| 248 | unsigned char hex[HEX_CHARS]; | ||
| 249 | unsigned char *data; | ||
| 250 | unsigned char byte; | ||
| 251 | int i, j; | ||
| 252 | |||
| 253 | BUG_ON(len >= HEX_CHARS); | ||
| 254 | |||
| 255 | data = mem; | ||
| 256 | |||
| 257 | #ifdef __BIG_ENDIAN | ||
| 258 | for (i = 0, j = 0; i < len; i++) { | ||
| 259 | #else | ||
| 260 | for (i = len-1, j = 0; i >= 0; i--) { | ||
| 261 | #endif | ||
| 262 | byte = data[i]; | ||
| 263 | |||
| 264 | hex[j] = byte & 0x0f; | ||
| 265 | if (hex[j] >= 10) | ||
| 266 | hex[j] += 'a' - 10; | ||
| 267 | else | ||
| 268 | hex[j] += '0'; | ||
| 269 | j++; | ||
| 270 | |||
| 271 | hex[j] = byte >> 4; | ||
| 272 | if (hex[j] >= 10) | ||
| 273 | hex[j] += 'a' - 10; | ||
| 274 | else | ||
| 275 | hex[j] += '0'; | ||
| 276 | j++; | ||
| 277 | } | ||
| 278 | hex[j] = ' '; | ||
| 279 | j++; | ||
| 280 | |||
| 281 | return trace_seq_putmem(s, hex, j); | ||
| 282 | } | ||
| 283 | |||
| 241 | static notrace void | 284 | static notrace void |
| 242 | trace_seq_reset(struct trace_seq *s) | 285 | trace_seq_reset(struct trace_seq *s) |
| 243 | { | 286 | { |
| @@ -1274,6 +1317,51 @@ do { \ | |||
| 1274 | return 0; \ | 1317 | return 0; \ |
| 1275 | } while (0) | 1318 | } while (0) |
| 1276 | 1319 | ||
| 1320 | #define SEQ_PUT_HEX_FIELD_RET(s, x) \ | ||
| 1321 | do { \ | ||
| 1322 | if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \ | ||
| 1323 | return 0; \ | ||
| 1324 | } while (0) | ||
| 1325 | |||
| 1326 | static notrace int print_hex_fmt(struct trace_iterator *iter) | ||
| 1327 | { | ||
| 1328 | struct trace_seq *s = &iter->seq; | ||
| 1329 | unsigned char newline = '\n'; | ||
| 1330 | struct trace_entry *entry; | ||
| 1331 | int S; | ||
| 1332 | |||
| 1333 | entry = iter->ent; | ||
| 1334 | |||
| 1335 | SEQ_PUT_HEX_FIELD_RET(s, entry->pid); | ||
| 1336 | SEQ_PUT_HEX_FIELD_RET(s, iter->cpu); | ||
| 1337 | SEQ_PUT_HEX_FIELD_RET(s, entry->t); | ||
| 1338 | |||
| 1339 | switch (entry->type) { | ||
| 1340 | case TRACE_FN: | ||
| 1341 | SEQ_PUT_HEX_FIELD_RET(s, entry->fn.ip); | ||
| 1342 | SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); | ||
| 1343 | break; | ||
| 1344 | case TRACE_CTX: | ||
| 1345 | S = entry->ctx.prev_state < sizeof(state_to_char) ? | ||
| 1346 | state_to_char[entry->ctx.prev_state] : 'X'; | ||
| 1347 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid); | ||
| 1348 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio); | ||
| 1349 | SEQ_PUT_HEX_FIELD_RET(s, S); | ||
| 1350 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_pid); | ||
| 1351 | SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_prio); | ||
| 1352 | SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip); | ||
| 1353 | break; | ||
| 1354 | case TRACE_SPECIAL: | ||
| 1355 | SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg1); | ||
| 1356 | SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg2); | ||
| 1357 | SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg3); | ||
| 1358 | break; | ||
| 1359 | } | ||
| 1360 | SEQ_PUT_FIELD_RET(s, newline); | ||
| 1361 | |||
| 1362 | return 1; | ||
| 1363 | } | ||
| 1364 | |||
| 1277 | static notrace int print_bin_fmt(struct trace_iterator *iter) | 1365 | static notrace int print_bin_fmt(struct trace_iterator *iter) |
| 1278 | { | 1366 | { |
| 1279 | struct trace_seq *s = &iter->seq; | 1367 | struct trace_seq *s = &iter->seq; |
| @@ -1327,6 +1415,9 @@ static int print_trace_line(struct trace_iterator *iter) | |||
| 1327 | if (trace_flags & TRACE_ITER_BIN) | 1415 | if (trace_flags & TRACE_ITER_BIN) |
| 1328 | return print_bin_fmt(iter); | 1416 | return print_bin_fmt(iter); |
| 1329 | 1417 | ||
| 1418 | if (trace_flags & TRACE_ITER_HEX) | ||
| 1419 | return print_hex_fmt(iter); | ||
| 1420 | |||
| 1330 | if (trace_flags & TRACE_ITER_RAW) | 1421 | if (trace_flags & TRACE_ITER_RAW) |
| 1331 | return print_raw_fmt(iter); | 1422 | return print_raw_fmt(iter); |
| 1332 | 1423 | ||
