[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [Patch v3 3/7] common/vsprintf: Add %ps and %pS format specifier support
Introduce the %ps and %pS format options for printing a symbol. %ps will print the symbol name and optional offset and size %pS will print the symbol name and unconditional offset and size Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Keir Fraser <keir@xxxxxxx> CC: Jan Beulich <JBeulich@xxxxxxxx> --- Changes in v3: * %ps now only conditionally excludes the offset and size. * Coding style --- docs/misc/printk-formats.txt | 17 +++++++++++++++++ xen/common/vsprintf.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 docs/misc/printk-formats.txt diff --git a/docs/misc/printk-formats.txt b/docs/misc/printk-formats.txt new file mode 100644 index 0000000..4c4222b --- /dev/null +++ b/docs/misc/printk-formats.txt @@ -0,0 +1,17 @@ +Xen custom %p format options. A subset, borrowed from Linux. + +All parameters to a %p option should be compatible with void*. Regular +pointers are fine. Numbers should make use of the _p() macro. + +Symbol/Function pointers: + + %ps Symbol name with condition offset and size (iff offset != 0) + e.g. printk + default_idle+0x78/0x7d + + %pS Symbol name with unconditional offset and size + e.g. printk+0/0x48 + default_idle+0x78/0x7d + + In the case that an appropriate symbol name can't be found, %p[sS] will + fall back to '%p' and print the address in hex. diff --git a/xen/common/vsprintf.c b/xen/common/vsprintf.c index 8f8d2f6..f26aa42 100644 --- a/xen/common/vsprintf.c +++ b/xen/common/vsprintf.c @@ -17,6 +17,7 @@ */ #include <xen/ctype.h> +#include <xen/symbols.h> #include <xen/lib.h> #include <asm/div64.h> #include <asm/page.h> @@ -261,10 +262,46 @@ static char *string(char *str, char *end, const char *s, return str; } -static char *pointer(char *str, char *end, +static char *pointer(char *str, char *end, const char **fmt_ptr, const void *arg, int field_width, int precision, int flags) { + const char *fmt = *fmt_ptr, *s; + + /* Custom %p suffixes. See XEN_ROOT/docs/misc/printk-formats.txt */ + switch ( fmt[1] ) + { + case 's': /* Symbol name with offset and size (iff offset != 0) */ + case 'S': /* Symbol name unconditionally with offset and size */ + { + unsigned long sym_size, sym_offset; + char namebuf[KSYM_NAME_LEN+1]; + + /* Advance parents fmt string, as we have consumed 's' or 'S' */ + ++*fmt_ptr; + + s = symbols_lookup((unsigned long)arg, &sym_size, &sym_offset, namebuf); + + /* If the symbol is not found, fall back to printing the address */ + if ( !s ) + break; + + /* Print symbol name */ + str = string(str, end, s, -1, -1, 0); + + if ( fmt[1] == 'S' || sym_offset != 0 ) + { + /* Print '+<offset>/<len>' */ + str = number(str, end, sym_offset, 16, -1, -1, SPECIAL|SIGN|PLUS); + if ( str <= end ) + *str++ = '/'; + str = number(str, end, sym_size, 16, -1, -1, SPECIAL); + } + + return str; + } + } + if ( field_width == -1 ) { field_width = 2 * sizeof(void *); @@ -413,7 +450,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case 'p': - str = pointer(str, end, va_arg(args, void *), + /* pointer() might advance fmt (%pS for example) */ + str = pointer(str, end, &fmt, va_arg(args, void *), field_width, precision, flags); continue; -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |