aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTobin C. Harding2017-11-23 10:59:45 +1100
committerTobin C. Harding2017-11-29 12:13:14 +1100
commit7b1924a1d930eb27fc79c4e4e2a6c1c970623e68 (patch)
treecdd958371ba49a69d64aae5df68ac0f181ba945d /lib
parentad67b74d2469d9b82aaa572d76474c95bc484d57 (diff)
vsprintf: add printk specifier %px
printk specifier %p now hashes all addresses before printing. Sometimes we need to see the actual unmodified address. This can be achieved using %lx but then we face the risk that if in future we want to change the way the Kernel handles printing of pointers we will have to grep through the already existent 50 000 %lx call sites. Let's add specifier %px as a clear, opt-in, way to print a pointer and maintain some level of isolation from all the other hex integer output within the Kernel. Add printk specifier %px to print the actual unmodified address. Signed-off-by: Tobin C. Harding <me@tobin.cc>
Diffstat (limited to 'lib')
-rw-r--r--lib/vsprintf.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index d69452a0f2fa..d960aead0336 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1646,6 +1646,20 @@ char *device_node_string(char *buf, char *end, struct device_node *dn,
return widen_string(buf, buf - buf_start, end, spec);
}
+static noinline_for_stack
+char *pointer_string(char *buf, char *end, const void *ptr,
+ struct printf_spec spec)
+{
+ spec.base = 16;
+ spec.flags |= SMALL;
+ if (spec.field_width == -1) {
+ spec.field_width = 2 * sizeof(ptr);
+ spec.flags |= ZEROPAD;
+ }
+
+ return number(buf, end, (unsigned long int)ptr, spec);
+}
+
static bool have_filled_random_ptr_key __read_mostly;
static siphash_key_t ptr_key __read_mostly;
@@ -1818,6 +1832,8 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec)
* c major compatible string
* C full compatible string
*
+ * - 'x' For printing the address. Equivalent to "%lx".
+ *
* ** Please update also Documentation/printk-formats.txt when making changes **
*
* Note: The difference between 'S' and 'F' is that on ia64 and ppc64
@@ -1940,6 +1956,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
case 'F':
return device_node_string(buf, end, ptr, spec, fmt + 1);
}
+ case 'x':
+ return pointer_string(buf, end, ptr, spec);
}
/* default is to _not_ leak addresses, hash before printing */