From 0288486b731b3da05dd4b42635bfcf3dae285400 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 23 Jun 2016 15:16:25 +0200 Subject: [PATCH] use target byte order --- src/memory.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/memory.rs b/src/memory.rs index 9718527280df..d537e9fc91ec 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,4 +1,4 @@ -use byteorder::{NativeEndian, ReadBytesExt, WriteBytesExt}; +use byteorder::{ReadBytesExt, WriteBytesExt, LittleEndian, BigEndian, self}; use std::collections::Bound::{Included, Excluded}; use std::collections::{btree_map, BTreeMap, HashMap, HashSet, VecDeque}; use std::{fmt, iter, mem, ptr}; @@ -6,7 +6,7 @@ use std::{fmt, iter, mem, ptr}; use rustc::hir::def_id::DefId; use rustc::ty::BareFnTy; use rustc::ty::subst::Substs; -use rustc::ty::layout::TargetDataLayout; +use rustc::ty::layout::{self, TargetDataLayout}; use error::{EvalError, EvalResult}; use primval::PrimVal; @@ -159,6 +159,10 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { pub fn pointer_size(&self) -> usize { self.layout.pointer_size.bytes() as usize } + + pub fn endianess(&self) -> layout::Endian { + self.layout.endian + } } /// Allocation accessors @@ -340,7 +344,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { let size = self.pointer_size(); self.check_defined(ptr, size)?; let offset = self.get_bytes_unchecked(ptr, size)? - .read_uint::(size).unwrap() as usize; + .read_target_uint(size, self.endianess()).unwrap() as usize; let alloc = self.get(ptr.alloc_id)?; match alloc.relocations.get(&ptr.offset) { Some(&alloc_id) => Ok(Pointer { alloc_id: alloc_id, offset: offset }), @@ -387,19 +391,21 @@ impl<'a, 'tcx> Memory<'a, 'tcx> { } pub fn read_int(&self, ptr: Pointer, size: usize) -> EvalResult<'tcx, i64> { - self.get_bytes(ptr, size).map(|mut b| b.read_int::(size).unwrap()) + self.get_bytes(ptr, size).map(|mut b| b.read_target_int(size, self.endianess()).unwrap()) } pub fn write_int(&mut self, ptr: Pointer, n: i64, size: usize) -> EvalResult<'tcx, ()> { - self.get_bytes_mut(ptr, size).map(|mut b| b.write_int::(n, size).unwrap()) + let endianess = self.endianess(); + self.get_bytes_mut(ptr, size).map(|mut b| b.write_target_int(n, size, endianess).unwrap()) } pub fn read_uint(&self, ptr: Pointer, size: usize) -> EvalResult<'tcx, u64> { - self.get_bytes(ptr, size).map(|mut b| b.read_uint::(size).unwrap()) + self.get_bytes(ptr, size).map(|mut b| b.read_target_uint(size, self.endianess()).unwrap()) } pub fn write_uint(&mut self, ptr: Pointer, n: u64, size: usize) -> EvalResult<'tcx, ()> { - self.get_bytes_mut(ptr, size).map(|mut b| b.write_uint::(n, size).unwrap()) + let endianess = self.endianess(); + self.get_bytes_mut(ptr, size).map(|mut b| b.write_target_uint(n, size, endianess).unwrap()) } pub fn read_isize(&self, ptr: Pointer) -> EvalResult<'tcx, i64> { @@ -585,3 +591,43 @@ impl UndefMask { fn bit_index(bits: usize) -> (usize, usize) { (bits / BLOCK_SIZE, bits % BLOCK_SIZE) } + +trait ReadBytesExt2 { + fn read_target_uint(&mut self, nbytes: usize, endian: layout::Endian) -> Result; + fn read_target_int(&mut self, nbytes: usize, endian: layout::Endian) -> Result; +} + +impl ReadBytesExt2 for T { + fn read_target_uint(&mut self, nbytes: usize, endian: layout::Endian) -> Result { + match endian { + layout::Endian::Little => ReadBytesExt::read_uint::(self, nbytes), + layout::Endian::Big => ReadBytesExt::read_uint::(self, nbytes), + } + } + fn read_target_int(&mut self, nbytes: usize, endian: layout::Endian) -> Result { + match endian { + layout::Endian::Little => ReadBytesExt::read_int::(self, nbytes), + layout::Endian::Big => ReadBytesExt::read_int::(self, nbytes), + } + } +} + +trait WriteBytesExt2 { + fn write_target_uint(&mut self, data: u64, nbytes: usize, endian: layout::Endian) -> Result<(), byteorder::Error>; + fn write_target_int(&mut self, data: i64, nbytes: usize, endian: layout::Endian) -> Result<(), byteorder::Error>; +} + +impl WriteBytesExt2 for T { + fn write_target_uint(&mut self, data: u64, nbytes: usize, endian: layout::Endian) -> Result<(), byteorder::Error> { + match endian { + layout::Endian::Little => WriteBytesExt::write_uint::(self, data, nbytes), + layout::Endian::Big => WriteBytesExt::write_uint::(self, data, nbytes), + } + } + fn write_target_int(&mut self, data: i64, nbytes: usize, endian: layout::Endian) -> Result<(), byteorder::Error> { + match endian { + layout::Endian::Little => WriteBytesExt::write_int::(self, data, nbytes), + layout::Endian::Big => WriteBytesExt::write_int::(self, data, nbytes), + } + } +}