我试图了解如何正确读取 ARM 编译器生成的重定位条目(我正在使用 (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release))。
据我对 REL 类型的理解,与 RELA 不同,没有 r_addend 并且加数放置在要重定位的部分内,因此如果我的重定位条目是:
Relocation section '.rel.text' at offset 0x127fc contains 26 entries:
000004fc 00000302 R_ARM_ABS32 00000000 .data
我应该读取文本部分中偏移量 4fc 处的加数。然而,我看到的值是 0xFFFFFFFC:
Contents of section .text:
04f0 0df13808 4046f926 b9e700bf fcffffff ..8.@F.&........
引用此重定位的反汇编片段:
00000278 <al0_sorting_algorithm_test>:
278: e92d 41f0 stmdb sp!, {r4, r5, r6, r7, r8, lr}
27c: 4d9f ldr r5, [pc, #636] ; (4fc <al0_sorting_algorithm_test+0x284>)
27e: b0ce sub sp, #312 ; 0x138
280: ae04 add r6, sp, #16
282: f105 0424 add.w r4, r5, #36 ; 0x24
286: 462b mov r3, r5
288: 4632 mov r2, r6
28a: f853 1f04 ldr.w r1, [r3, #4]!
28e: f842 1f04 str.w r1, [r2, #4]!
292: 42a3 cmp r3, r4
294: d1f9 bne.n 28a <al0_sorting_algorithm_test+0x12>
296: 4f9a ldr r7, [pc, #616] ; (500 <al0_sorting_algorithm_test+0x288>)
298: f8df 8290 ldr.w r8, [pc, #656] ; 52c <al0_sorting_algorithm_test+0x2b4>
29c: a805 add r0, sp, #20
29e: 2109 movs r1, #9
2a0: f7ff fffe bl 1e0 <al0_SelectionSort>
我无法在任何地方找到我需要进行什么样的计算才能找到我的重定位条目的实际加数。 任何帮助将不胜感激。
我尝试阅读所有能找到的手册,但找不到任何相关信息。 通常,适当的加数是一个小值,我可以添加到 .data 部分(或其他相关符号)以获取相关数据。
您看到的加数是
0xFFFFFFFC
。将其添加到 .data 部分基地址,就像处理任何其他值一样。整数环绕就可以发挥作用,得到的地址将是.data - 4
。当然,访问该结果地址是没有任何意义的。但这不是它的使用方式。
27c: 4d9f ldr r5, [pc, #636] ; (4fc <al0_sorting_algorithm_test+0x284>)
; r5 now contains the relocated address of .data - 4
; ...
282: f105 0424 add.w r4, r5, #36 ; r4 now contains .data - 4 + 36
;...
292: 42a3 cmp r3, r4 ; and it is only used as a boundary
我不知道为什么编译器决定将 -4 放入加数中,而不是将其设置为 0 并简单地添加 32,或者可能将加数设置为 32 并且稍后不进行加法。也许相同的重定位值可以在其他地方重用?例如。考虑一下编译器如何计算
.data + r3 - 4
值(如果需要的话)——也许是为了寻址位于 .data 开头的数组中的最后一个元素?将 -4 作为加数而不是在汇编中进行加法是有意义的。