From b388b529ada7897da9c7ea095918e5207cf23e6c Mon Sep 17 00:00:00 2001 From: Astro Date: Mon, 27 Jul 2020 19:54:53 +0200 Subject: [PATCH] dyld: remove KERNEL_EXIDX_START/END globals, move dl_unwind_find_exidx() into runtime::kernel::core1 Gitea issue #16 --- src/libdyld/src/lib.rs | 57 ++++++++------------------------- src/runtime/src/kernel/core1.rs | 36 +++++++++++++++++++++ src/runtime/src/main.rs | 1 + 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/src/libdyld/src/lib.rs b/src/libdyld/src/lib.rs index 4285849b..5b11b8ca 100644 --- a/src/libdyld/src/lib.rs +++ b/src/libdyld/src/lib.rs @@ -4,7 +4,7 @@ extern crate alloc; extern crate log; extern crate libcortex_a9; -use core::{convert, fmt, str}; +use core::{convert, fmt, ops::Range, str}; use alloc::string::String; use log::{debug, trace}; use elf::*; @@ -58,44 +58,11 @@ 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::() as u32; - start = KERNEL_EXIDX_START; - } - *len_ptr = length; - } - start -} - pub struct Library { pub image: Image, pub arch: Arch, dyn_section: DynamicSection, + exidx: Range, } impl Library { @@ -170,6 +137,10 @@ impl Library { pub fn rebind(&self, name: &[u8], addr: *const ()) -> Result<(), Error> { reloc::rebind(self.arch, self, name, addr as Elf32_Word) } + + pub fn exidx(&self) -> &[u32] { + self.image.get_ref_slice_unchecked(&self.exidx) + } } pub fn load( @@ -226,18 +197,17 @@ pub fn load( } } + let mut exidx = None; // 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 { - KERNEL_EXIDX_START = slice.as_ptr() as u32; - KERNEL_EXIDX_END = slice.as_ptr().add(slice.len()) as u32; - } + let range = shdr.sh_addr as usize.. + (shdr.sh_addr + shdr.sh_size) as usize; + let _ = image.get(range.clone()) + .ok_or("section header specifies EXIDX outside of image (in target)")?; + exidx = Some(range); } _ => {} } @@ -252,7 +222,8 @@ pub fn load( let lib = Library { arch, image, - dyn_section + dyn_section, + exidx: exidx.ok_or("no EXIDX section")?, }; for rela in lib.rela() { diff --git a/src/runtime/src/kernel/core1.rs b/src/runtime/src/kernel/core1.rs index b5c619c4..50e81943 100644 --- a/src/runtime/src/kernel/core1.rs +++ b/src/runtime/src/kernel/core1.rs @@ -22,6 +22,18 @@ use super::{ cache }; +// 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; +} + unsafe fn attribute_writeback(typeinfo: *const ()) { struct Attr { offset: usize, @@ -205,3 +217,27 @@ pub fn terminate(exception: &'static eh_artiq::Exception<'static>, backtrace: &' error!("Core1 uncaught exception"); loop {} } + +/// Called by llvm_libunwind +#[no_mangle] +extern fn dl_unwind_find_exidx(pc: *const u32, len_ptr: *mut u32) -> *const u32 { + let exidx = unsafe { + KERNEL_IMAGE.as_ref() + .expect("dl_unwind_find_exidx kernel image") + .library.get().as_ref().unwrap().exidx() + }; + + let length; + let start: *const u32; + unsafe { + if &__text_start as *const u32 <= pc && pc < &__text_end as *const u32 { + length = (&__exidx_end as *const u32).offset_from(&__exidx_start) as u32; + start = &__exidx_start; + } else { + length = exidx.len() as u32; + start = exidx.as_ptr(); + } + *len_ptr = length; + } + start +} diff --git a/src/runtime/src/main.rs b/src/runtime/src/main.rs index c82381eb..7d12fba3 100644 --- a/src/runtime/src/main.rs +++ b/src/runtime/src/main.rs @@ -5,6 +5,7 @@ #![feature(panic_info_message)] #![feature(c_variadic)] #![feature(const_btree_new)] +#![feature(ptr_offset_from)] extern crate alloc;