holey-bytes/hbasm/src/object.rs

95 lines
2.1 KiB
Rust
Raw Normal View History

2024-02-22 16:57:29 -06:00
//! Code object
2023-10-27 20:29:02 -05:00
use {rhai::ImmutableString, std::collections::HashMap};
2024-02-22 16:57:29 -06:00
/// Section tabel
2023-10-27 20:29:02 -05:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Section {
Text,
Data,
}
2024-02-22 16:57:29 -06:00
/// Symbol entry (in what section, where)
2023-10-27 20:29:02 -05:00
#[derive(Clone, Copy, Debug)]
pub struct SymbolEntry {
pub location: Section,
pub offset: usize,
}
2024-02-22 16:57:29 -06:00
/// Relocation table key
2023-10-27 20:29:02 -05:00
#[derive(Clone, Debug)]
pub enum RelocKey {
2024-02-22 16:57:29 -06:00
/// Direct reference
2023-10-27 20:29:02 -05:00
Symbol(usize),
2024-02-22 16:57:29 -06:00
/// Indirect reference
2023-10-27 20:29:02 -05:00
Label(ImmutableString),
}
2024-02-22 16:57:29 -06:00
/// Relocation type
2023-10-27 20:29:02 -05:00
#[derive(Clone, Copy, Debug)]
pub enum RelocType {
Rel32,
Rel16,
Abs64,
}
2024-02-22 16:57:29 -06:00
/// Relocation table entry
2023-10-27 20:29:02 -05:00
#[derive(Clone, Debug)]
pub struct RelocEntry {
pub key: RelocKey,
pub ty: RelocType,
}
2024-02-22 16:57:29 -06:00
/// Object code
2023-10-27 20:29:02 -05:00
#[derive(Clone, Debug, Default)]
pub struct Sections {
pub text: Vec<u8>,
pub data: Vec<u8>,
}
2024-02-22 16:57:29 -06:00
/// Object
2023-10-27 20:29:02 -05:00
#[derive(Clone, Debug, Default)]
pub struct Object {
2024-02-22 16:57:29 -06:00
/// Vectors with sections
2023-10-27 20:29:02 -05:00
pub sections: Sections,
2024-02-22 16:57:29 -06:00
/// Symbol table
2023-10-27 20:29:02 -05:00
pub symbols: Vec<Option<SymbolEntry>>,
2024-02-22 16:57:29 -06:00
/// Labels to symbols table
2023-10-27 20:29:02 -05:00
pub labels: HashMap<ImmutableString, usize>,
2024-02-22 16:57:29 -06:00
/// Relocation table
2023-10-27 20:29:02 -05:00
pub relocs: HashMap<usize, RelocEntry>,
}
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct SymbolRef(pub usize);
impl Object {
2024-02-22 16:57:29 -06:00
/// Insert symbol at current location in specified section
2023-10-27 20:29:02 -05:00
pub fn symbol(&mut self, section: Section) -> SymbolRef {
let section_buf = match section {
Section::Text => &mut self.sections.text,
Section::Data => &mut self.sections.data,
};
self.symbols.push(Some(SymbolEntry {
location: section,
offset: section_buf.len(),
}));
SymbolRef(self.symbols.len() - 1)
}
2024-02-22 16:57:29 -06:00
/// Insert to relocation table and write zeroes to code
2023-10-27 20:29:02 -05:00
pub fn relocation(&mut self, key: RelocKey, ty: RelocType) {
self.relocs
.insert(self.sections.text.len(), RelocEntry { key, ty });
self.sections.text.extend(match ty {
RelocType::Rel32 => &[0_u8; 4] as &[u8],
RelocType::Rel16 => &[0; 2],
RelocType::Abs64 => &[0; 8],
});
}
}