Always support unaligned reads (#861)

The "unaligned" feature now has no effect.
This commit is contained in:
Philip Craig
2026-03-20 12:31:43 +10:00
committed by GitHub
parent 8891835459
commit 3849b8b774
21 changed files with 205 additions and 610 deletions
+7 -14
View File
@@ -43,8 +43,8 @@ alloc = { version = '1.0.0', optional = true, package = 'rustc-std-workspace-all
# Core read support. You will need to enable some file formats too.
read_core = []
# Read support for most file formats (including unaligned files).
read = ["read_core", "archive", "coff", "elf", "macho", "pe", "xcoff", "unaligned"]
# Read support for most file formats.
read = ["read_core", "archive", "coff", "elf", "macho", "pe", "xcoff"]
# Core write support. You will need to enable some file formats too.
write_core = ["dep:crc32fast", "dep:indexmap", "dep:hashbrown"]
# Core write support with libstd features. You will need to enable some file formats too.
@@ -65,12 +65,6 @@ std = ["memchr/std"]
# Enable decompression of compressed sections.
# This feature is not required if you want to do your own decompression.
compression = ["dep:flate2", "dep:ruzstd", "std"]
# Treat all types as unaligned.
# Normally types use the alignment required by the specifications, but
# sometimes files do not strictly follow the specifications.
# This may be useful to enable when processing files for architectures
# that have no alignment constraints.
unaligned = []
#=======================================
# File format features.
@@ -96,12 +90,11 @@ all = ["read", "write", "build", "std", "compression", "wasm"]
cargo-all = []
#=======================================
# Documentation should be generated with everything in "all" except for "unaligned".
doc = [
"read_core", "write_std", "build_core",
"std", "compression",
"archive", "coff", "elf", "macho", "pe", "wasm", "xcoff",
]
doc = ["all"]
#=======================================
# Deprecated features.
unaligned = []
#=======================================
# Unstable features. Breaking changes in these features will not affect versioning.
+2 -2
View File
@@ -236,7 +236,7 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
// This relocation is paired with a R_RISCV_PCREL_LO12_I.
let info_offset = u64::from(r_offset).wrapping_sub(info_addr);
let instruction = info_data
.read_at::<object::U32Bytes<Elf::Endian>>(info_offset)
.read_at::<object::U32<Elf::Endian>>(info_offset)
.unwrap()
.get(endian);
// auipc
@@ -249,7 +249,7 @@ fn copy_file<Elf: FileHeader<Endian = Endianness>>(
if let Some(mut got_address) = got_address.take() {
let info_offset = u64::from(r_offset).wrapping_sub(info_addr);
let instruction = info_data
.read_at::<object::U32Bytes<Elf::Endian>>(info_offset)
.read_at::<object::U32<Elf::Endian>>(info_offset)
.unwrap()
.get(endian);
// ld
+3 -3
View File
@@ -4,7 +4,7 @@ use object::read::coff::ImageSymbol as _;
use object::read::coff::*;
use object::read::pe::*;
use object::LittleEndian as LE;
use object::{Bytes, U32Bytes, U64Bytes};
use object::{Bytes, U32, U64};
pub(super) fn print_coff(p: &mut Printer<'_>, data: &[u8]) {
let mut offset = 0;
@@ -822,10 +822,10 @@ fn print_reloc_dir(
let offset = (reloc.virtual_address - block_address) as usize;
if let Some(addend) = match reloc.typ {
IMAGE_REL_BASED_HIGHLOW => block_data
.and_then(|data| data.read_at::<U32Bytes<LE>>(offset).ok())
.and_then(|data| data.read_at::<U32<LE>>(offset).ok())
.map(|addend| u64::from(addend.get(LE))),
IMAGE_REL_BASED_DIR64 => block_data
.and_then(|data| data.read_at::<U64Bytes<LE>>(offset).ok())
.and_then(|data| data.read_at::<U64<LE>>(offset).ok())
.map(|addend| addend.get(LE)),
_ => None,
} {
+8 -8
View File
@@ -8,7 +8,7 @@
#![allow(missing_docs)]
#![allow(clippy::identity_op)]
use crate::endian::{Endian, U32Bytes, U64Bytes, I32, I64, U16, U32, U64};
use crate::endian::{Endian, I32, I64, U16, U32, U64};
use crate::pod::Pod;
/// The header at the start of every 32-bit ELF file.
@@ -804,11 +804,11 @@ pub const SHF_EXCLUDE: u32 = 0x8000_0000;
#[repr(C)]
pub struct CompressionHeader32<E: Endian> {
/// Compression format. One of the `ELFCOMPRESS_*` values.
pub ch_type: U32Bytes<E>,
pub ch_type: U32<E>,
/// Uncompressed data size.
pub ch_size: U32Bytes<E>,
pub ch_size: U32<E>,
/// Uncompressed data alignment.
pub ch_addralign: U32Bytes<E>,
pub ch_addralign: U32<E>,
}
/// Section compression header.
@@ -821,13 +821,13 @@ pub struct CompressionHeader32<E: Endian> {
#[repr(C)]
pub struct CompressionHeader64<E: Endian> {
/// Compression format. One of the `ELFCOMPRESS_*` values.
pub ch_type: U32Bytes<E>,
pub ch_type: U32<E>,
/// Reserved.
pub ch_reserved: U32Bytes<E>,
pub ch_reserved: U32<E>,
/// Uncompressed data size.
pub ch_size: U64Bytes<E>,
pub ch_size: U64<E>,
/// Uncompressed data alignment.
pub ch_addralign: U64Bytes<E>,
pub ch_addralign: U64<E>,
}
/// ZLIB/DEFLATE algorithm.
+91 -481
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -7,7 +7,7 @@
#![allow(missing_docs)]
use crate::endian::{BigEndian, Endian, U64Bytes, U16, U32, U64};
use crate::endian::{BigEndian, Endian, U16, U32, U64};
use crate::pod::Pod;
// Definitions from "/usr/include/mach/machine.h".
@@ -2660,8 +2660,7 @@ pub struct Nlist64<E: Endian> {
/// see <mach-o/stab.h>
pub n_desc: U16<E>,
/// value of this symbol (or stab offset)
// Note: 4 byte alignment has been observed in practice.
pub n_value: U64Bytes<E>,
pub n_value: U64<E>,
}
/*
+35 -39
View File
@@ -9,7 +9,7 @@
use core::convert::TryInto;
use crate::endian::{I32Bytes, LittleEndian as LE, U16Bytes, U32Bytes, I32, U16, U32, U64};
use crate::endian::{LittleEndian as LE, I32, U16, U32, U64};
use crate::pod::Pod;
/// MZ
@@ -811,15 +811,14 @@ pub const IMAGE_SCN_SCALE_INDEX: u32 = 0x0000_0001;
// Symbol format.
//
// This struct has alignment 1.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ImageSymbol {
/// If first 4 bytes are 0, then second 4 bytes are offset into string table.
pub name: [u8; 8],
pub value: U32Bytes<LE>,
pub section_number: U16Bytes<LE>,
pub typ: U16Bytes<LE>,
pub value: U32<LE>,
pub section_number: U16<LE>,
pub typ: U16<LE>,
pub storage_class: u8,
pub number_of_aux_symbols: u8,
}
@@ -830,15 +829,14 @@ pub const IMAGE_SIZEOF_SYMBOL: usize = 18;
#[repr(C)]
pub struct ImageSymbolBytes(pub [u8; IMAGE_SIZEOF_SYMBOL]);
// This struct has alignment 1.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ImageSymbolEx {
/// If first 4 bytes are 0, then second 4 bytes are offset into string table.
pub name: [u8; 8],
pub value: U32Bytes<LE>,
pub section_number: I32Bytes<LE>,
pub typ: U16Bytes<LE>,
pub value: U32<LE>,
pub section_number: I32<LE>,
pub typ: U16<LE>,
pub storage_class: u8,
pub number_of_aux_symbols: u8,
}
@@ -950,7 +948,6 @@ pub const IMAGE_SYM_DTYPE_SHIFT: usize = N_BTSHFT;
//
// Used for both ImageSymbol and ImageSymbolEx (with padding).
// This struct has alignment 1.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ImageAuxSymbolTokenDef {
@@ -958,7 +955,7 @@ pub struct ImageAuxSymbolTokenDef {
pub aux_type: u8,
/// Must be 0
pub reserved1: u8,
pub symbol_table_index: U32Bytes<LE>,
pub symbol_table_index: U32<LE>,
/// Must be 0
pub reserved2: [u8; 12],
}
@@ -966,14 +963,13 @@ pub struct ImageAuxSymbolTokenDef {
pub const IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF: u16 = 1;
/// Auxiliary symbol format 1: function definitions.
// This struct has alignment 1.
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ImageAuxSymbolFunction {
pub tag_index: U32Bytes<LE>,
pub total_size: U32Bytes<LE>,
pub pointer_to_linenumber: U32Bytes<LE>,
pub pointer_to_next_function: U32Bytes<LE>,
pub tag_index: U32<LE>,
pub total_size: U32<LE>,
pub pointer_to_linenumber: U32<LE>,
pub pointer_to_next_function: U32<LE>,
pub unused: [u8; 2],
}
@@ -984,9 +980,9 @@ pub struct ImageAuxSymbolFunction {
pub struct ImageAuxSymbolFunctionBeginEnd {
pub unused1: [u8; 4],
/// declaration line number
pub linenumber: U16Bytes<LE>,
pub linenumber: U16<LE>,
pub unused2: [u8; 6],
pub pointer_to_next_function: U32Bytes<LE>,
pub pointer_to_next_function: U32<LE>,
pub unused3: [u8; 2],
}
@@ -998,8 +994,8 @@ pub struct ImageAuxSymbolFunctionBeginEnd {
#[repr(C)]
pub struct ImageAuxSymbolWeak {
/// the weak extern default symbol index
pub weak_default_sym_index: U32Bytes<LE>,
pub weak_search_type: U32Bytes<LE>,
pub weak_default_sym_index: U32<LE>,
pub weak_search_type: U32<LE>,
}
/// Auxiliary symbol format 5: sections.
@@ -1010,20 +1006,20 @@ pub struct ImageAuxSymbolWeak {
#[repr(C)]
pub struct ImageAuxSymbolSection {
/// section length
pub length: U32Bytes<LE>,
pub length: U32<LE>,
/// number of relocation entries
pub number_of_relocations: U16Bytes<LE>,
pub number_of_relocations: U16<LE>,
/// number of line numbers
pub number_of_linenumbers: U16Bytes<LE>,
pub number_of_linenumbers: U16<LE>,
/// checksum for communal
pub check_sum: U32Bytes<LE>,
pub check_sum: U32<LE>,
/// section number to associate with
pub number: U16Bytes<LE>,
pub number: U16<LE>,
/// communal selection type
pub selection: u8,
pub reserved: u8,
/// high bits of the section number
pub high_number: U16Bytes<LE>,
pub high_number: U16<LE>,
}
// Used for both ImageSymbol and ImageSymbolEx (both with padding).
@@ -1031,7 +1027,7 @@ pub struct ImageAuxSymbolSection {
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ImageAuxSymbolCrc {
pub crc: U32Bytes<LE>,
pub crc: U32<LE>,
}
//
@@ -1060,9 +1056,9 @@ pub const IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY: u32 = 4;
#[repr(C)]
pub struct ImageRelocation {
/// Also `RelocCount` when IMAGE_SCN_LNK_NRELOC_OVFL is set
pub virtual_address: U32Bytes<LE>,
pub symbol_table_index: U32Bytes<LE>,
pub typ: U16Bytes<LE>,
pub virtual_address: U32<LE>,
pub symbol_table_index: U32<LE>,
pub typ: U16<LE>,
}
//
@@ -1721,9 +1717,9 @@ pub const X3_EMPTY_INST_VAL_POS_X: u16 = 0;
pub struct ImageLinenumber {
/// Symbol table index of function name if Linenumber is 0.
/// Otherwise virtual address of line number.
pub symbol_table_index_or_virtual_address: U32Bytes<LE>,
pub symbol_table_index_or_virtual_address: U32<LE>,
/// Line number.
pub linenumber: U16Bytes<LE>,
pub linenumber: U16<LE>,
}
//
@@ -1918,17 +1914,17 @@ pub struct ImageTlsDirectory32 {
pub struct ImageImportDescriptor {
/// RVA to original unbound IAT (`ImageThunkData32`/`ImageThunkData64`)
/// 0 for terminating null import descriptor
pub original_first_thunk: U32Bytes<LE>,
pub original_first_thunk: U32<LE>,
/// 0 if not bound,
/// -1 if bound, and real date\time stamp
/// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
/// O.W. date/time stamp of DLL bound to (Old BIND)
pub time_date_stamp: U32Bytes<LE>,
pub time_date_stamp: U32<LE>,
/// -1 if no forwarders
pub forwarder_chain: U32Bytes<LE>,
pub name: U32Bytes<LE>,
pub forwarder_chain: U32<LE>,
pub name: U32<LE>,
/// RVA to IAT (if bound this IAT has actual addresses)
pub first_thunk: U32Bytes<LE>,
pub first_thunk: U32<LE>,
}
impl ImageImportDescriptor {
@@ -2237,10 +2233,10 @@ pub struct ImagePrologueDynamicRelocationHeader {
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct ImageEpilogueDynamicRelocationHeader {
pub epilogue_count: U32Bytes<LE>,
pub epilogue_count: U32<LE>,
pub epilogue_byte_count: u8,
pub branch_descriptor_element_size: u8,
pub branch_descriptor_count: U16Bytes<LE>,
pub branch_descriptor_count: U16<LE>,
// pub branch_descriptors[...],
// pub branch_descriptor_bit_map[...],
}
+21 -21
View File
@@ -23,7 +23,7 @@
use core::convert::TryInto;
use core::slice;
use crate::endian::{BigEndian as BE, LittleEndian as LE, U16Bytes, U32Bytes, U64Bytes};
use crate::endian::{BigEndian as BE, LittleEndian as LE, U16, U32, U64};
use crate::read::{self, Bytes, Error, ReadError, ReadRef};
use crate::{archive, SkipDebugList};
@@ -612,7 +612,7 @@ enum SymbolIteratorInternal<'data> {
/// - the offsets of the member headers as 32-bit big-endian integers
/// - the symbol names as null-terminated strings
Gnu {
offsets: slice::Iter<'data, U32Bytes<BE>>,
offsets: slice::Iter<'data, U32<BE>>,
names: Bytes<'data>,
},
/// A GNU 64-bit symbol table
@@ -622,7 +622,7 @@ enum SymbolIteratorInternal<'data> {
/// - the offsets of the member headers as 64-bit big-endian integers
/// - the symbol names as null-terminated strings
Gnu64 {
offsets: slice::Iter<'data, U64Bytes<BE>>,
offsets: slice::Iter<'data, U64<BE>>,
names: Bytes<'data>,
},
/// A BSD symbol table.
@@ -634,7 +634,7 @@ enum SymbolIteratorInternal<'data> {
/// - the size in bytes of the symbol names as a 32-bit little-endian integer
/// - the symbol names as null-terminated strings
Bsd {
offsets: slice::Iter<'data, [U32Bytes<LE>; 2]>,
offsets: slice::Iter<'data, [U32<LE>; 2]>,
names: Bytes<'data>,
},
/// A BSD 64-bit symbol table.
@@ -646,7 +646,7 @@ enum SymbolIteratorInternal<'data> {
/// - the size in bytes of the symbol names as a 64-bit little-endian integer
/// - the symbol names as null-terminated strings
Bsd64 {
offsets: slice::Iter<'data, [U64Bytes<LE>; 2]>,
offsets: slice::Iter<'data, [U64<LE>; 2]>,
names: Bytes<'data>,
},
/// A Windows COFF symbol table.
@@ -658,8 +658,8 @@ enum SymbolIteratorInternal<'data> {
/// - the member index for each symbol as a 16-bit little-endian integer
/// - the symbol names as null-terminated strings in lexical order
Coff {
members: &'data [U32Bytes<LE>],
indices: slice::Iter<'data, U16Bytes<LE>>,
members: &'data [U32<LE>],
indices: slice::Iter<'data, U16<LE>>,
names: Bytes<'data>,
},
}
@@ -675,25 +675,25 @@ impl<'data> ArchiveSymbolIterator<'data> {
match kind {
ArchiveKind::Unknown => Ok(ArchiveSymbolIterator(SymbolIteratorInternal::None)),
ArchiveKind::Gnu => {
let offsets_count = data.read::<U32Bytes<BE>>()?.get(BE);
let offsets = data.read_slice::<U32Bytes<BE>>(offsets_count as usize)?;
let offsets_count = data.read::<U32<BE>>()?.get(BE);
let offsets = data.read_slice::<U32<BE>>(offsets_count as usize)?;
Ok(ArchiveSymbolIterator(SymbolIteratorInternal::Gnu {
offsets: offsets.iter(),
names: data,
}))
}
ArchiveKind::Gnu64 => {
let offsets_count = data.read::<U64Bytes<BE>>()?.get(BE);
let offsets = data.read_slice::<U64Bytes<BE>>(offsets_count as usize)?;
let offsets_count = data.read::<U64<BE>>()?.get(BE);
let offsets = data.read_slice::<U64<BE>>(offsets_count as usize)?;
Ok(ArchiveSymbolIterator(SymbolIteratorInternal::Gnu64 {
offsets: offsets.iter(),
names: data,
}))
}
ArchiveKind::Bsd => {
let offsets_size = data.read::<U32Bytes<LE>>()?.get(LE);
let offsets = data.read_slice::<[U32Bytes<LE>; 2]>(offsets_size as usize / 8)?;
let names_size = data.read::<U32Bytes<LE>>()?.get(LE);
let offsets_size = data.read::<U32<LE>>()?.get(LE);
let offsets = data.read_slice::<[U32<LE>; 2]>(offsets_size as usize / 8)?;
let names_size = data.read::<U32<LE>>()?.get(LE);
let names = data.read_bytes(names_size as usize)?;
Ok(ArchiveSymbolIterator(SymbolIteratorInternal::Bsd {
offsets: offsets.iter(),
@@ -701,9 +701,9 @@ impl<'data> ArchiveSymbolIterator<'data> {
}))
}
ArchiveKind::Bsd64 => {
let offsets_size = data.read::<U64Bytes<LE>>()?.get(LE);
let offsets = data.read_slice::<[U64Bytes<LE>; 2]>(offsets_size as usize / 16)?;
let names_size = data.read::<U64Bytes<LE>>()?.get(LE);
let offsets_size = data.read::<U64<LE>>()?.get(LE);
let offsets = data.read_slice::<[U64<LE>; 2]>(offsets_size as usize / 16)?;
let names_size = data.read::<U64<LE>>()?.get(LE);
let names = data.read_bytes(names_size as usize)?;
Ok(ArchiveSymbolIterator(SymbolIteratorInternal::Bsd64 {
offsets: offsets.iter(),
@@ -711,10 +711,10 @@ impl<'data> ArchiveSymbolIterator<'data> {
}))
}
ArchiveKind::Coff => {
let members_count = data.read::<U32Bytes<LE>>()?.get(LE);
let members = data.read_slice::<U32Bytes<LE>>(members_count as usize)?;
let indices_count = data.read::<U32Bytes<LE>>()?.get(LE);
let indices = data.read_slice::<U16Bytes<LE>>(indices_count as usize)?;
let members_count = data.read::<U32<LE>>()?.get(LE);
let members = data.read_slice::<U32<LE>>(members_count as usize)?;
let indices_count = data.read::<U32<LE>>()?.get(LE);
let indices = data.read_slice::<U16<LE>>(indices_count as usize)?;
Ok(ArchiveSymbolIterator(SymbolIteratorInternal::Coff {
members,
indices: indices.iter(),
+2 -2
View File
@@ -5,7 +5,7 @@ use core::fmt::Debug;
use core::str;
use super::{CoffCommon, CoffHeader, SectionTable};
use crate::endian::{LittleEndian as LE, U32Bytes};
use crate::endian::{LittleEndian as LE, U32};
use crate::pe;
use crate::pod::{bytes_of, bytes_of_slice, Pod};
use crate::read::util::StringTable;
@@ -51,7 +51,7 @@ impl<'data, R: ReadRef<'data>, Coff: CoffHeader> SymbolTable<'data, R, Coff> {
// Note: don't update data when reading length; the length includes itself.
let length = data
.read_at::<U32Bytes<_>>(offset)
.read_at::<U32<_>>(offset)
.read_error("Missing COFF string table")?
.get(LE);
let str_end = offset
+2 -2
View File
@@ -81,7 +81,7 @@ impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> {
// First read the subsection length.
let mut data = self.data;
let length = data
.read::<endian::U32Bytes<Elf::Endian>>()
.read::<endian::U32<Elf::Endian>>()
.read_error("ELF attributes section is too short")?
.get(self.endian);
@@ -180,7 +180,7 @@ impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> {
.read::<u8>()
.read_error("ELF attributes subsection is too short")?;
let length = data
.read::<endian::U32Bytes<Elf::Endian>>()
.read::<endian::U32<Elf::Endian>>()
.read_error("ELF attributes subsection is too short")?
.get(self.endian);
+3 -3
View File
@@ -2,7 +2,7 @@ use core::fmt::Debug;
use core::{iter, slice, str};
use crate::elf;
use crate::endian::{Endianness, U32Bytes};
use crate::endian::{Endianness, U32};
use crate::read::{self, ComdatKind, ObjectComdat, ReadError, ReadRef, SectionIndex, SymbolIndex};
use super::{ElfFile, FileHeader, SectionHeader, Sym};
@@ -74,7 +74,7 @@ where
{
file: &'file ElfFile<'data, Elf, R>,
section: &'data Elf::SectionHeader,
sections: &'data [U32Bytes<Elf::Endian>],
sections: &'data [U32<Elf::Endian>],
}
impl<'data, 'file, Elf, R> ElfComdat<'data, 'file, Elf, R>
@@ -169,7 +169,7 @@ where
R: ReadRef<'data>,
{
file: &'file ElfFile<'data, Elf, R>,
sections: slice::Iter<'data, U32Bytes<Elf::Endian>>,
sections: slice::Iter<'data, U32<Elf::Endian>>,
}
impl<'data, 'file, Elf, R> Iterator for ElfComdatSectionIterator<'data, 'file, Elf, R>
+3 -3
View File
@@ -2,7 +2,7 @@ use core::fmt::Debug;
use core::{iter, slice, str};
use crate::elf;
use crate::endian::{self, Endianness, U32Bytes};
use crate::endian::{self, Endianness, U32};
use crate::pod::{self, Pod};
use crate::read::{
self, gnu_compression, CompressedData, CompressedFileRange, CompressionFormat, Error,
@@ -976,13 +976,13 @@ pub trait SectionHeader: Debug + Pod {
&self,
endian: Self::Endian,
data: R,
) -> read::Result<Option<(u32, &'data [U32Bytes<Self::Endian>])>> {
) -> read::Result<Option<(u32, &'data [U32<Self::Endian>])>> {
if self.sh_type(endian) != elf::SHT_GROUP {
return Ok(None);
}
let msg = "Invalid ELF group section offset or size";
let data = self.data(endian, data).read_error(msg)?;
let (flag, data) = pod::from_bytes::<U32Bytes<_>>(data).read_error(msg)?;
let (flag, data) = pod::from_bytes::<U32<_>>(data).read_error(msg)?;
let sections = pod::slice_from_all_bytes(data).read_error(msg)?;
Ok(Some((flag.get(endian), sections)))
}
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::read::{self, Error, ReadError as _};
use crate::{endian, CompressedFileRange, CompressionFormat, ReadRef, U32Bytes};
use crate::{endian, CompressedFileRange, CompressionFormat, ReadRef, U32};
// Attempt to parse the the CompressedFileRange for a section using the GNU-style
// inline compression header format. This is used by the Go compiler in Mach-O files
@@ -20,7 +20,7 @@ pub(super) fn compressed_file_range<'data, R: ReadRef<'data>>(
return Err(Error("Invalid GNU compressed section header"));
}
let uncompressed_size = file_data
.read::<U32Bytes<_>>(&mut offset)
.read::<U32<_>>(&mut offset)
.read_error("GNU compressed section is too short")?
.get(endian::BigEndian)
.into();
+2 -2
View File
@@ -532,13 +532,13 @@ where
if let Some(pc_bytes) = thread_data.get(pc_offset..pc_offset + 8) {
let mut bytes = [0u8; 8];
bytes.copy_from_slice(pc_bytes);
return self.endian.read_u64_bytes(bytes);
return self.endian.read_u64(bytes);
}
} else if pc_size == 4 {
if let Some(pc_bytes) = thread_data.get(pc_offset..pc_offset + 4) {
let mut bytes = [0u8; 4];
bytes.copy_from_slice(pc_bytes);
return u64::from(self.endian.read_u32_bytes(bytes));
return u64::from(self.endian.read_u32(bytes));
}
}
}
+10 -10
View File
@@ -1,7 +1,7 @@
use alloc::vec::Vec;
use core::fmt::Debug;
use crate::endian::{LittleEndian as LE, U16Bytes, U32Bytes};
use crate::endian::{LittleEndian as LE, U16, U32};
use crate::pe;
use crate::read::{ByteString, Bytes, Error, ReadError, ReadRef, Result};
@@ -88,9 +88,9 @@ pub struct ExportTable<'data> {
data: Bytes<'data>,
virtual_address: u32,
directory: &'data pe::ImageExportDirectory,
addresses: &'data [U32Bytes<LE>],
names: &'data [U32Bytes<LE>],
name_ordinals: &'data [U16Bytes<LE>],
addresses: &'data [U32<LE>],
names: &'data [U32<LE>],
name_ordinals: &'data [U16<LE>],
}
impl<'data> ExportTable<'data> {
@@ -103,7 +103,7 @@ impl<'data> ExportTable<'data> {
let address_of_functions = directory.address_of_functions.get(LE);
if address_of_functions != 0 {
addresses = data
.read_slice_at::<U32Bytes<_>>(
.read_slice_at::<U32<_>>(
address_of_functions.wrapping_sub(virtual_address) as usize,
directory.number_of_functions.get(LE) as usize,
)
@@ -121,13 +121,13 @@ impl<'data> ExportTable<'data> {
let number = directory.number_of_names.get(LE) as usize;
names = data
.read_slice_at::<U32Bytes<_>>(
.read_slice_at::<U32<_>>(
address_of_names.wrapping_sub(virtual_address) as usize,
number,
)
.read_error("Invalid PE export name pointer table")?;
name_ordinals = data
.read_slice_at::<U16Bytes<_>>(
.read_slice_at::<U16<_>>(
address_of_name_ordinals.wrapping_sub(virtual_address) as usize,
number,
)
@@ -166,14 +166,14 @@ impl<'data> ExportTable<'data> {
///
/// An address table entry may be a local address, or the address of a forwarded export entry.
/// See [`Self::is_forward`] and [`Self::target_from_address`].
pub fn addresses(&self) -> &'data [U32Bytes<LE>] {
pub fn addresses(&self) -> &'data [U32<LE>] {
self.addresses
}
/// Returns the unparsed name pointer table.
///
/// A name pointer table entry can be used with [`Self::name_from_pointer`].
pub fn name_pointers(&self) -> &'data [U32Bytes<LE>] {
pub fn name_pointers(&self) -> &'data [U32<LE>] {
self.names
}
@@ -181,7 +181,7 @@ impl<'data> ExportTable<'data> {
///
/// An ordinal table entry is a 0-based index into the address table.
/// See [`Self::address_by_index`] and [`Self::target_by_index`].
pub fn name_ordinals(&self) -> &'data [U16Bytes<LE>] {
pub fn name_ordinals(&self) -> &'data [U16<LE>] {
self.name_ordinals
}
+3 -3
View File
@@ -1,7 +1,7 @@
use core::fmt::Debug;
use core::mem;
use crate::endian::{LittleEndian as LE, U16Bytes};
use crate::endian::{LittleEndian as LE, U16};
use crate::pe;
use crate::pod::Pod;
use crate::read::{Bytes, ReadError, Result};
@@ -87,7 +87,7 @@ impl<'data> ImportTable<'data> {
data.skip(offset as usize)
.read_error("Invalid PE import thunk address")?;
let hint = data
.read::<U16Bytes<LE>>()
.read::<U16<LE>>()
.read_error("Missing PE import thunk hint")?
.get(LE);
let name = data
@@ -326,7 +326,7 @@ impl<'data> DelayLoadImportTable<'data> {
data.skip(offset as usize)
.read_error("Invalid PE delay load import thunk address")?;
let hint = data
.read::<U16Bytes<LE>>()
.read::<U16<LE>>()
.read_error("Missing PE delay load import thunk hint")?
.get(LE);
let name = data
+4 -7
View File
@@ -1,7 +1,7 @@
use alloc::string::String;
use core::char;
use crate::endian::{LittleEndian as LE, U16Bytes};
use crate::endian::{LittleEndian as LE, U16};
use crate::pe;
use crate::read::{ReadError, ReadRef, Result};
@@ -155,18 +155,15 @@ impl ResourceName {
}
/// Returns the string unicode buffer.
pub fn data<'data>(
&self,
directory: ResourceDirectory<'data>,
) -> Result<&'data [U16Bytes<LE>]> {
pub fn data<'data>(&self, directory: ResourceDirectory<'data>) -> Result<&'data [U16<LE>]> {
let mut offset = u64::from(self.offset);
let len = directory
.data
.read::<U16Bytes<LE>>(&mut offset)
.read::<U16<LE>>(&mut offset)
.read_error("Invalid resource name offset")?;
directory
.data
.read_slice::<U16Bytes<LE>>(&mut offset, len.get(LE).into())
.read_slice::<U16<LE>>(&mut offset, len.get(LE).into())
.read_error("Invalid resource name length")
}
+2 -1
View File
@@ -80,7 +80,8 @@ pub trait ReadRef<'a>: Clone + Copy {
/// `read_bytes` does not return bytes with the correct alignment for `T`.
/// Implementors may want to provide their own implementation that ensures
/// the alignment can be satisfied. Alternatively, only use this method with
/// types that do not need alignment (see the `unaligned` feature of this crate).
/// types that do not need alignment. The types provided by this crate do not
/// need alignment.
fn read<T: Pod>(self, offset: &mut u64) -> Result<&'a T> {
let size = mem::size_of::<T>().try_into().map_err(|_| ())?;
let bytes = self.read_bytes(offset, size)?;
+2 -2
View File
@@ -4,7 +4,7 @@ use core::fmt::Debug;
use core::marker::PhantomData;
use core::str;
use crate::endian::{BigEndian as BE, U32Bytes};
use crate::endian::{BigEndian as BE, U32};
use crate::pod::{bytes_of, Pod};
use crate::read::{
self, Bytes, Error, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Result, SectionIndex,
@@ -60,7 +60,7 @@ where
// Parse the string table.
// Note: don't update data when reading length; the length includes itself.
let length = data
.read_at::<U32Bytes<_>>(offset)
.read_at::<U32<_>>(offset)
.read_error("Missing XCOFF string table")?
.get(BE);
let str_end = offset
+1 -1
View File
@@ -1177,7 +1177,7 @@ impl<E: Endian> MachO for MachO64<E> {
n_type: nlist.n_type,
n_sect: nlist.n_sect,
n_desc: U16::new(endian, nlist.n_desc),
n_value: U64Bytes::new(endian, nlist.n_value),
n_value: U64::new(endian, nlist.n_value),
};
buffer.write(&nlist);
}

Some files were not shown because too many files have changed in this diff Show More