Commit 89274638 authored by Bas Lijnse's avatar Bas Lijnse

Added support for running additional linkers on linux

parent 33f86dd5
This diff is collapsed.
...@@ -7,4 +7,6 @@ IF_MACOSX macosx not_macosx :== not_macosx ...@@ -7,4 +7,6 @@ IF_MACOSX macosx not_macosx :== not_macosx
DirSeparator:=='/' DirSeparator:=='/'
DirSeparatorString:=="/" DirSeparatorString:=="/"
TempDir :== "/tmp"
application_path :: !{#Char} -> {#Char} application_path :: !{#Char} -> {#Char}
implementation module PmCleanSystem implementation module PmCleanSystem
import StdEnv,StdMisc import StdEnv,StdMisc,StdMaybe
from Directory import pd_StringToPath,getFileInfo,createDirectory,::Path,::FileInfo{pi_fileInfo},::PI_FileInfo{isDirectory},::DirError(..) from Directory import pd_StringToPath,getFileInfo,createDirectory,::Path,::FileInfo{pi_fileInfo},::PI_FileInfo{isDirectory},::DirError(..)
import UtilStrictLists import UtilStrictLists
from Platform import DirSeparatorString from Platform import DirSeparatorString
import StdPathname import StdPathname
from PmTypes import ::CodeGenOptions(..),::Processor,::ApplicationOptions(..),::Output(..),::LinkMethod,::ModuleDirAndName(..) import PmTypes
from PmCompilerOptions import ::CompilerOptions(..),::ListTypes(..),instance == ListTypes from PmCompilerOptions import ::CompilerOptions(..),::ListTypes(..),instance == ListTypes
from PmPath import ModuleDirAndNameToABCSystemPathname,ModuleDirAndNameToObjSystemPathname from PmPath import ModuleDirAndNameToABCSystemPathname,ModuleDirAndNameToObjSystemPathname
import PmCallBack import PmCallBack
from PmParse import IsTypeSpec,IsImportError20 from PmParse import IsTypeSpec,IsImportError20
from linkargs import ReadLinkErrors,WriteLinkOpts,:: LinkInfo`(..),:: LPathname
from Platform import TempDir
tooltempdir =: TempDir
:: CompileOrCheckSyntax = SyntaxCheck | Compilation :: CompileOrCheckSyntax = SyntaxCheck | Compilation
...@@ -365,6 +369,7 @@ finish_code_generator process_handle {scg_abc_path,scg_path_without_suffix,scg_s ...@@ -365,6 +369,7 @@ finish_code_generator process_handle {scg_abc_path,scg_path_without_suffix,scg_s
ps) ps)
= (exit_code==0, ps) = (exit_code==0, ps)
import StdDebug, StdMisc
Link :: !String !(WindowFun *GeneralSt) !Pathname !ApplicationOptions Link :: !String !(WindowFun *GeneralSt) !Pathname !ApplicationOptions
!Pathname !(List Pathname) !(List Pathname) !(List Pathname) !Bool !Bool !Bool !Bool !String !Pathname !(List Pathname) !(List Pathname) !(List Pathname) !Bool !Bool !Bool !Bool !String
!Bool !String !Pathname !String !Processor !Bool !*GeneralSt !Bool !String !Pathname !String !Processor !Bool !*GeneralSt
...@@ -388,70 +393,119 @@ Link linker winfun path ...@@ -388,70 +393,119 @@ Link linker winfun path
# (options_file_ok,ps) = accFiles (write_options_file optionspathname flags hs ss initial_heap_size heap_size_multiple minheap use_64_bit_processor) ps # (options_file_ok,ps) = accFiles (write_options_file optionspathname flags hs ss initial_heap_size heap_size_multiple minheap use_64_bit_processor) ps
| not options_file_ok | not options_file_ok
= (winfun ["Linker error: Could not write the options object file: "+++optionspathname] ps,False) = (winfun ["Linker error: Could not write the options object file: "+++optionspathname] ps,False)
# use_optimizing_linker_and_gcc = is_optimizing_linker linker
# object_paths = [optionspathname : StrictListToList (RemoveDup object_file_names)] | use_optimizing_linker_and_gcc
//First call the optimizing linker to generate an intermediate optimized object file which is then passed to gcc
# temp_file_name = "/tmp/linkerXXXXXX" +++ "\0" // +++ because modified by mkstemp # object_paths = [optionspathname : StrictListToList (RemoveDup object_file_names)]
# fd = mkstemp temp_file_name
| fd== -1 # temp_file_name = "/tmp/linkerXXXXXX" +++ "\0" // +++ because modified by mkstemp
= abort "mkstemp failed" # fd = mkstemp temp_file_name
# r = close fd | fd== -1
| r== -1 = abort "mkstemp failed"
= abort "close failed" # r = close fd
| r== -1
# linker_args = [temp_file_name:object_paths] = abort "close failed"
# (argv,args_memory) = make_argv [linker:linker_args] //Call optimized linker
# linker_args = [temp_file_name:object_paths]
# linker_pid = fork # (argv,args_memory) = make_argv [linker:linker_args]
| linker_pid<0
= abort "fork failed" # linker_pid = fork
| linker_pid==0 | linker_pid<0
| execv (linker+++"\0") argv<0 = abort "fork failed"
= abort "execv failed" | linker_pid==0
= abort "execution continued after execv" | execv (linker+++"\0") argv<0
# (w_pid,status) = wait_pid linker_pid 0 = abort "execv failed"
| w_pid <> -1 && w_pid<>linker_pid = abort "execution continued after execv"
= abort "waitpid failed" # (w_pid,status) = wait_pid linker_pid 0
# result = (status bitand 0xff00) >> 8 | w_pid <> -1 && w_pid<>linker_pid
# wtermsig = status bitand 0x7f = abort "waitpid failed"
| wtermsig<>0 # result = (status bitand 0xff00) >> 8
= abort "linker exited abnormally" # wtermsig = status bitand 0x7f
| free args_memory<0 | wtermsig<>0
= abort "free failed" = abort "linker exited abnormally"
| free args_memory<0
# link_ok = result>=0 = abort "free failed"
| not link_ok
# link_ok = result>=0
| not link_ok
| unlink (temp_file_name+++"\0")<>0
= (ps,link_ok)
= (ps,link_ok)
//Call gcc
# ld_args = ["-o",path,temp_file_name:StrictListToList (Append library_file_names "-lm")]
# ld = "/usr/bin/gcc"
# (argv,args_memory) = make_argv [ld,"-s":ld_args]
# ld_pid = fork
| ld_pid<0
= abort "fork failed"
| ld_pid==0
| execv (ld+++"\0") argv<0
= abort "execv failed"
= abort "execution continued after execv"
| free args_memory<0
= abort "free failed"
# (w_pid,status) = wait_pid ld_pid 0
| w_pid <> -1 && w_pid<>ld_pid
= abort "waitpid failed"
# result = (status bitand 0xff00) >> 8
# wtermsig = status bitand 0x7f
| wtermsig<>0
= abort "ld exited abnormally"
# link_ok = result>=0
| unlink (temp_file_name+++"\0")<>0 | unlink (temp_file_name+++"\0")<>0
= (ps,link_ok) = (ps,link_ok)
= (ps,link_ok) = (ps,link_ok)
| otherwise
# ld_args = ["-o",path,temp_file_name:StrictListToList (Append library_file_names "-lm")] //Call other/additional linker
# ld = "/usr/bin/gcc" # linkopts =
{ exe_path = path
# (argv,args_memory) = make_argv [ld,"-s":ld_args] , res_path = resource_path
, open_console = o <> NoConsole
# ld_pid = fork , static_link = static
| ld_pid<0 , gen_relocs = gen_relocs
= abort "fork failed" , gen_linkmap = gen_linkmap
| ld_pid==0 , link_resources = link_resources
| execv (ld+++"\0") argv<0 , object_paths = optionspathname :! (RemoveDup object_file_names)
= abort "execv failed" , dynamic_libs = RemoveDup library_file_names
= abort "execution continued after execv" , static_libs = RemoveDup static_libraries
| free args_memory<0 , stack_size = ss
= abort "free failed" , gen_dll = gen_dll
# (w_pid,status) = wait_pid ld_pid 0 , dll_names = dll_syms
| w_pid <> -1 && w_pid<>ld_pid , dynamics_path = startupdir +++. DirSeparatorString +++. dynlstr
= abort "waitpid failed" , lib_name_obj_path = MakeFullPathname tooltempdir "lib_name.o"
# result = (status bitand 0xff00) >> 8 }
# wtermsig = status bitand 0x7f # linkoptspath = MakeFullPathname tooltempdir "linkopts"
| wtermsig<>0 # linkerrspath = MakeFullPathname tooltempdir "linkerrs"
= abort "ld exited abnormally" # (err,ps) = accFiles (WriteLinkOpts linkoptspath linkopts) ps
| isJust err
# link_ok = result>=0 = (winfun (fromJust err) ps,False)
| unlink (temp_file_name+++"\0")<>0 # linker_args = ["-I",linkoptspath,"-O",linkerrspath]
= (ps,link_ok) # (argv,args_memory) = make_argv [linker:linker_args]
# linker_pid = fork
| linker_pid<0
= abort "fork failed"
| linker_pid==0
| execv (linker+++"\0") argv<0
= abort "execv failed"
= abort "execution continued after execv"
# (w_pid,status) = wait_pid linker_pid 0
| w_pid <> -1 && w_pid<>linker_pid
= abort "waitpid failed"
# result = (status bitand 0xff00) >> 8
# wtermsig = status bitand 0x7f
| wtermsig<>0
= abort "linker exited abnormally"
| free args_memory<0
= abort "free failed"
# link_ok = result>=0
= (ps,link_ok) = (ps,link_ok)
is_optimizing_linker :: !{#Char} -> Bool
is_optimizing_linker name
# len = size name
= len >= 14 && (name % (len - 14, len) == "lib/exe/linker")
DelayEventLoop :: !.ps -> .ps DelayEventLoop :: !.ps -> .ps
DelayEventLoop ps DelayEventLoop ps
= ps = ps
......
...@@ -8,7 +8,7 @@ set_return_code_world i world = IF_INT_64_OR_32 (set_return_code_world64 i world ...@@ -8,7 +8,7 @@ set_return_code_world i world = IF_INT_64_OR_32 (set_return_code_world64 i world
set_return_code_world64 :: !Int !*World -> *World set_return_code_world64 :: !Int !*World -> *World
set_return_code_world64 i world = code { set_return_code_world64 i world = code {
pushI 0 pushI 0
pushLc _return_code pushLc return_code
:xxx :xxx
pop_b 3 pop_b 3
| mov dword ptr [rbx+r10],eax | mov dword ptr [rbx+r10],eax
...@@ -25,7 +25,7 @@ set_return_code_world32 i world = code { ...@@ -25,7 +25,7 @@ set_return_code_world32 i world = code {
fill_a 0 1 fill_a 0 1
pop_a 1 pop_a 1
pushI 0 pushI 0
pushLc _return_code pushLc return_code
:xxx :xxx
pop_b 3 pop_b 3
| mov (%esp),%edx | mov (%esp),%edx
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment