Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 19 Dec 2017 17:46:22 +0000
From: Nicholas Wilson <nicholas.wilson@...lvnc.com>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: Re: [PATCH] split __libc_start_main.c into two files (Wasm)

On 19 December 2017 15:56, Rich Felker wrote:
> This is not ELF-specific, and it's not different from the discussion
> we had before. You seem to be under the impression that exit "gets
> called" because __libc_start_main is called. This is not true. exit is
> only called if main returns. (In fact, if you have LTO, the linker
> will even optimize out exit like you wanted if main does not return.)

>From our point of view, exit being called *is* a consequence of __libc_start_main. Everything must return; there's no way to hold up the JavaScript main loop in a browser (unless you spin at 100% CPU and freeze the entire browser page, which is totally unacceptable). Wasm is run in a single-threaded asynchronous environment, really just like normal JavaScript, where every function is non-blocking.

(The difference between JavaScript and Wasm is that Wasm doesn't use the JS heap, is guaranteed to generate no JS garbage, and is strongly-typed so can be compiled to native x86/ARM code as soon as the browser receives it, so it runs at the same speed as a native executable. A typical C function compiled the "normal" way to a native C executable will have nearly identical x86 assembly to the x86 code that a browser produces for the corresponding Wasm function. Neat! But, it does mean no non-blocking functions, since the JavaScript environment is not able to handle that. The JavaScript host environment is event-driven: when I/O happens or some other event occurs, we'll call into the Wasm module again, and expect to return promptly so that the browser's event loop isn't blocked.)

> As for why it's not ELF-specific, returning from main producing
> behavior as if exit were called is part of the C language.

Yes, I agree - main must call exit when it returns. But in Wasm we don't want main to get called at all - since immediately afterwards the Wasm module becomes unusable for anything else (because of exit cleanup). For people with one-shot applications, there will be provision for calling main if they want it. However, I don't expect it to be common for people to use that functionality.

>> However, given that we need to call __init_libc
>> directly anyway, we may as well save some code and just register
>> __init_libc with the Wasm start mechanism.
> From my perspective, doing things in gratuitously arch-dependent ways
> to "save some code" doesn't make sense when you're trading a small
> (trivial relative size) amount of code for a permanent interface
> boundary and maintenance burden.

I mean, we have to call __init_libc directly anyway, so may as well just depend on a single internal interface, rather than using a second internal interface as well like __libc_start_init. By "short" I mean "use the absolute minimum of internal Musl dependencies". Because of the requirement not to call exit, I can't see a way of not calling *any* internal Musl functions, so getting it down to just __init_libc is the least-intrusive we can be.

Responding to Szabolcs:

On 19 December 2017 15:27, Szabolcs Nagy wrote:
> the correctness of the runtime is only guaranteed if you
> go via the symbol __libc_start_main otherwise future
> changes to that function can easily break your wasm port.

Yes, we'll have to make sure each time we update our fork that it still works. That's acceptable to me, we understand that the dependency is purely internal to libc, it's a not a public interface that Musl has to support forever. I accept that as long as we have a fork, we risk having to do some maintenance whenever we update to the latest Musl release. (But, with many people at Google and Mozilla working on Wasm long-term, I'm not worried that Wasm support will stagnate.)

That's why I was hoping to eventually merge the Wasm support upstream, so that changes to interfaces used internally within Musl can take Wasm into account, rather than risk using internal interfaces without your knowledge.

All the best,
Nick

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.