Skip to content

Commit

Permalink
Fix reading little-endian .line section
Browse files Browse the repository at this point in the history
  • Loading branch information
encounter committed Aug 19, 2024
1 parent 3710b6a commit fd555a6
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
12 changes: 6 additions & 6 deletions objdiff-core/src/obj/read.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<ObjSectionKind> {
Expand Down Expand Up @@ -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::<BigEndian>()?;
let base_address = reader.read_u32::<BigEndian>()? 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 {
Expand All @@ -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::<BigEndian>()? as u64;
let statement_pos = reader.read_u16::<BigEndian>()?;
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::<BigEndian>()? 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);
}
Expand Down
16 changes: 15 additions & 1 deletion objdiff-core/src/util.rs
Original file line number Diff line number Diff line change
@@ -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<N: PrimInt>(pub(crate) N);
Expand All @@ -22,3 +28,11 @@ impl<N: PrimInt> UpperHex for ReallySigned<N> {
f.pad_integral(num >= 0, prefix, &bare_hex)
}
}

pub fn read_u32<R: Read>(obj_file: &object::File, reader: &mut R) -> Result<u32> {
Ok(obj_file.endianness().read_u32(reader.read_u32::<NativeEndian>()?))
}

pub fn read_u16<R: Read>(obj_file: &object::File, reader: &mut R) -> Result<u16> {
Ok(obj_file.endianness().read_u16(reader.read_u16::<NativeEndian>()?))
}

0 comments on commit fd555a6

Please sign in to comment.