Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

SPARC: 重定位

在 SPARC 平台上,重定位项应用于字节 (byte8)、半字 (half16)、字 (word32) 和扩展字 (xword64)。

image:SPARC 基本重定位项。

重定位字段 (disp19, disp22, disp30) 的 dispn 系列都是字对齐、带符号扩展的 PC 相对位移。全部将值编码为其最低有效位都位于字的位置 0,仅在分配给值的位数方面有所不同。

image:SPARC disp 重定位项。

d2/disp8d2/disp14 变体使用两个非连续位字段 d2dispn 对 16 位和 10 位位移值进行编码。

image:SPARC d2/disp 重定位项。

重定位字段的 immn 系列imm5imm6imm7imm10imm13imm22)表示无符号整型常数。全部将值编码为其最低有效位都位于字的位置 0,仅在分配给值的位数方面有所不同。

image:SPARC imm 重定位项。

重定位字段的 simmn 系列(simm10simm11simm13simm22)表示带符号的整型常数。全部将值编码为其最低有效位都位于字的位置 0,仅在分配给值的位数方面有所不同。

image:SPARC simm 重定位项。

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

注 -  其他重定位类型可用于线程局部存储引用。这些重定位类型将在Chapter 14, 线程局部存储中介绍。

一些重定位类型的语义不只是简单的计算:

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_H44R_SPARC_M44 重定位类型一起使用,以生成 44 位的绝对寻址模型。

R_SPARC_REGISTER

用于初始化寄存器符号。此重定位偏移成员包含要初始化的寄存器编号。对于此寄存器必须存在对应的寄存器符号。该符号必须为 SHN_ABS 类型。

R_SPARC_GOTDATA_OP_HIX22R_SPARC_GOTDATA_OP_LOX10R_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 位带符号的直接字段。