dyld: keep EXIDX section data through program header entry

This commit is contained in:
Astro 2020-06-24 00:18:34 +02:00
parent 64cdf0ade3
commit 571ab66114
2 changed files with 22 additions and 10 deletions

View File

@ -255,6 +255,7 @@ pub const PT_SUNWSTACK: u32 = 1879048187;
pub const PT_HISUNW: u32 = 1879048191; pub const PT_HISUNW: u32 = 1879048191;
pub const PT_HIOS: u32 = 1879048191; pub const PT_HIOS: u32 = 1879048191;
pub const PT_LOPROC: u32 = 1879048192; pub const PT_LOPROC: u32 = 1879048192;
pub const PT_ARM_EXIDX: u32 = 1879048193;
pub const PT_HIPROC: u32 = 2147483647; pub const PT_HIPROC: u32 = 2147483647;
pub const PF_X: usize = 1; pub const PF_X: usize = 1;
pub const PF_W: usize = 2; pub const PF_W: usize = 2;
@ -1334,7 +1335,6 @@ pub const SHF_ARM_COMDEF: usize = 2147483648;
pub const PF_ARM_SB: usize = 268435456; pub const PF_ARM_SB: usize = 268435456;
pub const PF_ARM_PI: usize = 536870912; pub const PF_ARM_PI: usize = 536870912;
pub const PF_ARM_ABS: usize = 1073741824; pub const PF_ARM_ABS: usize = 1073741824;
pub const PT_ARM_EXIDX: usize = 1879048193;
pub const SHT_ARM_EXIDX: usize = 1879048193; pub const SHT_ARM_EXIDX: usize = 1879048193;
pub const SHT_ARM_PREEMPTMAP: usize = 1879048194; pub const SHT_ARM_PREEMPTMAP: usize = 1879048194;
pub const SHT_ARM_ATTRIBUTES: usize = 1879048195; pub const SHT_ARM_ATTRIBUTES: usize = 1879048195;

View File

@ -4,7 +4,7 @@ extern crate alloc;
extern crate log; extern crate log;
use core::{fmt, str, convert}; use core::{fmt, str, convert};
use alloc::string::String; use alloc::{borrow::ToOwned, string::String, vec::Vec};
use log::{debug, trace}; use log::{debug, trace};
use elf::*; use elf::*;
@ -60,6 +60,7 @@ fn elf_hash(name: &[u8]) -> u32 {
pub struct Library { pub struct Library {
pub image: Image, pub image: Image,
dyn_section: DynamicSection, dyn_section: DynamicSection,
pub exidx: Vec<u8>,
} }
impl Library { impl Library {
@ -164,22 +165,32 @@ pub fn load(
.map_err(|_| "cannot allocate target image")?; .map_err(|_| "cannot allocate target image")?;
debug!("ELF target: {} bytes, align to {:X}, allocated at {:08X}", image_size, image_align, image.ptr() as usize); debug!("ELF target: {} bytes, align to {:X}, allocated at {:08X}", image_size, image_align, image.ptr() as usize);
let mut exidx = None;
// LOAD // LOAD
for phdr in file.program_headers() { for phdr in file.program_headers() {
let phdr = phdr.ok_or("cannot read program header")?; let phdr = phdr.ok_or("cannot read program header")?;
if phdr.p_type != PT_LOAD { continue; }
trace!("Program header: {:08X}+{:08X} to {:08X}", trace!("Program header: {:08X}+{:08X} to {:08X}",
phdr.p_offset, phdr.p_filesz, phdr.p_offset, phdr.p_filesz,
image.ptr() as u32 image.ptr() as u32
); );
let src = file.get(phdr.p_offset as usize..(phdr.p_offset + phdr.p_filesz) as usize) let file_range = phdr.p_offset as usize..(phdr.p_offset + phdr.p_filesz) as usize;
match phdr.p_type {
PT_LOAD => {
let src = file.get(file_range)
.ok_or("program header requests an out of bounds load (in file)")?; .ok_or("program header requests an out of bounds load (in file)")?;
let dst = image.get_mut(phdr.p_vaddr as usize.. let dst = image.get_mut(phdr.p_vaddr as usize..
(phdr.p_vaddr + phdr.p_filesz) as usize) (phdr.p_vaddr + phdr.p_filesz) as usize)
.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 src = file.get(file_range)
.ok_or("program header requests an out of bounds load (in file)")?;
exidx = Some(src.to_owned());
}
_ => {}
}
}
// relocate DYNAMIC // relocate DYNAMIC
let dyn_range = file.dyn_header_vaddr() let dyn_range = file.dyn_header_vaddr()
@ -190,6 +201,7 @@ pub fn load(
let lib = Library { let lib = Library {
image, image,
dyn_section, dyn_section,
exidx: exidx.ok_or("missing EXIDX program header")?,
}; };
for rela in lib.rela() { for rela in lib.rela() {