public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
To: binutils <binutils@sourceware.org>
Subject: Re: How to define a symbol with absolute address for AArch64?
Date: Wed, 13 Sep 2023 08:04:51 +0200	[thread overview]
Message-ID: <b7b091cc-fe04-4675-9ded-72296e64559b@embedded-brains.de> (raw)
In-Reply-To: <7747e9af-e9fb-3979-a181-d1b23e8cf340@foss.arm.com>

On 12.09.23 18:18, Richard Earnshaw wrote:
> 
> 
> On 12/09/2023 15:23, Sebastian Huber wrote:
>> On 12.09.23 15:46, Xi Ruoyao wrote:
>>> On Tue, 2023-09-12 at 14:58 +0200, Sebastian Huber wrote:
>>>> On 12.09.23 13:21, Richard Earnshaw wrote:
>>>>>
>>>>> On 12/09/2023 11:02, Sebastian Huber wrote:
>>>>>> Hello,
>>>>>>
>>>>>> I would like to define a global symbol with an absolute address in an
>>>>>> assembly/C source file for the AArch64 target. This works for all
>>>>>> other architectures I tried so far, but not for AArch64:
>>>>>>
>>>>>> extern char abs_symbol[];
>>>>>> extern char abs_symbol_2[];
>>>>>>
>>>>>> __asm__(
>>>>>>     "\t.globl abs_symbol\n"
>>>>>>     "\t.set abs_symbol, 0x123\n"
>>>>>> );
>>>>>>
>>>>>> unsigned long f_abs_symbol(void)
>>>>>> {
>>>>>>     return (unsigned long)abs_symbol;
>>>>>> }
>>>>>>
>>>>>> unsigned long f_abs_symbol_2(void)
>>>>>> {
>>>>>>     return (unsigned long)abs_symbol_2;
>>>>>> }
>>>>>>
>>>>>> unsigned long _start(void)
>>>>>> {
>>>>>>     return f_abs_symbol() + f_abs_symbol_2();
>>>>>> }
>>>>>>
>>>>>> aarch64-rtems6-gcc abs.c -Wl,--gc-sections 
>>>>>> -Wl,--defsym=abs_symbol_2=291
>>>>> Have you tried -mcmodel=large?  With that I get:
>>>> I get the same result with -mcmodel=large. With -mcmodel=tiny I get:
>>>>
>>>> aarch64-rtems6-gcc abs.c -Wl,--gc-sections 
>>>> -Wl,--defsym=abs_symbol_2=291
>>>> -mcmodel=tiny
>>>> /tmp/ccKUnvyq.o: in function `f_abs_symbol_2':
>>>> abs.c:(.text+0x8): relocation truncated to fit: R_AARCH64_ADR_PREL_LO21
>>>> against symbol `abs_symbol_2' defined in*ABS*  section in a.out
>>>> collect2: error: ld returned 1 exit status
>>>>
>>>> Is this a tool bug?
>>> No, it's how code models are defined.  GCC documentation says clearly:
>>>
>>>         -mcmodel=tiny
>>>             Generate code for  the  tiny  code  model.   The  program 
>>> and  its
>>>             statically  defined  symbols  must  be  within  1MB  of 
>>> each other.
>>>             Programs can be statically or dynamically linked.
>>>
>>> Here the text is located at 0x400000 but abs_symbol_2 is at 0x123, thus
>>> violating the definition of -mcmodel=tiny.
>>
>> Yes, this makes sense.
>>
>>>
>>>> Is there some way to make this working with -mcmodel=small?
>>> No because -mcmodel=small only assumes the program and the symbols are
>>> within*a*  4GB range - for example it's allowed to be [47GB, 51GB).
>>> This is different from the default code model of RISC-V (-
>>> mcmodel=medlow) where the symbols must be in [-2GB, 2GB).
>>>
>>> If you really think GCC should support this you can ask GCC for adding a
>>> new code model.  Anyway this is not a linker issue because the adrp-add
>>> pairs are generated by GCC.
>>
>> Thanks for the explanation.
>>
>> I guess what reliably works across code models is using the address of 
>> an existing symbol and then add a constant which fits into the code 
>> model. To retrieve the constant, we just have to subtract the address 
>> of the other symbol.
>>
> 
> There are various ways you can code this:
> 
> 1) An alternative when using the large code model is to just write
> 
> extern char abs_symbol[];
> 
> char * const abs_sym_ptr = abs_symbol;
> 
> unsigned long f_abs_symbol(void)
> {
>    return (unsigned long)abs_sym_ptr;
> }
> 
> Which assembles to:
> 0000000000400000 <f_abs_symbol>:
>    400000:       90000000        adrp    x0, 400000 <f_abs_symbol>
>    400004:       91004000        add     x0, x0, #0x10
>    400008:       f9400000        ldr     x0, [x0]
>    40000c:       d65f03c0        ret
>    400010:       00000123        .word   0x00000123
>    400014:       00000000        .word   0x00000000
> 
> 2) If you really want to use other code models, you can try things like:
> 
> extern char abs_symbol[];
> 
> char * const volatile  abs_sym_ptr = abs_symbol;
> 
> unsigned long f_abs_symbol(void)
> {
>    return (unsigned long)abs_sym_ptr;
> }
> 
> The "const volatile" forces the compiler not to try to inline the 
> pointer value dereference, so you end up with:
> 
> 0000000000400000 <f_abs_symbol>:
>    400000:       90000000        adrp    x0, 400000 <f_abs_symbol>
>    400004:       f9400c00        ldr     x0, [x0, #24]
>    400008:       d65f03c0        ret
> 
> ...
> 
> Disassembly of section .rodata:
> 
> 0000000000400018 <abs_sym_ptr>:
>    400018:       00000123 00000000                       #.......
> 
> 
> In other respects, though, the pointer is const, so attempts to modify 
> it via normal C code will be inhibited by the compiler.
> 
> This should work with both the small and tiny models as well as the 
> large model.

For my use case, I can't use things in the data or read-only data 
section. The RTEMS real-time operating system is deployed as a start.o 
start file and a set of static libraries. Applications are statically 
linked with the operating system. The operating system is configured by 
the application through a set of objects and some symbols those 
addresses are configuration values. One of these symbols is the size of 
the interrupt and system initialization stack. Setting up the system 
initialization stack is usually one of the first things done by the 
startup code in start.o. This is done before the data sections are 
copied from the load memory area to the virtual (runtime) memory area. 
For example on AArch64 it uses this code currently:

   /* Calculate interrupt stack area end for current processor */
#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
   ldr w1, =_ISR_Stack_size
#else
   ldr x1, =_ISR_Stack_size
#endif
#ifdef RTEMS_SMP
   add x3, x7, #1
   mul x1, x1, x3
#endif
#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
   ldr w2, =_ISR_Stack_area_begin
#else
   ldr x2, =_ISR_Stack_area_begin
#endif
   add x3, x1, x2

I adjusted our test cases so that they work now also for AArch64:

https://git.rtems.org/rtems/commit/?id=d7a6e803984e5508c30aa9e3625c76460beb807b

-- 
embedded brains GmbH
Herr Sebastian HUBER
Dornierstr. 4
82178 Puchheim
Germany
email: sebastian.huber@embedded-brains.de
phone: +49-89-18 94 741 - 16
fax:   +49-89-18 94 741 - 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/

  reply	other threads:[~2023-09-13  6:04 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-12 10:02 Sebastian Huber
2023-09-12 11:21 ` Richard Earnshaw
2023-09-12 12:58   ` Sebastian Huber
2023-09-12 13:46     ` Xi Ruoyao
2023-09-12 14:23       ` Sebastian Huber
2023-09-12 16:18         ` Richard Earnshaw
2023-09-13  6:04           ` Sebastian Huber [this message]
2023-09-13 10:02             ` Richard Earnshaw (lists)
2023-09-14  7:30               ` Sebastian Huber

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b7b091cc-fe04-4675-9ded-72296e64559b@embedded-brains.de \
    --to=sebastian.huber@embedded-brains.de \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).