objtool-amd-v5-impl-p1
Contents
armv8 二进制位表示(C4 章节):https://developer.arm.com/documentation/ddi0487/latest/
在 tools/objtool/check.h
中有这样一个 instruction
结构体表示一个指令:
1 | struct instruction { |
Data Processing – Immediate
处理立即数。
对应代码:
1 | int arm_decode_dp_imm(u32 instr, enum insn_type *type, |
也就是含有dp_imm
的函数都属于Data Processing -- Immediate
操作。
它的布局如下:
1 | 31 30 29+28 | 26|25 |23|22 | 0| |
当 28-26 位为 100 时,armv8 的指令格式如上。其中,op0 的数字的不同有不同的作用 (C4.1.86):
Decode fields op0 | Decode group or instruction |
---|---|
00x | PC-rel. addressing |
010 | Add/subtract(immediate) |
011 | Add/subtract(immediate, with tags) |
100 | Logical(immediate) |
101 | Move wide(immediate) |
110 | Bitfield |
111 | Extract |
详细情况查阅文档 (c4.1.86)
1 | (((opcode) >> 23) & (NR_DP_IMM_SUBCLASS - 1)) |
INSN_DP_IMM_SUBCLASS
的操作就是获取 op0 的值。
tools/objtool/arch/arm64/decode.c
中有这样一个数组:
1 |
|
这个数组用于将不同编码类别的 ARM64 指令与对应的解码函数关联。op0 的值不同有不同的解析函数。
-
arm_decode_pcrel
:PC-relative addressing:ADRP x0, {pc}. -
arm_decode_move_wide
:move wide instruction:MOVZ,MOVK,MOVS…https://developer.arm.com/documentation/dui0489/i/arm-and-thumb-instructions/mov
-
arm_decode_bitfield
:bitfield operation: -
arm_decode_extract
:bit extract
tools/objtool/arch/arm64/include/bit_operations.h
中有这样一段宏定义,定义一些常见的位操作:
1 | // 生成 N 位全为 1 的值 |
处理 PC-rel. addressing 的情况:
布局:
1 | + + + + |
具有以下设定:
op | instruction |
---|---|
0 | ADR |
1 | ADRP |
1 | int arm_decode_pcrel(u32 instr, enum insn_type *type, |
关于 ADR 与 ADRP:
- ADR 指令用于计算相对于程序计数器(PC)的地址偏移量,并将结果加载到目标寄存器中。
ADR ro, jump_target
- ADRP 则是用于计算相对于页表的地址偏移量,并将结果加载到目标寄存器。
ADRP x0, page_table_entry
. ADRP 在计算出的地址偏移量的高 12 位上会填充一些数据(待查找,似乎是相应的页表索引)
处理 Move wide (immediate) 的情况
布局:
1 | + + + + + |
具有以下设定:
sf(op) | opc | hw | instruction |
---|---|---|---|
- | 01 | - | Unallocated. |
0 | - | 1x | Unallocated |
0 | 00 | 0x | MOVN-32-bit variant |
0 | 10 | 0x | MOVZ-32-bit variant |
0 | 11 | 0x | MOVK-32-bit variant |
1 | 00 | - | MOVN-64-bit variant |
1 | 10 | - | MOVZ-64-bit variant |
1 | 11 | - | MOVK-64-bit variant |
1 | int arm_decode_move_wide(u32 instr, enum insn_type *type, |
处理 Bitfield 的情况
布局:
1 | 31 30 29 28 | 27 26 25 24 | 23 22 21 | 16| 15 | 10 9 | 5 4 | 0| |
具有以下设定:
sf | opc | N | instruction |
---|---|---|---|
- | 11 | - | Unallocated. |
0 | - | 1 | Unallocated |
0 | 00 | 0 | SBFM-32-bit variant |
0 | 01 | 0 | BFM-32-bit varian |
0 | 10 | 0 | UBFM-32-bit varian |
1 | - | 0 | Unallocated. |
1 | 00 | 1 | SBFM-64-bit variant |
1 | 01 | 1 | BFM-64-bit varian |
1 | 10 | 1 | UBFM-64-bit varian |
1 | int arm_decode_bitfield(u32 instr, enum insn_type *type, |
关于BFM
指令表示 Bit Field Move,位域移动指令。前面有 S 则为 signed 表示有符号,U 表示无符号。用于从一个操作数中提取一个位域,并将其移动到目标寄存器中。
SBFM <Wd>, <Wn>, #<immr>, #<imms>
其中:
- Rd 是目标寄存器,用于存储提取的位域值。
- Rn 是源寄存器,包含要提取位域的源操作数。
- #immr 是右移位数的立即数。它定义了从源操作数中提取位域时的右移数。
- #imms 是位域长度的立即数。它定义了要提取的位域的长度。
处理 extract 的情况
布局
1 | 31 30 29 28 | 27 26 25 24 | 23 22 21 20 | 16| 15 | 10 9 | 5 4 | 0| |
具有以下设定:
sf | op21 | N | o0 | imms | instruction |
---|---|---|---|---|---|
- | x1 | - | - | - | Unallocated. |
- | 00 | - | 1 | - | Unallocated. |
- | 1x | - | - | - | Unallocated. |
0 | - | - | - | 1xxxxx | Unallocated. |
0 | - | 1 | - | - | Unallocated. |
0 | 00 | 0 | 0 | 0xxxxx | EXTR-32-bit variant |
1 | - | 0 | - | - | Unallocated. |
1 | 00 | 1 | 0 | - | EXTR-64-bit variant |
1 | int arm_decode_extract(u32 instr, enum insn_type *type, |
类似的,以下操作都可以根据 armv8 手册 查找到,这部分内容是处理立即数:C4.1.86
Add/subtract (immediate)
在函数 arm_decode_add_subarm_decode_add_sub
实现。
关于它的布局查看手册。其中 rn 表示源寄存器,rd 表示目标寄存器。
1 |
|
Add/subtract (immediate, with tags)
在函数 arm_decode_add_sub_tags
实现。
Logical (immediate)
1 |
|
有两个函数:decode_bit_masks
和 arm_decode_logical
,其中前者是在 bit_operations.c
文件中实现,后者调用了前者。
decode_bit_masks
返回一个 bitmask immediate。其中对于 32 位返回imms:immr
,64 位返回N:imms:immr
。可以查看 Arm 的实现 (https://developer.arm.com/documentation/ddi0596/2020-12/Shared-Pseudocode/AArch64-Instrs?lang=en#impl-aarch64.DecodeBitMasks.4).
在函数 arm_decode_logical.c
中实现。
Author: xun
Link: http://blog.fooo.in/2023/07/22/assembly/objtool-amd-v5-impl-p1/
License:
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。