1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-06-29 03:51:35 +02:00

Updates for Rust 1.82 (#2449)

Rust 1.82 adds `&raw` expressions, and marks some attributes as unsafe.
This commit is contained in:
Andrew Walbran
2024-11-01 07:39:56 +00:00
committed by GitHub
parent 2bba470415
commit f8882190f3
24 changed files with 100 additions and 72 deletions

View File

@ -17,13 +17,15 @@ use log::{error, info, trace};
use smccc::psci::system_off;
use smccc::Hvc;
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn sync_exception_current(_elr: u64, _spsr: u64) {
error!("sync_exception_current");
system_off::<Hvc>().unwrap();
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn irq_current(_elr: u64, _spsr: u64) {
trace!("irq_current");
let intid =
@ -31,37 +33,43 @@ extern "C" fn irq_current(_elr: u64, _spsr: u64) {
info!("IRQ {intid:?}");
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn fiq_current(_elr: u64, _spsr: u64) {
error!("fiq_current");
system_off::<Hvc>().unwrap();
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn serr_current(_elr: u64, _spsr: u64) {
error!("serr_current");
system_off::<Hvc>().unwrap();
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn sync_lower(_elr: u64, _spsr: u64) {
error!("sync_lower");
system_off::<Hvc>().unwrap();
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn irq_lower(_elr: u64, _spsr: u64) {
error!("irq_lower");
system_off::<Hvc>().unwrap();
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn fiq_lower(_elr: u64, _spsr: u64) {
error!("fiq_lower");
system_off::<Hvc>().unwrap();
}
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn serr_lower(_elr: u64, _spsr: u64) {
error!("serr_lower");
system_off::<Hvc>().unwrap();

View File

@ -50,7 +50,8 @@ const PL031_BASE_ADDRESS: *mut u32 = 0x901_0000 as _;
const PL031_IRQ: IntId = IntId::spi(2);
// ANCHOR: main
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
extern "C" fn main(x0: u64, x1: u64, x2: u64, x3: u64) {
// SAFETY: `PL011_BASE_ADDRESS` is the base address of a PL011 device, and
// nothing else accesses that address range.

View File

@ -15,7 +15,6 @@
#![allow(unused)]
use core::fmt::{self, Write};
use core::ptr::{addr_of, addr_of_mut};
// ANCHOR: Flags
use bitflags::bitflags;
@ -126,7 +125,7 @@ impl Uart {
// of a PL011 device which is appropriately mapped.
unsafe {
// Write to the TX buffer.
addr_of_mut!((*self.registers).dr).write_volatile(byte.into());
(&raw mut (*self.registers).dr).write_volatile(byte.into());
}
// Wait until the UART is no longer busy.
@ -141,7 +140,7 @@ impl Uart {
} else {
// SAFETY: We know that self.registers points to the control
// registers of a PL011 device which is appropriately mapped.
let data = unsafe { addr_of!((*self.registers).dr).read_volatile() };
let data = unsafe { (&raw const (*self.registers).dr).read_volatile() };
// TODO: Check for error conditions in bits 8-11.
Some(data as u8)
}
@ -150,7 +149,7 @@ impl Uart {
fn read_flag_register(&self) -> Flags {
// SAFETY: We know that self.registers points to the control registers
// of a PL011 device which is appropriately mapped.
unsafe { addr_of!((*self.registers).fr).read_volatile() }
unsafe { (&raw const (*self.registers).fr).read_volatile() }
}
}
// ANCHOR_END: Uart

View File

@ -13,8 +13,6 @@
// limitations under the License.
// ANCHOR: solution
use core::ptr::{addr_of, addr_of_mut};
#[repr(C, align(4))]
struct Registers {
/// Data register
@ -63,7 +61,7 @@ impl Rtc {
pub fn read(&self) -> u32 {
// SAFETY: We know that self.registers points to the control registers
// of a PL031 device which is appropriately mapped.
unsafe { addr_of!((*self.registers).dr).read_volatile() }
unsafe { (&raw const (*self.registers).dr).read_volatile() }
}
/// Writes a match value. When the RTC value matches this then an interrupt
@ -71,7 +69,7 @@ impl Rtc {
pub fn set_match(&mut self, value: u32) {
// SAFETY: We know that self.registers points to the control registers
// of a PL031 device which is appropriately mapped.
unsafe { addr_of_mut!((*self.registers).mr).write_volatile(value) }
unsafe { (&raw mut (*self.registers).mr).write_volatile(value) }
}
/// Returns whether the match register matches the RTC value, whether or not
@ -79,7 +77,7 @@ impl Rtc {
pub fn matched(&self) -> bool {
// SAFETY: We know that self.registers points to the control registers
// of a PL031 device which is appropriately mapped.
let ris = unsafe { addr_of!((*self.registers).ris).read_volatile() };
let ris = unsafe { (&raw const (*self.registers).ris).read_volatile() };
(ris & 0x01) != 0
}
@ -90,7 +88,7 @@ impl Rtc {
pub fn interrupt_pending(&self) -> bool {
// SAFETY: We know that self.registers points to the control registers
// of a PL031 device which is appropriately mapped.
let ris = unsafe { addr_of!((*self.registers).mis).read_volatile() };
let ris = unsafe { (&raw const (*self.registers).mis).read_volatile() };
(ris & 0x01) != 0
}
@ -102,14 +100,14 @@ impl Rtc {
let imsc = if mask { 0x01 } else { 0x00 };
// SAFETY: We know that self.registers points to the control registers
// of a PL031 device which is appropriately mapped.
unsafe { addr_of_mut!((*self.registers).imsc).write_volatile(imsc) }
unsafe { (&raw mut (*self.registers).imsc).write_volatile(imsc) }
}
/// Clears a pending interrupt, if any.
pub fn clear_interrupt(&mut self) {
// SAFETY: We know that self.registers points to the control registers
// of a PL031 device which is appropriately mapped.
unsafe { addr_of_mut!((*self.registers).icr).write_volatile(0x01) }
unsafe { (&raw mut (*self.registers).icr).write_volatile(0x01) }
}
}

View File

@ -4,7 +4,8 @@ In your Chromium build, add a new Rust target to `//ui/base/BUILD.gn`
containing:
```rust
#[no_mangle]
// SAFETY: There is no other global function of this name.
#[unsafe(no_mangle)]
pub extern "C" fn hello_from_rust() {
println!("Hello from Rust!")
}
@ -32,7 +33,7 @@ subsequent exercises. If you've succeeded, you will be able to use right-click
## Where to find help
- The options available to the [`rust_static_library` gn template][0]
- Information about [`#[no_mangle]`][1]
- Information about [`#[unsafe(no_mangle)]`][1]
- Information about [`extern "C"`][2]
- Information about gn's [`--export-rust-project`][3] switch
- [How to install rust-analyzer in VSCode][4]
@ -45,9 +46,9 @@ This example is unusual because it boils down to the lowest-common-denominator
interop language, C. Both C++ and Rust can natively declare and call C ABI
functions. Later in the course, we'll connect C++ directly to Rust.
`allow_unsafe = true` is required here because `#[no_mangle]` might allow Rust
to generate two functions with the same name, and Rust can no longer guarantee
that the right one is called.
`allow_unsafe = true` is required here because `#[unsafe(no_mangle)]` might
allow Rust to generate two functions with the same name, and Rust can no longer
guarantee that the right one is called.
If you need a pure Rust executable, you can also do that using the
`rust_executable` gn template.

View File

@ -6,7 +6,7 @@
specifies a single function, to be called from C++, called `hello_from_rust`,
taking no parameters and returning no value.
- Modify your previous `hello_from_rust` function to remove `extern "C"` and
`#[no_mangle]`. This is now just a standard Rust function.
`#[unsafe(no_mangle)]`. This is now just a standard Rust function.
- Modify your `gn` target to build these bindings.
- In your C++ code, remove the forward-declaration of `hello_from_rust`.
Instead, include the generated header file.