mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +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::{
|
use object::{
|
||||||
pe::{ImageImportDescriptor, ImageNtHeaders64, ImageSectionHeader, ImageThunkData64},
|
pe::{ImageImportDescriptor, ImageNtHeaders64, ImageSectionHeader, ImageThunkData64},
|
||||||
read::pe::ImportTable,
|
read::pe::ImportTable,
|
||||||
LittleEndian as LE, SectionIndex,
|
LittleEndian as LE, RelocationTarget, SectionIndex,
|
||||||
};
|
};
|
||||||
use roc_collections::MutMap;
|
use roc_collections::MutMap;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
|
@ -532,8 +532,8 @@ enum SectionKind {
|
||||||
struct Section {
|
struct Section {
|
||||||
/// File range of the section (in the app object)
|
/// File range of the section (in the app object)
|
||||||
file_range: Range<usize>,
|
file_range: Range<usize>,
|
||||||
|
|
||||||
kind: SectionKind,
|
kind: SectionKind,
|
||||||
|
relocations: MutMap<String, (u64, object::Relocation)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -574,6 +574,24 @@ impl AppSections {
|
||||||
_ => continue,
|
_ => 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 (start, length) = section.file_range().unwrap();
|
||||||
let file_range = start as usize..(start + length) as usize;
|
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);
|
sections.push(section);
|
||||||
}
|
}
|
||||||
|
@ -990,6 +1012,10 @@ mod test {
|
||||||
return 123456;
|
return 123456;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub export fn roc_realloc() u64 {
|
||||||
|
return 111111;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
try stdout.print("Hello, {} {} {} {}!\n", .{roc_magic1(), roc_magic2(), roc_one, roc_three});
|
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_one: u64 = 1;
|
||||||
export const roc_three: u64 = 3;
|
export const roc_three: u64 = 3;
|
||||||
|
|
||||||
|
extern fn roc_alloc() u64;
|
||||||
|
extern fn roc_realloc() u64;
|
||||||
|
|
||||||
export fn roc_magic1() u64 {
|
export fn roc_magic1() u64 {
|
||||||
return 42;
|
return roc_alloc() + roc_realloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
export fn roc_magic2() u8 {
|
export fn roc_magic2() u8 {
|
||||||
|
@ -1107,6 +1136,18 @@ mod test {
|
||||||
let file = PeFile64::parse(app.deref()).unwrap();
|
let file = PeFile64::parse(app.deref()).unwrap();
|
||||||
let last_host_section = file.sections().nth(last_host_section_index).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
|
let optional_header_offset = file.dos_header().nt_headers_offset() as usize
|
||||||
+ std::mem::size_of::<u32>()
|
+ std::mem::size_of::<u32>()
|
||||||
+ std::mem::size_of::<ImageFileHeader>();
|
+ std::mem::size_of::<ImageFileHeader>();
|
||||||
|
@ -1179,6 +1220,26 @@ mod test {
|
||||||
for section in it {
|
for section in it {
|
||||||
let slice = &app_obj[section.file_range.start..section.file_range.end];
|
let slice = &app_obj[section.file_range.start..section.file_range.end];
|
||||||
app[offset..][..slice.len()].copy_from_slice(slice);
|
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();
|
offset += slice.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1235,7 +1296,7 @@ mod test {
|
||||||
|
|
||||||
let output = String::from_utf8_lossy(&output.stdout);
|
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]
|
#[ignore]
|
||||||
|
@ -1263,6 +1324,6 @@ mod test {
|
||||||
|
|
||||||
let output = String::from_utf8_lossy(&output.stdout);
|
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