|
Message-ID: <976551e8-229e-54c1-8fb2-c5df94b979c3@c-s.fr> Date: Sat, 25 Apr 2020 14:20:45 +0200 From: Christophe Leroy <christophe.leroy@....fr> To: Nicholas Piggin <npiggin@...il.com>, binutils@...rceware.org, linuxppc-dev@...ts.ozlabs.org Cc: Adhemerval Zanella <adhemerval.zanella@...aro.org>, Rich Felker <dalias@...c.org>, libc-alpha@...rceware.org, libc-dev@...ts.llvm.org, Andy Lutomirski <luto@...nel.org>, musl@...ts.openwall.com, Thomas Gleixner <tglx@...utronix.de>, Vincenzo Frascino <vincenzo.frascino@....com> Subject: Re: New powerpc vdso calling convention Le 25/04/2020 à 12:56, Nicholas Piggin a écrit : > Excerpts from Christophe Leroy's message of April 25, 2020 5:47 pm: >> >> >> Le 25/04/2020 à 07:22, Nicholas Piggin a écrit : >>> As noted in the 'scv' thread, powerpc's vdso calling convention does not >>> match the C ELF ABI calling convention (or the proposed scv convention). >>> I think we could implement a new ABI by basically duplicating function >>> entry points with different names. >> >> I think doing this is a real good idea. >> >> I've been working at porting powerpc VDSO to the GENERIC C VDSO, and the >> main pitfall has been that our vdso calling convention is not compatible >> with C calling convention, so we have go through an ASM entry/exit. >> >> See https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=171469 >> >> We should kill this error flag return through CR[SO] and get it the >> "modern" way like other architectectures implementing the C VDSO: return >> 0 when successfull, return -err when failed. > > Agreed. > >>> The ELF v2 ABI convention would suit it well, because the caller already >>> requires the function address for ctr, so having it in r12 will >>> eliminate the need for address calculation, which suits the vdso data >>> page access. >>> >>> Is there a need for ELF v1 specific calls as well, or could those just be >>> deprecated and remain on existing functions or required to use the ELF >>> v2 calls using asm wrappers? >> >> What's ELF v1 and ELF v2 ? Is ELF v1 what PPC32 uses ? If so, I'd say >> yes, it would be good to have it to avoid going through ASM in the middle. > > I'm not sure about PPC32. On PPC64, ELFv2 functions must be called with > their address in r12 if called at their global entry point. ELFv1 have a > function descriptor with call address and TOC in it, caller has to load > the TOC if it's global. > > The vdso doesn't have TOC, it has one global address (the vdso data > page) which it loads by calculating its own address. > > The kernel doesn't change the vdso based on whether it's called by a v1 > or v2 userspace (it doesn't really know itself and would have to export > different functions). glibc has a hack to create something: > > # define VDSO_IFUNC_RET(value) \ > ({ \ > static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \ > vdso_opd.fd_func = (Elf64_Addr)value; \ > &vdso_opd; \ > }) > > If we could make something which links more like any other dso with > ELFv1, that would be good. Otherwise I think v2 is preferable so it > doesn't have to calculate its own address. I see the following in glibc. So looks like PPC32 is like PPC64 elfv1. By the way, they are talking about something not completely finished in the kernel. Can we finish it ? #if (defined(__PPC64__) || defined(__powerpc64__)) && _CALL_ELF != 2 /* The correct solution is for _dl_vdso_vsym to return the address of the OPD for the kernel VDSO function. That address would then be stored in the __vdso_* variables and returned as the result of the IFUNC resolver function. Yet, the kernel does not contain any OPD entries for the VDSO functions (incomplete implementation). However, PLT relocations for IFUNCs still expect the address of an OPD to be returned from the IFUNC resolver function (since PLT entries on PPC64 are just copies of OPDs). The solution for now is to create an artificial static OPD for each VDSO function returned by a resolver function. The TOC value is set to a non-zero value to avoid triggering lazy symbol resolution via .glink0/.plt0 for a zero TOC (requires thread-safe PLT sequences) when the dynamic linker isn't prepared for it e.g. RTLD_NOW. None of the kernel VDSO routines use the TOC or AUX values so any non-zero value will work. Note that function pointer comparisons will not use this artificial static OPD since those are resolved via ADDR64 relocations and will point at the non-IFUNC default OPD for the symbol. Lastly, because the IFUNC relocations are processed immediately at startup the resolver functions and this code need not be thread-safe, but if the caller writes to a PLT slot it must do so in a thread-safe manner with all the required barriers. */ #define VDSO_IFUNC_RET(value) \ ({ \ static Elf64_FuncDesc vdso_opd = { .fd_toc = ~0x0 }; \ vdso_opd.fd_func = (Elf64_Addr)value; \ &vdso_opd; \ }) #else #define VDSO_IFUNC_RET(value) ((void *) (value)) #endif Christophe
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.