From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 1085 invoked from network); 9 Mar 2021 16:54:25 -0000 Received: from mother.openwall.net (195.42.179.200) by inbox.vuxu.org with ESMTPUTF8; 9 Mar 2021 16:54:25 -0000 Received: (qmail 31913 invoked by uid 550); 9 Mar 2021 16:54:16 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 31895 invoked from network); 9 Mar 2021 16:54:16 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1615308845; bh=+JVgf/9efStTUFEd9pMFf/MR52GboFYYWbINF1cCNzM=; h=X-UI-Sender-Class:Date:From:To:Subject:References:In-Reply-To; b=YhOq1kmRt4jXzaibFEcBZuwRadzs3jcu59WeU6+4VV+m1wKkozkzZVLeEAdzXulQa TMw9AyCXzUw4wKta0TWbYEttqBTvfPmFJtP/z4dq0zEyUo/DSRNIeAwfV1nVrNcA0J UYXM/oecJOqsDOVyWB/9J1ZZJAESHAdc9gkWTUwQ= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Date: Tue, 9 Mar 2021 17:54:04 +0100 From: Markus Wichmann To: musl@lists.openwall.com Message-ID: <20210309165404.GB2766@voyager> References: <20210309035652.32453-1-ericonr@disroot.org> <20210309134242.GS32655@brightrain.aerifal.cx> <20210309150320.GU32655@brightrain.aerifal.cx> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210309150320.GU32655@brightrain.aerifal.cx> User-Agent: Mutt/1.9.4 (2018-02-28) X-Provags-ID: V03:K1:vkvBMGzOP+YaflQ3q0YEByy+bs8gqLYq5akhOb1Ho0tvh9jJKHk O1jRMIPbFucSAPr5wFnSc5SW0i7mUpUC9lmhVZiTrdKWOLv5+eQHG5gy5aGqjgmus3DWiTe iUcPLRoPkdbBciIp/ZSUXwOTl2ekt+6fVvQAFo2Oo8SaOvw64flcnxrnTursnFP+eIVpY/S ZCC/rKlZu2jVLRzkKEl5Q== X-UI-Out-Filterresults: notjunk:1;V03:K0:nBUsv9NT59g=:+E6CvmKnl4i+FCWSgRAVA3 YvfuaJ2LV/lzraIcnbhDuOOjmXI9/ltTkev88aNE2rUPxV+Oi2rdaQR/ad3dcfsTMEiqNxL2i 6OgPapLsEhZd9ZZiNvh1Xb3m/D6Sc24iC35+58ZCUyIQz61sNIFAZOsL2sryA6LLufjqONias Wf0sBLOblTpepF2R6pCRncaxuA5tBONd2lRntJqXl7xDE8SsHoIgpCJNZo3tqOsFwjr9FkT06 uJ7k/nRbnbLYeTnXJ4tGqLyYsl4HeWScYYqvDbv3s8znY5CoMfz7vM0lbWC1vnG6hOd1DAgTN C34WmiUJa+T+NRCktoiubdSW8o4gFcb7T4kXWNcDNbMjTo2PfnaBKfjIiNvUxc6aI8q8vq8qC YBCDHv8wZzQalI4V0wpxOQQh+DxaDaKubqEyfvtN5VFnTnd/MKEvp23GDWgnsCuPlzkgP+omC D/FtSAPnQa/RjeVWH6zzmWly0mBSX+pJmh0WmwooreXIQjDYB2QZ/i/qSCoB/GiWwl9UgJ8s/ 4eVcwQm8bYmC6vX7Dm6fe+WXfbUUHvCzDh+se+uQdaBDnS5prxivZAiASqkT1GWzUSUHsIFdE sE1FqfqrUke7zRUuMGVcjqYhwi36rzzQwPzTfVdodNsvplyLQKRtpPk4QSUi43qXJqXpTYMi/ 2n2GeK/BM+HAobdOQ3/tWRc2hAxJDO7cmCtxVTU3sf+QAaK5huVkbhTRv4Lv2Hu783sWPQRSu lt6rfN22CvhA9W2rfdAISWyyuLV12Gch75Ek31rb8vMHbS/FOyAatDoT/fWqHBqp4POrI8Hyw aYZyMpxO8oUuR8hsJvlQ0MM2Ry+2i06K1s7oRwRFdmjeWeJwW3FgU7HStpCb62mBWaPuA8n4K sYlBrfVd3KdhBex33hqw== Content-Transfer-Encoding: quoted-printable Subject: Re: [musl] [PATCH v2] add qsort_r. On Tue, Mar 09, 2021 at 10:03:22AM -0500, Rich Felker wrote: > On Tue, Mar 09, 2021 at 05:13:39PM +0300, Alexander Monakov wrote: > > Second, if you make a "conventional" wrapper, then on popular architec= tures > > it is a single instruction (powerpc64 ABI demonstrates its insanity he= re): > > > > static int wrapper_cmp(void *v1, void *v2, void *ctx) > > { > > return ((cmpfun)ctx)(v1, v2); > > } > > > > Some examples: > > > > amd64: jmp %rdx > > i386: jmp *12(%esp) > > arm: bx r2 > > aarch64:br x2 > > > > How is this not obvious? > > [...] > > For some reason though it's gigantic on powerpc64. It fails to do a > tail call at all... > So, I experimented a bit with clang (for simplicity, since clang can switch targets with a compiler switch). And indeed the above is reproducible. Had to search around a bit for the ELFv2 ABI switch for clang (the ELFv1 version is even worse, since it uses function descriptors, so calling through a function pointer requires reading out the function descriptors before being able to use them). So with ELFv2, the function consists of buildup and teardown of a stack frame, save and restore of R2, and the actual indirect call. The stack frame is necessary because of R2 being spilled, and R2 being spilled is necessary since the wrapper function might be called locally (so the contract is that R2 is preserved), but the function pointer might point to a function in another module, so R2 would be overwritten by the call. That makes sense. What doesn't make sense is that the stack frame is still used in 32-bit powerpc. Nothing is saved into that stack frame; "mtctr 5; bctr" would be a valid implementation. But no matter what switches I threw at it, the stack frame remained. For other architectures: I could not test microblaze, mipsn32, m68k, or1k, riscv64, and sh, since clang did not recognize those architectures. Probably not included by default. MIPS and MIPS64 both establish a stack frame, and s390x does not. Ciao, Markus