Dyld: provides unwind section for libunwind
This commit is contained in:
parent
d915211264
commit
9282dcffdb
@ -57,10 +57,43 @@ fn elf_hash(name: &[u8]) -> u32 {
|
||||
h
|
||||
}
|
||||
|
||||
// linker symbols
|
||||
extern "C" {
|
||||
#[no_mangle]
|
||||
static __text_start: u32;
|
||||
#[no_mangle]
|
||||
static __text_end: u32;
|
||||
#[no_mangle]
|
||||
static __exidx_start: u32;
|
||||
#[no_mangle]
|
||||
static __exidx_end: u32;
|
||||
}
|
||||
|
||||
static mut KERNEL_EXIDX_START: u32 = 0;
|
||||
static mut KERNEL_EXIDX_END: u32 = 0;
|
||||
|
||||
#[no_mangle]
|
||||
extern fn dl_unwind_find_exidx(pc: u32, len_ptr: *mut u32) -> u32 {
|
||||
let length: u32;
|
||||
let start: u32;
|
||||
unsafe {
|
||||
if (&__text_start as *const u32 as u32) <= pc && pc < (&__text_end as *const u32 as u32) {
|
||||
length = (&__exidx_end - &__exidx_start) as u32;
|
||||
start = &__exidx_start as *const u32 as u32;
|
||||
} else {
|
||||
// make sure that the kernel is loaded
|
||||
assert_ne!(KERNEL_EXIDX_START, 0);
|
||||
length = (KERNEL_EXIDX_END - KERNEL_EXIDX_START) / core::mem::size_of::<u32>() as u32;
|
||||
start = KERNEL_EXIDX_START;
|
||||
}
|
||||
*len_ptr = length;
|
||||
}
|
||||
start
|
||||
}
|
||||
|
||||
pub struct Library {
|
||||
pub image: Image,
|
||||
dyn_section: DynamicSection,
|
||||
exidx: Range<usize>,
|
||||
}
|
||||
|
||||
impl Library {
|
||||
@ -130,10 +163,6 @@ impl Library {
|
||||
Ok(self.strtab().get(offset..offset + size)
|
||||
.ok_or("cannot read symbol name")?)
|
||||
}
|
||||
|
||||
pub fn exidx(&self) -> &[usize] {
|
||||
self.image.get_ref_slice_unchecked(&self.exidx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load(
|
||||
@ -169,7 +198,6 @@ pub fn load(
|
||||
.map_err(|_| "cannot allocate target image")?;
|
||||
debug!("ELF target: {} bytes, align to {:X}, allocated at {:08X}", image_size, image_align, image.ptr() as usize);
|
||||
|
||||
let mut exidx = None;
|
||||
// LOAD
|
||||
for phdr in file.program_headers() {
|
||||
let phdr = phdr.ok_or("cannot read program header")?;
|
||||
@ -188,8 +216,13 @@ pub fn load(
|
||||
dst.copy_from_slice(src);
|
||||
}
|
||||
PT_ARM_EXIDX => {
|
||||
exidx = Some(phdr.p_vaddr as usize..
|
||||
(phdr.p_vaddr + phdr.p_filesz) as usize);
|
||||
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)")?;
|
||||
unsafe {
|
||||
KERNEL_EXIDX_START = range.as_ptr() as u32;
|
||||
KERNEL_EXIDX_END = range.as_ptr().add(range.len()) as u32;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -203,8 +236,7 @@ pub fn load(
|
||||
dyn_section.rela.len(), dyn_section.rel.len(), dyn_section.pltrel.len());
|
||||
let lib = Library {
|
||||
image,
|
||||
dyn_section,
|
||||
exidx: exidx.ok_or("missing EXIDX program header")?,
|
||||
dyn_section
|
||||
};
|
||||
|
||||
for rela in lib.rela() {
|
||||
|
@ -17,12 +17,26 @@ MEMORY
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
__text_start = .;
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.text.exceptions));
|
||||
*(.text.boot);
|
||||
*(.text .text.*);
|
||||
} > SDRAM
|
||||
__text_end = .;
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > SDRAM
|
||||
__exidx_end = .;
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
* (.ARM.extab*)
|
||||
} > SDRAM
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
@ -62,12 +76,4 @@ SECTIONS
|
||||
. += 0x10000;
|
||||
__stack0_start = .;
|
||||
} > SDRAM
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
/* Unused exception related info that only wastes space */
|
||||
*(.ARM.exidx);
|
||||
*(.ARM.exidx.*);
|
||||
*(.ARM.extab.*);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user