カーネル/VM探検隊の懇親会でLinuxのprintkの%pが拡張されてるということを聞いてちょっと調べてみました。
カーネルに付属しているprintk-formats.txtに説明が色々書かれています。また、%pFと%pSで何が違うの?というところはvsprintf.cのコメントに書かれてました。
とりあえず、適当にカーネルモジュールを書いて試してみます。
[masami@saga:~/codes/printk_test]$ cat printk_test.c #include <linux/module.h> #include <linux/kernel.h> MODULE_DESCRIPTION("printk test module"); MODULE_AUTHOR("masami256"); MODULE_LICENSE("GPL"); static char *str = "moimoi"; static void foobar(void) { struct task_struct *task = current; printk(KERN_INFO"Test %%pF at %s\n%pF\n\n", __func__, &foobar); printk(KERN_INFO"Test %%pf at %s\n%pf\n\n", __func__, &foobar); printk(KERN_INFO"Test %%pB\n%pB\n\n", &foobar); printk(KERN_INFO"Test %%pK\n%pK\n\n", str); printk(KERN_INFO"Test %%pk\n%pk\n\n", str); printk(KERN_INFO"Test %%pR\n%pR\n\n", task); printk(KERN_INFO"Test %%pr\n%pr\n\n", task); } static int printk_test_init(void) { printk(KERN_INFO"[-]printk_test module is loaded\n"); foobar(); return 0; } static void printk_test_cleanup(void) { printk(KERN_INFO"[-]printk_test module is unloaded\n"); } module_init(printk_test_init); module_exit(printk_test_cleanup);
これをmake->insmodしてdmesgで確認するとこのようになりました。
[ 4021.186188] [-]printk_test module is loaded [ 4021.186193] Test %pF at foobar foobar+0x0/0xc0 [printk_test] [ 4021.186204] Test %pf at foobar foobar [printk_test] [ 4021.186218] Test %pB 0xffffffffa0509fff [ 4021.186221] Test %pK ffffffffa050b066 [ 4021.186224] Test %pk ffffffffa050b066 [ 4021.186228] Test %pR [??? 0x00000000-0xffff8807e7694000 flags 0x0] [ 4021.186232] Test %pr [??? 0x00000000-0xffff8807e7694000 flags 0x0]
んー、%pBの出力がprintk-formats.txtと違ってアドレスしか出てないですね。