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
|
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 struct Library {
|
||||||
pub image: Image,
|
pub image: Image,
|
||||||
dyn_section: DynamicSection,
|
dyn_section: DynamicSection,
|
||||||
exidx: Range<usize>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Library {
|
impl Library {
|
||||||
@ -130,10 +163,6 @@ impl Library {
|
|||||||
Ok(self.strtab().get(offset..offset + size)
|
Ok(self.strtab().get(offset..offset + size)
|
||||||
.ok_or("cannot read symbol name")?)
|
.ok_or("cannot read symbol name")?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exidx(&self) -> &[usize] {
|
|
||||||
self.image.get_ref_slice_unchecked(&self.exidx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(
|
pub fn load(
|
||||||
@ -169,7 +198,6 @@ 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")?;
|
||||||
@ -188,8 +216,13 @@ pub fn load(
|
|||||||
dst.copy_from_slice(src);
|
dst.copy_from_slice(src);
|
||||||
}
|
}
|
||||||
PT_ARM_EXIDX => {
|
PT_ARM_EXIDX => {
|
||||||
exidx = Some(phdr.p_vaddr as usize..
|
let range = image.get(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 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());
|
dyn_section.rela.len(), dyn_section.rel.len(), dyn_section.pltrel.len());
|
||||||
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() {
|
||||||
|
@ -17,12 +17,26 @@ MEMORY
|
|||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
|
__text_start = .;
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
KEEP(*(.text.exceptions));
|
KEEP(*(.text.exceptions));
|
||||||
*(.text.boot);
|
*(.text.boot);
|
||||||
*(.text .text.*);
|
*(.text .text.*);
|
||||||
} > SDRAM
|
} > SDRAM
|
||||||
|
__text_end = .;
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > SDRAM
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
* (.ARM.extab*)
|
||||||
|
} > SDRAM
|
||||||
|
|
||||||
.rodata : ALIGN(4)
|
.rodata : ALIGN(4)
|
||||||
{
|
{
|
||||||
@ -62,12 +76,4 @@ SECTIONS
|
|||||||
. += 0x10000;
|
. += 0x10000;
|
||||||
__stack0_start = .;
|
__stack0_start = .;
|
||||||
} > SDRAM
|
} > SDRAM
|
||||||
|
|
||||||
/DISCARD/ :
|
|
||||||
{
|
|
||||||
/* Unused exception related info that only wastes space */
|
|
||||||
*(.ARM.exidx);
|
|
||||||
*(.ARM.exidx.*);
|
|
||||||
*(.ARM.extab.*);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user