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

Add x86_64-unknown-uefi target #56769

Merged
merged 1 commit into from
Dec 15, 2018
Merged

Add x86_64-unknown-uefi target #56769

merged 1 commit into from
Dec 15, 2018

Conversation

dvdhrm
Copy link
Contributor

@dvdhrm dvdhrm commented Dec 13, 2018

This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).

UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...

Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.

This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a GlobalAlloc handler is provided. Both
have been tested with this target-configuration.

Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.

This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).

UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...

Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.

This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a `GlobalAlloc` handler is provided. Both
have been tested with this target-configuration.

Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.
@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @cramertj (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Dec 13, 2018
@cramertj
Copy link
Member

r? @alexcrichton

@alexcrichton
Copy link
Member

Thanks for this! My only hesitation would be that this defaults to link.exe for a linker, but that means this target would largely only work on Windows I think? That seems like a plausible place to start, but I imagine that we'd want to compile for this target on systems like Linux as well, right?

@IsaacWoods
Copy link
Contributor

@alexcrichton I believe this uses lld-link as the linker if I'm not mistaken, which is available from Linux as well and is able to compile UEFI compatible PEs

@dvdhrm
Copy link
Contributor Author

dvdhrm commented Dec 13, 2018

Thanks for this! My only hesitation would be that this defaults to link.exe for a linker, but that means this target would largely only work on Windows I think? That seems like a plausible place to start, but I imagine that we'd want to compile for this target on systems like Linux as well, right?

Ah, no, it doesn't default to link.exe. It defaults to the link backend of lld, which on linux, defaults to lld-link, not link.exe. I tested this on my linux machine and it works fine. This is a bit confusing, because lld has 2 backends, one for ELF (called lld-ld) and one for COFF (called lld-link), named after their respective native counterparts.

Thing is, you need a COFF/PE32+ linker for UEFI targets. So if you run this on linux, it is as if you cross-compile for Windows (UEFI and windows targets are almost the same). Since lld-link is a built-in of lld, it is a perfect default linker.
An alternative to lld would be to use GNU ld. But ld has the problem that each binary only supports one target triple. So to link COFF/PE32+ binaries, you need an ld cross-toolchain for windows (usually known as mingw-for-linux), which is only partially available in most mainstream distributions.
I personally admire the LLVM-lld approach of combining all target compilers/linkers in a single binary. And since LLVM is already available for rustc, I thought lld-link as default linker sounds good.

Long story short: The lld-link link-flavor just selects the COFF backend of lld as default linker.

@alexcrichton
Copy link
Member

@bors: r+

Oh wow sorry about that, I completely missed that aspect! Glad LLD can save the day again for us here :)

@bors
Copy link
Contributor

bors commented Dec 13, 2018

📌 Commit 88cf2a2 has been approved by alexcrichton

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 13, 2018
@alexcrichton
Copy link
Member

@bors: rollup

kennytm added a commit to kennytm/rust that referenced this pull request Dec 14, 2018
Add x86_64-unknown-uefi target

This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).

UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...

Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.

This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a `GlobalAlloc` handler is provided. Both
have been tested with this target-configuration.

Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.
kennytm added a commit to kennytm/rust that referenced this pull request Dec 14, 2018
Add x86_64-unknown-uefi target

This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).

UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...

Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.

This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a `GlobalAlloc` handler is provided. Both
have been tested with this target-configuration.

Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Dec 14, 2018
Add x86_64-unknown-uefi target

This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).

UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...

Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.

This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a `GlobalAlloc` handler is provided. Both
have been tested with this target-configuration.

Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.
// Non-standard subsystems have no default entry-point in PE+ files. We have to define
// one. "efi_main" seems to be a common choice amongst other implementations and the
// spec.
"/entry:efi_main".to_string(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work for application writers?

Are they responsible for defining an efi_main symbol? Perhaps not the best approach then, as we already have #[start] and expect function annotated with that attribute to get invoked at start-up even in #[no_std] contexts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some crate in your application must provide the efi_main symbol. If we port std, we could make the #[start] logic do this. However, I don't think core should provide wrappers around the entry-point. We explicitly want a way to link applications with full control over the entry-point. With this target, you need:

pub extern fn efi_main(_h: efi::Handle, st: *mut efi::SystemTable) -> efi::Status

..to exist somewhere in your application.

I expect applications to pull in helper crates that wrap the UEFI API with a safe rust interface. Those crates can then provide the entry-point and retain the system-table somehow. However, note that due to ExitBootServices(), it is non-trivial to safely wrap all of the UEFI API (at least it requires some thought). By blocking ExitBootServices() and the VM-remapping, it is at least easier to imagine a safe wrapper.

We already have a public crate that simply provides the symbols from the UEFI spec as rust symbols (really just copying the definitions, not wrapper code in there) at https://github.com/r-util/r-efi
Our safe wrappers are still being worked on.

base.abi_return_struct_as_int = true;

Ok(Target {
llvm_target: "x86_64-unknown-windows".to_string(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems debatable to me. Are you sure this is correct (as opposed to just "x86_64"?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have to trick llvm into creating COFF objects, rather than ELF objects. In theory this shouldn't matter. You should be able to use any available target compiler to get your object files, and then in the end tell your linker about the target format. However, this sadly does not work. The different object files have different capabilities, or specific annotations are only supported in one, not the other, etc. So I never succeeded in linking coff-objects into ELF-executables, or vice versa.

Preferably, I would use x86_64-unknown-coff, but that does not exit. If anyone has better suggestions, I would gladly switch over.

Selecting the windows target might cause LLVM to optimize for something that will not apply to LLVM. However, I don't think anyone can apply any assumptions on a generic target like the one I picked, because it has to be backwards-compatible to all the existing windows versions. So I believe this will be safe.

I contacted colleagues of mine here at Red Hat, maybe they have a suggestion. Sadly, it is all gcc, not LLVM ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense then. It appears that llc has no way to specify format of the produced object file either, which most likely makes the target specification like this the best approach.

// places no locality-restrictions, so it fits well here.
base.code_model = Some("large".to_string());

// UEFI mostly mirrors the calling-conventions used on windows. In case of x86-64 this means
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: x64 UEFI uses the exact same msabi (aka. x64) calling convention that windows uses. There is not a single difference (and therefore “mostly” is not applicable).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about that? UEFI explicitly disallows passing values bigger than 64bit by value (both as argument or return value; see UEFI-2.7 2.3.4.2). Isn't this allowed in msabi?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UEFI explicitly disallows passing values bigger than 64bit by value (both as argument or return value; see UEFI-2.7 2.3.4.2). Isn't this allowed in msabi?

Other than XMM/floating point registers, nothing larger than 64-bit is passed by-register in x64 msabi.

Copy link
Contributor Author

@dvdhrm dvdhrm Dec 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than XMM/floating point registers, nothing larger than 64-bit is passed by-register in x64 msabi.

Well, in registers, yes, but is that true for the stack as well? Does msabi require you to put objects bigger than 64bit in caller allocated memory and pass it by reference? Because that is how I read the UEFI spec, even for arguments passed on the stack.

The caller passes arrays and strings via a pointer to memory allocated by the
caller. The caller passes structures and unions of size 8, 16, 32, or 64 bits as if
they were integers of the same size. The caller is not allowed to pass structures
and unions of other than these sizes and must pass these unions and structures
via a pointer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Either way, this is proved by the fact that it wasn’t necessary for you to do anything special to implement UEFI’s ABI: it was already implemented!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, the MSDN docs are almost identical. Thanks a lot for the link!

I certainly expecteded the ABIs to be compatible. I just wasn't sure whether the UEFI ABI is a subset (e.g., their coding-convention forbids returning anything but ints, which I expected to be rooted in a restricted ABI). I am confident using the msabi will just work, given that's what tianocore does as well.

@nagisa
Copy link
Member

nagisa commented Dec 14, 2018

Cool trick with lld though!

pietroalbini added a commit to pietroalbini/rust that referenced this pull request Dec 15, 2018
Add x86_64-unknown-uefi target

This adds a new rustc target-configuration called 'x86_64-unknown_uefi'.
Furthermore, it adds a UEFI base-configuration to be used with other
targets supported by UEFI (e.g., i386, armv7hl, aarch64, itanium, ...).

UEFI systems provide a very basic operating-system environment, meant
to unify how systems are booted. It is tailored for simplicity and fast
setup, as it is only meant to bootstrap other systems. For instance, it
copies most of the ABI from Microsoft Windows, rather than inventing
anything on its own. Furthermore, any complex CPU features are
disabled. Only one CPU is allowed to be up, no interrupts other than
the timer-interrupt are allowed, no process-separation is performed,
page-tables are identity-mapped, ...

Nevertheless, UEFI has an application model. Its main purpose is to
allow operating-system vendors to write small UEFI applications that
load their kernel and terminate the UEFI system. However, many other
UEFI applications have emerged in the past, including network-boot,
debug-consoles, and more.

This UEFI target allows to compile rust code natively as UEFI
applications. No standard library support is added, but libcore can be
used out-of-the-box if a panic-handler is provided. Furthermore,
liballoc works as well, if a `GlobalAlloc` handler is provided. Both
have been tested with this target-configuration.

Note that full libstd support is unlikely to happen. While UEFI does
have standardized interfaces for networking and alike, none of these
are mandatory and they are unlikely to be shipped in common consumer
firmwares. Furthermore, several features like process-separation are
not available (or only in very limited fashion). Those parts of libstd
would have to be masked.
bors added a commit that referenced this pull request Dec 15, 2018
Rollup of 14 pull requests

Successful merges:

 - #56718 (Use libbacktrace pretty-printing)
 - #56725 (fix rust-lang/rust issue #50583)
 - #56731 (Add missing urls in ffi module docs)
 - #56738 (Fix private_no_mangle_fns message grammar)
 - #56746 (Add test of current behavior (infer free region within closure body))
 - #56747 (target: remove Box returned by get_targets)
 - #56751 (Allow ptr::hash to accept fat pointers)
 - #56755 (Account for `impl Trait` when suggesting lifetime)
 - #56758 (Add short emoji status to toolstate updates)
 - #56760 (Deduplicate unsatisfied trait bounds)
 - #56769 (Add x86_64-unknown-uefi target)
 - #56792 (Bootstrap: Add testsuite for compiletest tool)
 - #56808 (Fixes broken links)
 - #56809 (Fix docs path to PermissionsExt)

Failed merges:

r? @ghost
@bors bors merged commit 88cf2a2 into rust-lang:master Dec 15, 2018
josephlr added a commit to josephlr/uefi-rs that referenced this pull request Feb 6, 2019
Rust now supports uefi as a build target: rust-lang/rust#56769

This change mainly eliminates references to the custom JSON target
file. It also requires that the entry point's name be changed to
`efi_main`.

Note that the "C" abi is now correct for EFI applications, but will
still be incorrect when uefi-rs is brought in as an external dependancy
for a different target. This means the entry point should always be
`extern "C"` while the table of function pointers should be `extern
"win64"`.
GabrielMajeri pushed a commit to rust-osdev/uefi-rs that referenced this pull request Feb 6, 2019
Rust now supports uefi as a build target: rust-lang/rust#56769

This change mainly eliminates references to the custom JSON target
file. It also requires that the entry point's name be changed to
`efi_main`.

Note that the "C" abi is now correct for EFI applications, but will
still be incorrect when uefi-rs is brought in as an external dependancy
for a different target. This means the entry point should always be
`extern "C"` while the table of function pointers should be `extern
"win64"`.
@kkebo
Copy link

kkebo commented Feb 6, 2019

Why isn’t this using rust-lld as a linker? It is able to create an UEFI application and bundled with the default toolchain, so an external linker like lld-link is not needed.

@dvdhrm
Copy link
Contributor Author

dvdhrm commented Feb 6, 2019

rust-lld is only available for tier-1 platforms. It is not shipped with the others. I am not sure what the reasoning is, and whether that is still true. Furthermore, I considered the system linker to be preferable to a bundled one. I am not sure why rust-lld is bundled at all.
To be quite honest, I thought using the system linker is the expected behavior. If you have more insight on this topic, please lemme know what the recommended way here is (or, of course, feel free to open a PR).

@Rua
Copy link
Contributor

Rua commented Feb 22, 2019

When trying to compile a project with this target, lld-link can't be found. lld-link-6.0 exists, though. I'm using Linux Mint 19.1.

@joshtriplett
Copy link
Member

joshtriplett commented Feb 25, 2019

@dvdhrm

While UEFI does have standardized interfaces for networking and alike, none of these are mandatory and they are unlikely to be shipped in common consumer firmwares.

I've used those interfaces quite a bit, and they're available on many common firmware images. The filesystem interfaces are always available. And in general, almost all of what std needs should be regularly available, other than things that depend on fork or similar.

@dvdhrm
Copy link
Contributor Author

dvdhrm commented Feb 26, 2019

I've used those interfaces quite a bit, and they're available on many common firmware images.

I know implementations exist, and I know that people use them. Can you clarify what "many common firmware images" means? Does that include low-budget devices? Does it mean 50% of devices? 10%? Or 99.9%?

I know that we had issues with the most simple of UEFI protocols being implemented wrongly in consumer hardware (speaking of efi_simple_input_protocol and efi_graphics_output_protocol), and we had to work around peculiarities in very simple projects like gummiboot, sd-boot, efifb, etc. (see their implementations for details). So I am a bit skeptical if you claim that the more elaborate protocols like the network stack exists on many devices. I hope you are right ;)

The filesystem interfaces are always available. And in general, almost all of what std needs should be regularly available, other than things that depend on fork or similar.

Just because a protocol is available does not mean that you can use it. For instance, to safely use any of the UEFI protocols that support device hotplugging, you must register a EFI_DRIVER_BINDING_PROTOCOL instance yourself. Otherwise, there is no way that you are notified of devices being removed. For instance, UEFI Applications (unlike UEFI Drivers) usually only make use of singleton protocols (the ones that multiplex input/output of multiple devices on a single interface). While technically nobody stops you from using other protocols, they can be dropped at any point in time without you being notified, thus getting lots of stale pointers.

I still think porting std to UEFI is more complex than it initially looks. Furthermore, I think it requires a lot of background tasks to be performed, which you preferably don't want your standard library to do. Lastly, it requires global state which works against what the UEFI spec tries to build.

@joshtriplett
Copy link
Member

I've certainly encountered devices that don't have the EFI network protocols, I'm just saying I've run into many devices that do (various random PC hardware, both laptops and desktops). There'd be value in being able to write DXE applications using Rust, and also in writing PEI or similar code in Rust without std.

The stock Tiano core includes the network protocols, so it's more a matter of whether the device vendor shipped a working driver for network hardware.

netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Mar 3, 2019
Pkgsrc changes:
 * Bump required rust version to build to 1.32.0.
 * Adapt patches to changed file locations.
 * Since we now patch some more vendor/ modules, doctor the corresponding
   .cargo-checksum.json files accordingly

Upstream changes:

Version 1.33.0 (2019-02-28)
==========================

Language
--------
- [You can now use the `cfg(target_vendor)` attribute.][57465] E.g.
  `#[cfg(target_vendor="apple")] fn main() { println!("Hello Apple!"); }`
- [Integer patterns such as in a match expression can now be exhaustive.][56362]
  E.g. You can have match statement on a `u8` that covers `0..=255` and
  you would no longer be required to have a `_ => unreachable!()` case.
- [You can now have multiple patterns in `if let` and `while let`
  expressions.][57532] You can do this with the same syntax as a `match`
  expression. E.g.
  ```rust
  enum Creature {
      Crab(String),
      Lobster(String),
      Person(String),
  }

  fn main() {
      let state = Creature::Crab("Ferris");

      if let Creature::Crab(name) | Creature::Person(name) = state {
          println!("This creature's name is: {}", name);
      }
  }
  ```
- [You can now have irrefutable `if let` and `while let` patterns.][57535]
  Using this feature will by default produce a warning as this behaviour
  can be unintuitive. E.g. `if let _ = 5 {}`
- [You can now use `let` bindings, assignments, expression statements,
  and irrefutable pattern destructuring in const functions.][57175]
- [You can now call unsafe const functions.][57067] E.g.
  ```rust
  const unsafe fn foo() -> i32 { 5 }
  const fn bar() -> i32 {
      unsafe { foo() }
  }
  ```
- [You can now specify multiple attributes in a `cfg_attr` attribute.][57332]
  E.g. `#[cfg_attr(all(), must_use, optimize)]`
- [You can now specify a specific alignment with the `#[repr(packed)]`
  attribute.][57049] E.g. `#[repr(packed(2))] struct Foo(i16, i32);` is a
  struct with an alignment of 2 bytes and a size of 6 bytes.
- [You can now import an item from a module as an `_`.][56303] This allows you
  to import a trait's impls, and not have the name in the namespace. E.g.
  ```rust
  use std::io::Read as _;

  // Allowed as there is only one `Read` in the module.
  pub trait Read {}
  ```
- [You may now use `Rc`, `Arc`, and `Pin` as method receivers][56805].

Compiler
--------
- [You can now set a linker flavor for `rustc` with the `-Clinker-flavor`
  command line argument.][56351]
- [The mininum required LLVM version has been bumped to 6.0.][56642]
- [Added support for the PowerPC64 architecture on FreeBSD.][57615]
- [The `x86_64-fortanix-unknown-sgx` target support has been upgraded to
  tier 2 support.][57130] Visit the [platform support][platform-support]
  page for information on Rust's platform support.
- [Added support for the `thumbv7neon-linux-androideabi` and
  `thumbv7neon-unknown-linux-gnueabihf` targets.][56947]
- [Added support for the `x86_64-unknown-uefi` target.][56769]

Libraries
---------
- [The methods `overflowing_{add, sub, mul, shl, shr}` are now `const`
  functions for all numeric types.][57566]
- [The methods `rotate_left`, `rotate_right`, and `wrapping_{add, sub, mul,
  shl, shr}`
  are now `const` functions for all numeric types.][57105]
- [The methods `is_positive` and `is_negative` are now `const` functions for
  all signed numeric types.][57105]
- [The `get` method for all `NonZero` types is now `const`.][57167]
- [The methods `count_ones`, `count_zeros`, `leading_zeros`, `trailing_zeros`,
  `swap_bytes`, `from_be`, `from_le`, `to_be`, `to_le` are now `const` for all
  numeric types.][57234]
- [`Ipv4Addr::new` is now a `const` function][57234]

Stabilized APIs
---------------
- [`unix::FileExt::read_exact_at`]
- [`unix::FileExt::write_all_at`]
- [`Option::transpose`]
- [`Result::transpose`]
- [`convert::identity`]
- [`pin::Pin`]
- [`marker::Unpin`]
- [`marker::PhantomPinned`]
- [`Vec::resize_with`]
- [`VecDeque::resize_with`]
- [`Duration::as_millis`]
- [`Duration::as_micros`]
- [`Duration::as_nanos`]


Cargo
-----
- [Cargo should now rebuild a crate if a file was modified during the initial
  build.][cargo/6484]

Compatibility Notes
-------------------
- The methods `str::{trim_left, trim_right, trim_left_matches,
  trim_right_matches}` are now deprecated in the standard library, and their
  usage will now produce a warning.  Please use the `str::{trim_start,
  trim_end, trim_start_matches, trim_end_matches}` methods instead.
- The `Error::cause` method has been deprecated in favor of `Error::source`
  which supports downcasting.

[55982]: rust-lang/rust#55982
[56303]: rust-lang/rust#56303
[56351]: rust-lang/rust#56351
[56362]: rust-lang/rust#56362
[56642]: rust-lang/rust#56642
[56769]: rust-lang/rust#56769
[56805]: rust-lang/rust#56805
[56947]: rust-lang/rust#56947
[57049]: rust-lang/rust#57049
[57067]: rust-lang/rust#57067
[57105]: rust-lang/rust#57105
[57130]: rust-lang/rust#57130
[57167]: rust-lang/rust#57167
[57175]: rust-lang/rust#57175
[57234]: rust-lang/rust#57234
[57332]: rust-lang/rust#57332
[57465]: rust-lang/rust#57465
[57532]: rust-lang/rust#57532
[57535]: rust-lang/rust#57535
[57566]: rust-lang/rust#57566
[57615]: rust-lang/rust#57615
[cargo/6484]: rust-lang/cargo#6484
[`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at
[`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at
[`Option::transpose`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.transpose
[`Result::transpose`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.transpose
[`convert::identity`]: https://doc.rust-lang.org/std/convert/fn.identity.html
[`pin::Pin`]: https://doc.rust-lang.org/std/pin/struct.Pin.html
[`marker::Unpin`]: https://doc.rust-lang.org/stable/std/marker/trait.Unpin.html
[`marker::PhantomPinned`]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomPinned.html
[`Vec::resize_with`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.resize_with
[`VecDeque::resize_with`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.resize_with
[`Duration::as_millis`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_millis
[`Duration::as_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_micros
[`Duration::as_nanos`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_nanos
[platform-support]: https://forge.rust-lang.org/platform-support.html
kennytm added a commit to kennytm/rust that referenced this pull request Mar 11, 2019
Default to integrated `rust-lld` linker for UEFI targets

The `x86_64-unknown-uefi` target was added in rust-lang#56769 with the linker defaulting to `lld-link`. This means that a system linker with that name is required for linking.

I think defaulting to `rust-lld`, which is shipped with Rust, is a better default for the following reasons:

- Most systems don't have `lld-link` installed, so it forces users to install it first.
- The naming of LLD executables is not standarized, so users often need to create an additional symlink before things work. For example, on Ubuntu `apt install lld` leads to an executable named `lld-link-6.0`.
- We already default to `rust-lld` for [many targets](https://github.com/rust-lang/rust/search?utf8=%E2%9C%93&q=rust-lld&type=), including embedded and WASM targets, so doing the same for UEFI crates seems consistent to me. (It even seems like `x86_64-unknown-uefi` is the [only target](https://github.com/rust-lang/rust/search?q=lld-link&unscoped_q=lld-link) that uses `lld-link`.)

cc @dvdhrm who added the target and @KKK669 who [proposed to use `rust-lld`](rust-lang#56769 (comment)).
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Mar 14, 2019
Default to integrated `rust-lld` linker for UEFI targets

The `x86_64-unknown-uefi` target was added in rust-lang#56769 with the linker defaulting to `lld-link`. This means that a system linker with that name is required for linking.

I think defaulting to `rust-lld`, which is shipped with Rust, is a better default for the following reasons:

- Most systems don't have `lld-link` installed, so it forces users to install it first.
- The naming of LLD executables is not standarized, so users often need to create an additional symlink before things work. For example, on Ubuntu `apt install lld` leads to an executable named `lld-link-6.0`.
- We already default to `rust-lld` for [many targets](https://github.com/rust-lang/rust/search?utf8=%E2%9C%93&q=rust-lld&type=), including embedded and WASM targets, so doing the same for UEFI crates seems consistent to me. (It even seems like `x86_64-unknown-uefi` is the [only target](https://github.com/rust-lang/rust/search?q=lld-link&unscoped_q=lld-link) that uses `lld-link`.)

cc @dvdhrm who added the target and @KKK669 who [proposed to use `rust-lld`](rust-lang#56769 (comment)).
kennytm added a commit to kennytm/rust that referenced this pull request Mar 15, 2019
Default to integrated `rust-lld` linker for UEFI targets

The `x86_64-unknown-uefi` target was added in rust-lang#56769 with the linker defaulting to `lld-link`. This means that a system linker with that name is required for linking.

I think defaulting to `rust-lld`, which is shipped with Rust, is a better default for the following reasons:

- Most systems don't have `lld-link` installed, so it forces users to install it first.
- The naming of LLD executables is not standarized, so users often need to create an additional symlink before things work. For example, on Ubuntu `apt install lld` leads to an executable named `lld-link-6.0`.
- We already default to `rust-lld` for [many targets](https://github.com/rust-lang/rust/search?utf8=%E2%9C%93&q=rust-lld&type=), including embedded and WASM targets, so doing the same for UEFI crates seems consistent to me. (It even seems like `x86_64-unknown-uefi` is the [only target](https://github.com/rust-lang/rust/search?q=lld-link&unscoped_q=lld-link) that uses `lld-link`.)

cc @dvdhrm who added the target and @KKK669 who [proposed to use `rust-lld`](rust-lang#56769 (comment)).
kennytm added a commit to kennytm/rust that referenced this pull request Mar 16, 2019
Default to integrated `rust-lld` linker for UEFI targets

The `x86_64-unknown-uefi` target was added in rust-lang#56769 with the linker defaulting to `lld-link`. This means that a system linker with that name is required for linking.

I think defaulting to `rust-lld`, which is shipped with Rust, is a better default for the following reasons:

- Most systems don't have `lld-link` installed, so it forces users to install it first.
- The naming of LLD executables is not standarized, so users often need to create an additional symlink before things work. For example, on Ubuntu `apt install lld` leads to an executable named `lld-link-6.0`.
- We already default to `rust-lld` for [many targets](https://github.com/rust-lang/rust/search?utf8=%E2%9C%93&q=rust-lld&type=), including embedded and WASM targets, so doing the same for UEFI crates seems consistent to me. (It even seems like `x86_64-unknown-uefi` is the [only target](https://github.com/rust-lang/rust/search?q=lld-link&unscoped_q=lld-link) that uses `lld-link`.)

cc @dvdhrm who added the target and @KKK669 who [proposed to use `rust-lld`](rust-lang#56769 (comment)).
@Centril Centril added this to the 1.33 milestone Apr 26, 2019
jperkin pushed a commit to TritonDataCenter/pkgsrc that referenced this pull request Jun 20, 2019
Pkgsrc changes:
 * Bump required rust version to build to 1.32.0.
 * Adapt patches to changed file locations.
 * Since we now patch some more vendor/ modules, doctor the corresponding
   .cargo-checksum.json files accordingly

Upstream changes:

Version 1.33.0 (2019-02-28)
==========================

Language
--------
- [You can now use the `cfg(target_vendor)` attribute.][57465] E.g.
  `#[cfg(target_vendor="apple")] fn main() { println!("Hello Apple!"); }`
- [Integer patterns such as in a match expression can now be exhaustive.][56362]
  E.g. You can have match statement on a `u8` that covers `0..=255` and
  you would no longer be required to have a `_ => unreachable!()` case.
- [You can now have multiple patterns in `if let` and `while let`
  expressions.][57532] You can do this with the same syntax as a `match`
  expression. E.g.
  ```rust
  enum Creature {
      Crab(String),
      Lobster(String),
      Person(String),
  }

  fn main() {
      let state = Creature::Crab("Ferris");

      if let Creature::Crab(name) | Creature::Person(name) = state {
          println!("This creature's name is: {}", name);
      }
  }
  ```
- [You can now have irrefutable `if let` and `while let` patterns.][57535]
  Using this feature will by default produce a warning as this behaviour
  can be unintuitive. E.g. `if let _ = 5 {}`
- [You can now use `let` bindings, assignments, expression statements,
  and irrefutable pattern destructuring in const functions.][57175]
- [You can now call unsafe const functions.][57067] E.g.
  ```rust
  const unsafe fn foo() -> i32 { 5 }
  const fn bar() -> i32 {
      unsafe { foo() }
  }
  ```
- [You can now specify multiple attributes in a `cfg_attr` attribute.][57332]
  E.g. `#[cfg_attr(all(), must_use, optimize)]`
- [You can now specify a specific alignment with the `#[repr(packed)]`
  attribute.][57049] E.g. `#[repr(packed(2))] struct Foo(i16, i32);` is a
  struct with an alignment of 2 bytes and a size of 6 bytes.
- [You can now import an item from a module as an `_`.][56303] This allows you
  to import a trait's impls, and not have the name in the namespace. E.g.
  ```rust
  use std::io::Read as _;

  // Allowed as there is only one `Read` in the module.
  pub trait Read {}
  ```
- [You may now use `Rc`, `Arc`, and `Pin` as method receivers][56805].

Compiler
--------
- [You can now set a linker flavor for `rustc` with the `-Clinker-flavor`
  command line argument.][56351]
- [The mininum required LLVM version has been bumped to 6.0.][56642]
- [Added support for the PowerPC64 architecture on FreeBSD.][57615]
- [The `x86_64-fortanix-unknown-sgx` target support has been upgraded to
  tier 2 support.][57130] Visit the [platform support][platform-support]
  page for information on Rust's platform support.
- [Added support for the `thumbv7neon-linux-androideabi` and
  `thumbv7neon-unknown-linux-gnueabihf` targets.][56947]
- [Added support for the `x86_64-unknown-uefi` target.][56769]

Libraries
---------
- [The methods `overflowing_{add, sub, mul, shl, shr}` are now `const`
  functions for all numeric types.][57566]
- [The methods `rotate_left`, `rotate_right`, and `wrapping_{add, sub, mul,
  shl, shr}`
  are now `const` functions for all numeric types.][57105]
- [The methods `is_positive` and `is_negative` are now `const` functions for
  all signed numeric types.][57105]
- [The `get` method for all `NonZero` types is now `const`.][57167]
- [The methods `count_ones`, `count_zeros`, `leading_zeros`, `trailing_zeros`,
  `swap_bytes`, `from_be`, `from_le`, `to_be`, `to_le` are now `const` for all
  numeric types.][57234]
- [`Ipv4Addr::new` is now a `const` function][57234]

Stabilized APIs
---------------
- [`unix::FileExt::read_exact_at`]
- [`unix::FileExt::write_all_at`]
- [`Option::transpose`]
- [`Result::transpose`]
- [`convert::identity`]
- [`pin::Pin`]
- [`marker::Unpin`]
- [`marker::PhantomPinned`]
- [`Vec::resize_with`]
- [`VecDeque::resize_with`]
- [`Duration::as_millis`]
- [`Duration::as_micros`]
- [`Duration::as_nanos`]


Cargo
-----
- [Cargo should now rebuild a crate if a file was modified during the initial
  build.][cargo/6484]

Compatibility Notes
-------------------
- The methods `str::{trim_left, trim_right, trim_left_matches,
  trim_right_matches}` are now deprecated in the standard library, and their
  usage will now produce a warning.  Please use the `str::{trim_start,
  trim_end, trim_start_matches, trim_end_matches}` methods instead.
- The `Error::cause` method has been deprecated in favor of `Error::source`
  which supports downcasting.

[55982]: rust-lang/rust#55982
[56303]: rust-lang/rust#56303
[56351]: rust-lang/rust#56351
[56362]: rust-lang/rust#56362
[56642]: rust-lang/rust#56642
[56769]: rust-lang/rust#56769
[56805]: rust-lang/rust#56805
[56947]: rust-lang/rust#56947
[57049]: rust-lang/rust#57049
[57067]: rust-lang/rust#57067
[57105]: rust-lang/rust#57105
[57130]: rust-lang/rust#57130
[57167]: rust-lang/rust#57167
[57175]: rust-lang/rust#57175
[57234]: rust-lang/rust#57234
[57332]: rust-lang/rust#57332
[57465]: rust-lang/rust#57465
[57532]: rust-lang/rust#57532
[57535]: rust-lang/rust#57535
[57566]: rust-lang/rust#57566
[57615]: rust-lang/rust#57615
[cargo/6484]: rust-lang/cargo#6484
[`unix::FileExt::read_exact_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.read_exact_at
[`unix::FileExt::write_all_at`]: https://doc.rust-lang.org/std/os/unix/fs/trait.FileExt.html#method.write_all_at
[`Option::transpose`]: https://doc.rust-lang.org/std/option/enum.Option.html#method.transpose
[`Result::transpose`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.transpose
[`convert::identity`]: https://doc.rust-lang.org/std/convert/fn.identity.html
[`pin::Pin`]: https://doc.rust-lang.org/std/pin/struct.Pin.html
[`marker::Unpin`]: https://doc.rust-lang.org/stable/std/marker/trait.Unpin.html
[`marker::PhantomPinned`]: https://doc.rust-lang.org/nightly/std/marker/struct.PhantomPinned.html
[`Vec::resize_with`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.resize_with
[`VecDeque::resize_with`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html#method.resize_with
[`Duration::as_millis`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_millis
[`Duration::as_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_micros
[`Duration::as_nanos`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_nanos
[platform-support]: https://forge.rust-lang.org/platform-support.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.