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/trace/trace.c | |
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/trace/trace.c')
-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 | ||