Home > Software engineering >  How to declare a variable (in data section) and load the address of the variable in arm64 assembly?
How to declare a variable (in data section) and load the address of the variable in arm64 assembly?

Time:08-11

I think I knew this but I forgot how to do it.
In an assembly program (in arch/arm64/kernel/head.S of linux) I declare a variable like this

__INITDATA
mydata1 : .long 0x22222222

and then in the __primary_switch function in __INIT section, which is .init.text, I want to overwrite 0x1406 at mydata1,

mov x27, #0x1406
adrp x25, mydata1
add x25, x25, :lo12:mydata1
str x27, [x25]
dc cvac, x25

But I get this error message when I compile it.

/tmp/ccy8ayvt.s: Error: .size expression for __primary_switch does not evaluate to a constant

What am I doing wrong?

ADD :
I found what my mistake was : I put

__INITDATTA
mydata1: .long 0x22222222

inside a function definition! (right before SYM_FUNC_END(__primary_switch) statement..) That's causing the weird error message.

CodePudding user response:

Just try it?

unsigned long x=0x22222222;
void fun ( void )
{
    x=0x1406;
}

aarch64-none-elf-gcc -fno-section-anchors -O2 -c -save-temps so.c -o so.o

    .arch armv8-a
    .file   "so.c"
    .text
    .align  2
    .p2align 4,,11
    .global fun
    .type   fun, %function
fun:
    adrp    x0, x
    mov x1, 5126
    str x1, [x0, #:lo12:x]
    ret
    .size   fun, .-fun
    .global x
    .data
    .align  3
    .type   x, %object
    .size   x, 8
x:
    .xword  572662306
    .ident  "GCC: (GNU) 11.1.0"

so

    .global fun
fun:
    adrp    x0, x
    mov x1, 0x1406
    str x1, [x0, #:lo12:x]
    ret

    .data
    .global x
x:
    .xword  0x22222222

minimal linking to see it in action

Disassembly of section .text:

0000000000400000 <fun>:
  400000:   90000080    adrp    x0, 410000 <fun 0x10000>
  400004:   d28280c1    mov x1, #0x1406                 // #5126
  400008:   f9000801    str x1, [x0, #16]
  40000c:   d65f03c0    ret

Disassembly of section .data:

0000000000410010 <__data_start>:
  410010:   22222222    .inst   0x22222222 ; undefined
  410014:   00000000    udf #0

Can do this too

    .global fun
fun:
    adrp    x0, x
    add    x0,x0,#:lo12:x
    mov x1, #0x1406
    str x1, [x0]
    ret

    .data
    .global x
x:
    .xword  0x22222222

but even if I

.data
mydata1 : .long 0x22222222

.text
mov x27, #0x1406
adrp x25, mydata1
add x25, x25, :lo12:mydata1
str x27, [x25]
dc cvac, x25

aarch64-none-elf-as so.s -o so.o
aarch64-none-elf-objdump -D so.o

so.o:     file format elf64-littleaarch64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   d28280db    mov x27, #0x1406                    // #5126
   4:   90000019    adrp    x25, 0 <.text>
   8:   91000339    add x25, x25, #0x0
   c:   f900033b    str x27, [x25]
  10:   d50b7a39    dc  cvac, x25

Disassembly of section .data:

0000000000000000 <mydata1>:
   0:   22222222    .inst   0x22222222 ; undefined

What tool (and version) are you using and can you provide a complete minimal example. I do not see the error. Since it talks about size then what does the .size show in your code and why does it not resolve? That is where you need to start

  • Related