t_human68k.pas 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. {
  2. Copyright (c) 2020 by Free Pascal Development Team
  3. This unit implements support import, export, link routines
  4. for the Human 68k (a.k.a. Sharp X68000) 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_human68k;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. rescmn, comprsrc, link;
  23. type
  24. PLinkerHuman68k = ^TLinkerHuman68k;
  25. TLinkerHuman68k = class(texternallinker)
  26. private
  27. Origin: DWord;
  28. UseVLink: boolean;
  29. function WriteResponseFile(isdll: boolean): boolean;
  30. procedure SetHuman68kInfo;
  31. function MakeHuman68kExe: boolean;
  32. public
  33. constructor Create; override;
  34. procedure SetDefaultInfo; override;
  35. procedure InitSysInitUnitName; override;
  36. function MakeExecutable: boolean; override;
  37. end;
  38. implementation
  39. uses
  40. sysutils,cutils,cfileutl,cclasses,aasmbase,
  41. globtype,globals,systems,verbose,cscript,fmodule,i_human68k;
  42. constructor TLinkerHuman68k.Create;
  43. begin
  44. UseVLink:=(cs_link_vlink in current_settings.globalswitches);
  45. Inherited Create;
  46. { allow duplicated libs (PM) }
  47. SharedLibFiles.doubles:=true;
  48. StaticLibFiles.doubles:=true;
  49. end;
  50. procedure TLinkerHuman68k.SetHuman68kInfo;
  51. begin
  52. with Info do
  53. begin
  54. if not UseVLink then
  55. begin
  56. ExeCmd[1]:='ld -b xfile -m human68kxfile $DYNLINK $GCSECTIONS $OPT $MAP -d -n -o $EXE $RES';
  57. end
  58. else
  59. begin
  60. ExeCmd[1]:='vlink -b xfile $FLAGS $GCSECTIONS $OPT $STRIP $MAP -o $EXE -T $RES';
  61. end;
  62. end;
  63. end;
  64. procedure TLinkerHuman68k.SetDefaultInfo;
  65. begin
  66. if target_info.system = system_m68k_human68k then
  67. SetHuman68kInfo;
  68. end;
  69. procedure TLinkerHuman68k.InitSysInitUnitName;
  70. begin
  71. sysinitunit:='si_prc';
  72. end;
  73. function TLinkerHuman68k.WriteResponseFile(isdll: boolean): boolean;
  74. var
  75. linkres : TLinkRes;
  76. HPath : TCmdStrListItem;
  77. s : string;
  78. begin
  79. WriteResponseFile:=False;
  80. { Open link.res file }
  81. LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true);
  82. if UseVLink and (source_info.dirsep <> '/') then
  83. LinkRes.fForceUseForwardSlash:=true;
  84. { Write path to search libraries }
  85. HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
  86. while assigned(HPath) do
  87. begin
  88. s:=HPath.Str;
  89. if (cs_link_on_target in current_settings.globalswitches) then
  90. s:=ScriptFixFileName(s);
  91. LinkRes.Add('-L'+s);
  92. HPath:=TCmdStrListItem(HPath.Next);
  93. end;
  94. HPath:=TCmdStrListItem(LibrarySearchPath.First);
  95. while assigned(HPath) do
  96. begin
  97. s:=HPath.Str;
  98. if s<>'' then
  99. LinkRes.Add('SEARCH_DIR("'+s+'")');
  100. HPath:=TCmdStrListItem(HPath.Next);
  101. end;
  102. LinkRes.Add('INPUT (');
  103. { add objectfiles, start with prt0 always }
  104. if not (target_info.system in systems_internal_sysinit) then
  105. begin
  106. s:=FindObjectFile('prt0','',false);
  107. LinkRes.AddFileName(maybequoted(s));
  108. end;
  109. while not ObjectFiles.Empty do
  110. begin
  111. s:=ObjectFiles.GetFirst;
  112. if s<>'' then
  113. begin
  114. { vlink doesn't use SEARCH_DIR for object files }
  115. if UseVLink then
  116. s:=FindObjectFile(s,'',false);
  117. LinkRes.AddFileName(maybequoted(s));
  118. end;
  119. end;
  120. { Write staticlibraries }
  121. if not StaticLibFiles.Empty then
  122. begin
  123. { vlink doesn't need, and doesn't support GROUP }
  124. if not UseVLink then
  125. begin
  126. LinkRes.Add(')');
  127. LinkRes.Add('GROUP(');
  128. end;
  129. while not StaticLibFiles.Empty do
  130. begin
  131. S:=StaticLibFiles.GetFirst;
  132. LinkRes.AddFileName(maybequoted(s));
  133. end;
  134. end;
  135. LinkRes.Add(')');
  136. { Write and Close response }
  137. linkres.writetodisk;
  138. linkres.free;
  139. WriteResponseFile:=True;
  140. end;
  141. function TLinkerHuman68k.MakeHuman68kExe: boolean;
  142. var
  143. BinStr,
  144. CmdStr : TCmdStr;
  145. StripStr: string[40];
  146. DynLinkStr : ansistring;
  147. GCSectionsStr : string;
  148. FlagsStr : string;
  149. MapStr: string;
  150. ExeName: string;
  151. begin
  152. StripStr:='';
  153. GCSectionsStr:='';
  154. DynLinkStr:='';
  155. MapStr:='';
  156. FlagsStr:='';
  157. if (cs_link_map in current_settings.globalswitches) then
  158. if UseVLink then
  159. MapStr:='-M'+maybequoted(ScriptFixFileName(current_module.mapfilename))
  160. else
  161. MapStr:='-Map '+maybequoted(ScriptFixFileName(current_module.mapfilename));
  162. if (cs_link_strip in current_settings.globalswitches) then
  163. StripStr:='-s';
  164. if rlinkpath<>'' then
  165. DynLinkStr:='--rpath-link '+rlinkpath;
  166. if UseVLink then
  167. begin
  168. if create_smartlink_sections then
  169. GCSectionsStr:='-gc-all -sc';
  170. end
  171. else
  172. if (cs_link_smart in current_settings.globalswitches) and
  173. create_smartlink_sections then
  174. GCSectionsStr:='--gc-sections';
  175. ExeName:=current_module.exefilename;
  176. { Call linker }
  177. SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr);
  178. binstr:=FindUtil(utilsprefix+BinStr);
  179. Replace(cmdstr,'$OPT',Info.ExtraOptions);
  180. Replace(cmdstr,'$EXE',maybequoted(ScriptFixFileName(ExeName)));
  181. Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName)));
  182. Replace(cmdstr,'$MAP',MapStr);
  183. Replace(cmdstr,'$FLAGS',FlagsStr);
  184. Replace(cmdstr,'$STRIP',StripStr);
  185. Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
  186. Replace(cmdstr,'$DYNLINK',DynLinkStr);
  187. MakeHuman68kExe:=DoExec(BinStr,CmdStr,true,false);
  188. end;
  189. function TLinkerHuman68k.MakeExecutable:boolean;
  190. var
  191. success : boolean;
  192. bootfile : TScript;
  193. ExeName: String;
  194. begin
  195. if not(cs_link_nolink in current_settings.globalswitches) then
  196. Message1(exec_i_linking,current_module.exefilename);
  197. { Write used files and libraries }
  198. WriteResponseFile(false);
  199. success:=MakeHuman68kExe;
  200. { Remove ReponseFile }
  201. if (success) and not(cs_link_nolink in current_settings.globalswitches) then
  202. DeleteFile(outputexedir+Info.ResName);
  203. MakeExecutable:=success; { otherwise a recursive call to link method }
  204. end;
  205. {*****************************************************************************
  206. Initialize
  207. *****************************************************************************}
  208. initialization
  209. RegisterLinker(ld_human68k,TLinkerHuman68k);
  210. RegisterTarget(system_m68k_human68k_info);
  211. end.