#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SymbolType {
Func,
Object,
Tls,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SymbolScope {
Global,
Local,
Weak,
}
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
pub enum SectionKind {
Null,
DynStr,
DynSym,
RelaDyn,
RelaPlt,
RelDyn,
RelPlt,
Dynamic,
Hash,
ShStrTab,
Plt,
Text,
Data,
Got,
GotPlt,
Tls,
}
#[derive(Debug, Clone)]
pub struct Content {
pub data: Vec<u8>,
pub kind: SectionKind,
}
#[derive(Clone, Debug)]
pub struct SymbolDesc {
pub name: String,
pub sym_type: SymbolType,
pub scope: SymbolScope,
pub content: Option<Content>,
pub size: Option<u64>,
}
impl SymbolDesc {
pub fn global_func(name: impl Into<String>, code: &[u8]) -> Self {
Self {
name: name.into(),
sym_type: SymbolType::Func,
scope: SymbolScope::Global,
content: Some(Content {
data: code.to_vec(),
kind: SectionKind::Text,
}),
size: Some(code.len() as u64),
}
}
pub fn global_object(name: impl Into<String>, data: &[u8]) -> Self {
Self {
name: name.into(),
sym_type: SymbolType::Object,
scope: SymbolScope::Global,
content: Some(Content {
data: data.to_vec(),
kind: SectionKind::Data,
}),
size: Some(data.len() as u64),
}
}
pub fn undefined_func(name: impl Into<String>) -> Self {
Self {
name: name.into(),
sym_type: SymbolType::Func,
scope: SymbolScope::Global,
content: None,
size: None,
}
}
pub fn undefined_object(name: impl Into<String>) -> Self {
Self {
name: name.into(),
sym_type: SymbolType::Object,
scope: SymbolScope::Global,
content: None,
size: None,
}
}
pub fn global_tls(name: impl Into<String>, data: &[u8]) -> Self {
Self {
name: name.into(),
sym_type: SymbolType::Tls,
scope: SymbolScope::Global,
content: Some(Content {
data: data.to_vec(),
kind: SectionKind::Tls,
}),
size: Some(data.len() as u64),
}
}
pub fn undefined_tls(name: impl Into<String>) -> Self {
Self {
name: name.into(),
sym_type: SymbolType::Tls,
scope: SymbolScope::Global,
content: None,
size: None,
}
}
pub fn plt_func(name: impl Into<String>, code: Vec<u8>) -> Self {
let size = code.len() as u64;
Self {
name: name.into(),
sym_type: SymbolType::Func,
scope: SymbolScope::Global,
content: Some(Content {
data: code,
kind: SectionKind::Plt,
}),
size: Some(size),
}
}
pub fn with_size(mut self, size: u64) -> Self {
self.size = Some(size);
self
}
pub fn with_scope(mut self, scope: SymbolScope) -> Self {
self.scope = scope;
self
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct RelocType(pub u32);
impl RelocType {
pub fn as_u32(&self) -> u32 {
self.0
}
pub fn as_u64(&self) -> u64 {
self.0 as u64
}
}
#[derive(Clone, Debug)]
pub struct RelocEntry {
pub symbol_name: String,
pub r_type: RelocType,
pub addend: i64,
}
impl RelocEntry {
pub fn with_name(symbol_name: impl Into<String>, r_type: u32) -> Self {
Self {
symbol_name: symbol_name.into(),
r_type: RelocType(r_type),
addend: 0,
}
}
pub fn new(r_type: u32) -> Self {
Self {
symbol_name: String::new(),
r_type: RelocType(r_type),
addend: 0,
}
}
pub fn with_addend(mut self, addend: i64) -> Self {
self.addend = addend;
self
}
pub fn jump_slot(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
Self::with_name(symbol_name, arch.jump_slot_reloc())
}
pub fn glob_dat(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
Self::with_name(symbol_name, arch.glob_dat_reloc())
}
pub fn relative(arch: crate::Arch) -> Self {
Self::new(arch.relative_reloc())
}
pub fn irelative(arch: crate::Arch) -> Self {
Self::new(arch.irelative_reloc())
}
pub fn copy(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
Self::with_name(symbol_name, arch.copy_reloc())
}
pub fn dtpoff(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
Self::with_name(symbol_name, arch.dtpoff_reloc())
}
pub fn dtpmod(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
Self::with_name(symbol_name, arch.dtpmod_reloc())
}
pub fn abs(symbol_name: impl Into<String>, arch: crate::Arch) -> Self {
Self::with_name(symbol_name, arch.abs_reloc())
}
}