Initial implementation of SVR4 debugging interface for runtime linker
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
use crate::{c_str::CString, platform::types::*};
|
||||
use alloc::boxed::Box;
|
||||
|
||||
#[repr(C)]
|
||||
pub enum RTLDState {
|
||||
/// Mapping change is complete.
|
||||
RT_CONSISTENT,
|
||||
/// Beginning to add a new object.
|
||||
RT_ADD,
|
||||
/// Beginning to remove an object mapping.
|
||||
RT_DELETE,
|
||||
}
|
||||
|
||||
/// Data structure for sharing debugging information from the
|
||||
/// run-time dynamic linker for loaded ELF shared objects.
|
||||
#[repr(C)]
|
||||
pub struct RTLDDebug {
|
||||
/// Version number for this protocol.
|
||||
r_version: i32,
|
||||
/// Head of the chain of loaded objects.
|
||||
r_map: *mut LinkMap,
|
||||
//struct link_map *r_map;
|
||||
/// This is the address of a function internal to the run-time linker,
|
||||
/// that will always be called when the linker begins to map in a
|
||||
/// library or unmap it, and again when the mapping change is complete.
|
||||
/// The debugger can set a breakpoint at this address if it wants to
|
||||
/// notice shared object mapping changes.
|
||||
pub r_brk: extern "C" fn(),
|
||||
|
||||
/// This state value describes the mapping change taking place when
|
||||
/// the `r_brk' address is called.
|
||||
pub state: RTLDState,
|
||||
|
||||
/// Base address the linker is loaded at.
|
||||
pub r_ldbase: usize,
|
||||
}
|
||||
|
||||
impl RTLDDebug {
|
||||
const NEW: Self = RTLDDebug {
|
||||
r_version: 1,
|
||||
r_map: 0 as *mut LinkMap,
|
||||
r_brk: _dl_debug_state,
|
||||
state: RTLDState::RT_CONSISTENT,
|
||||
r_ldbase: 0,
|
||||
};
|
||||
|
||||
pub fn insert(&mut self, l_addr: usize, name: &str, l_ld: usize) {
|
||||
if self.r_map.is_null() {
|
||||
self.r_map = LinkMap::new_with_args(l_addr, name, l_ld);
|
||||
} else {
|
||||
unsafe { (*self.r_map).add_object(l_addr, name, l_ld) };
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct LinkMap {
|
||||
/* These members are part of the protocol with the debugger.
|
||||
This is the same format used in SVR4. */
|
||||
/// Difference between the address in the ELF
|
||||
/// file and the addresses in memory.
|
||||
l_addr: usize,
|
||||
/// Absolute file name object was found in.
|
||||
l_name: *const c_char,
|
||||
/// Dynamic section of the shared object.
|
||||
l_ld: usize,
|
||||
l_next: *mut LinkMap,
|
||||
l_prev: *mut LinkMap,
|
||||
}
|
||||
|
||||
impl LinkMap {
|
||||
fn new() -> *mut Self {
|
||||
let map = Box::new(LinkMap {
|
||||
l_addr: 0,
|
||||
l_name: 0 as *const c_char,
|
||||
l_ld: 0,
|
||||
l_next: 0 as *mut LinkMap,
|
||||
l_prev: 0 as *mut LinkMap,
|
||||
});
|
||||
Box::into_raw(map)
|
||||
}
|
||||
|
||||
fn new_with_args(l_addr: usize, name: &str, l_ld: usize) -> *mut Self {
|
||||
let map = LinkMap::new();
|
||||
unsafe {
|
||||
(*map).l_addr = l_addr;
|
||||
(*map).l_ld = l_ld;
|
||||
let c_name = CString::new(name).unwrap();
|
||||
(*map).l_name = c_name.into_raw() as *const c_char;
|
||||
}
|
||||
map
|
||||
}
|
||||
|
||||
fn add_object(&mut self, l_addr: usize, name: &str, l_ld: usize) {
|
||||
let node = LinkMap::new_with_args(l_addr, name, l_ld);
|
||||
let mut last = self;
|
||||
while !last.l_next.is_null() {
|
||||
last = unsafe { last.l_next.as_mut() }.unwrap();
|
||||
}
|
||||
unsafe {
|
||||
(*node).l_prev = last;
|
||||
(*last).l_next = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Gdb may be looking for this fuction with that exact name and set
|
||||
* break point there
|
||||
*/
|
||||
#[linkage = "weak"]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _dl_debug_state() {}
|
||||
|
||||
#[no_mangle]
|
||||
pub static mut _r_debug: RTLDDebug = RTLDDebug::NEW;
|
||||
+1
-1
@@ -5,10 +5,10 @@ use crate::start::Stack;
|
||||
|
||||
pub const PAGE_SIZE: usize = 4096;
|
||||
|
||||
pub mod debug;
|
||||
pub mod linker;
|
||||
pub mod start;
|
||||
pub mod tcb;
|
||||
|
||||
pub fn static_init(sp: &'static Stack) {
|
||||
let mut phdr_opt = None;
|
||||
let mut phent_opt = None;
|
||||
|
||||
Reference in New Issue
Block a user