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 国际许可协议进行许可。