Get zig host working

This commit is contained in:
Brendan Hansknecht 2021-09-15 11:45:44 -07:00
parent e8e7f9cad8
commit da28b669bb
9 changed files with 157 additions and 90 deletions

View file

@ -92,9 +92,9 @@ pub fn build_zig_host_native(
.env("PATH", env_path)
.env("HOME", env_home);
if let Some(shared_lib_path) = shared_lib_path {
command.args(&["build-exe", shared_lib_path.to_str().unwrap()]);
command.args(&["build-exe", "-fPIE", shared_lib_path.to_str().unwrap()]);
} else {
command.arg("build-obj");
command.args(&["build-obj", "-fPIC"]);
}
command.args(&[
zig_host_src,
@ -108,7 +108,6 @@ pub fn build_zig_host_native(
// include libc
"--library",
"c",
"-fPIC",
// cross-compile?
"-target",
target,
@ -176,9 +175,9 @@ pub fn build_zig_host_native(
.env("PATH", &env_path)
.env("HOME", &env_home);
if let Some(shared_lib_path) = shared_lib_path {
command.args(&["build-exe", shared_lib_path.to_str().unwrap()]);
command.args(&["build-exe", "-fPIE", shared_lib_path.to_str().unwrap()]);
} else {
command.arg("build-obj");
command.args(&["build-obj", "-fPIC"]);
}
command.args(&[
zig_host_src,
@ -195,7 +194,6 @@ pub fn build_zig_host_native(
// include libc
"--library",
"c",
"-fPIC",
]);
if matches!(opt_level, OptLevel::Optimize) {
command.args(&["-O", "ReleaseSafe"]);
@ -267,10 +265,11 @@ pub fn build_c_host_native(
.env("PATH", &env_path)
.env("HOME", &env_home)
.args(sources)
.args(&["-fPIC", "-o", dest]);
.args(&["-o", dest]);
if let Some(shared_lib_path) = shared_lib_path {
command.args(&[
shared_lib_path.to_str().unwrap(),
"-fPIE",
"-lm",
"-lpthread",
"-ldl",
@ -278,7 +277,7 @@ pub fn build_c_host_native(
"-lutil",
]);
} else {
command.arg("-c");
command.args(&["-fPIC", "-c"]);
}
if matches!(opt_level, OptLevel::Optimize) {
command.arg("-O2");

View file

@ -33,6 +33,8 @@ const Align = extern struct { a: usize, b: usize };
extern fn malloc(size: usize) callconv(.C) ?*align(@alignOf(Align)) c_void;
extern fn realloc(c_ptr: [*]align(@alignOf(Align)) u8, size: usize) callconv(.C) ?*c_void;
extern fn free(c_ptr: [*]align(@alignOf(Align)) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
const DEBUG: bool = false;
@ -74,6 +76,14 @@ export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
std.process.exit(0);
}
export fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void{
return memcpy(dst, src, size);
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void{
return memset(dst, value, size);
}
const Unit = extern struct {};
pub fn main() u8 {

View file

@ -32,6 +32,8 @@ extern fn roc__mainForHost_1_Fx_result_size() i64;
extern fn malloc(size: usize) callconv(.C) ?*c_void;
extern fn realloc(c_ptr: [*]align(@alignOf(u128)) u8, size: usize) callconv(.C) ?*c_void;
extern fn free(c_ptr: [*]align(@alignOf(u128)) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
return malloc(size);
@ -52,6 +54,14 @@ export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
std.process.exit(0);
}
export fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void{
return memcpy(dst, src, size);
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void{
return memset(dst, value, size);
}
const Unit = extern struct {};
pub export fn main() u8 {

View file

@ -1,7 +1,12 @@
#include <stdio.h>
#include <string.h>
extern int rust_main();
int main() {
return rust_main();
int main() { return rust_main(); }
void *roc_memcpy(void *dest, const void *src, size_t n) {
return memcpy(dest, src, n);
}
void *roc_memset(void *str, int c, size_t n) { return memset(str, c, n); }

View file

@ -1,36 +1,38 @@
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void* roc_alloc(size_t size, unsigned int alignment) {
return malloc(size);
}
void* roc_alloc(size_t size, unsigned int alignment) { return malloc(size); }
void* roc_realloc(void* ptr, size_t old_size, size_t new_size, unsigned int alignment) {
void* roc_realloc(void* ptr, size_t old_size, size_t new_size,
unsigned int alignment) {
return realloc(ptr, new_size);
}
void roc_dealloc(void* ptr, unsigned int alignment) {
free(ptr);
}
void roc_dealloc(void* ptr, unsigned int alignment) { free(ptr); }
void roc_panic(void* ptr, unsigned int alignment) {
char* msg = (char *)ptr;
fprintf(stderr, "Application crashed with message\n\n %s\n\nShutting down\n", msg);
char* msg = (char*)ptr;
fprintf(stderr,
"Application crashed with message\n\n %s\n\nShutting down\n", msg);
exit(0);
}
void* roc_memcpy(void* dest, const void* src, size_t n) {
return memcpy(dest, src, n);
}
void* roc_memset(void* str, int c, size_t n) { return memset(str, c, n); }
struct RocStr {
char* bytes;
size_t len;
};
bool is_small_str(struct RocStr str) {
return ((ssize_t)str.len) < 0;
}
bool is_small_str(struct RocStr str) { return ((ssize_t)str.len) < 0; }
// Determine the length of the string, taking into
// account the small string optimization
@ -56,7 +58,7 @@ struct RocCallResult {
struct RocStr content;
};
extern void roc__mainForHost_1_exposed(struct RocCallResult *re);
extern void roc__mainForHost_1_exposed(struct RocCallResult* re);
int main() {
// Make space for the Roc call result

View file

@ -23,6 +23,8 @@ const Align = extern struct { a: usize, b: usize };
extern fn malloc(size: usize) callconv(.C) ?*align(@alignOf(Align)) c_void;
extern fn realloc(c_ptr: [*]align(@alignOf(Align)) u8, size: usize) callconv(.C) ?*c_void;
extern fn free(c_ptr: [*]align(@alignOf(Align)) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
export fn roc_alloc(size: usize, alignment: u32) callconv(.C) ?*c_void {
_ = alignment;
@ -51,6 +53,14 @@ export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
std.process.exit(0);
}
export fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void{
return memcpy(dst, src, size);
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void{
return memset(dst, value, size);
}
const mem = std.mem;
const Allocator = mem.Allocator;

View file

@ -26,6 +26,8 @@ const Align = extern struct { a: usize, b: usize };
extern fn malloc(size: usize) callconv(.C) ?*align(@alignOf(Align)) c_void;
extern fn realloc(c_ptr: [*]align(@alignOf(Align)) u8, size: usize) callconv(.C) ?*c_void;
extern fn free(c_ptr: [*]align(@alignOf(Align)) u8) callconv(.C) void;
extern fn memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void;
extern fn memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void;
const DEBUG: bool = false;
@ -67,6 +69,14 @@ export fn roc_panic(c_ptr: *c_void, tag_id: u32) callconv(.C) void {
std.process.exit(0);
}
export fn roc_memcpy(dst: [*]u8, src: [*]u8, size: usize) callconv(.C) void{
return memcpy(dst, src, size);
}
export fn roc_memset(dst: [*]u8, value: i32, size: usize) callconv(.C) void{
return memset(dst, value, size);
}
// warning! the array is currently stack-allocated so don't make this too big
const NUM_NUMS = 100;

View file

@ -170,17 +170,18 @@ pub fn link_preprocessed_host(
) -> io::Result<()> {
let metadata = host_input_path.with_file_name("metadata");
let prehost = host_input_path.with_file_name("preprocessedhost");
std::fs::copy(prehost, binary_path)?;
if surgery_impl(
roc_app_obj.to_str().unwrap(),
metadata.to_str().unwrap(),
prehost.to_str().unwrap(),
binary_path.to_str().unwrap(),
false,
false,
)? != 0
{
panic!("Failed to surgically link host");
}
std::fs::rename(prehost, binary_path)
Ok(())
}
fn generate_dynamic_lib(
@ -197,8 +198,15 @@ fn generate_dynamic_lib(
let text_section = out_object.section_id(write::StandardSection::Text);
for sym in exposed_to_host {
for name in &[
format!("roc__{}_1_exposed", sym),
format!("roc__{}_1_Fx_caller", sym),
format!("roc__{}_1_Fx_size", sym),
format!("roc__{}_1_Fx_result_size", sym),
format!("roc__{}_size", sym),
] {
out_object.add_symbol(write::Symbol {
name: format!("roc__{}_1_exposed", sym).as_bytes().to_vec(),
name: name.as_bytes().to_vec(),
value: 0,
size: 0,
kind: SymbolKind::Text,
@ -208,6 +216,7 @@ fn generate_dynamic_lib(
flags: SymbolFlags::None,
});
}
}
std::fs::write(
&dummy_obj_file,
out_object.write().expect("failed to build output object"),
@ -994,16 +1003,22 @@ fn preprocess_impl(
}
let saving_metadata_start = SystemTime::now();
// This block ensure that the metadata is fully written and timed before continuing.
{
let output = fs::File::create(metadata_filename)?;
let output = BufWriter::new(output);
if let Err(err) = serialize_into(output, &md) {
println!("Failed to serialize metadata: {}", err);
return Ok(-1);
};
}
let saving_metadata_duration = saving_metadata_start.elapsed().unwrap();
let flushing_data_start = SystemTime::now();
out_mmap.flush()?;
// Also drop files to to ensure data is fully written here.
drop(out_mmap);
drop(out_file);
let flushing_data_duration = flushing_data_start.elapsed().unwrap();
let total_duration = total_start.elapsed().unwrap();
@ -1523,9 +1538,11 @@ fn surgery_impl(
let flushing_data_start = SystemTime::now();
exec_mmap.flush()?;
let flushing_data_duration = flushing_data_start.elapsed().unwrap();
// Also drop files to to ensure data is fully written here.
drop(exec_mmap);
exec_file.set_len(offset as u64 + 1)?;
drop(exec_file);
let flushing_data_duration = flushing_data_start.elapsed().unwrap();
// Make sure the final executable has permision to execute.
let mut perms = fs::metadata(out_filename)?.permissions();

View file

@ -4,3 +4,7 @@ zig-cache
zig-out
*.o
dynhost
preprocessedhost
metadata