[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 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 alone %pS will print the symbol name + offset / size Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Keir Fraser <keir@xxxxxxx> CC: Jan Beulich <JBeulich@xxxxxxxx> --- docs/misc/printk-formats.txt | 11 ++++++++ xen/common/vsprintf.c | 58 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 7 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..ef25e16 --- /dev/null +++ b/docs/misc/printk-formats.txt @@ -0,0 +1,11 @@ +Xen custom %p format options. A subset, borrowed from Linux. + +All parameters to a %p option should be enclosed with the _p() macro + +Symbol/Function pointers: + + %ps Symbol name only + %pS Symbol name + offset / function length + + 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 5fdd391..5ac5b9b 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,19 +262,61 @@ 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, unsigned long val, int field_width, int precision, int flags) { - if ( field_width == -1 ) + const char *fmt = *fmt_ptr, *s; + + /* + * Custom %p suffixes, compatible with Linux. + * See XEN_ROOT/docs/misc/printk-formats.txt + */ + switch ( fmt[1] ) { - field_width = 2 * sizeof(void *); - flags |= ZEROPAD; + case 's': /* Symbol name */ + case 'S': /* Symbol name with offset and size */ + { + unsigned long sym_size, sym_offset; + char namebuf[KSYM_NAME_LEN+1]; + + /* Advance fmt pointer, as we have consumed 's' or 'S'. Leave fmt + * along for consistency. */ + (*fmt_ptr)++; + + s = symbols_lookup(val, &sym_size, &sym_offset, namebuf); + + /* If the symbol is not found, fall back to printing the address */ + if ( !s ) + goto regular_pointer; + + /* Print symbol name */ + str = string(str, end, s, -1, -1, 0); + + if ( fmt[1] == 'S' ) + { + /* Print '+0x<offset>/0x<len>' */ + str = string(str, end, "+0x", -1, -1, 0); + str = number(str, end, sym_offset, 16, -1, -1, 0); + str = string(str, end, "/0x", -1, -1, 0); + str = number(str, end, sym_size, 16, -1, -1, 0); + } + + return str; } - str = number(str, end, val, 16, field_width, precision, flags); + default: + regular_pointer: + + if ( field_width == -1 ) + { + field_width = 2 * sizeof(void *); + flags |= ZEROPAD; + } + + return number(str, end, val, 16, field_width, precision, flags); + } - return str; } /** @@ -414,7 +457,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) continue; case 'p': - str = pointer(str, end, (unsigned long) va_arg(args, void *), + /* pointer() might advance fmt (%pS for example) */ + str = pointer(str, end, &fmt, (unsigned long) 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 |