From fd555a6e0ff660ceec77b8382a0ee3ac8f01959d Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 18 Aug 2024 21:57:25 -0600 Subject: [PATCH] Fix reading little-endian `.line` section --- objdiff-core/src/obj/read.rs | 12 ++++++------ objdiff-core/src/util.rs | 16 +++++++++++++++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index 6ff9f93..bc1e550 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -1,7 +1,6 @@ use std::{collections::HashSet, fs, io::Cursor, path::Path}; use anyhow::{anyhow, bail, ensure, Context, Result}; -use byteorder::{BigEndian, ReadBytesExt}; use cwextab::decode_extab; use filetime::FileTime; use flagset::Flags; @@ -18,6 +17,7 @@ use crate::{ ObjExtab, ObjInfo, ObjReloc, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, }, + util::{read_u16, read_u32}, }; fn to_obj_section_kind(kind: SectionKind) -> Option { @@ -415,8 +415,8 @@ fn line_info(obj_file: &File<'_>, sections: &mut [ObjSection]) -> Result<()> { .index() .0; let start = reader.position(); - let size = reader.read_u32::()?; - let base_address = reader.read_u32::()? as u64; + let size = read_u32(obj_file, &mut reader)?; + let base_address = read_u32(obj_file, &mut reader)? as u64; let Some(out_section) = sections.iter_mut().find(|s| s.orig_index == text_section_index) else { @@ -426,12 +426,12 @@ fn line_info(obj_file: &File<'_>, sections: &mut [ObjSection]) -> Result<()> { }; let end = start + size as u64; while reader.position() < end { - let line_number = reader.read_u32::()? as u64; - let statement_pos = reader.read_u16::()?; + let line_number = read_u32(obj_file, &mut reader)? as u64; + let statement_pos = read_u16(obj_file, &mut reader)?; if statement_pos != 0xFFFF { log::warn!("Unhandled statement pos {}", statement_pos); } - let address_delta = reader.read_u32::()? as u64; + let address_delta = read_u32(obj_file, &mut reader)? as u64; out_section.line_info.insert(base_address + address_delta, line_number); log::debug!("Line: {:#x} -> {}", base_address + address_delta, line_number); } diff --git a/objdiff-core/src/util.rs b/objdiff-core/src/util.rs index 16e86d9..5f99e94 100644 --- a/objdiff-core/src/util.rs +++ b/objdiff-core/src/util.rs @@ -1,6 +1,12 @@ -use std::fmt::{LowerHex, UpperHex}; +use std::{ + fmt::{LowerHex, UpperHex}, + io::Read, +}; +use anyhow::Result; +use byteorder::{NativeEndian, ReadBytesExt}; use num_traits::PrimInt; +use object::{Endian, Object}; // https://stackoverflow.com/questions/44711012/how-do-i-format-a-signed-integer-to-a-sign-aware-hexadecimal-representation pub(crate) struct ReallySigned(pub(crate) N); @@ -22,3 +28,11 @@ impl UpperHex for ReallySigned { f.pad_integral(num >= 0, prefix, &bare_hex) } } + +pub fn read_u32(obj_file: &object::File, reader: &mut R) -> Result { + Ok(obj_file.endianness().read_u32(reader.read_u32::()?)) +} + +pub fn read_u16(obj_file: &object::File, reader: &mut R) -> Result { + Ok(obj_file.endianness().read_u16(reader.read_u16::()?)) +}