mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-26 18:23:42 +02:00
264 lines
6.8 KiB
ObjectPascal
264 lines
6.8 KiB
ObjectPascal
{
|
|
Copyright (c) 2019 by Dmitry Boyarintsev
|
|
|
|
This unit implements support import,export,link routines
|
|
for the WASI target
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
|
|
unit t_wasi;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
systems,
|
|
|
|
globtype, globals,
|
|
aasmbase,
|
|
cfileutl, cutils, cclasses,
|
|
|
|
import, export, aasmdata, aasmcpu,
|
|
fmodule, ogbase,
|
|
|
|
symsym, symdef,
|
|
|
|
link,
|
|
|
|
i_wasi, tgcpu;
|
|
|
|
type
|
|
|
|
{ texportlibwasi }
|
|
|
|
texportlibwasi=class(texportlib)
|
|
procedure preparelib(const s : string);override;
|
|
procedure exportprocedure(hp : texported_item);override;
|
|
procedure exportvar(hp : texported_item);override;
|
|
procedure generatelib;override;
|
|
end;
|
|
|
|
{ timportlibwasi }
|
|
timportlibwasi = class(timportlib)
|
|
procedure generatelib;override;
|
|
end;
|
|
|
|
{ tlinkerwasi }
|
|
|
|
tlinkerwasi=class(texternallinker)
|
|
public
|
|
constructor Create;override;
|
|
procedure SetDefaultInfo;override;
|
|
|
|
procedure InitSysInitUnitName;override;
|
|
|
|
function MakeExecutable:boolean;override;
|
|
function MakeSharedLibrary:boolean;override;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils,
|
|
verbose;
|
|
|
|
{ timportlibwasi }
|
|
|
|
procedure timportlibwasi.generatelib;
|
|
begin
|
|
end;
|
|
|
|
{ tlinkerwasi }
|
|
|
|
constructor tlinkerwasi.Create;
|
|
begin
|
|
inherited Create;
|
|
end;
|
|
|
|
procedure tlinkerwasi.SetDefaultInfo;
|
|
begin
|
|
Info.DllCmd[1] := 'wasm-ld $SONAME $GCSECTIONS $MAP -o $EXE';
|
|
//Info.DllCmd[2] := 'wasmtool --exportrename $INPUT $EXE';
|
|
end;
|
|
|
|
procedure tlinkerwasi.InitSysInitUnitName;
|
|
begin
|
|
sysinitunit:='si_prc';
|
|
end;
|
|
|
|
function tlinkerwasi.MakeExecutable:boolean;
|
|
var
|
|
GCSectionsStr : ansistring;
|
|
binstr, cmdstr : Tcmdstr;
|
|
InitStr,
|
|
FiniStr,
|
|
SoNameStr : string[80];
|
|
mapstr,ltostr : TCmdStr;
|
|
success : Boolean;
|
|
|
|
tmp : TCmdStrListItem;
|
|
tempFileName : ansistring;
|
|
begin
|
|
if not(cs_link_nolink in current_settings.globalswitches) then
|
|
Message1(exec_i_linking,current_module.exefilename);
|
|
|
|
{ Create some replacements }
|
|
mapstr:='';
|
|
if (cs_link_map in current_settings.globalswitches) then
|
|
mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
|
|
if (cs_link_smart in current_settings.globalswitches) and
|
|
create_smartlink_sections then
|
|
GCSectionsStr:='--gc-sections'
|
|
else
|
|
GCSectionsStr:='';
|
|
|
|
SoNameStr:='';
|
|
SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
|
|
Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
|
|
|
|
tmp := TCmdStrListItem(ObjectFiles.First);
|
|
while Assigned(tmp) do begin
|
|
cmdstr := tmp.Str+ ' ' + cmdstr;
|
|
tmp := TCmdStrListItem(tmp.Next);
|
|
end;
|
|
|
|
// if HasExports then
|
|
// cmdstr := cmdstr + ' --export-dynamic'; //' --export-dynamic';
|
|
|
|
cmdstr := cmdstr + ' --no-entry';
|
|
|
|
if (cs_link_strip in current_settings.globalswitches) then
|
|
begin
|
|
{ only remove non global symbols and debugging info for a library }
|
|
cmdstr := cmdstr + ' --strip-all';
|
|
end;
|
|
|
|
//Replace(cmdstr,'$OPT',Info.ExtraOptions);
|
|
//Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
|
|
//Replace(cmdstr,'$INIT',InitStr);
|
|
//Replace(cmdstr,'$FINI',FiniStr);
|
|
Replace(cmdstr,'$SONAME',SoNameStr);
|
|
Replace(cmdstr,'$MAP',mapstr);
|
|
//Replace(cmdstr,'$LTO',ltostr);
|
|
Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
|
|
success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
|
|
|
|
//SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
|
|
//Replace(cmdstr,'$INPUT',current_module.objfilename );
|
|
//Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
|
|
//DoExec(FindUtil(utilsprefix+binstr),cmdstr,false,false);
|
|
|
|
MakeExecutable:=success;
|
|
end;
|
|
|
|
function tlinkerwasi.MakeSharedLibrary: boolean;
|
|
var
|
|
GCSectionsStr : ansistring;
|
|
binstr, cmdstr : Tcmdstr;
|
|
InitStr,
|
|
FiniStr,
|
|
SoNameStr : string[80];
|
|
mapstr,ltostr : TCmdStr;
|
|
success : Boolean;
|
|
|
|
tmp : TCmdStrListItem;
|
|
tempFileName : ansistring;
|
|
begin
|
|
//Result := true;
|
|
//Result:=inherited MakeSharedLibrary;
|
|
if (cs_link_smart in current_settings.globalswitches) and
|
|
create_smartlink_sections then
|
|
GCSectionsStr:='--gc-sections'
|
|
else
|
|
GCSectionsStr:='';
|
|
|
|
SoNameStr:='';
|
|
SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
|
|
Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
|
|
|
|
tmp := TCmdStrListItem(ObjectFiles.First);
|
|
while Assigned(tmp) do begin
|
|
cmdstr := tmp.Str+ ' ' + cmdstr;
|
|
tmp := TCmdStrListItem(tmp.Next);
|
|
end;
|
|
|
|
if HasExports then
|
|
cmdstr := cmdstr + ' --export-dynamic'; //' --export-dynamic';
|
|
|
|
cmdstr := cmdstr + ' --no-entry --allow-undefined';
|
|
|
|
if (cs_link_strip in current_settings.globalswitches) then
|
|
begin
|
|
{ only remove non global symbols and debugging info for a library }
|
|
cmdstr := cmdstr + ' --strip-all';
|
|
end;
|
|
|
|
//Replace(cmdstr,'$OPT',Info.ExtraOptions);
|
|
//Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
|
|
//Replace(cmdstr,'$INIT',InitStr);
|
|
//Replace(cmdstr,'$FINI',FiniStr);
|
|
Replace(cmdstr,'$SONAME',SoNameStr);
|
|
//Replace(cmdstr,'$MAP',mapstr);
|
|
//Replace(cmdstr,'$LTO',ltostr);
|
|
Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
|
|
writeln(utilsprefix+binstr,' ',cmdstr);
|
|
success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
|
|
|
|
//SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
|
|
//Replace(cmdstr,'$INPUT',current_module.objfilename );
|
|
//Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
|
|
//DoExec(FindUtil(utilsprefix+binstr),cmdstr,false,false);
|
|
|
|
MakeSharedLibrary:=success;
|
|
end;
|
|
|
|
{ texportlibwasi }
|
|
|
|
procedure texportlibwasi.preparelib(const s: string);
|
|
begin
|
|
//nothing to happen. wasm files are modules
|
|
end;
|
|
|
|
procedure texportlibwasi.exportprocedure(hp: texported_item);
|
|
var
|
|
nm : TSymStr;
|
|
begin
|
|
nm := tprocdef(tprocsym(hp.sym).ProcdefList[0]).mangledname;
|
|
current_asmdata.asmlists[al_exports].Concat(tai_impexp.create(hp.name^, nm, ie_Func));
|
|
end;
|
|
|
|
procedure texportlibwasi.exportvar(hp: texported_item);
|
|
begin
|
|
//inherited exportvar(hp);
|
|
end;
|
|
|
|
procedure texportlibwasi.generatelib;
|
|
begin
|
|
//inherited generatelib;
|
|
end;
|
|
|
|
initialization
|
|
RegisterTarget(system_wasm32_wasi_info);
|
|
RegisterImport(system_wasm32_wasi, timportlibwasi);
|
|
RegisterExport(system_wasm32_wasi, texportlibwasi);
|
|
RegisterLinker(ld_wasi, tlinkerwasi);
|
|
|
|
end.
|