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 symboladr 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?
Thanks for the input surati,
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.
using the clang compiler here, so may be this compiler is not supported with adrl command. will cross verify this with GCC.
We have this assembly file and to be made part of the binary, i can make this part of shared library, but still this shared library will not be ASLR compliant.
checked in other kernel with x86, mips architecture, if we use the pc relocatable instruction then it will be ASLR compliant.
So with the link given above only possible way is to have the label within the 4096B offset in A32. adr command support only this, need to check for the more jump option.
DeepakHegde said:You mentioned linked article specifies the way to calculate the valid address, is there a link that i can read and get the offset?
The possible valid offsets accepted by the A32-adr instruction, is given here: "... an have any value that can be produced by rotating an 8-bit value right by any even number of bits within a 32-bit word".
Was the adr instruction originally an "ldr r1, =__be_forkx" instruction?
Since the modification succeeds with A64-adrp instruction, you may want to confirm that the failure of A32-adr instruction is actually because of the range limitation.
A32-adrl is supported, at least by GNU as. The invalid-instruction error, upon encountering adrl, points towards the assembler. One can write a small testcase to see if the assembler recognizes adrl. If not, since adr/l are, beneath the surface, add/sub instructions, they can be hand-coded using add/sub, although I did read somewhere that such a practice is discouraged.
Assuming that a relocatable, bare-metal binary is being built, would it not be simpler to build it as a shared object? Such a build should emit appropriate relocations that some startup code can easily fix.
That startup code may have to be written carefully, but majority of the binary may not need such instruction-level modifications.
You may also want to investigate, within the limits imposed by your employer and by licenses involved, how other kernels implement relocations/randomizations.
It is static linking at the end. but still with the PIC enabled, at run time it will get the location for __be_forkx, so should be able to load it run time.
I think ADRP works here because it can load starting page address and can have more jump. but adrp is not there in A32.
Yes, your understanding is correct, want to achieve Address Space Layout Randomisation (ASLR).
You mentioned linked article specifies the way to calculate the valid address, is there a link that i can read and get the offset? is there a way i can get this done?
DeepakHegde said:this may not satisfy 4K condition
Apologies. 4K is under T32. For e.g., the A32 adr instruction "x: add r0,pc,#0x20000000" calculates the address of a location 512MB above pc (i.e., r0 = x+8+0x20000000). The linked article describes how valid offsets are calculated.
DeepakHegde said:label __be_forkx is there in another link library
And is that library statically linked with your application? or dynamically? I am trying to understand how adrp worked here but adr fails.
DeepakHegde said:We need to generate PIC enabled code to make sure that addresses not tracked and to avoid the same address in every invocation of the binary.
I did not understand this. Oh, may be it is address space randomization?
Thanks for the reply surati,
1) label __be_forkx is there in another link library, so this may not satisfy 4K condition, so in wanted to use adrl command, but it seems not supported. in 64bit version using adrp and add.
2) We need to generate PIC enabled code to make sure that addresses not tracked and to avoid the same address in every invocation of the binary.
This is a direct assembly code, so is there any equivalent operation that can be used to avoid this? PIC enabled?
DeepakHegde said:../asm-arm/unix_arm.S:115:1: error: unsupported relocation on symboladr r1, __be_forkx ../asm-arm/unix_arm.S:60:1: error: invalid instruction, did you mean: adr?adrl r1, __be_forkx
The encoding for adr instruction (in the A32 ISA) says that it can address locations which are within some range [4KB either side of that instruction is for T32]. Does the location "__be_forkx" satisfy that constraint?
Why is there a need for generating PIC devoid of any relocations?
Edit: Correction in the range of adr. I originally listed the restriction for T32.
View all questions in Arm Development Platforms forum