SPARC: 重定位
在 SPARC 平台上,重定位项应用于字节 (byte8)、半字 (half16)、字 (word32) 和扩展字 (xword64)。
重定位字段 (disp19, disp22, disp30) 的 dispn 系列都是字对齐、带符号扩展的 PC 相对位移。全部将值编码为其最低有效位都位于字的位置 0,仅在分配给值的位数方面有所不同。
d2/disp8 和 d2/disp14 变体使用两个非连续位字段 d2 和 dispn 对 16 位和 10 位位移值进行编码。
重定位字段的 immn 系列(imm5、imm6、imm7、imm10、imm13 和 imm22)表示无符号整型常数。全部将值编码为其最低有效位都位于字的位置 0,仅在分配给值的位数方面有所不同。
重定位字段的 simmn 系列(simm10、simm11、simm13 和 simm22)表示带符号的整型常数。全部将值编码为其最低有效位都位于字的位置 0,仅在分配给值的位数方面有所不同。
SPARC: 重定位类型
下表中的字段名称可确定重定位类型是否会检查 overflow。计算出的重定位值可以大于预期的字段,并且重定位类型可以验证 (V) 值是适合结果还是将结果截断 (T)。例如,V-simm13 表示计算出的值不能包含 simm13 字段外有意义的非零位。
表 12-16 SPARC: ELF 重定位类型
|
|
|
|
R_SPARC_NONE
|
0
|
无
|
无
|
R_SPARC_8
|
1
|
V-byte8
|
S + A
|
R_SPARC_16
|
2
|
V-half16
|
S + A
|
R_SPARC_32
|
3
|
V-word32
|
S + A
|
R_SPARC_DISP8
|
4
|
V-byte8
|
S + A - P
|
R_SPARC_DISP16
|
5
|
V-half16
|
S + A - P
|
R_SPARC_DISP32
|
6
|
V-disp32
|
S + A - P
|
R_SPARC_WDISP30
|
7
|
V-disp30
|
(S + A - P) >> 2
|
R_SPARC_WDISP22
|
8
|
V-disp22
|
(S + A - P) >> 2
|
R_SPARC_HI22
|
9
|
T-imm22
|
(S + A) >> 10
|
R_SPARC_22
|
10
|
V-imm22
|
S + A
|
R_SPARC_13
|
11
|
V-simm13
|
S + A
|
R_SPARC_LO10
|
12
|
T-simm13
|
(S + A) & 0x3ff
|
R_SPARC_GOT10
|
13
|
T-simm13
|
G & 0x3ff
|
R_SPARC_GOT13
|
14
|
V-simm13
|
G
|
R_SPARC_GOT22
|
15
|
T-simm22
|
G >> 10
|
R_SPARC_PC10
|
16
|
T-simm13
|
(S + A - P) & 0x3ff
|
R_SPARC_PC22
|
17
|
V-disp22
|
(S + A - P) >> 10
|
R_SPARC_WPLT30
|
18
|
V-disp30
|
(L + A - P) >> 2
|
R_SPARC_COPY
|
19
|
无
|
请参阅此表后面的说明。
|
R_SPARC_GLOB_DAT
|
20
|
V-word32
|
S + A
|
R_SPARC_JMP_SLOT
|
21
|
无
|
请参阅此表后面的说明。
|
R_SPARC_RELATIVE
|
22
|
V-word32
|
B + A
|
R_SPARC_UA32
|
23
|
V-word32
|
S + A
|
R_SPARC_PLT32
|
24
|
V-word32
|
L + A
|
R_SPARC_HIPLT22
|
25
|
T-imm22
|
(L + A) >> 10
|
R_SPARC_LOPLT10
|
26
|
T-simm13
|
(L + A) & 0x3ff
|
R_SPARC_PCPLT32
|
27
|
V-word32
|
L + A - P
|
R_SPARC_PCPLT22
|
28
|
V-disp22
|
(L + A - P) >> 10
|
R_SPARC_PCPLT10
|
29
|
V-simm13
|
(L + A - P) & 0x3ff
|
R_SPARC_10
|
30
|
V-simm10
|
S + A
|
R_SPARC_11
|
31
|
V-simm11
|
S + A
|
R_SPARC_HH22
|
34
|
V-imm22
|
(S + A) >> 42
|
R_SPARC_HM10
|
35
|
T-simm13
|
((S + A) >> 32) & 0x3ff
|
R_SPARC_LM22
|
36
|
T-imm22
|
(S + A) >> 10
|
R_SPARC_PC_HH22
|
37
|
V-imm22
|
(S + A - P) >> 42
|
R_SPARC_PC_HM10
|
38
|
T-simm13
|
((S + A - P) >> 32) & 0x3ff
|
R_SPARC_PC_LM22
|
39
|
T-imm22
|
(S + A - P) >> 10
|
R_SPARC_WDISP16
|
40
|
V-d2/disp14
|
(S + A - P) >> 2
|
R_SPARC_WDISP19
|
41
|
V-disp19
|
(S + A - P) >> 2
|
R_SPARC_7
|
43
|
V-imm7
|
S + A
|
R_SPARC_5
|
44
|
V-imm5
|
S + A
|
R_SPARC_6
|
45
|
V-imm6
|
S + A
|
R_SPARC_HIX22
|
48
|
V-imm22
|
((S + A) ^ 0xffffffffffffffff) >> 10
|
R_SPARC_LOX10
|
49
|
T-simm13
|
((S + A) & 0x3ff) | 0x1c00
|
R_SPARC_H44
|
50
|
V-imm22
|
(S + A) >> 22
|
R_SPARC_M44
|
51
|
T-imm10
|
((S + A) >> 12) & 0x3ff
|
R_SPARC_L44
|
52
|
T-imm13
|
(S + A) & 0xfff
|
R_SPARC_REGISTER
|
53
|
V-word32
|
S + A
|
R_SPARC_UA16
|
55
|
V-half16
|
S + A
|
R_SPARC_GOTDATA_HIX22
|
80
|
V-imm22
|
((S + A - GOT) >> 10) ^ ((S + A - GOT) >> 31)
|
R_SPARC_GOTDATA_LOX10
|
81
|
T-imm13
|
((S + A - GOT) & 0x3ff) | (((S + A - GOT) >> 31) & 0x1c00)
|
R_SPARC_GOTDATA_OP_HIX22
|
82
|
T-imm22
|
(G >> 10) ^ (G >> 31)
|
R_SPARC_GOTDATA_OP_LOX10
|
83
|
T-imm13
|
(G & 0x3ff) | ((G >> 31) & 0x1c00)
|
R_SPARC_GOTDATA_OP
|
84
|
Word32
|
请参阅此表后面的说明。
|
R_SPARC_SIZE32
|
86
|
V-word32
|
Z + A
|
R_SPARC_WDISP10
|
88
|
V-d2/disp8
|
(S + A - P) >> 2
|
|
一些重定位类型的语义不只是简单的计算:
- R_SPARC_GOT10
-
与 R_SPARC_LO10 类似,不同的是此重定位指向符号的 GOT 项的地址。此外,R_SPARC_GOT10 还指示链接编辑器创建全局偏移表。
- R_SPARC_GOT13
-
与 R_SPARC_13 类似,不同的是此重定位指向符号的 GOT 项的地址。此外,R_SPARC_GOT13 还指示链接编辑器创建全局偏移表。
- R_SPARC_GOT22
-
与 R_SPARC_22 类似,不同的是此重定位指向符号的 GOT 项的地址。此外,R_SPARC_GOT22 还指示链接编辑器创建全局偏移表。
- R_SPARC_WPLT30
-
与 R_SPARC_WDISP30 类似,不同的是此重定位指向符号的过程链接表项的地址。此外,R_SPARC_WPLT30 还指示链接编辑器创建过程链接表。
- R_SPARC_COPY
-
由链接编辑器为动态可执行文件创建,用于保留只读文本段。此重定位偏移成员指向可写段中的位置。符号表索引指定应在当前目标文件和共享目标文件中同时存在的符号。执行过程中,运行时链接程序将与共享目标文件的符号关联的数据复制到偏移所指定的位置。请参见复制重定位。
- R_SPARC_GLOB_DAT
-
与 R_SPARC_32 类似,不同的是此重定位会将 GOT 项设置为所指定符号的地址。使用特殊重定位类型,可以确定符号和 GOT 项之间的对应关系。
- R_SPARC_JMP_SLOT
-
由链接编辑器为动态目标文件创建,用于提供延迟绑定。此重定位偏移成员可指定过程链接表项的位置。运行时链接程序会修改过程链接表项,以将控制权转移到指定的符号地址。
- R_SPARC_RELATIVE
-
由链接编辑器为动态目标文件创建。此重定位偏移成员可指定共享目标文件中包含表示相对地址的值的位置。运行时链接程序通过将装入共享目标文件的虚拟地址与相对地址相加,计算对应的虚拟地址。此类型的重定位项必须为符号表索引指定值零。
- R_SPARC_UA32
-
与 R_SPARC_32 类似,不同的是此重定位指向未对齐的字。必须将要重定位的字作为任意对齐的四个独立字节进行处理,而不是作为根据体系结构要求对齐的字进行处理。
- R_SPARC_LM22
-
与 R_SPARC_HI22 类似,不同的是此重定位会进行截断而不是验证。
- R_SPARC_PC_LM22
-
与 R_SPARC_PC22 类似,不同的是此重定位会进行截断而不是验证。
- R_SPARC_HIX22
-
与 R_SPARC_LOX10 一起用于可执行文件,这些可执行文件在 64 位地址空间中的上限为 4 GB。与 R_SPARC_HI22 类似,但会提供链接值的补码。
- R_SPARC_LOX10
-
与 R_SPARC_HIX22 一起使用。与 R_SPARC_LO10 类似,但始终设置链接值的位 10 到 12。
- R_SPARC_L44
-
与 R_SPARC_H44 和 R_SPARC_M44 重定位类型一起使用,以生成 44 位的绝对寻址模型。
- R_SPARC_REGISTER
-
用于初始化寄存器符号。此重定位偏移成员包含要初始化的寄存器编号。对于此寄存器必须存在对应的寄存器符号。该符号必须为 SHN_ABS 类型。
- R_SPARC_GOTDATA_OP_HIX22、R_SPARC_GOTDATA_OP_LOX10 和 R_SPARC_GOTDATA_OP
-
这些重定位类型用于代码转换。
64-bit SPARC: 重定位类型
重定位计算中使用的以下表示法是特定于 64 位 SPARC 的。
- O
-
用于计算重定位字段的值的辅助加数。此加数通过应用 ELF64_R_TYPE_DATA 宏从 r_info 字段中提取。
下表中列出的重定位类型是扩展或修改针对 32 位 SPARC 定义的重定位类型所得的。请参见重定位类型。
表 12-17 64-bit SPARC: ELF 重定位类型
|
|
|
|
R_SPARC_HI22
|
9
|
V-imm22
|
(S + A) >> 10
|
R_SPARC_GLOB_DAT
|
20
|
V-xword64
|
S + A
|
R_SPARC_RELATIVE
|
22
|
V-xword64
|
B + A
|
R_SPARC_64
|
32
|
V-xword64
|
S + A
|
R_SPARC_OLO10
|
33
|
V-simm13
|
((S + A) & 0x3ff) + O
|
R_SPARC_DISP64
|
46
|
V-xword64
|
S + A - P
|
R_SPARC_PLT64
|
47
|
V-xword64
|
L + A
|
R_SPARC_REGISTER
|
53
|
V-xword64
|
S + A
|
R_SPARC_UA64
|
54
|
V-xword64
|
S + A
|
R_SPARC_H34
|
85
|
V-imm22
|
(S + A) >> 12
|
R_SPARC_SIZE64
|
87
|
V-xword64
|
Z + A
|
|
以下重定位类型的语义不只是简单的计算:
- R_SPARC_OLO10
-
与 R_SPARC_LO10 类似,不同的是会添加额外的偏移,以充分利用 13 位带符号的直接字段。