Skip to content
Snippets Groups Projects
Commit 369d7b42 authored by Ahmed Abd El Mawgood's avatar Ahmed Abd El Mawgood
Browse files

Initial implementation of SVR4 debugging interface for runtime linker

parent cdbbd4a4
No related branches found
No related tags found
No related merge requests found
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;
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment