cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

printk-formats.rst (16551B)


      1.. include:: ../disclaimer-zh_CN.rst
      2
      3:Original: Documentation/core-api/printk-formats.rst
      4
      5:翻译:
      6
      7 司延腾 Yanteng Si <siyanteng@loongson.cn>
      8
      9.. _cn_printk-formats.rst:
     10
     11==============================
     12如何获得正确的printk格式占位符
     13==============================
     14
     15
     16
     17:作者: Randy Dunlap <rdunlap@infradead.org>
     18:作者: Andrew Murray <amurray@mpc-data.co.uk>
     19
     20
     21整数类型
     22========
     23
     24::
     25
     26	        若变量类型是Type,则使用printk格式占位符。
     27	        -------------------------------------------
     28		char			%d 或 %x
     29		unsigned char		%u 或 %x
     30		short int		%d 或 %x
     31		unsigned short int	%u 或 %x
     32		int			%d 或 %x
     33		unsigned int		%u 或 %x
     34		long			%ld 或 %lx
     35		unsigned long		%lu 或 %lx
     36		long long		%lld 或 %llx
     37		unsigned long long	%llu 或 %llx
     38		size_t			%zu 或 %zx
     39		ssize_t			%zd 或 %zx
     40		s8			%d 或 %x
     41		u8			%u 或 %x
     42		s16			%d 或 %x
     43		u16			%u 或 %x
     44		s32			%d 或 %x
     45		u32			%u 或 %x
     46		s64			%lld 或 %llx
     47		u64			%llu 或 %llx
     48
     49
     50如果 <type> 的大小依赖于配置选项 (例如 sector_t, blkcnt_t) 或其大小依赖于架构
     51(例如 tcflag_t),则使用其可能的最大类型的格式占位符并显式强制转换为它。
     52
     53例如
     54
     55::
     56
     57	printk("test: sector number/total blocks: %llu/%llu\n",
     58		(unsigned long long)sector, (unsigned long long)blockcount);
     59
     60提醒:sizeof()返回类型为size_t。
     61
     62内核的printf不支持%n。显而易见,浮点格式(%e, %f, %g, %a)也不被识别。使用任何不
     63支持的占位符或长度限定符都会导致一个WARN并且终止vsnprintf()执行。
     64
     65指针类型
     66========
     67
     68一个原始指针值可以用%p打印,它将在打印前对地址进行哈希处理。内核也支持扩展占位符来打印
     69不同类型的指针。
     70
     71一些扩展占位符会打印给定地址上的数据,而不是打印地址本身。在这种情况下,以下错误消息可能
     72会被打印出来,而不是无法访问的消息::
     73
     74	(null)	 data on plain NULL address
     75	(efault) data on invalid address
     76	(einval) invalid data on a valid address
     77
     78普通指针
     79----------
     80
     81::
     82
     83	%p	abcdef12 or 00000000abcdef12
     84
     85没有指定扩展名的指针(即没有修饰符的%p)被哈希(hash),以防止内核内存布局消息的泄露。这
     86样还有一个额外的好处,就是提供一个唯一的标识符。在64位机器上,前32位被清零。当没有足够的
     87熵进行散列处理时,内核将打印(ptrval)代替
     88
     89如果可能的话,使用专门的修饰符,如%pS或%pB(如下所述),以避免打印一个必须事后解释的非哈
     90希地址。如果不可能,而且打印地址的目的是为调试提供更多的消息,使用%p,并在调试过程中
     91用 ``no_hash_pointers`` 参数启动内核,这将打印所有未修改的%p地址。如果你 *真的* 想知
     92道未修改的地址,请看下面的%px。
     93
     94如果(也只有在)你将地址作为虚拟文件的内容打印出来,例如在procfs或sysfs中(使用
     95seq_printf(),而不是printk())由用户空间进程读取,使用下面描述的%pK修饰符,不
     96要用%p或%px。
     97
     98
     99错误指针
    100--------
    101
    102::
    103
    104	%pe	-ENOSPC
    105
    106用于打印错误指针(即IS_ERR()为真的指针)的符号错误名。不知道符号名的错误值会以十进制打印,
    107而作为%pe参数传递的非ERR_PTR会被视为普通的%p。
    108
    109符号/函数指针
    110-------------
    111
    112::
    113
    114	%pS	versatile_init+0x0/0x110
    115	%ps	versatile_init
    116	%pSR	versatile_init+0x9/0x110
    117		(with __builtin_extract_return_addr() translation)
    118	%pB	prev_fn_of_versatile_init+0x88/0x88
    119
    120
    121``S`` 和 ``s`` 占位符用于打印符号格式的指针。它们的结果是符号名称带有(S)或不带有(s)偏移
    122量。如果禁用KALLSYMS,则打印符号地址。
    123
    124``B`` 占位符的结果是带有偏移量的符号名,在打印堆栈回溯时应该使用。占位符将考虑编译器优化
    125的影响,当使用尾部调用并使用noreturn GCC属性标记时,可能会发生这种优化。
    126
    127如果指针在一个模块内,模块名称和可选的构建ID将被打印在符号名称之后,并在说明符的末尾添加
    128一个额外的 ``b`` 。
    129
    130::
    131
    132	%pS	versatile_init+0x0/0x110 [module_name]
    133	%pSb	versatile_init+0x0/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
    134	%pSRb	versatile_init+0x9/0x110 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
    135		(with __builtin_extract_return_addr() translation)
    136	%pBb	prev_fn_of_versatile_init+0x88/0x88 [module_name ed5019fdf5e53be37cb1ba7899292d7e143b259e]
    137
    138来自BPF / tracing追踪的探查指针
    139----------------------------------
    140
    141::
    142
    143	%pks	kernel string
    144	%pus	user string
    145
    146``k`` 和 ``u`` 指定符用于打印来自内核内存(k)或用户内存(u)的先前探测的内存。后面的 ``s`` 指
    147定符的结果是打印一个字符串。对于直接在常规的vsnprintf()中使用时,(k)和(u)注释被忽略,但是,当
    148在BPF的bpf_trace_printk()之外使用时,它会读取它所指向的内存,不会出现错误。
    149
    150内核指针
    151--------
    152
    153::
    154
    155	%pK	01234567 or 0123456789abcdef
    156
    157用于打印应该对非特权用户隐藏的内核指针。%pK的行为取决于kptr_restrict sysctl——详见
    158Documentation/admin-guide/sysctl/kernel.rst。
    159
    160未经修改的地址
    161--------------
    162
    163::
    164
    165	%px	01234567 or 0123456789abcdef
    166
    167对于打印指针,当你 *真的* 想打印地址时。在用%px打印指针之前,请考虑你是否泄露了内核内
    168存布局的敏感消息。%px在功能上等同于%lx(或%lu)。%px是首选,因为它在grep查找时更唯一。
    169如果将来我们需要修改内核处理打印指针的方式,我们将能更好地找到调用点。
    170
    171在使用%px之前,请考虑使用%p并在调试过程中启用' ' no_hash_pointer ' '内核参数是否足
    172够(参见上面的%p描述)。%px的一个有效场景可能是在panic发生之前立即打印消息,这样无论如何
    173都可以防止任何敏感消息被利用,使用%px就不需要用no_hash_pointer来重现panic。
    174
    175指针差异
    176--------
    177
    178::
    179
    180	%td	2560
    181	%tx	a00
    182
    183为了打印指针的差异,使用ptrdiff_t的%t修饰符。
    184
    185例如::
    186
    187	printk("test: difference between pointers: %td\n", ptr2 - ptr1);
    188
    189结构体资源(Resources)
    190-----------------------
    191
    192::
    193
    194	%pr	[mem 0x60000000-0x6fffffff flags 0x2200] or
    195		[mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
    196	%pR	[mem 0x60000000-0x6fffffff pref] or
    197		[mem 0x0000000060000000-0x000000006fffffff pref]
    198
    199用于打印结构体资源。 ``R`` 和 ``r`` 占位符的结果是打印出的资源带有(R)或不带有(r)解码标志
    200成员。
    201
    202通过引用传递。
    203
    204物理地址类型 phys_addr_t
    205------------------------
    206
    207::
    208
    209	%pa[p]	0x01234567 or 0x0123456789abcdef
    210
    211用于打印phys_addr_t类型(以及它的衍生物,如resource_size_t),该类型可以根据构建选项而
    212变化,无论CPU数据真实物理地址宽度如何。
    213
    214通过引用传递。
    215
    216DMA地址类型dma_addr_t
    217---------------------
    218
    219::
    220
    221	%pad	0x01234567 or 0x0123456789abcdef
    222
    223用于打印dma_addr_t类型,该类型可以根据构建选项而变化,而不考虑CPU数据路径的宽度。
    224
    225通过引用传递。
    226
    227原始缓冲区为转义字符串
    228----------------------
    229
    230::
    231
    232	%*pE[achnops]
    233
    234用于将原始缓冲区打印成转义字符串。对于以下缓冲区::
    235
    236		1b 62 20 5c 43 07 22 90 0d 5d
    237
    238几个例子展示了如何进行转换(不包括两端的引号)。::
    239
    240		%*pE		"\eb \C\a"\220\r]"
    241		%*pEhp		"\x1bb \C\x07"\x90\x0d]"
    242		%*pEa		"\e\142\040\\\103\a\042\220\r\135"
    243
    244转换规则是根据可选的标志组合来应用的(详见:c:func:`string_escape_mem` 内核文档):
    245
    246	- a - ESCAPE_ANY
    247	- c - ESCAPE_SPECIAL
    248	- h - ESCAPE_HEX
    249	- n - ESCAPE_NULL
    250	- o - ESCAPE_OCTAL
    251	- p - ESCAPE_NP
    252	- s - ESCAPE_SPACE
    253
    254默认情况下,使用 ESCAPE_ANY_NP。
    255
    256ESCAPE_ANY_NP是许多情况下的明智选择,特别是对于打印SSID。
    257
    258如果字段宽度被省略,那么将只转义1个字节。
    259
    260原始缓冲区为十六进制字符串
    261--------------------------
    262
    263::
    264
    265	%*ph	00 01 02  ...  3f
    266	%*phC	00:01:02: ... :3f
    267	%*phD	00-01-02- ... -3f
    268	%*phN	000102 ... 3f
    269
    270对于打印小的缓冲区(最长64个字节),可以用一定的分隔符作为一个
    271十六进制字符串。对于较大的缓冲区,可以考虑使用
    272:c:func:`print_hex_dump` 。
    273
    274MAC/FDDI地址
    275------------
    276
    277::
    278
    279	%pM	00:01:02:03:04:05
    280	%pMR	05:04:03:02:01:00
    281	%pMF	00-01-02-03-04-05
    282	%pm	000102030405
    283	%pmR	050403020100
    284
    285用于打印以十六进制表示的6字节MAC/FDDI地址。 ``M`` 和 ``m`` 占位符导致打印的
    286地址有(M)或没有(m)字节分隔符。默认的字节分隔符是冒号(:)。
    287
    288对于FDDI地址,可以在 ``M`` 占位符之后使用 ``F`` 说明,以使用破折号(——)分隔符
    289代替默认的分隔符。
    290
    291对于蓝牙地址, ``R`` 占位符应使用在 ``M`` 占位符之后,以使用反转的字节顺序,适
    292合于以小尾端顺序的蓝牙地址的肉眼可见的解析。
    293
    294通过引用传递。
    295
    296IPv4地址
    297--------
    298
    299::
    300
    301	%pI4	1.2.3.4
    302	%pi4	001.002.003.004
    303	%p[Ii]4[hnbl]
    304
    305用于打印IPv4点分隔的十进制地址。 ``I4`` 和 ``i4`` 占位符的结果是打印的地址
    306有(i4)或没有(I4)前导零。
    307
    308附加的 ``h`` 、 ``n`` 、 ``b`` 和 ``l`` 占位符分别用于指定主机、网络、大
    309尾端或小尾端地址。如果没有提供占位符,则使用默认的网络/大尾端顺序。
    310
    311通过引用传递。
    312
    313IPv6 地址
    314---------
    315
    316::
    317
    318	%pI6	0001:0002:0003:0004:0005:0006:0007:0008
    319	%pi6	00010002000300040005000600070008
    320	%pI6c	1:2:3:4:5:6:7:8
    321
    322用于打印IPv6网络顺序的16位十六进制地址。 ``I6`` 和 ``i6`` 占位符的结果是
    323打印的地址有(I6)或没有(i6)分号。始终使用前导零。
    324
    325额外的 ``c`` 占位符可与 ``I`` 占位符一起使用,以打印压缩的IPv6地址,如
    326https://tools.ietf.org/html/rfc5952 所述
    327
    328通过引用传递。
    329
    330IPv4/IPv6地址(generic, with port, flowinfo, scope)
    331--------------------------------------------------
    332
    333::
    334
    335	%pIS	1.2.3.4		or 0001:0002:0003:0004:0005:0006:0007:0008
    336	%piS	001.002.003.004	or 00010002000300040005000600070008
    337	%pISc	1.2.3.4		or 1:2:3:4:5:6:7:8
    338	%pISpc	1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345
    339	%p[Ii]S[pfschnbl]
    340
    341用于打印一个IP地址,不需要区分它的类型是AF_INET还是AF_INET6。一个指向有效结构
    342体sockaddr的指针,通过 ``IS`` 或 ``IS`` 指定,可以传递给这个格式占位符。
    343
    344附加的 ``p`` 、  ``f`` 和 ``s`` 占位符用于指定port(IPv4, IPv6)、
    345flowinfo (IPv6)和sope(IPv6)。port有一个 ``:`` 前缀,flowinfo是 ``/`` 和
    346范围是 ``%`` ,每个后面都跟着实际的值。
    347
    348对于IPv6地址,如果指定了额外的指定符 ``c`` ,则使用
    349https://tools.ietf.org/html/rfc5952 描述的压缩IPv6地址。
    350如https://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07
    351所建议的,IPv6地址由'[',']'包围,以防止出现额外的占位符 ``p`` , ``f`` 或 ``s`` 。
    352
    353对于IPv4地址,也可以使用额外的 ``h`` , ``n`` , ``b`` 和 ``l`` 说
    354明符,但对于IPv6地址则忽略。
    355
    356通过引用传递。
    357
    358更多例子::
    359
    360	%pISfc		1.2.3.4		or [1:2:3:4:5:6:7:8]/123456789
    361	%pISsc		1.2.3.4		or [1:2:3:4:5:6:7:8]%1234567890
    362	%pISpfc		1.2.3.4:12345	or [1:2:3:4:5:6:7:8]:12345/123456789
    363
    364UUID/GUID地址
    365-------------
    366
    367::
    368
    369	%pUb	00010203-0405-0607-0809-0a0b0c0d0e0f
    370	%pUB	00010203-0405-0607-0809-0A0B0C0D0E0F
    371	%pUl	03020100-0504-0706-0809-0a0b0c0e0e0f
    372	%pUL	03020100-0504-0706-0809-0A0B0C0E0E0F
    373
    374用于打印16字节的UUID/GUIDs地址。附加的 ``l`` , ``L`` , ``b`` 和 ``B`` 占位符用
    375于指定小写(l)或大写(L)十六进制表示法中的小尾端顺序,以及小写(b)或大写(B)十六进制表
    376示法中的大尾端顺序。
    377
    378如果没有使用额外的占位符,则将打印带有小写十六进制表示法的默认大端顺序。
    379
    380通过引用传递。
    381
    382目录项(dentry)的名称
    383----------------------
    384
    385::
    386
    387	%pd{,2,3,4}
    388	%pD{,2,3,4}
    389
    390用于打印dentry名称;如果我们用 :c:func:`d_move` 和它比较,名称可能是新旧混合的,但
    391不会oops。 %pd dentry比较安全,其相当于我们以前用的%s dentry->d_name.name,%pd<n>打
    392印 ``n`` 最后的组件。 %pD对结构文件做同样的事情。
    393
    394
    395通过引用传递。
    396
    397块设备(block_device)名称
    398--------------------------
    399
    400::
    401
    402	%pg	sda, sda1 or loop0p1
    403
    404用于打印block_device指针的名称。
    405
    406va_format结构体
    407---------------
    408
    409::
    410
    411	%pV
    412
    413用于打印结构体va_format。这些结构包含一个格式字符串
    414和va_list如下
    415
    416::
    417
    418	struct va_format {
    419		const char *fmt;
    420		va_list *va;
    421	};
    422
    423实现 "递归vsnprintf"。
    424
    425如果没有一些机制来验证格式字符串和va_list参数的正确性,请不要使用这个功能。
    426
    427通过引用传递。
    428
    429设备树节点
    430----------
    431
    432::
    433
    434	%pOF[fnpPcCF]
    435
    436
    437用于打印设备树节点结构。默认行为相当于%pOFf。
    438
    439	- f - 设备节点全称
    440	- n - 设备节点名
    441	- p - 设备节点句柄
    442	- P - 设备节点路径规范(名称+@单位)
    443	- F - 设备节点标志
    444	- c - 主要兼容字符串
    445	- C - 全兼容字符串
    446
    447当使用多个参数时,分隔符是':'。
    448
    449例如
    450
    451::
    452
    453	%pOF	/foo/bar@0			- Node full name
    454	%pOFf	/foo/bar@0			- Same as above
    455	%pOFfp	/foo/bar@0:10			- Node full name + phandle
    456	%pOFfcF	/foo/bar@0:foo,device:--P-	- Node full name +
    457	                                          major compatible string +
    458						  node flags
    459							D - dynamic
    460							d - detached
    461							P - Populated
    462							B - Populated bus
    463
    464通过引用传递。
    465
    466Fwnode handles
    467--------------
    468
    469::
    470
    471	%pfw[fP]
    472
    473用于打印fwnode_handles的消息。默认情况下是打印完整的节点名称,包括路径。
    474这些修饰符在功能上等同于上面的%pOF。
    475
    476	- f - 节点的全名,包括路径。
    477	- P - 节点名称,包括地址(如果有的话)。
    478
    479例如 (ACPI)
    480
    481::
    482
    483	%pfwf	\_SB.PCI0.CIO2.port@1.endpoint@0	- Full node name
    484	%pfwP	endpoint@0				- Node name
    485
    486例如 (OF)
    487
    488::
    489
    490	%pfwf	/ocp@68000000/i2c@48072000/camera@10/port/endpoint - Full name
    491	%pfwP	endpoint				- Node name
    492
    493时间和日期
    494----------
    495
    496::
    497
    498	%pt[RT]			YYYY-mm-ddTHH:MM:SS
    499	%pt[RT]s		YYYY-mm-dd HH:MM:SS
    500	%pt[RT]d		YYYY-mm-dd
    501	%pt[RT]t		HH:MM:SS
    502	%pt[RT][dt][r][s]
    503
    504用于打印日期和时间::
    505
    506	R  struct rtc_time structure
    507	T  time64_t type
    508
    509以我们(人类)可读的格式。
    510
    511默认情况下,年将以1900为单位递增,月将以1为单位递增。 使用%pt[RT]r (raw)
    512来抑制这种行为。
    513
    514%pt[RT]s(空格)将覆盖ISO 8601的分隔符,在日期和时间之间使用''(空格)而
    515不是'T'(大写T)。当日期或时间被省略时,它不会有任何影响。
    516
    517通过引用传递。
    518
    519clk结构体
    520---------
    521
    522::
    523
    524	%pC	pll1
    525	%pCn	pll1
    526
    527用于打印clk结构。%pC 和 %pCn 打印时钟的名称(通用时钟框架)或唯一的32位
    528ID(传统时钟框架)。
    529
    530通过引用传递。
    531
    532位图及其衍生物,如cpumask和nodemask
    533-----------------------------------
    534
    535::
    536
    537	%*pb	0779
    538	%*pbl	0,3-6,8-10
    539
    540对于打印位图(bitmap)及其派生的cpumask和nodemask,%*pb输出以字段宽度为位数的位图,
    541%*pbl输出以字段宽度为位数的范围列表。
    542
    543字段宽度用值传递,位图用引用传递。可以使用辅助宏cpumask_pr_args()和
    544nodemask_pr_args()来方便打印cpumask和nodemask。
    545
    546标志位字段,如页标志、gfp_flags
    547-------------------------------
    548
    549::
    550
    551	%pGp	referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff
    552	%pGg	GFP_USER|GFP_DMA32|GFP_NOWARN
    553	%pGv	read|exec|mayread|maywrite|mayexec|denywrite
    554
    555将flags位字段打印为构造值的符号常量集合。标志的类型由第三个字符给出。目前支持的
    556是[p]age flags, [v]ma_flags(都期望 ``unsigned long *`` )和
    557[g]fp_flags(期望 ``gfp_t *`` )。标志名称和打印顺序取决于特定的类型。
    558
    559注意,这种格式不应该直接用于跟踪点的:c:func:`TP_printk()` 部分。相反,应使
    560用 <trace/events/mmflags.h>中的show_*_flags()函数。
    561
    562通过引用传递。
    563
    564网络设备特性
    565------------
    566
    567::
    568
    569	%pNF	0x000000000000c000
    570
    571用于打印netdev_features_t。
    572
    573通过引用传递。
    574
    575V4L2和DRM FourCC代码(像素格式)
    576------------------------------
    577
    578::
    579
    580	%p4cc
    581
    582打印V4L2或DRM使用的FourCC代码,包括格式端序及其十六进制的数值。
    583
    584通过引用传递。
    585
    586例如::
    587
    588	%p4cc	BG12 little-endian (0x32314742)
    589	%p4cc	Y10  little-endian (0x20303159)
    590	%p4cc	NV12 big-endian (0xb231564e)
    591
    592谢谢
    593====
    594
    595如果您添加了其他%p扩展,请在可行的情况下,用一个或多个测试用例扩展<lib/test_printf.c>。
    596
    597谢谢你的合作和关注。