Skip to content

Commit

Permalink
Parses DT_INIT and DT_FINI (#274)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Jul 26, 2023
1 parent f8c7631 commit ea25816
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 99 deletions.
6 changes: 6 additions & 0 deletions src/elf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,12 @@ impl<I: Read + Seek> Elf<I> {
}
}

impl<I: Read + Seek> From<Elf<I>> for (String, Vec<Program>, Option<FileInfo>) {
fn from(v: Elf<I>) -> Self {
(v.name, v.programs, v.info)
}
}

/// Contains data specific for SELF.
struct SelfData {
segments: Vec<SelfSegment>,
Expand Down
13 changes: 6 additions & 7 deletions src/kernel/src/ee/llvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ impl<'a, 'b: 'a> LlvmEngine<'a, 'b> {

fn lift(&self, module: &Module<'b>) -> Result<crate::llvm::module::ExecutionEngine, LiftError> {
// Get a list of public functions.
let image = module.image();
let path: VPathBuf = image.name().try_into().unwrap();
let targets = match image.entry_addr() {
let path = module.path();
let targets = match module.entry() {
Some(v) => vec![v],
None => Vec::new(),
};
Expand All @@ -46,26 +45,26 @@ impl<'a, 'b: 'a> LlvmEngine<'a, 'b> {

for &addr in &targets {
if let Err(e) = disasm.disassemble(addr) {
return Err(LiftError::DisassembleFailed(path, addr, e));
return Err(LiftError::DisassembleFailed(path.to_owned(), addr, e));
}
}

disasm.fixup();

// Lift the public functions.
let mut lifting = self.llvm.create_module(image.name());
let mut lifting = self.llvm.create_module(path.as_ref());
let mut codegen = Codegen::new(&disasm, &mut lifting);

for &addr in &targets {
if let Err(e) = codegen.lift(addr) {
return Err(LiftError::LiftingFailed(path, addr, e));
return Err(LiftError::LiftingFailed(path.to_owned(), addr, e));
}
}

// Create LLVM execution engine.
let lifted = match lifting.create_execution_engine() {
Ok(v) => v,
Err(e) => return Err(LiftError::CreateExecutionEngineFailed(path, e)),
Err(e) => return Err(LiftError::CreateExecutionEngineFailed(path.to_owned(), e)),
};

Ok(lifted)
Expand Down
14 changes: 7 additions & 7 deletions src/kernel/src/ee/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ impl<'a, 'b: 'a> NativeEngine<'a, 'b> {

for module in ld.list() {
let count = self.patch_mod(module)?;
let path: VPathBuf = module.image().name().try_into().unwrap();
let path = module.path();

counts.push((path, count));
counts.push((path.to_owned(), count));
}

Ok(counts)
Expand All @@ -48,7 +48,7 @@ impl<'a, 'b: 'a> NativeEngine<'a, 'b> {
/// # Safety
/// No other threads may access the memory of `module`.
unsafe fn patch_mod(&self, module: &Module) -> Result<usize, PatchModsError> {
let path: VPathBuf = module.image().name().try_into().unwrap();
let path = module.path();

// Patch all executable sections.
let mem = module.memory();
Expand All @@ -63,11 +63,11 @@ impl<'a, 'b: 'a> NativeEngine<'a, 'b> {
// Unprotect the segment.
let mut seg = match mem.unprotect_segment(i) {
Ok(v) => v,
Err(e) => return Err(PatchModsError::UnprotectMemoryFailed(path, e)),
Err(e) => return Err(PatchModsError::UnprotectMemoryFailed(path.to_owned(), e)),
};

// Patch segment.
count += self.patch_segment(&path, base, mem, seg.as_mut())?;
count += self.patch_segment(path, base, mem, seg.as_mut())?;
}

Ok(count)
Expand Down Expand Up @@ -444,8 +444,8 @@ impl<'a, 'b> ExecutionEngine for NativeEngine<'a, 'b> {
let ld = self.rtld.read().unwrap();
let eboot = ld.app();

if eboot.image().dynamic().is_none() {
todo!("A statically linked eboot.bin is not supported yet.");
if eboot.file_info().is_none() {
todo!("a statically linked eboot.bin is not supported yet");
}

// Get boot module.
Expand Down
6 changes: 6 additions & 0 deletions src/kernel/src/fs/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ impl VPath {
}
}

impl AsRef<str> for VPath {
fn as_ref(&self) -> &str {
&self.0
}
}

impl From<&VPath> for String {
fn from(value: &VPath) -> Self {
String::from(&value.0)
Expand Down
60 changes: 36 additions & 24 deletions src/kernel/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ fn main() -> ExitCode {
// Print application module.
let mut log = info!();

writeln!(log, "Application : {}", ld.app().image().name()).unwrap();
writeln!(log, "Application : {}", ld.app().path()).unwrap();
print_module(&mut log, ld.app());

print(log);
Expand Down Expand Up @@ -308,18 +308,16 @@ fn exec<E: ee::ExecutionEngine>(mut ee: E) -> ExitCode {
}

fn print_module(log: &mut LogEntry, module: &Module) {
// Image details.
let image = module.image();

if image.self_segments().is_some() {
// Image info.
if module.is_self() {
writeln!(log, "Image format : SELF").unwrap();
} else {
writeln!(log, "Image format : ELF").unwrap();
}

writeln!(log, "Image type : {}", image.ty()).unwrap();
writeln!(log, "Image type : {}", module.file_type()).unwrap();

for (i, p) in image.programs().iter().enumerate() {
for (i, p) in module.programs().iter().enumerate() {
let offset = p.offset();
let end = offset + p.file_size();

Expand All @@ -339,10 +337,13 @@ fn print_module(log: &mut LogEntry, module: &Module) {
}

// Runtime info.
writeln!(log, "Module flags : {}", module.flags()).unwrap();
if !module.flags().is_empty() {
writeln!(log, "Module flags : {}", module.flags()).unwrap();
}

writeln!(log, "TLS index : {}", module.tls_index()).unwrap();

// Memory.
// Memory info.
let mem = module.memory();

writeln!(
Expand All @@ -353,24 +354,35 @@ fn print_module(log: &mut LogEntry, module: &Module) {
)
.unwrap();

if let Some(entry) = image.entry_addr() {
writeln!(log, "Entry address : {:#018x}", mem.addr() + entry).unwrap();
if let Some(v) = module.init() {
writeln!(log, "Initialization: {:#018x}", mem.addr() + v).unwrap();
}

if let Some(v) = module.entry() {
writeln!(log, "Entry address : {:#018x}", mem.addr() + v).unwrap();
}

if let Some(v) = module.fini() {
writeln!(log, "Finalization : {:#018x}", mem.addr() + v).unwrap();
}

for s in mem.segments().iter() {
if let Some(p) = s.program() {
let addr = mem.addr() + s.start();

writeln!(
log,
"Program {} is mapped to {:#018x}:{:#018x} with {}.",
p,
addr,
addr + s.len(),
image.programs()[p].flags(),
)
.unwrap();
}
let p = match s.program() {
Some(v) => v,
None => continue,
};

let addr = mem.addr() + s.start();

writeln!(
log,
"Program {} is mapped to {:#018x}:{:#018x} with {}.",
p,
addr,
addr + s.len(),
module.program(p).unwrap().flags(),
)
.unwrap();
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/kernel/src/rtld/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,8 @@ impl<'a> RuntimeLinker<'a> {

/// See `relocate_one_object` on the PS4 kernel for a reference.
unsafe fn relocate_single(&self, module: &Module<'a>) -> Result<(), RelocateError> {
let image = module.image();
let path: &VPath = image.name().try_into().unwrap();
let info = image.info().unwrap(); // Let it panic because the PS4 assume it is available.
let path = module.path();
let info = module.file_info().unwrap(); // Let it panic because the PS4 assume it is available.

// Unprotect the memory.
let mut mem = match module.memory().unprotect() {
Expand Down
Loading

0 comments on commit ea25816

Please sign in to comment.