In the u-boot link script I see these lines (https://source.denx.de/u-boot/u-boot/-/blob/v2021.10/arch/arm/cpu/armv8/u-boot.lds near line 134).
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rela.dyn : {
*(.rela*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
And this is a code doing relocation. (https://source.denx.de/u-boot/u-boot/-/blob/v2021.10/arch/arm/cpu/armv8/start.S near line 88)
But I can't exactly understand the following lines.
adrp x2, __rel_dyn_start /* x2 <- Runtime &__rel_dyn_start */
add x2, x2, #:lo12:__rel_dyn_start
adrp x3, __rel_dyn_end /* x3 <- Runtime &__rel_dyn_end */
add x3, x3, #:lo12:__rel_dyn_end
pie_fix_loop:
ldp x0, x1, [x2], #16 /* (x0, x1) <- (Link location, fixup) */
ldr x4, [x2], #8 /* x4 <- addend */
cmp w1, #1027 /* relative fixup? */ // <==== from here??
bne pie_skip_reloc
/* relative fix: store addend plus offset at dest location */
add x0, x0, x9
add x4, x4, x9
str x4, [x0]
pie_skip_reloc:
cmp x2, x3
b.lo pie_fix_loop
My first question is about adrp x2, __rel_dyn_start instruction.
From the linker script I see .__rel_dyn_start is the name of a section. But I couldn't find the variable named __rel_dyn_start(without the dot). Where is it coming from?
My second question is about the code from cmp w1, #1027 (marked <==== from here?? above).
I guess at this point, x0, x1 and x4 contain the first three 8-byte values in the .__rel_dyn_start section(assuming __rel_dyn_start is the first variable in the combined .rel_dyn_start section). And x9 seems to contain the offset for the relocation.
So in cmp w1, #1027, why does it compare w1 (the lower part of the second 8-byte value in the relocation section(?)) with #1027? and if it is equal, why does it add the relocation offset to x0 and x4 and store the copied value x4 to the new address x0? (maybe x0 and x4 was containg some kind of addrsses). I can't follow the next codes without understanding this.
Thank you for reading and I will be very grateful if someone could explain to me the main logic behind this and what all these codes are doing.