t_wasi.pas 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. {
  2. Copyright (c) 2019 by Dmitry Boyarintsev
  3. This unit implements support import,export,link routines
  4. for the WASI target
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit t_wasi;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. systems,
  23. globtype, globals,
  24. aasmbase,
  25. cfileutl, cutils, cclasses,
  26. import, export, aasmdata, aasmcpu,
  27. fmodule, ogbase,
  28. symconst, symsym, symdef, symcpu,
  29. link,
  30. i_wasi, tgcpu;
  31. type
  32. { texportlibwasi }
  33. texportlibwasi=class(texportlib)
  34. procedure preparelib(const s : string);override;
  35. procedure exportprocedure(hp : texported_item);override;
  36. procedure exportvar(hp : texported_item);override;
  37. procedure generatelib;override;
  38. end;
  39. { timportlibwasi }
  40. timportlibwasi = class(timportlib)
  41. procedure generatelib;override;
  42. end;
  43. { tlinkerwasi }
  44. tlinkerwasi=class(texternallinker)
  45. public
  46. constructor Create;override;
  47. procedure SetDefaultInfo;override;
  48. procedure InitSysInitUnitName;override;
  49. function MakeExecutable:boolean;override;
  50. function MakeSharedLibrary:boolean;override;
  51. end;
  52. implementation
  53. uses
  54. SysUtils,
  55. verbose;
  56. { timportlibwasi }
  57. procedure timportlibwasi.generatelib;
  58. begin
  59. end;
  60. { tlinkerwasi }
  61. constructor tlinkerwasi.Create;
  62. begin
  63. inherited Create;
  64. end;
  65. procedure tlinkerwasi.SetDefaultInfo;
  66. begin
  67. with Info do
  68. begin
  69. ExeCmd[1] := 'wasm-ld -m wasm32 $SONAME $GCSECTIONS $MAP -z stack-size=$STACKSIZE $OPT -o $EXE';
  70. DllCmd[1] := 'wasm-ld -m wasm32 $SONAME $GCSECTIONS $MAP -z stack-size=$STACKSIZE $OPT -o $EXE';
  71. end;
  72. end;
  73. procedure tlinkerwasi.InitSysInitUnitName;
  74. begin
  75. if current_module.islibrary then
  76. sysinitunit:='si_dll'
  77. else
  78. sysinitunit:='si_prc';
  79. end;
  80. function tlinkerwasi.MakeExecutable:boolean;
  81. var
  82. GCSectionsStr : ansistring;
  83. binstr, cmdstr : Tcmdstr;
  84. InitStr,
  85. FiniStr,
  86. SoNameStr : string[80];
  87. mapstr,ltostr : TCmdStr;
  88. success : Boolean;
  89. tmp : TCmdStrListItem;
  90. tempFileName : ansistring;
  91. begin
  92. if not(cs_link_nolink in current_settings.globalswitches) then
  93. Message1(exec_i_linking,current_module.exefilename);
  94. { Create some replacements }
  95. mapstr:='';
  96. if (cs_link_map in current_settings.globalswitches) then
  97. mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
  98. if (cs_link_smart in current_settings.globalswitches) and
  99. create_smartlink_sections then
  100. GCSectionsStr:='--gc-sections'
  101. else
  102. GCSectionsStr:='';
  103. SoNameStr:='';
  104. SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
  105. Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
  106. tmp := TCmdStrListItem(ObjectFiles.First);
  107. while Assigned(tmp) do begin
  108. cmdstr := tmp.Str+ ' ' + cmdstr;
  109. tmp := TCmdStrListItem(tmp.Next);
  110. end;
  111. // if HasExports then
  112. // cmdstr := cmdstr + ' --export-dynamic'; //' --export-dynamic';
  113. cmdstr := cmdstr + ' --no-entry';
  114. if ts_wasm_threads in current_settings.targetswitches then
  115. begin
  116. cmdstr := cmdstr + ' --import-memory --shared-memory --initial-memory=16777216 --max-memory=16777216 --global-base=1024';
  117. end;
  118. if (cs_link_strip in current_settings.globalswitches) then
  119. begin
  120. { only remove non global symbols and debugging info for a library }
  121. cmdstr := cmdstr + ' --strip-all';
  122. end;
  123. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  124. //Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  125. //Replace(cmdstr,'$INIT',InitStr);
  126. //Replace(cmdstr,'$FINI',FiniStr);
  127. Replace(cmdstr,'$STACKSIZE',tostr(stacksize));
  128. Replace(cmdstr,'$SONAME',SoNameStr);
  129. Replace(cmdstr,'$MAP',mapstr);
  130. //Replace(cmdstr,'$LTO',ltostr);
  131. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  132. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
  133. MakeExecutable:=success;
  134. end;
  135. function tlinkerwasi.MakeSharedLibrary: boolean;
  136. var
  137. GCSectionsStr : ansistring;
  138. binstr, cmdstr : Tcmdstr;
  139. InitStr,
  140. FiniStr,
  141. SoNameStr : string[80];
  142. mapstr,ltostr : TCmdStr;
  143. success : Boolean;
  144. tmp : TCmdStrListItem;
  145. tempFileName : ansistring;
  146. begin
  147. Result:=false;
  148. if not(cs_link_nolink in current_settings.globalswitches) then
  149. Message1(exec_i_linking,current_module.sharedlibfilename);
  150. { Create some replacements }
  151. mapstr:='';
  152. if (cs_link_map in current_settings.globalswitches) then
  153. mapstr:='-Map '+maybequoted(ChangeFileExt(current_module.sharedlibfilename,'.map'));
  154. if (cs_link_smart in current_settings.globalswitches) and
  155. create_smartlink_sections then
  156. GCSectionsStr:='--gc-sections'
  157. else
  158. GCSectionsStr:='';
  159. SoNameStr:='';
  160. SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
  161. Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
  162. tmp := TCmdStrListItem(ObjectFiles.First);
  163. while Assigned(tmp) do begin
  164. cmdstr := tmp.Str+ ' ' + cmdstr;
  165. tmp := TCmdStrListItem(tmp.Next);
  166. end;
  167. // if HasExports then
  168. // cmdstr := cmdstr + ' --export-dynamic'; //' --export-dynamic';
  169. cmdstr := cmdstr + ' --no-entry';
  170. if (cs_link_strip in current_settings.globalswitches) then
  171. begin
  172. { only remove non global symbols and debugging info for a library }
  173. cmdstr := cmdstr + ' --strip-all';
  174. end;
  175. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  176. //Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
  177. //Replace(cmdstr,'$INIT',InitStr);
  178. //Replace(cmdstr,'$FINI',FiniStr);
  179. Replace(cmdstr,'$STACKSIZE',tostr(stacksize));
  180. Replace(cmdstr,'$SONAME',SoNameStr);
  181. Replace(cmdstr,'$MAP',mapstr);
  182. //Replace(cmdstr,'$LTO',ltostr);
  183. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  184. success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
  185. MakeSharedLibrary:=success;
  186. end;
  187. { texportlibwasi }
  188. procedure texportlibwasi.preparelib(const s: string);
  189. begin
  190. //nothing to happen. wasm files are modules
  191. end;
  192. procedure texportlibwasi.exportprocedure(hp: texported_item);
  193. var
  194. nm : TSymStr;
  195. pd: tcpuprocdef;
  196. begin
  197. pd:=tcpuprocdef(tprocsym(hp.sym).ProcdefList[0]);
  198. if eo_promising_first in hp.options then
  199. pd.add_promising_export(hp.name^,false)
  200. else if eo_promising_last in hp.options then
  201. pd.add_promising_export(hp.name^,true)
  202. else
  203. begin
  204. nm := pd.mangledname;
  205. current_asmdata.asmlists[al_exports].Concat(tai_export_name.create(hp.name^, nm, ie_Func));
  206. end;
  207. end;
  208. procedure texportlibwasi.exportvar(hp: texported_item);
  209. begin
  210. //inherited exportvar(hp);
  211. end;
  212. procedure texportlibwasi.generatelib;
  213. begin
  214. //inherited generatelib;
  215. end;
  216. initialization
  217. RegisterTarget(system_wasm32_wasi_info);
  218. RegisterImport(system_wasm32_wasi, timportlibwasi);
  219. RegisterExport(system_wasm32_wasi, texportlibwasi);
  220. RegisterLinker(ld_wasi, tlinkerwasi);
  221. end.