From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dedi548.your-server.de (dedi548.your-server.de [85.10.215.148]) by sourceware.org (Postfix) with ESMTPS id ECD9D385772D for ; Thu, 14 Sep 2023 07:30:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ECD9D385772D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=embedded-brains.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=embedded-brains.de Received: from sslproxy05.your-server.de ([78.46.172.2]) by dedi548.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qggnc-0006oY-7n for binutils@sourceware.org; Thu, 14 Sep 2023 09:30:04 +0200 Received: from [82.100.198.138] (helo=mail.embedded-brains.de) by sslproxy05.your-server.de with esmtpsa (TLSv1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qggnb-000SJP-6D for binutils@sourceware.org; Thu, 14 Sep 2023 09:30:03 +0200 Received: from localhost (localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id B61F24801B9 for ; Thu, 14 Sep 2023 09:30:02 +0200 (CEST) Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavis, port 10032) with ESMTP id ryTz0DUkfCCi for ; Thu, 14 Sep 2023 09:30:02 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.embedded-brains.de (Postfix) with ESMTP id 06D25480188 for ; Thu, 14 Sep 2023 09:30:02 +0200 (CEST) X-Virus-Scanned: amavis at zimbra.eb.localhost Received: from mail.embedded-brains.de ([127.0.0.1]) by localhost (zimbra.eb.localhost [127.0.0.1]) (amavis, port 10026) with ESMTP id fyVR5Iz03gur for ; Thu, 14 Sep 2023 09:30:01 +0200 (CEST) Received: from [192.168.96.179] (unknown [192.168.96.179]) by mail.embedded-brains.de (Postfix) with ESMTPSA id CE722480157 for ; Thu, 14 Sep 2023 09:30:01 +0200 (CEST) Message-ID: <6aeb48c2-bde0-4392-b91f-8477d80b6154@embedded-brains.de> Date: Thu, 14 Sep 2023 09:30:01 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: How to define a symbol with absolute address for AArch64? Content-Language: en-US To: binutils References: <2d247374-92a2-463b-ba23-8a6dc36d13c0@embedded-brains.de> <580f9122-f63d-628e-4503-dfcefbb1b304@foss.arm.com> <57bfc9fd-e7b2-40b0-aeac-0447d6d0245e@embedded-brains.de> <2706d31f-7f35-46f9-9a20-78cf069e9602@embedded-brains.de> <7747e9af-e9fb-3979-a181-d1b23e8cf340@foss.arm.com> From: Sebastian Huber In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable X-Authenticated-Sender: smtp-embedded@poldi-networks.de X-Virus-Scanned: Clear (ClamAV 0.103.8/27030/Wed Sep 13 09:38:36 2023) X-Spam-Status: No, score=-3.7 required=5.0 tests=BAYES_00,BODY_8BITS,KAM_DMARC_STATUS,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 13.09.23 12:02, Richard Earnshaw (lists) wrote: > On 13/09/2023 07:04, Sebastian Huber wrote: >> 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 al= l >>>>>>>> other architectures I tried so far, but not for AArch64: >>>>>>>> >>>>>>>> extern char abs_symbol[]; >>>>>>>> extern char abs_symbol_2[]; >>>>>>>> >>>>>>>> __asm__( >>>>>>>> =C2=A0=C2=A0=C2=A0 "\t.globl abs_symbol\n" >>>>>>>> =C2=A0=C2=A0=C2=A0 "\t.set abs_symbol, 0x123\n" >>>>>>>> ); >>>>>>>> >>>>>>>> unsigned long f_abs_symbol(void) >>>>>>>> { >>>>>>>> =C2=A0=C2=A0=C2=A0 return (unsigned long)abs_symbol; >>>>>>>> } >>>>>>>> >>>>>>>> unsigned long f_abs_symbol_2(void) >>>>>>>> { >>>>>>>> =C2=A0=C2=A0=C2=A0 return (unsigned long)abs_symbol_2; >>>>>>>> } >>>>>>>> >>>>>>>> unsigned long _start(void) >>>>>>>> { >>>>>>>> =C2=A0=C2=A0=C2=A0 return f_abs_symbol() + f_abs_symbol_2(); >>>>>>>> } >>>>>>>> >>>>>>>> aarch64-rtems6-gcc abs.c -Wl,--gc-sections -Wl,--defsym=3Dabs_sy= mbol_2=3D291 >>>>>>> Have you tried -mcmodel=3Dlarge?=C2=A0 With that I get: >>>>>> I get the same result with -mcmodel=3Dlarge. With -mcmodel=3Dtiny = I get: >>>>>> >>>>>> aarch64-rtems6-gcc abs.c -Wl,--gc-sections -Wl,--defsym=3Dabs_symb= ol_2=3D291 >>>>>> -mcmodel=3Dtiny >>>>>> /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*=C2=A0 section in a.o= ut >>>>>> collect2: error: ld returned 1 exit status >>>>>> >>>>>> Is this a tool bug? >>>>> No, it's how code models are defined.=C2=A0 GCC documentation says = clearly: >>>>> >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 -mcmodel=3Dtiny >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= Generate code for=C2=A0 the=C2=A0 tiny=C2=A0 code=C2=A0 model.=C2=A0=C2=A0= The=C2=A0 program and=C2=A0 its >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= statically=C2=A0 defined=C2=A0 symbols=C2=A0 must=C2=A0 be=C2=A0 within=C2= =A0 1MB=C2=A0 of each other. >>>>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= 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=3Dtiny. >>>> Yes, this makes sense. >>>> >>>>>> Is there some way to make this working with -mcmodel=3Dsmall? >>>>> No because -mcmodel=3Dsmall only assumes the program and the symbol= s are >>>>> within*a*=C2=A0 4GB range - for example it's allowed to be [47GB, 5= 1GB). >>>>> This is different from the default code model of RISC-V (- >>>>> mcmodel=3Dmedlow) where the symbols must be in [-2GB, 2GB). >>>>> >>>>> If you really think GCC should support this you can ask GCC for add= ing a >>>>> new code model.=C2=A0 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 mo= del. To retrieve the constant, we just have to subtract the address of th= e 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 =3D abs_symbol; >>> >>> unsigned long f_abs_symbol(void) >>> { >>> =C2=A0=C2=A0 return (unsigned long)abs_sym_ptr; >>> } >>> >>> Which assembles to: >>> 0000000000400000 : >>> =C2=A0=C2=A0 400000:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 90000000=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 adrp=C2=A0=C2=A0=C2=A0 x0, 400000= >>> =C2=A0=C2=A0 400004:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 91004000=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 add=C2=A0=C2=A0=C2=A0=C2=A0 x0, x= 0, #0x10 >>> =C2=A0=C2=A0 400008:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 f9400000=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ldr=C2=A0=C2=A0=C2=A0=C2=A0 x0, [= x0] >>> =C2=A0=C2=A0 40000c:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 d65f03c0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ret >>> =C2=A0=C2=A0 400010:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 00000123=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .word=C2=A0=C2=A0 0x00000123 >>> =C2=A0=C2=A0 400014:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 00000000=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 .word=C2=A0=C2=A0 0x00000000 >>> >>> 2) If you really want to use other code models, you can try things li= ke: >>> >>> extern char abs_symbol[]; >>> >>> char * const volatile=C2=A0 abs_sym_ptr =3D abs_symbol; >>> >>> unsigned long f_abs_symbol(void) >>> { >>> =C2=A0=C2=A0 return (unsigned long)abs_sym_ptr; >>> } >>> >>> The "const volatile" forces the compiler not to try to inline the poi= nter value dereference, so you end up with: >>> >>> 0000000000400000 : >>> =C2=A0=C2=A0 400000:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 90000000=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 adrp=C2=A0=C2=A0=C2=A0 x0, 400000= >>> =C2=A0=C2=A0 400004:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 f9400c00=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ldr=C2=A0=C2=A0=C2=A0=C2=A0 x0, [= x0, #24] >>> =C2=A0=C2=A0 400008:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 d65f03c0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ret >>> >>> ... >>> >>> Disassembly of section .rodata: >>> >>> 0000000000400018 : >>> =C2=A0=C2=A0 400018:=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 00000123 00= 000000=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 #....... >>> >>> >>> In other respects, though, the pointer is const, so attempts to modif= y 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 l= arge model. >> For my use case, I can't use things in the data or read-only data sect= ion. The RTEMS real-time operating system is deployed as a start.o start = file and a set of static libraries. Applications are statically linked wi= th the operating system. The operating system is configured by the applic= ation through a set of objects and some symbols those addresses are confi= guration values. One of these symbols is the size of the interrupt and sy= stem 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 c= ode currently: >> >> =C2=A0 /* Calculate interrupt stack area end for current processor */ >> #ifdef AARCH64_MULTILIB_ARCH_V8_ILP32 >> =C2=A0 ldr w1, =3D_ISR_Stack_size >> #else >> =C2=A0 ldr x1, =3D_ISR_Stack_size >> #endif >> #ifdef RTEMS_SMP >> =C2=A0 add x3, x7, #1 >> =C2=A0 mul x1, x1, x3 >> #endif >> #ifdef AARCH64_MULTILIB_ARCH_V8_ILP32 >> =C2=A0 ldr w2, =3D_ISR_Stack_area_begin >> #else >> =C2=A0 ldr x2, =3D_ISR_Stack_area_begin >> #endif >> =C2=A0 add x3, x1, x2 >> >> I adjusted our test cases so that they work now also for AArch64: >> >> https://git.rtems.org/rtems/commit/?id=3Dd7a6e803984e5508c30aa9e3625c7= 6460beb807b >> > So force the symbol into the text section. It's a bit naughty, but it = should work, assuming the text section has read permission: >=20 > extern char abs_symbol[]; >=20 > char * const volatile __attribute__((section (".text.constdata"))) > abs_sym_ptr =3D abs_symbol; >=20 > unsigned long f_abs_symbol(void) > { > return (unsigned long)abs_sym_ptr; > } >=20 > unsigned long _start(void) > { > return f_abs_symbol(); > } >=20 > $ aarch64-none-elf-gcc -O -nostartfiles -nostdlib start.c -Wl,--gc-sect= ions -Wl,--defsym=3Dabs_symbol=3D291 > $ aarch64-linux-gnu-objdump -d a.out >=20 > a.out: file format elf64-littleaarch64 >=20 >=20 > Disassembly of section .text: >=20 > 0000000000400000 : > 400000: 90000000 adrp x0, 400000 > 400004: f9400c00 ldr x0, [x0, #24] > 400008: d65f03c0 ret >=20 > 000000000040000c <_start>: > 40000c: 90000000 adrp x0, 400000 > 400010: f9400c00 ldr x0, [x0, #24] > 400014: d65f03c0 ret >=20 > 0000000000400018 : > 400018: 00000123 00000000 #....... Thanks for the trick with the const volatile object. We had some other=20 places which used symbols with an arbitrary address directly. Using the=20 const volatile objects worked fine. Independent of this, I think in the -mcmodel=3Dsmall case some tool shoul= d=20 issue an error instead of getting an invalid value at runtime. Just like=20 in the -mcmodel=3Dtiny case, where you get a relocation truncated error. --=20 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=C3=BCnchen Registernummer: HRB 157899 Vertretungsberechtigte Gesch=C3=A4ftsf=C3=BChrer: Peter Rasmussen, Thomas= D=C3=B6rfler Unsere Datenschutzerkl=C3=A4rung finden Sie hier: https://embedded-brains.de/datenschutzerklaerung/