From 2f7aa3f0ae524305b7c3e8ba06a5ed0d2ba70891 Mon Sep 17 00:00:00 2001
From: Tom Smeding <tom.smeding@gmail.com>
Date: Sun, 15 Apr 2018 10:19:08 +0200
Subject: Let generated code work with yasm on linux

---
 Compiler.hs | 31 +++++++++++++++++++++++--------
 Main.hs     |  9 ++++++++-
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/Compiler.hs b/Compiler.hs
index eab7058..f02a50a 100644
--- a/Compiler.hs
+++ b/Compiler.hs
@@ -5,6 +5,7 @@ module Compiler(compile) where
 import Control.Monad.State.Strict
 import Control.Monad.Writer.Strict
 import Data.List
+import qualified System.Info as System (os)
 
 import AST
 
@@ -30,6 +31,19 @@ genId :: LineWriter Int
 genId = state $ \i -> (i, i + 1)
 
 
+mangleName :: String -> String
+mangleName f = case System.os of
+    "darwin" -> '_' : f
+    "linux" -> f
+    _ -> undefined
+
+generateCall :: String -> String
+generateCall f = case System.os of
+    "darwin" -> "call " ++ mangleName f
+    "linux" -> "call [" ++ mangleName f ++ " wrt ..got]"
+    _ -> undefined
+
+
 compile :: Program -> String
 compile (Program inss) = runLineWriter $ do
     emit0 prologue
@@ -67,12 +81,12 @@ compileIns (ILoop inss off) = do
     emit $ "jnz .Lbd_" ++ show loopid
     emit0 $ ".Laf_" ++ show loopid ++ ":"
 compileIns (IInput off) = do
-    emit "call _getchar"
+    emit $ generateCall "getchar"
     emit $ "mov [" ++ cursorOffset off ++ "], al"
 compileIns (IOutput off) = do
     emit "xor edi, edi"
     emit $ "mov dil, [" ++ cursorOffset off ++ "]"
-    emit "call _putchar"
+    emit $ generateCall "putchar"
 compileIns IStart = return ()
 
 isTwoPower :: Byte -> Maybe Int
@@ -81,19 +95,20 @@ isTwoPower v = findIndex (==v) (take 8 $ iterate (* 2) 1)
 
 prologue :: String
 prologue =
-         "global _main"
-    ++ "\nextern _calloc, _free, _putchar, _getchar, _write"
+         "global " ++ mangleName "main"
+    ++ "\nextern " ++ intercalate ", "
+            (map mangleName ["calloc", "free", "putchar", "getchar", "write"])
     ++ "\ndefault rel"
     ++ "\nsection .text"
 
-    ++ "\n_main:"
+    ++ "\n" ++ mangleName "main" ++ ":"
     ++ "\n\tpush rbp"
     ++ "\n\tmov rbp, rsp"
     ++ "\n\tpush rbx"
     ++ "\n\tsub rsp, 8"
     ++ "\n\tmov edi, " ++ show tapeLength
     ++ "\n\tmov esi, 1"
-    ++ "\n\tcall _calloc"
+    ++ "\n\t" ++ generateCall "calloc"
     ++ "\n\ttest rax, rax"
     ++ "\n\tjz .allocation_failure"
     ++ "\n\tlea rbx, [rax + " ++ show (tapeLength `div` 2) ++ "]  ; rbx = cursor"
@@ -103,7 +118,7 @@ prologue =
 epilogue :: String
 epilogue =
        "\n\tmov rdi, [rsp]"
-    ++ "\n\tcall _free"
+    ++ "\n\t" ++ generateCall "free"
     ++ "\n\txor eax, eax"
     ++ "\n.return:"
     ++ "\n\tadd rsp, 8"
@@ -122,7 +137,7 @@ epilogue =
     ++ "\n\tmov edi, 2"
     ++ "\n\tmov rsi, rsp"
     ++ "\n\tmov edx, 20"
-    ++ "\n\tcall _write"
+    ++ "\n\t" ++ generateCall "write"
     ++ "\n\tadd rsp, 32"
     ++ "\n\tmov eax, 1"
     ++ "\n\tjmp .return"
diff --git a/Main.hs b/Main.hs
index 9c33f83..c7ca464 100644
--- a/Main.hs
+++ b/Main.hs
@@ -4,6 +4,7 @@ import Control.Monad
 import Data.Char
 import System.Environment
 import System.Exit
+import qualified System.Info as System (os)
 import System.Process
 
 import AST
@@ -40,5 +41,11 @@ main = do
             interpret opt (map (fromIntegral . ord) input) >>= (putStr . map (chr . fromIntegral))
         EMCompile -> do
             writeFile (fname ++ ".asm") $ compile opt
-            callProcess "yasm" ["-f", "macho64", fname ++ ".asm", "-o", fname ++ ".o"]
+
+            let format = case System.os of
+                            "darwin" -> "macho64"
+                            "linux" -> "elf64"
+                            _ -> undefined
+
+            callProcess "yasm" ["-f", format, fname ++ ".asm", "-o", fname ++ ".o"]
             callProcess "gcc" [fname ++ ".o", "-o", fname ++ ".exe"]
-- 
cgit v1.2.3-70-g09d2