|
|
|
use std::fmt::Display;
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
common::{Output, Relocatable},
|
|
|
|
error::Error,
|
|
|
|
};
|
|
|
|
|
|
|
|
pub struct Linker<'data> {
|
|
|
|
relocatables: Vec<Box<dyn Relocatable + 'data>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'data> Linker<'data> {
|
|
|
|
pub fn new(relocatables: Vec<Box<dyn Relocatable + 'data>>) -> Self {
|
|
|
|
Self { relocatables }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_relocatable(&mut self, relocatable: Box<dyn Relocatable + 'data>) {
|
|
|
|
self.relocatables.push(relocatable);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn link(&self, output: &mut dyn Output) -> Result<u64, Error> {
|
|
|
|
let allocated = output.allocate(self.total_size()?)?;
|
|
|
|
|
|
|
|
for r in self.relocatables.iter() {
|
|
|
|
for s in r.sections() {
|
|
|
|
output.append_section(&s?)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(allocated)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn total_size(&self) -> Result<u64, Error> {
|
|
|
|
let mut result = 0u64;
|
|
|
|
|
|
|
|
for o in self.relocatables.iter() {
|
|
|
|
for s in o.sections() {
|
|
|
|
result += s?.size()?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for Linker<'_> {
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
writeln!(f, "===Relocatables===")?;
|
|
|
|
|
|
|
|
for r in self.relocatables.iter() {
|
|
|
|
write!(f, "{}", r)?;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|