Re: the printk problem
From: Vegard Nossum <hidden>
Date: 2008-07-05 12:52:47
Also in:
lkml
Subsystem:
library code, the rest, vsprintf · Maintainers:
Andrew Morton, Linus Torvalds, Petr Mladek, Steven Rostedt
On Sat, Jul 5, 2008 at 1:33 PM, Jan Engelhardt [off-list ref] wrote:
On Saturday 2008-07-05 00:01, Andrew Morton wrote:quoted
We don't know how much interest there would be in churning NIPQUAD from the net guys. Interestingly, there's also %C (wint_t) which is a 32-bit quantity. So we could just go and say "%C prints an ipv4 address" and be done with it. But there's no way of doing that for ipv6 addresses so things would become asymmetrical there.struct in6_addr src; printk("Source address: %p{ipv6}\n", &src); How about %p{feature}?
Something like this?
(It's hard on the stack, yes, I know. We should fix kallsyms.)
Vegard
From: Vegard Nossum <redacted>
Date: Sat, 5 Jul 2008 14:01:00 +0200
Subject: [PATCH] printf: add %p{} extension
Signed-off-by: Vegard Nossum <redacted>
---
lib/vsprintf.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 6021757..011cf3f 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c@@ -17,6 +17,7 @@ */ #include <stdarg.h> +#include <linux/kallsyms.h> #include <linux/module.h> #include <linux/types.h> #include <linux/string.h>
@@ -366,6 +367,30 @@ static noinline char* put_dec(char *buf, unsigned long long num) #define SMALL 32 /* Must be 32 == 0x20 */ #define SPECIAL 64 /* 0x */ +static char *custom_format(char *buf, char *end, + const char *fmt, unsigned int fmtlen, void *arg) +{ + if (!strncmp(fmt, "sym", fmtlen)) { + char name[KSYM_SYMBOL_LEN]; + int len; + int i; + + len = sprint_symbol(name, (unsigned long) arg); + if (len < 0) + return buf; + + i = 0; + while (i < len) { + if (buf < end) + *buf = name[i]; + ++buf; + ++i; + } + } + + return buf; +} + static char *number(char *buf, char *end, unsigned long long num, int base, int size, int precision, int type) { /* we are called with base 8, 10 or 16, only, thus don't need "G..." */
@@ -648,6 +673,25 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case 'p': + if (fmt[1] == '{') { + const char *cfmt; + + /* Skip the '%{' */ + ++fmt; + ++fmt; + + cfmt = fmt; + + /* Skip everything up to the '}' */ + while (*fmt && *fmt != '}') + ++fmt; + + str = custom_format(str, end, + cfmt, fmt - cfmt, + va_arg(args, void *)); + continue; + } + flags |= SMALL; if (field_width == -1) { field_width = 2*sizeof(void *);
--
1.5.4.1