I'm trying to understand how to correctly read the relocation entries generated by my ARM compiler (I'm using (GNU Arm Embedded Toolchain 9-2020-q2-update) 9.3.1 20200408 (release)).
To my understanding in REL types, unlike RELA, there is no r_addend and the addend is placed inside the section being relocated so if my relocation entry is:
Relocation section '.rel.text' at offset 0x127fc contains 26 entries:
000004fc 00000302 R_ARM_ABS32 00000000 .data
I should read the addend placed at offset 4fc in the text section. However, the value I'm seeing is 0xFFFFFFFC:
Contents of section .text:
04f0 0df13808 4046f926 b9e700bf fcffffff ..8.@F.&........
Snippet of the disassembly referencing this relocation:
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>
I couldn't find anywhere what sort of calculation I need to do in order to find the actual addend of my relocation entry. Any help would be appreciated.
I tried reading all the manuals I could find, but couldn't find any relevant information. Usually the addend in place is a small value I can add to the .data section (or other relevant symbol) to reach the relevant data.
The addend you see is 0xFFFFFFFC
. Add it to the .data section base address, just like you would do with any other value. Integer wraparound would do its trick, and the resulting address would be .data - 4
. It wouldn't make any sense to access that resulting address of course. It is not how it is used, though.
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
I don't know why a compiler decided to put -4 into addend instead of settings it to 0 and simply adding 32, or maybe setting addend to 32 and not doing the addition later. Maybe same relocated value is reused elsewhere? E.g. think about how a compiler would calculate .data + r3 - 4
value, if it needed it to - maybe to address the last element in an array placed at the beginning of .data? It would make sense to put -4 as an addend instead of doing that addition in assembly.