Skip to content

Commit 31382d5

Browse files
committed
Remove the read_byte_loop_raw function, because it is unsound.
See #12
1 parent 8d00b35 commit 31382d5

File tree

3 files changed

+20
-77
lines changed

3 files changed

+20
-77
lines changed

CHANGELOG.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99

1010

11+
## Unreleased
12+
13+
### Internal Changes
14+
15+
- Removed `read_byte_loop_raw` function, because it is unsound. Thanks to [workingjubilee](https://github.com/workingjubilee) for pointing this out. (https://github.com/Cryptjar/avr-progmem-rs/issues/12)
16+
- Made the `lpm-asm-loop` crate feature obsolete, because the lpm assembly loop is now the only implementation.
17+
18+
1119

1220
## [0.3.2] - 2023-01-22
1321
[0.3.2]: https://github.com/Cryptjar/avr-progmem-rs/compare/v0.3.1...v0.3.2
@@ -62,7 +70,7 @@ Changes since `v0.2.0`.
6270
- Deny storing a reference in progmem (i.e. a direct `&T`) via the `progmem` macro, this should catch some common mistakes.
6371
- Deny storing a `LoadedString` directly in progmem via the `progmem` macro, use the special `string` rule instead.
6472

65-
### Internal changes
73+
### Internal Changes
6674

6775
- Migrate from `llvm_asm` to `asm`.
6876
- Use the `addr_of` macro to never ever have a reference to progmem, just raw pointers.
@@ -91,7 +99,7 @@ Changes since `v0.1.5`.
9199
- Emit a warning when just storing a reference in progmem instead of the actual data via the `progmem` macro.
92100
- Add an [`PmIter::iter`] method to lazily iterate through an array (loading only one element at a time).
93101

94-
### Internal changes
102+
### Internal Changes
95103

96104
- Change `ProgMem` from a direct value wrapper into a pointer wrapper, thus no more references into program memory are kept only raw pointers (the accessible `static`s containing the `ProgMem` struct are in RAM, the data is stored in hidden `static`s in progmem).
97105
- Patch `ufmt` to fix u32 formatting (https://github.com/Cryptjar/avr-progmem-rs/commit/9d351038fc31d769206b29cd7228b35aa457b518)
@@ -138,7 +146,7 @@ Changes since `v0.1.2`.
138146

139147
- Deprecate [`read_slice`] function, because it is based on passing around plain slices (aka a reference) to program memory, which is extremely hazardous, if not **UB**, and thus will not be supported in the future.
140148

141-
### Internal changes
149+
### Internal Changes
142150

143151
- Pin the Rust toolchain to `nightly-2021-01-07`, because at the time of writing it is the latest Rust version that supports AVR (future version are broken, also see <https://github.com/rust-lang/compiler-builtins/issues/400>).
144152
- Add Github CI.
@@ -167,7 +175,7 @@ Changes since `v0.1.0`.
167175

168176
- Use the `.progmem.data` section instead of just `.progmem` to keep compatibility with `avr-binutils >= 2.30` by [@Rahix](https://github.com/Rahix) (https://github.com/Cryptjar/avr-progmem-rs/pull/2)
169177

170-
### Internal changes
178+
### Internal Changes
171179

172180
- Setup a cargo config to target the Arduino Uno by default (instead of the host), and allow to run the examples directly via `cargo run` by [@Rahix](https://github.com/Rahix) (https://github.com/Cryptjar/avr-progmem-rs/pull/2)
173181

Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ opt-level = "s"
3030

3131
[features]
3232
default = ["lpm-asm-loop", "ufmt"]
33-
# Enables the use of the `lpm r0, Z+` in an assembly loop, instead of the plain
34-
# `lpm` instruction with a Rust loop.
33+
34+
# Deprecated, the assembly loop is now the only implementation. Enabling
35+
# (or disabling) this feature makes no difference, anymore.
3536
lpm-asm-loop = []
37+
3638
# Enables some tweak to ease debugging, should not be use in production
3739
dev = []
3840
# Enables unsize utilities, such as wrapper coercing.

src/raw.rs

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -125,63 +125,6 @@ pub unsafe fn read_byte(p_addr: *const u8) -> u8 {
125125
}
126126
}
127127

128-
/// Read an array of type `T` from progmem into data array.
129-
///
130-
/// This function uses the above byte-wise `read_byte` function instead
131-
/// of the looped assembly of `read_asm_loop_raw`.
132-
///
133-
///
134-
/// # Safety
135-
///
136-
/// This call is analog to `core::ptr::copy(p_addr, out, len as usize)` thus it
137-
/// has the same basic requirements such as both pointers must be valid for
138-
/// dereferencing i.e. not dangling and both pointers must
139-
/// be valid to read or write, respectively, of `len` many elements of type `T`,
140-
/// i.e. `len * size_of::<T>()` bytes.
141-
///
142-
/// Additionally, `p_addr` must be a valid pointer into the program memory
143-
/// domain. And `out` must be valid point to a writable location in the data
144-
/// memory.
145-
///
146-
/// However alignment is not strictly required for AVR, since the read/write is
147-
/// done byte-wise.
148-
///
149-
#[allow(dead_code)]
150-
unsafe fn read_byte_loop_raw<T>(p_addr: *const T, out: *mut T, len: u8)
151-
where
152-
T: Sized + Copy,
153-
{
154-
// Convert to byte pointers
155-
let p_addr_bytes = p_addr as *const u8;
156-
let out_bytes = out as *mut u8;
157-
158-
// Get size in bytes of T
159-
let size_type = size_of::<T>();
160-
// Must not exceed 256 byte
161-
assert!(size_type <= u8::MAX as usize);
162-
163-
// Multiply with the given length
164-
let size_bytes = size_type * len as usize;
165-
// Must still not exceed 256 byte
166-
assert!(size_bytes <= u8::MAX as usize);
167-
// Now its fine to cast down to u8
168-
let size_bytes = size_bytes as u8;
169-
170-
for i in 0..size_bytes {
171-
let i: isize = i.into();
172-
173-
let value = unsafe {
174-
// SAFETY: The caller must ensure that `p_addr` points into the
175-
// program domain.
176-
read_byte(p_addr_bytes.offset(i))
177-
};
178-
unsafe {
179-
// SAFETY: The caller must ensure that `size_bytes` of `out` are
180-
// to write to (data-domain) and are valid for `T`.
181-
out_bytes.offset(i).write(value);
182-
}
183-
}
184-
}
185128

186129

187130
/// Read an array of type `T` from progmem into data array.
@@ -347,20 +290,10 @@ unsafe fn read_value_raw<T>(p_addr: *const T, out: *mut T, len: u8)
347290
where
348291
T: Sized + Copy,
349292
{
350-
cfg_if! {
351-
if #[cfg(feature = "lpm-asm-loop")] {
352-
unsafe {
353-
// SAFETY: The caller must ensuer the validity of the pointers
354-
// and their domains.
355-
read_asm_loop_raw(p_addr, out, len)
356-
}
357-
} else {
358-
unsafe {
359-
// SAFETY: The caller must ensuer the validity of the pointers
360-
// and their domains.
361-
read_byte_loop_raw(p_addr, out, len)
362-
}
363-
}
293+
unsafe {
294+
// SAFETY: The caller must ensure the validity of the pointers
295+
// and their domains.
296+
read_asm_loop_raw(p_addr, out, len)
364297
}
365298
}
366299

0 commit comments

Comments
 (0)