Skip to content

Commit 7bc1054

Browse files
committed
rustc_metadata: Fix unaligned loads
Creating a `&[u32]` from a `&[u8]` was not valid; the data is not necessarily well aligned.
1 parent 0d1b9f4 commit 7bc1054

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/librustc_metadata/index.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl<'tcx> LazySeq<Index> {
7070
index,
7171
words.len());
7272

73-
let position = u32::from_le(words[index]);
73+
let position = u32::from_le(words[index].get());
7474
if position == u32::MAX {
7575
debug!("Index::lookup: position=u32::MAX");
7676
None
@@ -84,7 +84,7 @@ impl<'tcx> LazySeq<Index> {
8484
bytes: &'a [u8])
8585
-> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a {
8686
let words = &bytes_to_words(&bytes[self.position..])[..self.len];
87-
words.iter().enumerate().filter_map(|(index, &position)| {
87+
words.iter().map(|word| word.get()).enumerate().filter_map(|(index, position)| {
8888
if position == u32::MAX {
8989
None
9090
} else {
@@ -95,8 +95,16 @@ impl<'tcx> LazySeq<Index> {
9595
}
9696
}
9797

98-
fn bytes_to_words(b: &[u8]) -> &[u32] {
99-
unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len() / 4) }
98+
#[repr(packed)]
99+
#[derive(Copy, Clone)]
100+
struct Unaligned<T>(T);
101+
102+
impl<T> Unaligned<T> {
103+
fn get(self) -> T { self.0 }
104+
}
105+
106+
fn bytes_to_words(b: &[u8]) -> &[Unaligned<u32>] {
107+
unsafe { slice::from_raw_parts(b.as_ptr() as *const Unaligned<u32>, b.len() / 4) }
100108
}
101109

102110
fn words_to_bytes(w: &[u32]) -> &[u8] {

0 commit comments

Comments
 (0)