Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add `no_entry` attribute to omit entry point symbol #2735

Open
wants to merge 1 commit into
base: master
from

Conversation

@joshtriplett
Copy link
Member

commented Jul 30, 2019

This allows people to write their own entry point, without needing to
manually link or create a .cargo/config with target-specific linker
arguments.

RFC: Add `no_entry` attribute to omit entry point symbol
This allows people to write their own entry point, without needing to
manually link or create a `.cargo/config` with target-specific linker
arguments.
@joshtriplett

This comment has been minimized.

Copy link
Member Author

commented Jul 30, 2019

cc @retep998

As discussed on Discord, I added an explanation of the behavior on platforms that can't support no_entry:

Some targets may be able to support invoking the C library without running the startup code provided by the C library; other targets may not support this, or have limitations on such support. Targets that do not support this should document the target-specific limitations of no_entry for their target, may require no_std in addition to no_entry, or may not support no_entry at all.

text/0000-no-entry.md Show resolved Hide resolved
text/0000-no-entry.md Show resolved Hide resolved
binary. When linking, Rust will pass any necessary target-specific arguments to
the toolchain to omit the target's entry-point code, such as `-nostartfiles`.

Binaries built with this attribute set will typically not link unless the user

This comment has been minimized.

Copy link
@Centril

Centril Jul 31, 2019

Member

Elaborate on typically?

text/0000-no-entry.md Show resolved Hide resolved
text/0000-no-entry.md Show resolved Hide resolved

We could make this a rustc command-line option, rather than an attribute.
However, that would separate the configuration required to build a crate from
the crate itself. We have substantial precedent for including such

This comment has been minimized.

Copy link
@Centril

Centril Jul 31, 2019

Member

I believe this is true but enumerate some examples nonetheless?

text/0000-no-entry.md Show resolved Hide resolved
text/0000-no-entry.md Show resolved Hide resolved
text/0000-no-entry.md Show resolved Hide resolved
[future-possibilities]: #future-possibilities

We should simplify the declaration of an entry-point symbol, such as by
providing an `#[entry]` attribute. The symbol itself would still have a

This comment has been minimized.

Copy link
@Centril

Centril Jul 31, 2019

Member

If we have #[entry] on unsafe ... fn foobar(...) do we then also need #![no_entry]?

This comment has been minimized.

Copy link
@joshtriplett

joshtriplett Jul 31, 2019

Author Member

@Centril Yes, we do. entry could be used in a library, for instance, with a binary crate using no_entry and using that library. I'll add a note that it would make sense to have a lint if you use entry in a binary crate without using no_entry, though.

This comment has been minimized.

Copy link
@Centril

Centril Jul 31, 2019

Member

@joshtriplett Ah I see; so this is akin to "needs / provides" of #![requires_allocator] (because every program requires an entry point) and #[global_allocator]. -- Please mention this similarity explicitly as well as the use-case for library/binary division in the text also. :)

This comment has been minimized.

Copy link
@joshtriplett

joshtriplett Aug 1, 2019

Author Member

What do you mean by requires_allocator? I don't see any references to that or similar names anywhere on the web.

The RFC already mentions the use case of library/binary division, in the rationale and alternatives section: "However, this would make it difficult to flexibly provide the entry point from a library or other mechanism."

This comment has been minimized.

Copy link
@Centril

Centril Aug 1, 2019

Member

What do you mean by requires_allocator? I don't see any references to that or similar names anywhere on the web.

Ooops; It's called #![needs_allocator] in https://github.com/rust-lang/rust/blob/master/src/liballoc/lib.rs#L65 apparently.

The RFC already mentions the use case of library/binary division, in the rationale and alternatives section: "However, this would make it difficult to flexibly provide the entry point from a library or other mechanism."

Yes, but connecting this to entry and no_entry is another matter, it would be helpful to clarify that this is what is referred to by that sentence.

@Amanieu

This comment has been minimized.

Copy link
Contributor

commented Jul 31, 2019

My main objection to this RFC is that this attribute should be described as part of the target specification rather than as an attribute. All of the use cases that you described will run without any libc, and therefore will want to use a custom target rather than one of the existing targets. As I noted in my comment on the pre-RFC thread, you can already do what is proposed in this RFC by adding -nostdlib to the pre-link-args section of the target json, without needing to mess with .cargo/config.

@fintelia

This comment has been minimized.

Copy link

commented Jul 31, 2019

It would be really helpful for this RFC to describe of exactly what functions are called during program startup under each valid configuration of #![no_main] × #![no_start] × #![no_std] × #![no_core] × ![no_entry]. From what I can tell, the order seems to be something like the following. (At any point the user can replace a function and chose to either skip the rest of setup or continue down the list):

  1. Linker provided function named something like _start (replaceable by naming a different entrypoint symbol via linker args or script, or by using the same one and setting #![no_entry])
  2. glibc initialization function or similar
  3. main function (replaceable by setting #[no_main] and providing a symbol with the right name)
  4. lang_start function (replaceable with #[start] + #![no_start])
  5. user provided main function (renamed with #[main])

Based on that list, I'd be curious to understand why it wouldn't be enough to just add an attribute that said "set #![no_start] and make (possibly extern) #[start] item the executable entry point".

@joshtriplett

This comment has been minimized.

Copy link
Member Author

commented Aug 1, 2019

@Amanieu

My main objection to this RFC is that this attribute should be described as part of the target specification rather than as an attribute.

I commented on that in the pre-RFC thread: target specifications are unstable, and likely to remain so for the foreseeable future since they fundamentally depend on LLVM and LLVM internals. In addition, this would require specifying a custom target, and potentially building core/std for that target, which will again require nightly for the foreseeable future.

All of the use cases that you described will run without any libc, and therefore will want to use a custom target rather than one of the existing targets.

That does not describe my use cases. I intend to use this on existing linux targets as well, for instance.

by adding -nostdlib to the pre-link-args section of the target json

What target json? I'm not looking to use this exclusively for custom targets, nor do I want to permanently require nightly. Target json is a strictly worse solution for many use cases than .cargo/config; I'm looking to build a better solution than .cargo/config.

@comex

This comment has been minimized.

Copy link

commented Aug 1, 2019

Point of clarification:

On Darwin, executable startup used to follow a scheme similar to Linux, with a _start symbol defined by crt0. But years ago it was replaced with a simpler design, where executables directly encode the address of main (in a load command called LC_MAIN), and there is no crt0 at all.

What, if anything, should #[no_entry] (or a hypothetical #[entry]) do on this platform?

@joshtriplett

This comment has been minimized.

Copy link
Member Author

commented Aug 8, 2019

(Current status: revising RFC based on feedback, will post new version that addresses comments.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants
You can’t perform that action at this time.