From owner-freebsd-hackers@freebsd.org Sun Jun 4 22:44:34 2017 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E4E43BF147A for ; Sun, 4 Jun 2017 22:44:34 +0000 (UTC) (envelope-from vangyzen@FreeBSD.org) Received: from smtp.vangyzen.net (hotblack.vangyzen.net [IPv6:2607:fc50:1000:7400:216:3eff:fe72:314f]) by mx1.freebsd.org (Postfix) with ESMTP id D0187641EB for ; Sun, 4 Jun 2017 22:44:34 +0000 (UTC) (envelope-from vangyzen@FreeBSD.org) Received: from ford.home.vangyzen.net (unknown [76.164.15.242]) by smtp.vangyzen.net (Postfix) with ESMTPSA id 437655646B for ; Sun, 4 Jun 2017 17:44:34 -0500 (CDT) To: FreeBSD Hackers From: Eric van Gyzen Subject: Function attribute for optimization level Message-ID: <85c47390-dd27-aa74-24fe-25a9a5352527@FreeBSD.org> Date: Sun, 4 Jun 2017 17:44:31 -0500 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 Jun 2017 22:44:35 -0000 _thr_rtld_init() calls memcpy() for the sole purpose of resolving its PLT entry. With clang 4.0 and the current code, compiler optimization defeats this attempt by completely eliding the call. Other compilers or code might emit inline instructions instead of the library call, also defeating the purpose. I propose adding "__no_optimization" to sys/cdefs.h. The patch is below. Empirical testing shows that clang 3.7 and later support "optnone", and gcc 4.6 and later support "optimize()". Clang 3.4 does not support either, so it takes the define-to-empty case. I did not test clang 3.5 or 3.6. Side note: GCC 4.6 with optimize(0) on amd64 emits two movq instructions for memset(x,0,16), but GCC 5 emits a call to memset(). I have done no research to see if other popular codebases have such a definition. If you know of one, please tell me; I would gladly adopt an already common name for this proposal, for the sake of portability. Thanks in advance for your feedback. Eric diff --git a/sys/sys/cdefs.h b/sys/sys/cdefs.h index 9cdc03c861cb..e370f6d6459e 100644 --- a/sys/sys/cdefs.h +++ b/sys/sys/cdefs.h @@ -396,6 +396,14 @@ #define __unreachable() ((void)0) #endif +#if __has_attribute(optnone) +#define __no_optimization __attribute__((optnone)) +#elif __has_attribute(optimize) +#define __no_optimization __attribute__((optimize(0))) +#else +#define __no_optimization +#endif + /* XXX: should use `#if __STDC_VERSION__ < 199901'. */ #if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER) #define __func__ NULL