From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id EE5943858D3C for ; Tue, 12 Sep 2023 16:18:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org EE5943858D3C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=foss.arm.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=foss.arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EB983C15; Tue, 12 Sep 2023 09:19:03 -0700 (PDT) Received: from [10.57.35.116] (unknown [10.57.35.116]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2528F3F738; Tue, 12 Sep 2023 09:18:26 -0700 (PDT) Message-ID: <7747e9af-e9fb-3979-a181-d1b23e8cf340@foss.arm.com> Date: Tue, 12 Sep 2023 17:18:24 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.15.0 Subject: Re: How to define a symbol with absolute address for AArch64? Content-Language: en-GB To: Sebastian Huber , Xi Ruoyao , 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> From: Richard Earnshaw In-Reply-To: <2706d31f-7f35-46f9-9a20-78cf069e9602@embedded-brains.de> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3488.5 required=5.0 tests=BAYES_00,BODY_8BITS,KAM_DMARC_STATUS,KAM_LAZY_DOMAIN_SECURITY,NICE_REPLY_A,SPF_HELO_NONE,SPF_NONE,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 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 : 400000: 90000000 adrp x0, 400000 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 : 400000: 90000000 adrp x0, 400000 400004: f9400c00 ldr x0, [x0, #24] 400008: d65f03c0 ret ... Disassembly of section .rodata: 0000000000400018 : 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. R.