Skip to content

Commit

Permalink
rustc_metadata: Fix unaligned loads
Browse files Browse the repository at this point in the history
Creating a `&[u32]` from a `&[u8]` was not valid; the data is not
necessarily well aligned.
  • Loading branch information
bluss committed Dec 13, 2016
1 parent 0d1b9f4 commit 7bc1054
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/librustc_metadata/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl<'tcx> LazySeq<Index> {
index,
words.len());

let position = u32::from_le(words[index]);
let position = u32::from_le(words[index].get());
if position == u32::MAX {
debug!("Index::lookup: position=u32::MAX");
None
Expand All @@ -84,7 +84,7 @@ impl<'tcx> LazySeq<Index> {
bytes: &'a [u8])
-> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a {
let words = &bytes_to_words(&bytes[self.position..])[..self.len];
words.iter().enumerate().filter_map(|(index, &position)| {
words.iter().map(|word| word.get()).enumerate().filter_map(|(index, position)| {
if position == u32::MAX {
None
} else {
Expand All @@ -95,8 +95,16 @@ impl<'tcx> LazySeq<Index> {
}
}

fn bytes_to_words(b: &[u8]) -> &[u32] {
unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len() / 4) }
#[repr(packed)]
#[derive(Copy, Clone)]
struct Unaligned<T>(T);

impl<T> Unaligned<T> {
fn get(self) -> T { self.0 }
}

fn bytes_to_words(b: &[u8]) -> &[Unaligned<u32>] {
unsafe { slice::from_raw_parts(b.as_ptr() as *const Unaligned<u32>, b.len() / 4) }
}

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

0 comments on commit 7bc1054

Please sign in to comment.