On 2/24/25 06:55, Sam Edwards wrote:
LLVM's IAS does not (and cannot easily) support the 'adrl'
pseudoinstruction, and ARM developers generally do not consider it
portable across assembler implementations either.

Instead, expand it into the two subtract instructions it would emit
anyway. An explanation of the math follows:

The .+8 and .+4 refer to the same memory location; this is because the

Are we sure that we never generate thumb instructions here?

.+4 expression occurs in a subsequent instruction, 4 bytes after the
first. This memory location is the value of the PC register when it is
read by the first sub instruction. Thus, both inner parenthesized
expressions evaluate to the same result: PC's offset relative to
image_base. The subtract instructions then remove one byte each
(low, then high) of the total offset, thereby getting the absolute
address of image_base loaded in r0.

Signed-off-by: Sam Edwards <cfswo...@gmail.com>
---
  arch/arm/lib/crt0_arm_efi.S | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/lib/crt0_arm_efi.S b/arch/arm/lib/crt0_arm_efi.S
index 91b0fe12c51..235b3a0c48f 100644
--- a/arch/arm/lib/crt0_arm_efi.S
+++ b/arch/arm/lib/crt0_arm_efi.S
@@ -149,7 +149,8 @@ _start:
        adr             r1, .L_DYNAMIC
        ldr             r0, [r1]
        add             r1, r0, r1
-       adrl            r0, image_base
+       sub             r0, pc, #((.+8-image_base) & 0xff)
+       sub             r0, r0, #((.+4-image_base) & 0xff00)

These are the instructions resulting from building qemu_arm_defconfig:

sub     r0, pc, #24
sub     r0, r0, #16, 24 @ 0x1000

The last instruction subtracts 0x1000000.

I can't see how your instructions would be doing the same.

Best regards

Heinrich

        bl              _relocate
        teq             r0, #0
        bne             0f

Reply via email to