From 696efd25b5a7506ce061bd8c67b5abb3f39aa976 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Sun, 1 Mar 2020 14:30:22 +0100 Subject: [PATCH] Modify runtime symbol decoration C name decoration varies across platforms. On macOS, names from C are prefixed with an underscore. On Linux, they're not, and on 64-bit Windows they're not. The macOS situation observed by inspecting the symbols. Linux compatibility issue discovered here (and above in the thread): https://twitter.com/16kbps/status/1233955883148861440 Windows symbol decoration documented here: https://docs.microsoft.com/en-us/cpp/build/reference/decorated-names#FormatC > Note that in a 64-bit environment, functions are not decorated. Currently handling this with conditional compilation, but that prevents cross-compilation. In the future it would be good to have the formatting method select how to print them, but that would involve switching away from fmt::Display, since we can't pass the ABI information into that. Alternately, we could pack the ABI information into the symbol enum. --- src/trans/x64.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/trans/x64.rs b/src/trans/x64.rs index fbc7398..2608c79 100644 --- a/src/trans/x64.rs +++ b/src/trans/x64.rs @@ -7,6 +7,15 @@ use std::{ io::{self, Write}, }; +#[cfg(target_os = "macos")] +macro_rules! extern_label { + ($l:literal) => { Label::Extern(concat!("_", $l)) } +} +#[cfg(not(target_os = "macos"))] +macro_rules! extern_label { + ($l:literal) => { Label::Extern($l) } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Label { Global(u32), @@ -216,7 +225,7 @@ fn compile_func(func: &Func) -> Definition { body.push(Inst::Lea(Reg::Rdi, Addr::Rip(Label::Function(*name)))); body.push(Inst::Imm(Reg::Rsi, *params as i64)); body.push(Inst::Imm(Reg::Rdx, upvars.len() as i64)); - body.push(Inst::Call(Label::Extern("_ivy_make_lam"))); + body.push(Inst::Call(extern_label!("ivy_make_lam"))); // @TODO: Implement copying in closure captures assert!(upvars.is_empty()); body.push(Inst::Store(stack(ssa), Reg::Rax)); @@ -231,11 +240,11 @@ fn compile_func(func: &Func) -> Definition { Some(s) => body.push(Inst::Load(Reg::Rsi, stack(s))), None => body.push(Inst::Imm(Reg::Rsi, 0)), } - body.push(Inst::Call(Label::Extern("_ivy_app"))); + body.push(Inst::Call(extern_label!("ivy_app"))); while let Some(term) = terms.next() { body.push(Inst::Mov(Reg::Rdi, Reg::Rax)); body.push(Inst::Load(Reg::Rsi, stack(term))); - body.push(Inst::Call(Label::Extern("_ivy_app_mut"))); + body.push(Inst::Call(extern_label!("ivy_app_mut"))); } body.push(Inst::Store(stack(ssa), Reg::Rax)); } @@ -345,7 +354,7 @@ fn builtin(name: &str) -> (u16, &'static str, &'static [Inst]) { "debug", &[ Inst::Load(Reg::Rdi, Addr::Off(Reg::Rdi, 0x18)), - Inst::Jmp(Label::Extern("_ivy_debug")), + Inst::Jmp(extern_label!("ivy_debug")), ], ), name => panic!("Unsupported builtin '{}' for x64", name), -- 2.47.0