This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

instruction equivalent to movw,movt with position independent and PC relocatable.

Using movw and movt to load a label address into a register in Arm 32 architecture. but this is not position independent  code.

movw r1, #:lower16:ASM_NAME(forkx)
movt r1, #:upper16:ASM_NAME(forkx)

As per the manual also it specifies that it will be resolved at the link time.

Need a position independent code, so as per the manual adr, adrl can be used, but getting below error:

../asm-arm/unix_arm.S:115:1: error: unsupported relocation on symbol
adr r1, __be_forkx

../asm-arm/unix_arm.S:60:1: error: invalid instruction, did you mean: adr?
adrl r1, __be_forkx

it seems label can not be used in the aarch32, it is fine in aarch64 and works as intendent.

is the usage of adr command is improper? Is there a way to achieve this in aarch32?  is there any equivalent command that can be used?

Parents
  • i checked the adr issue is with the range, if we add the label in the same file and then try for adr then it is fine.

    True, adr/l may not work for external symbols. GNU as complains about undefined symbol even if that symbol is declared as global (IMPORTed in clang/armasm).

    using the clang compiler here, so may be this compiler is not supported with adrl

    In that case, one can manually emit two add/sub instructions, the first one with "add/sub r1,pc,offset1" and second one with "add/sub r1,r1,offset2", such that the final value in r1 is the address required. The offset1 value must be such that "it can be produced by rotating an 8-bit value right by any even number of bits within a 32-bit word".

    checked in other kernel with x86, mips architecture, if we use the pc relocatable instruction then it will be ASLR compliant.

    The Linux kernel configuration for arm64 enables KASLR by default. The vmlinux binary thus built contains many relocations that the kernel's startup routine fixes at runtime. It may be not practical, or even possible, in certain cases, to utilize pc-relative addresses.

    only possible way is to have the label within the 4096B offset in A32.

    I am sorry for the confusion. With A32, one has accesses to considerably larger region than just 4KB. You may want to run a few test-cases with GNU assembler and the adrl instruction, and see how the addresses are generated there.

Reply
  • i checked the adr issue is with the range, if we add the label in the same file and then try for adr then it is fine.

    True, adr/l may not work for external symbols. GNU as complains about undefined symbol even if that symbol is declared as global (IMPORTed in clang/armasm).

    using the clang compiler here, so may be this compiler is not supported with adrl

    In that case, one can manually emit two add/sub instructions, the first one with "add/sub r1,pc,offset1" and second one with "add/sub r1,r1,offset2", such that the final value in r1 is the address required. The offset1 value must be such that "it can be produced by rotating an 8-bit value right by any even number of bits within a 32-bit word".

    checked in other kernel with x86, mips architecture, if we use the pc relocatable instruction then it will be ASLR compliant.

    The Linux kernel configuration for arm64 enables KASLR by default. The vmlinux binary thus built contains many relocations that the kernel's startup routine fixes at runtime. It may be not practical, or even possible, in certain cases, to utilize pc-relative addresses.

    only possible way is to have the label within the 4096B offset in A32.

    I am sorry for the confusion. With A32, one has accesses to considerably larger region than just 4KB. You may want to run a few test-cases with GNU assembler and the adrl instruction, and see how the addresses are generated there.

Children