dyld: obtain EXIDX offsets from section headers

Gitea issue #16
This commit is contained in:
Astro 2020-07-27 01:58:42 +02:00
parent 7f983a453d
commit 641204425e
2 changed files with 22 additions and 6 deletions

View File

@ -56,6 +56,14 @@ impl<'a> File<'a> {
}) })
} }
pub fn section_headers<'b>(&'b self) -> impl Iterator<Item = Option<Elf32_Shdr>> + 'b
{
(0..self.ehdr.e_shnum).map(move |i| {
let shdr_off = self.ehdr.e_shoff as usize + mem::size_of::<Elf32_Shdr>() * i as usize;
self.read_unaligned::<Elf32_Shdr>(shdr_off)
})
}
pub fn dyn_header_vaddr(&self) -> Option<Range<usize>> { pub fn dyn_header_vaddr(&self) -> Option<Range<usize>> {
self.program_headers() self.program_headers()
.filter_map(|phdr| phdr) .filter_map(|phdr| phdr)

View File

@ -222,13 +222,21 @@ pub fn load(
.ok_or("program header requests an out of bounds load (in target)")?; .ok_or("program header requests an out of bounds load (in target)")?;
dst.copy_from_slice(src); dst.copy_from_slice(src);
} }
PT_ARM_EXIDX => { _ => {}
let range = image.get(phdr.p_vaddr as usize.. }
(phdr.p_vaddr + phdr.p_filesz) as usize) }
.ok_or("program header requests and out of bounds load (in target)")?;
// Obtain EXIDX
for shdr in file.section_headers() {
let shdr = shdr.ok_or("cannot read section header")?;
match shdr.sh_type as usize {
SHT_ARM_EXIDX => {
let slice = image.get(shdr.sh_addr as usize..
(shdr.sh_addr + shdr.sh_size) as usize)
.ok_or("section header requests an out of bounds load (in target)")?;
unsafe { unsafe {
KERNEL_EXIDX_START = range.as_ptr() as u32; KERNEL_EXIDX_START = slice.as_ptr() as u32;
KERNEL_EXIDX_END = range.as_ptr().add(range.len()) as u32; KERNEL_EXIDX_END = slice.as_ptr().add(slice.len()) as u32;
} }
} }
_ => {} _ => {}