Multiple things:
The initial sections, moved when we need to extend the program header table, could end up creating a last segment that was read-only, which is wrong.
The initial sections could be moved anywhere after o + l, where o was the last offset of a session and l was the length of that same session. However, the BSS section can overlap others, so the code is now robust to that, even though it may not change too much.
The position of the .gnu.hash section wasn't being updated in the .dynamic section.
Unfortunately this couldn't really be tested separately since it only appeared when patching libraries to find transitive "needed libs".
ZV57M4VN53TJFCOLDOP7I4M4VAEN667SA37LR2HFFKFN5G2MTWIAC
}
#[allow(dead_code)]
impl ABI {
const SYSTEM_V: Self = ABI(0);
const HPUX: Self = ABI(1);
const NET_BSD: Self = ABI(2);
const LINUX: Self = ABI(3);
const GNU_HURD: Self = ABI(4);
const SOLARIS: Self = ABI(6);
const AIX: Self = ABI(7);
const IRIX: Self = ABI(8);
const FREE_BSD: Self = ABI(9);
const TRU64: Self = ABI(10);
const NOVELL_MODESTO: Self = ABI(11);
const OPEN_BSD: Self = ABI(12);
const OPEN_VMS: Self = ABI(13);
const NON_STOP_KERNEL: Self = ABI(14);
const AROS: Self = ABI(15);
const FENIX_OS: Self = ABI(16);
const NUXI_CLOUD_ABI: Self = ABI(17);
const OPEN_VOS: Self = ABI(18);
Ok(Parsed {
data: id.data,
dynstr,
dynamic,
interp,
})
pub fn section_bytes(&self, name_: &[u8]) -> Result<Option<&[u8]>, Error> {
let id = self.id();
let header = self.header();
let names = self.names(id.data, &header);
for i in 0..header.shnum(id.data) {
let s = self.section(i as usize);
let name = names.name(s.name(id.data) as usize)?;
if name.to_bytes() == name_ {
let offset = s.offset(id.data) as usize;
let size = s.size(id.data) as usize;
return Ok(Some(&self.map[offset..offset + size]));
}
}
Ok(None)
let current_len = self.f.metadata().unwrap().len() as usize;
// Max between the length of the file and the max of
// the sections' span.
let current_len =
sections.iter().map(|(o, l, t, _)|
if *t != Sht::NOBITS {
o + l
} else {
0
})
.max()
.unwrap_or(
self.f.metadata().unwrap().len() as usize
);
/// If the "needed" and/or "runpath" fields in the .dynamic section
/// point to the end of the .dynstr section, we can optimise the
/// .dynstr section by removing them first, and then adding them.
///
/// Otherwise, we will (in other functions) leave these fields where
/// they are, add new ones at the end and ignore the previous values.