ogrel.pas 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. {
  2. Copyright (c) 2020 by Nikolay Nikolov
  3. Contains the ASCII relocatable object file format (*.rel) reader and writer
  4. This is the object format used on the Z80 platforms.
  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 ogrel;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cclasses,globtype,
  24. { target }
  25. systems,
  26. { assembler }
  27. cpuinfo,cpubase,aasmbase,assemble,link,
  28. { output }
  29. ogbase,
  30. owbase;
  31. type
  32. { TRelObjData }
  33. TRelObjData = class(TObjData)
  34. public
  35. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  36. procedure writeReloc(Data:TRelocDataInt;len:aword;p:TObjSymbol;Reloctype:TObjRelocationType);override;
  37. end;
  38. { TRelObjOutput }
  39. TRelObjOutput = class(tObjOutput)
  40. private
  41. procedure writeString(const S: ansistring);
  42. procedure writeLine(const S: ansistring);
  43. protected
  44. function writeData(Data:TObjData):boolean;override;
  45. public
  46. constructor create(AWriter:TObjectWriter);override;
  47. end;
  48. { TRelAssembler }
  49. TRelAssembler = class(tinternalassembler)
  50. constructor create(info: pasminfo; smart:boolean);override;
  51. end;
  52. implementation
  53. uses
  54. SysUtils,
  55. cutils,verbose,globals,
  56. fmodule,aasmtai,aasmdata,
  57. ogmap,
  58. version
  59. ;
  60. function tohex(q: qword): string;
  61. begin
  62. result:=HexStr(q,16);
  63. while (Length(result)>1) and (result[1]='0') do
  64. delete(result,1,1);
  65. end;
  66. {*****************************************************************************
  67. TRelObjData
  68. *****************************************************************************}
  69. function TRelObjData.sectionname(atype: TAsmSectiontype; const aname: string; aorder: TAsmSectionOrder): string;
  70. const
  71. secnames : array[TAsmSectiontype] of string[length('__DATA, __datacoal_nt,coalesced')] = ('','',
  72. '_CODE',
  73. '_DATA',
  74. '_DATA',
  75. '.rodata',
  76. '.bss',
  77. '.threadvar',
  78. '.pdata',
  79. '', { stubs }
  80. '__DATA,__nl_symbol_ptr',
  81. '__DATA,__la_symbol_ptr',
  82. '__DATA,__mod_init_func',
  83. '__DATA,__mod_term_func',
  84. '.stab',
  85. '.stabstr',
  86. '.idata$2','.idata$4','.idata$5','.idata$6','.idata$7','.edata',
  87. '.eh_frame',
  88. '.debug_frame','.debug_info','.debug_line','.debug_abbrev','.debug_aranges','.debug_ranges',
  89. '.fpc',
  90. '.toc',
  91. '.init',
  92. '.fini',
  93. '.objc_class',
  94. '.objc_meta_class',
  95. '.objc_cat_cls_meth',
  96. '.objc_cat_inst_meth',
  97. '.objc_protocol',
  98. '.objc_string_object',
  99. '.objc_cls_meth',
  100. '.objc_inst_meth',
  101. '.objc_cls_refs',
  102. '.objc_message_refs',
  103. '.objc_symbols',
  104. '.objc_category',
  105. '.objc_class_vars',
  106. '.objc_instance_vars',
  107. '.objc_module_info',
  108. '.objc_class_names',
  109. '.objc_meth_var_types',
  110. '.objc_meth_var_names',
  111. '.objc_selector_strs',
  112. '.objc_protocol_ext',
  113. '.objc_class_ext',
  114. '.objc_property',
  115. '.objc_image_info',
  116. '.objc_cstring_object',
  117. '.objc_sel_fixup',
  118. '__DATA,__objc_data',
  119. '__DATA,__objc_const',
  120. '.objc_superrefs',
  121. '__DATA, __datacoal_nt,coalesced',
  122. '.objc_classlist',
  123. '.objc_nlclasslist',
  124. '.objc_catlist',
  125. '.obcj_nlcatlist',
  126. '.objc_protolist',
  127. '.stack',
  128. '.heap',
  129. '.gcc_except_table',
  130. '.ARM.attributes'
  131. );
  132. begin
  133. result:=secnames[atype];
  134. end;
  135. procedure TRelObjData.writeReloc(Data: TRelocDataInt; len: aword; p: TObjSymbol; Reloctype: TObjRelocationType);
  136. var
  137. bytes: array [0..1] of Byte;
  138. begin
  139. if len=2 then
  140. begin
  141. bytes[0]:=Byte(Data);
  142. bytes[1]:=Byte(Data shr 8);
  143. writebytes(bytes,2);
  144. end
  145. else if len=1 then
  146. begin
  147. bytes[0]:=Byte(Data);
  148. writebytes(bytes,1);
  149. end;
  150. end;
  151. {*****************************************************************************
  152. TRelObjOutput
  153. *****************************************************************************}
  154. procedure TRelObjOutput.writeString(const S: ansistring);
  155. begin
  156. FWriter.write(S[1],Length(S));
  157. end;
  158. procedure TRelObjOutput.writeLine(const S: ansistring);
  159. begin
  160. writeString(S+#10)
  161. end;
  162. function TRelObjOutput.writeData(Data: TObjData): boolean;
  163. var
  164. global_symbols_count: Integer = 0;
  165. secidx, idx, i, j: Integer;
  166. objsym: TObjSymbol;
  167. objsec: TObjSection;
  168. begin
  169. global_symbols_count:=0;
  170. for i:=0 to Data.ObjSymbolList.Count-1 do
  171. begin
  172. objsym:=TObjSymbol(Data.ObjSymbolList[i]);
  173. if objsym.bind in [AB_EXTERNAL,AB_GLOBAL] then
  174. Inc(global_symbols_count);
  175. end;
  176. writeLine('XL2');
  177. writeLine('H '+tohex(data.ObjSectionList.Count)+' areas '+tohex(global_symbols_count)+' global symbols');
  178. idx:=0;
  179. for i:=0 to Data.ObjSymbolList.Count-1 do
  180. begin
  181. objsym:=TObjSymbol(Data.ObjSymbolList[i]);
  182. if objsym.bind=AB_EXTERNAL then
  183. begin
  184. writeLine('S '+ApplyAsmSymbolRestrictions(objsym.Name)+' Ref0000');
  185. objsym.symidx:=idx;
  186. Inc(idx);
  187. end;
  188. end;
  189. secidx:=0;
  190. for i:=0 to Data.ObjSectionList.Count-1 do
  191. begin
  192. objsec:=TObjSection(Data.ObjSectionList[i]);
  193. writeLine('A '+objsec.Name+' size '+tohex(objsec.Size)+' flags 0 addr 0');
  194. objsec.SecSymIdx:=secidx;
  195. Inc(secidx);
  196. for j:=0 to Data.ObjSymbolList.Count-1 do
  197. begin
  198. objsym:=TObjSymbol(Data.ObjSymbolList[j]);
  199. if (objsym.bind=AB_GLOBAL) and (objsym.objsection=objsec) then
  200. begin
  201. writeLine('S '+ApplyAsmSymbolRestrictions(objsym.Name)+' Def'+HexStr(objsym.offset,4));
  202. objsym.symidx:=idx;
  203. Inc(idx);
  204. end;
  205. end;
  206. end;
  207. result:=true;
  208. end;
  209. constructor TRelObjOutput.create(AWriter: TObjectWriter);
  210. begin
  211. inherited;
  212. cobjdata:=TRelObjData;
  213. end;
  214. {*****************************************************************************
  215. TRelAssembler
  216. *****************************************************************************}
  217. constructor TRelAssembler.create(info: pasminfo; smart: boolean);
  218. begin
  219. inherited;
  220. CObjOutput:=TRelObjOutput;
  221. end;
  222. {*****************************************************************************
  223. Initialize
  224. *****************************************************************************}
  225. const
  226. as_z80_rel_info : tasminfo =
  227. (
  228. id : as_z80_rel;
  229. idtxt : 'REL';
  230. asmbin : '';
  231. asmcmd : '';
  232. supported_targets : [system_z80_embedded,system_z80_zxspectrum];
  233. flags : [af_outputbinary,af_smartlink_sections];
  234. labelprefix : '..@';
  235. labelmaxlen : 79;
  236. comment : '; ';
  237. dollarsign: '$';
  238. );
  239. initialization
  240. RegisterAssembler(as_z80_rel_info,TRelAssembler);
  241. end.