armelfcortex-mrelocation

Analyzing Relocations in ARM for cortex-m4


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.


Solution

  • 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.