assembler: we failing DSA with this one
This commit is contained in:
@@ -1,17 +1,58 @@
|
||||
//! This module contains the definitions for a Symbol.
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{model::module::ModuleId, symtab::SymbolTable};
|
||||
|
||||
/// Tuple struct for type safety. Has methods for fetching symbols by ID.
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub struct SymbolId(Uuid);
|
||||
|
||||
impl From<Symbol> for SymbolId {
|
||||
fn from(sym: Symbol) -> Self {
|
||||
sym.id
|
||||
}
|
||||
}
|
||||
|
||||
impl SymbolId {
|
||||
pub fn new() -> Self {
|
||||
Self(Uuid::new_v4())
|
||||
}
|
||||
|
||||
/// Convenience method to get the [`Module`] from a [`ModuleId`].
|
||||
pub fn to_module<'s>(&self, registry: &'s SymbolTable) -> Option<&'s Symbol> {
|
||||
registry.get(self)
|
||||
}
|
||||
|
||||
/// Convenience method to get the [`Module`] name from a [`ModuleId`].
|
||||
pub fn to_module_name<'m>(self, registry: &'m SymbolTable) -> Option<&'m str> {
|
||||
if let Some(module) = self.to_module(®istry) {
|
||||
Some(module.name.as_str())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A symbol is a named reference that may be resolved later to an address by a linker.
|
||||
#[derive(Debug)]
|
||||
pub struct Symbol {
|
||||
/// Stored cheaply instead of the name. Shall be stored in the symbol table under
|
||||
/// this key.
|
||||
pub id: Uuid,
|
||||
pub id: SymbolId,
|
||||
|
||||
/// The human-readable name for the symbol.
|
||||
pub name: String,
|
||||
|
||||
pub visibility: Visibility,
|
||||
|
||||
pub symbol_type: SymbolType,
|
||||
|
||||
/// The id of the module the symbol is defined in.
|
||||
module_id: Uuid,
|
||||
/// The id of the module the symbol is defined in. This will be different for symbols
|
||||
/// in different objects.
|
||||
pub module_id: ModuleId,
|
||||
|
||||
/// Whether or not the symbol requires relocating.
|
||||
pub needs_relocation: bool,
|
||||
@@ -30,21 +71,68 @@ pub struct Symbol {
|
||||
/// ```
|
||||
///
|
||||
/// Where `main` depends on `another_func`.
|
||||
pub dependencies: Vec<Uuid>,
|
||||
pub dependencies: HashSet<SymbolId>,
|
||||
|
||||
/// The address of the symbol.
|
||||
pub address: Option<u32>,
|
||||
/// The section the symbol is in.
|
||||
/// TODO: Perhaps make this a proper type?
|
||||
pub section: Option<String>,
|
||||
pub size: Option<u32>,
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
pub fn new(
|
||||
id: Uuid,
|
||||
name: String,
|
||||
module_id: ModuleId,
|
||||
visibility: Visibility,
|
||||
symbol_type: SymbolType,
|
||||
module_id: Uuid,
|
||||
) -> Self {
|
||||
Self {
|
||||
id,
|
||||
id: SymbolId::new(),
|
||||
name,
|
||||
module_id,
|
||||
address: None,
|
||||
section: None,
|
||||
size: None,
|
||||
visibility,
|
||||
symbol_type,
|
||||
module_id,
|
||||
needs_relocation: false,
|
||||
dependencies: HashSet::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a dependency on another [`Symbol`].
|
||||
pub fn add_dependency(&mut self, dep: SymbolId) {
|
||||
if self.id == dep {
|
||||
return;
|
||||
}
|
||||
|
||||
// We can resolve a lot of addresses at assembly time, but not really foreign
|
||||
// ones, since we aren't certain of their position.
|
||||
//
|
||||
/* TODO: Handle this for flat binary case i.e. no linker required. This may be
|
||||
* done using a similar method to before, such as just concatenating all
|
||||
* of the files together and handling jumps and halts.
|
||||
*
|
||||
* > Ask Harry or read the initial code.
|
||||
*/
|
||||
if self.dependencies.insert(dep) {
|
||||
self.needs_relocation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether a [`Symbol`] depends on `symbol_id`.
|
||||
pub fn depends_on(&self, symbol_id: &SymbolId) -> bool {
|
||||
self.dependencies.contains(symbol_id)
|
||||
}
|
||||
|
||||
/// Removes a [`Symbol`] from the dependency set.
|
||||
pub fn remove_dependency(&mut self, symbol_id: &SymbolId) {
|
||||
self.dependencies.remove(symbol_id);
|
||||
|
||||
if self.dependencies.is_empty() {
|
||||
self.needs_relocation = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +151,8 @@ pub enum Visibility {
|
||||
Weak,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum SymbolType {
|
||||
Function,
|
||||
Label,
|
||||
LabelOrFunction,
|
||||
Variable,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user