mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-24 20:42:29 +00:00
call host functions from the app
This commit is contained in:
parent
7399dc8ae4
commit
05feeeb253
1 changed files with 67 additions and 6 deletions
|
@ -4,7 +4,7 @@ use memmap2::{Mmap, MmapMut};
|
|||
use object::{
|
||||
pe::{ImageImportDescriptor, ImageNtHeaders64, ImageSectionHeader, ImageThunkData64},
|
||||
read::pe::ImportTable,
|
||||
LittleEndian as LE, SectionIndex,
|
||||
LittleEndian as LE, RelocationTarget, SectionIndex,
|
||||
};
|
||||
use roc_collections::MutMap;
|
||||
use roc_error_macros::internal_error;
|
||||
|
@ -532,8 +532,8 @@ enum SectionKind {
|
|||
struct Section {
|
||||
/// File range of the section (in the app object)
|
||||
file_range: Range<usize>,
|
||||
|
||||
kind: SectionKind,
|
||||
relocations: MutMap<String, (u64, object::Relocation)>,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -574,6 +574,24 @@ impl AppSections {
|
|||
_ => continue,
|
||||
};
|
||||
|
||||
let mut relocations = MutMap::default();
|
||||
|
||||
for (offset_in_section, relocation) in section.relocations() {
|
||||
match relocation.target() {
|
||||
RelocationTarget::Symbol(symbol_index) => {
|
||||
use object::ObjectSymbol;
|
||||
|
||||
let name = file
|
||||
.symbol_by_index(symbol_index)
|
||||
.and_then(|s| s.name())
|
||||
.unwrap_or_default();
|
||||
|
||||
relocations.insert(name.to_string(), (offset_in_section, relocation));
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
let (start, length) = section.file_range().unwrap();
|
||||
let file_range = start as usize..(start + length) as usize;
|
||||
|
||||
|
@ -591,7 +609,11 @@ impl AppSections {
|
|||
}
|
||||
}
|
||||
|
||||
let section = Section { file_range, kind };
|
||||
let section = Section {
|
||||
file_range,
|
||||
kind,
|
||||
relocations,
|
||||
};
|
||||
|
||||
sections.push(section);
|
||||
}
|
||||
|
@ -990,6 +1012,10 @@ mod test {
|
|||
return 123456;
|
||||
}
|
||||
|
||||
pub export fn roc_realloc() u64 {
|
||||
return 111111;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("Hello, {} {} {} {}!\n", .{roc_magic1(), roc_magic2(), roc_one, roc_three});
|
||||
|
@ -1002,8 +1028,11 @@ mod test {
|
|||
export const roc_one: u64 = 1;
|
||||
export const roc_three: u64 = 3;
|
||||
|
||||
extern fn roc_alloc() u64;
|
||||
extern fn roc_realloc() u64;
|
||||
|
||||
export fn roc_magic1() u64 {
|
||||
return 42;
|
||||
return roc_alloc() + roc_realloc();
|
||||
}
|
||||
|
||||
export fn roc_magic2() u8 {
|
||||
|
@ -1107,6 +1136,18 @@ mod test {
|
|||
let file = PeFile64::parse(app.deref()).unwrap();
|
||||
let last_host_section = file.sections().nth(last_host_section_index).unwrap();
|
||||
|
||||
let exports: MutMap<String, i64> = file
|
||||
.exports()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|e| {
|
||||
(
|
||||
String::from_utf8(e.name().to_vec()).unwrap(),
|
||||
(e.address() - image_base) as i64,
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let optional_header_offset = file.dos_header().nt_headers_offset() as usize
|
||||
+ std::mem::size_of::<u32>()
|
||||
+ std::mem::size_of::<ImageFileHeader>();
|
||||
|
@ -1179,6 +1220,26 @@ mod test {
|
|||
for section in it {
|
||||
let slice = &app_obj[section.file_range.start..section.file_range.end];
|
||||
app[offset..][..slice.len()].copy_from_slice(slice);
|
||||
|
||||
for (name, (offset_in_section, relocation)) in section.relocations.iter() {
|
||||
let destination = exports[name];
|
||||
|
||||
match relocation.kind() {
|
||||
object::RelocationKind::Relative => {
|
||||
// we implicitly only do 32-bit relocations
|
||||
debug_assert_eq!(relocation.size(), 32);
|
||||
|
||||
let delta =
|
||||
destination - virtual_address as i64 - *offset_in_section as i64
|
||||
+ relocation.addend();
|
||||
|
||||
app[offset + *offset_in_section as usize..][..4]
|
||||
.copy_from_slice(&(delta as i32).to_le_bytes());
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
offset += slice.len();
|
||||
}
|
||||
|
||||
|
@ -1235,7 +1296,7 @@ mod test {
|
|||
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
assert_eq!("Hello, 42 32 1 3!\n", output);
|
||||
assert_eq!("Hello, 234567 32 1 3!\n", output);
|
||||
}
|
||||
|
||||
#[ignore]
|
||||
|
@ -1263,6 +1324,6 @@ mod test {
|
|||
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
assert_eq!("Hello, 42 32 1 3!\n", output);
|
||||
assert_eq!("Hello, 234567 32 1 3!\n", output);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue