This repository was archived by the owner on Jan 24, 2022. It is now read-only.

Description
|
extern "C" { |
|
|
|
// These symbols come from `link.x` |
|
static mut __sbss: u32; |
|
static mut __ebss: u32; |
|
|
|
static mut __sdata: u32; |
|
static mut __edata: u32; |
|
static __sidata: u32; |
|
} |
|
|
|
extern "Rust" { |
|
// This symbol will be provided by the user via `#[pre_init]` |
|
fn __pre_init(); |
|
} |
|
|
|
__pre_init(); |
|
|
|
// Initialize RAM |
|
r0::zero_bss(&mut __sbss, &mut __ebss); |
|
r0::init_data(&mut __sdata, &mut __edata, &__sidata); |
This code uses a pointer to a single u32, but writes an arbitrary amount of data beyond the u32. This is UB, as it violates the contract of ptr::offset, which is called by r0. Namely:
Both the starting and resulting pointer must be either in bounds or one byte past the end of the same allocated object. Note that in Rust, every (stack-allocated) variable is considered a separate allocated object.