You've already forked comprehensive-rust
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:
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user