From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 5508F385781F; Wed, 30 Jun 2021 23:01:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5508F385781F From: "i at maskray dot me" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/101275] New: [RISCV] Document the machine constraint 'S' and make it non-internal Date: Wed, 30 Jun 2021 23:01:25 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: i at maskray dot me X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Jun 2021 23:01:25 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D101275 Bug ID: 101275 Summary: [RISCV] Document the machine constraint 'S' and make it non-internal Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: i at maskray dot me Target Milestone: --- An absolute symbolic operand is useful in inline asm. In aarch64 and x86-64, there is a documented (supported) approach. // aarch64 // 'S' is documented on https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constra= ints extern int var; void *addr() { return &var; } void *addr_via_asm() { void *ret; asm("adrp %0, %1\nadd %0, %0, :lo12:%1" : "=3Dr"(ret) : "S"(&var)); return ret; } // x86-64 // https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86-Operand-Modifie= rs // 'P' is useful in some cases. extern int var; void *addr() { return &var; } void *addr_via_asm() { void *ret; asm("movl %1, %k0" : "=3Dr"(ret) : "i"(&var)); return ret; } For riscv there is no supported approach. The following code works // riscv extern int var; void *addr() { return &var; } void *addr_via_asm() { void *ret; asm("lui %0, %%hi(%1)\naddi %0,%0,%%lo(%1)" : "=3Dr"(ret) : "S"(&var)); return ret; } but it uses the internal/undocumented constraint "S" // gcc/config/riscv/constraints.md (define_constraint "S" "@internal A constant call address." (match_operand 0 "absolute_symbolic_operand")) I hope this can made supported/documented/non-internal. --- Why do I want this? In the Linux kernel, arch/riscv/include/asm/vdso.h defines /* * The VDSO symbols are mapped into Linux so we can just use regular symb= ol * addressing to get their offsets in userspace. The symbols are mapped = at an * offset of 0, but since the linker must support setting weak undefined * symbols to the absolute address 0 it also happens to support other low * addresses even when the code model suggests those low addresses would = not * otherwise be availiable. */ #define VDSO_SYMBOL(base, name)=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20 \ ({=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20 \ extern const char __vdso_##name[];=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 \ (void __user *)((unsigned long)(base) + __vdso_##name);=20=20=20= =20=20=20=20=20=20=20=20=20=20=20 \ }) arch/riscv/kernel/signal.c has regs->ra =3D (unsigned long)VDSO_SYMBOL( current->mm->context.vdso, rt_sigreturn); The file is compiled with -fno-PIE -mcmodel=3Dmedany. Because of medany, au= ipc is generated: 36e: 00000697 auipc a3,0x0 36e: R_RISCV_PCREL_HI20 __vdso_rt_sigreturn 36e: R_RISCV_RELAX *ABS* 372: 00068693 mv a3,a3 At link time, auipc/mv (PC-relative) is rewritten as lui/addi (absolute): ffffffe000201880: 000016b7 lui a3,0x1 ffffffe000201884: 80068693 addi a3,a3,-2048 # 800 <__vdso_rt_sigreturn> The absolute address is needed for correctness. With PC-relative insns, the runtime address will be different from its link-time address and current->mm->context.vdso + __vdso_rt_sigreturn will be wrong. It is fragile to rely on linker instruction rewritting (part of linker relaxation) to do this correctness related stuff!=