mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-19 23:07:33 +03:00
Add basic elf relocation handling
This commit is contained in:
parent
2b6039d683
commit
a4b823a269
@ -1,9 +1,11 @@
|
||||
use crate::x86_64::X86_64Backend;
|
||||
use crate::{Backend, Env};
|
||||
use crate::{Backend, Env, Relocation};
|
||||
use bumpalo::collections::Vec;
|
||||
use object::write;
|
||||
use object::write::{Object, StandardSection, Symbol, SymbolSection};
|
||||
use object::{
|
||||
Architecture, BinaryFormat, Endianness, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
|
||||
Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind,
|
||||
SymbolFlags, SymbolKind, SymbolScope,
|
||||
};
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_module::symbol;
|
||||
@ -23,6 +25,7 @@ pub fn build_module<'a>(
|
||||
let mut output =
|
||||
Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
|
||||
let text = output.section_id(StandardSection::Text);
|
||||
let data_section = output.section_id(StandardSection::Data);
|
||||
let comment = output.add_section(vec![], b"comment".to_vec(), SectionKind::OtherString);
|
||||
output.append_section_data(
|
||||
comment,
|
||||
@ -55,15 +58,75 @@ pub fn build_module<'a>(
|
||||
flags: SymbolFlags::None,
|
||||
};
|
||||
let proc_id = output.add_symbol(proc_symbol);
|
||||
procs.push((proc_id, proc));
|
||||
procs.push((fn_name, proc_id, proc));
|
||||
}
|
||||
|
||||
// Build procedures.
|
||||
let mut backend: X86_64Backend = Backend::new(env, target)?;
|
||||
for (proc_id, proc) in procs {
|
||||
let (proc_data, _relocations) = backend.build_proc(proc)?;
|
||||
// TODO: handle relocations.
|
||||
output.add_symbol_data(proc_id, text, proc_data, 16);
|
||||
let mut local_data_index = 0;
|
||||
for (fn_name, proc_id, proc) in procs {
|
||||
let (proc_data, relocations) = backend.build_proc(proc)?;
|
||||
let proc_offset = output.add_symbol_data(proc_id, text, proc_data, 16);
|
||||
for reloc in relocations {
|
||||
let elfreloc = match reloc {
|
||||
Relocation::LocalData { offset, data } => {
|
||||
let data_symbol = write::Symbol {
|
||||
name: format!("{}.data{}", fn_name, local_data_index)
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Data,
|
||||
scope: SymbolScope::Compilation,
|
||||
weak: false,
|
||||
section: write::SymbolSection::Section(data_section),
|
||||
flags: SymbolFlags::None,
|
||||
};
|
||||
local_data_index += 1;
|
||||
let data_id = output.add_symbol(data_symbol);
|
||||
output.add_symbol_data(data_id, data_section, data, 4);
|
||||
write::Relocation {
|
||||
offset: *offset + proc_offset,
|
||||
size: 32,
|
||||
kind: RelocationKind::Relative,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
symbol: data_id,
|
||||
addend: -4,
|
||||
}
|
||||
}
|
||||
Relocation::LinkedData { offset, name } => {
|
||||
if let Some(sym_id) = output.symbol_id(name.as_bytes()) {
|
||||
write::Relocation {
|
||||
offset: *offset + proc_offset,
|
||||
size: 32,
|
||||
kind: RelocationKind::GotRelative,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
symbol: sym_id,
|
||||
addend: -4,
|
||||
}
|
||||
} else {
|
||||
return Err(format!("failed to find symbol for {:?}", name));
|
||||
}
|
||||
}
|
||||
Relocation::LinkedFunction { offset, name } => {
|
||||
if let Some(sym_id) = output.symbol_id(name.as_bytes()) {
|
||||
write::Relocation {
|
||||
offset: *offset + proc_offset,
|
||||
size: 32,
|
||||
kind: RelocationKind::PltRelative,
|
||||
encoding: RelocationEncoding::Generic,
|
||||
symbol: sym_id,
|
||||
addend: -4,
|
||||
}
|
||||
} else {
|
||||
return Err(format!("failed to find symbol for {:?}", name));
|
||||
}
|
||||
}
|
||||
};
|
||||
output
|
||||
.add_relocation(text, elfreloc)
|
||||
.map_err(|e| format!("{:?}", e))?;
|
||||
}
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user