holey-bytes/hbasm/src/linker.rs

48 lines
1.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//! Simple flat-bytecode linker
use {
crate::{
object::{RelocKey, RelocType, Section},
SharedObject,
},
std::io::Write,
};
pub fn link(object: SharedObject, out: &mut impl Write) -> std::io::Result<()> {
let obj = &mut *object.borrow_mut();
// Walk relocation table entries
for (&loc, entry) in &obj.relocs {
let value = match &entry.key {
// Symbol direct reference
RelocKey::Symbol(sym) => obj.symbols[*sym],
// Label indirect label reference
RelocKey::Label(label) => obj.symbols[obj.labels[label]],
}
.ok_or_else(|| std::io::Error::other("Invalid symbol"))?;
let offset = match value.location {
// Text section is on the beginning
Section::Text => value.offset,
// Data section follows text section immediately
Section::Data => value.offset + obj.sections.text.len(),
};
// Insert address or calulate relative offset
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()),
}
}
// Write to output
out.write_all(&obj.sections.text)?;
out.write_all(&obj.sections.data)
}