2024-02-22 16:57:29 -06:00
|
|
|
|
//! Simple flat-bytecode linker
|
|
|
|
|
|
2023-10-27 20:29:02 -05:00
|
|
|
|
use {
|
|
|
|
|
crate::{
|
|
|
|
|
object::{RelocKey, RelocType, Section},
|
|
|
|
|
SharedObject,
|
|
|
|
|
},
|
|
|
|
|
std::io::Write,
|
|
|
|
|
};
|
2023-10-22 08:08:45 -05:00
|
|
|
|
|
2023-10-27 20:29:02 -05:00
|
|
|
|
pub fn link(object: SharedObject, out: &mut impl Write) -> std::io::Result<()> {
|
|
|
|
|
let obj = &mut *object.borrow_mut();
|
2024-02-22 16:57:29 -06:00
|
|
|
|
|
|
|
|
|
// Walk relocation table entries
|
2023-10-27 20:29:02 -05:00
|
|
|
|
for (&loc, entry) in &obj.relocs {
|
|
|
|
|
let value = match &entry.key {
|
2024-02-22 16:57:29 -06:00
|
|
|
|
// Symbol – direct reference
|
2023-10-27 20:29:02 -05:00
|
|
|
|
RelocKey::Symbol(sym) => obj.symbols[*sym],
|
2024-02-22 16:57:29 -06:00
|
|
|
|
|
|
|
|
|
// Label – indirect label reference
|
2023-10-27 20:29:02 -05:00
|
|
|
|
RelocKey::Label(label) => obj.symbols[obj.labels[label]],
|
|
|
|
|
}
|
|
|
|
|
.ok_or_else(|| std::io::Error::other("Invalid symbol"))?;
|
|
|
|
|
|
|
|
|
|
let offset = match value.location {
|
2024-02-22 16:57:29 -06:00
|
|
|
|
// Text section is on the beginning
|
2023-10-27 20:29:02 -05:00
|
|
|
|
Section::Text => value.offset,
|
2024-02-22 16:57:29 -06:00
|
|
|
|
|
|
|
|
|
// Data section follows text section immediately
|
2023-10-27 20:29:02 -05:00
|
|
|
|
Section::Data => value.offset + obj.sections.text.len(),
|
|
|
|
|
};
|
2023-10-22 08:08:45 -05:00
|
|
|
|
|
2024-02-22 16:57:29 -06:00
|
|
|
|
// Insert address or calulate relative offset
|
2023-10-27 20:29:02 -05:00
|
|
|
|
match entry.ty {
|
|
|
|
|
RelocType::Rel32 => obj.sections.text[loc..loc + 4]
|
|
|
|
|
.copy_from_slice(&((offset as isize - loc as isize) as i32).to_le_bytes()),
|
|
|
|
|
RelocType::Rel16 => obj.sections.text[loc..loc + 2]
|
|
|
|
|
.copy_from_slice(&((offset as isize - loc as isize) as i16).to_le_bytes()),
|
|
|
|
|
RelocType::Abs64 => obj.sections.text[loc..loc + 8]
|
|
|
|
|
.copy_from_slice(&(offset as isize - loc as isize).to_le_bytes()),
|
2023-10-22 08:08:45 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-22 16:57:29 -06:00
|
|
|
|
// Write to output
|
2023-10-27 20:29:02 -05:00
|
|
|
|
out.write_all(&obj.sections.text)?;
|
|
|
|
|
out.write_all(&obj.sections.data)
|
2023-10-22 08:08:45 -05:00
|
|
|
|
}
|