mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: Re: [PATCH 1/2] init_array/fini_array cleanup
Date: Sun, 29 Nov 2015 18:25:22 -0500	[thread overview]
Message-ID: <20151129232522.GR3818@brightrain.aerifal.cx> (raw)
In-Reply-To: <20151129164724.GP23362@port70.net>

On Sun, Nov 29, 2015 at 05:47:24PM +0100, Szabolcs Nagy wrote:
> * Szabolcs Nagy <nsz@port70.net> [2015-11-29 16:30:51 +0100]:
> > -extern void (*const __init_array_start)(void), (*const __init_array_end)(void);
> > +extern void (*const __init_array_start[])(void), (*const __init_array_end[])(void);
> 
> Alexander Monakov pointed out that the compiler may
> consider arrays to be separate objects and then
> f<__init_array_end would be ub.
> 
> attached an updated version, the same code is generated
> on x86_64 as before, except there is no xor %eax,%eax
> now before the call (because there is prototype).

> >From 3c29dc0d9bdb2e4d5f735d7b3d272d92cb82d2c6 Mon Sep 17 00:00:00 2001
> From: Szabolcs Nagy <nsz@port70.net>
> Date: Sun, 29 Nov 2015 16:24:17 +0000
> Subject: [PATCH 1/2] cleaner init/fini array handling
> 
> Avoid casts and make sure there is a prototype when init/fini
> functions are called.
> ---
>  src/env/__libc_start_main.c | 6 +++---
>  src/exit/exit.c             | 6 +++---
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
> index 5c79be2..14a2825 100644
> --- a/src/env/__libc_start_main.c
> +++ b/src/env/__libc_start_main.c
> @@ -55,10 +55,10 @@ void __init_libc(char **envp, char *pn)
>  
>  static void libc_start_init(void)
>  {
> +	void (*const *f)(void);
>  	_init();
> -	uintptr_t a = (uintptr_t)&__init_array_start;
> -	for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
> -		(*(void (**)())a)();
> +	for (f=&__init_array_start; f<&__init_array_end; f++)
> +		(*f)();

This version still contains UB: since the initial f points to one
object (__init_array_start), the comparison against a different
object's address with < is UB, and after the first f++, all subsequent
f++ operations are also UB.

The original code was carefully written to avoid this by performing
all arithmetic in uintptr_t, but reportedly gcc and llvm even perform
origin analysis on integers, despite it being an invalid optimization,
so we may need to harden this further.

Using an array type (like your first patch) and using != instead of <
might be another suitable approach. Use of != would not be UB, and
since the result of equality comparisons between "one past the end" of
an array and a fixed other object must be consistent between multiple
ways of evaluating it, a compiler can't optimize out the !=. However,
this does not translate into a viable approach for the
opposite-direction iteration in the fini array.

I'm open to other ideas that are more robust against bad compiler
behavior.

Rich


      reply	other threads:[~2015-11-29 23:25 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-29 15:30 Szabolcs Nagy
2015-11-29 16:47 ` Szabolcs Nagy
2015-11-29 23:25   ` Rich Felker [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151129232522.GR3818@brightrain.aerifal.cx \
    --to=dalias@libc.org \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).