dbgjasm.pas 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. {
  2. Copyright (c) 2003-2006 by Peter Vreman, Florian Klaempfl, and Jonas Maebe
  3. This units contains support for Jasmin debug info generation
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit dbgjasm;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,globtype,
  22. aasmbase,aasmtai,aasmdata,
  23. symbase,symconst,symtype,symdef,symsym,
  24. finput,
  25. DbgBase;
  26. type
  27. { TDebugInfoJasmin }
  28. TDebugInfoJasmin=class(TDebugInfo)
  29. protected
  30. fcurrprocstart,
  31. fcurrprocafterstart,
  32. fcurrprocend: tasmsymbol;
  33. procedure appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym; startlab: tasmsymbol);
  34. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  35. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  36. procedure beforeappenddef(list:TAsmList;def:tdef);override;
  37. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  38. public
  39. procedure inserttypeinfo;override;
  40. procedure insertlineinfo(list:TAsmList);override;
  41. end;
  42. implementation
  43. uses
  44. sysutils,cutils,cfileutl,constexp,
  45. version,globals,verbose,systems,
  46. cpubase,cpuinfo,cgbase,paramgr,
  47. fmodule,
  48. defutil,symtable,symcpu,jvmdef,ppu
  49. ;
  50. {****************************************************************************
  51. TDebugInfoJasmin
  52. ****************************************************************************}
  53. procedure TDebugInfoJasmin.appendsym_localsym(list: TAsmList; sym: tabstractnormalvarsym; startlab: tasmsymbol);
  54. var
  55. jvar: tai_jvar;
  56. proc: tprocdef;
  57. begin
  58. if tdef(sym.owner.defowner).typ<>procdef then
  59. exit;
  60. if not(sym.localloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  61. exit;
  62. proc:=tprocdef(sym.owner.defowner);
  63. jvar:=tai_jvar.create(sym.localloc.reference.offset,jvmmangledbasename(sym,true),startlab,fcurrprocend);
  64. tcpuprocdef(proc).exprasmlist.InsertAfter(jvar,proc.procstarttai);
  65. end;
  66. procedure TDebugInfoJasmin.appendsym_paravar(list: TAsmList; sym: tparavarsym);
  67. begin
  68. appendsym_localsym(list,sym,fcurrprocstart);
  69. end;
  70. procedure TDebugInfoJasmin.appendsym_localvar(list: TAsmList; sym: tlocalvarsym);
  71. begin
  72. appendsym_localsym(list,sym,fcurrprocafterstart);
  73. end;
  74. procedure TDebugInfoJasmin.beforeappenddef(list: TAsmList; def: tdef);
  75. begin
  76. end;
  77. procedure TDebugInfoJasmin.appendprocdef(list: TAsmList; def: tprocdef);
  78. var
  79. procstartlabel,
  80. procendlabel,
  81. afterprocstartlabel : tasmlabel;
  82. hp,
  83. afterproccodestart : tai;
  84. begin
  85. { insert debug information for local variables and parameters, but only
  86. for routines implemented in the Pascal code }
  87. if not assigned(def.procstarttai) then
  88. exit;
  89. current_asmdata.getlabel(procstartlabel,alt_dbgtype);
  90. current_asmdata.getlabel(procendlabel,alt_dbgtype);
  91. tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(procstartlabel),def.procstarttai);
  92. tcpuprocdef(def).exprasmlist.insertbefore(tai_label.create(procendlabel),def.procendtai);
  93. fcurrprocstart:=procstartlabel;
  94. { set the start label for local variables after the first instruction,
  95. because javac's code completion support assumes that all info at
  96. bytecode position 0 is for parameters }
  97. afterproccodestart:=def.procstarttai;
  98. while assigned(afterproccodestart.next) do
  99. begin
  100. afterproccodestart:=tai(afterproccodestart.next);
  101. if (afterproccodestart.typ=ait_instruction) then
  102. break;
  103. end;
  104. { must be followed by at least one more instruction }
  105. hp:=tai(afterproccodestart.next);
  106. while assigned(hp) do
  107. begin
  108. if hp.typ=ait_instruction then
  109. break;
  110. hp:=tai(hp.next);
  111. end;
  112. if assigned(hp) then
  113. begin
  114. current_asmdata.getlabel(afterprocstartlabel,alt_dbgtype);
  115. tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(afterprocstartlabel),afterproccodestart);
  116. fcurrprocafterstart:=afterprocstartlabel;
  117. end
  118. else
  119. fcurrprocafterstart:=procstartlabel;
  120. fcurrprocend:=procendlabel;
  121. write_symtable_parasyms(list,def.paras);
  122. { not assigned for unit init }
  123. if assigned(def.localst) then
  124. write_symtable_syms(list,def.localst);
  125. end;
  126. procedure TDebugInfoJasmin.inserttypeinfo;
  127. begin
  128. { write all procedures and methods }
  129. if assigned(current_module.globalsymtable) then
  130. write_symtable_procdefs(nil,current_module.globalsymtable);
  131. if assigned(current_module.localsymtable) then
  132. write_symtable_procdefs(nil,current_module.localsymtable);
  133. end;
  134. procedure TDebugInfoJasmin.insertlineinfo(list: TAsmList);
  135. var
  136. currfileinfo,
  137. lastfileinfo : tfileposinfo;
  138. nolineinfolevel : Integer;
  139. currfuncname : pshortstring;
  140. hp : tai;
  141. begin
  142. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  143. hp:=Tai(list.first);
  144. nolineinfolevel:=0;
  145. while assigned(hp) do
  146. begin
  147. case hp.typ of
  148. ait_function_name :
  149. begin
  150. currfuncname:=tai_function_name(hp).funcname;
  151. list.concat(tai_comment.Create(strpnew('function: '+currfuncname^)));
  152. end;
  153. ait_force_line :
  154. begin
  155. lastfileinfo.line:=-1;
  156. end;
  157. ait_marker :
  158. begin
  159. case tai_marker(hp).kind of
  160. mark_NoLineInfoStart:
  161. inc(nolineinfolevel);
  162. mark_NoLineInfoEnd:
  163. dec(nolineinfolevel);
  164. else
  165. ;
  166. end;
  167. end;
  168. else
  169. ;
  170. end;
  171. { Java does not support multiple source files }
  172. if (hp.typ=ait_instruction) and
  173. (nolineinfolevel=0) and
  174. (tailineinfo(hp).fileinfo.fileindex=main_module.unit_index) then
  175. begin
  176. currfileinfo:=tailineinfo(hp).fileinfo;
  177. { line changed ? }
  178. if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
  179. begin
  180. { line directive }
  181. list.insertbefore(tai_directive.Create(asd_jline,tostr(currfileinfo.line)),hp);
  182. end;
  183. lastfileinfo:=currfileinfo;
  184. end;
  185. hp:=tai(hp.next);
  186. end;
  187. end;
  188. {****************************************************************************
  189. ****************************************************************************}
  190. const
  191. dbg_jasmin_info : tdbginfo =
  192. (
  193. id : dbg_jasmin;
  194. idtxt : 'JASMIN';
  195. );
  196. initialization
  197. RegisterDebugInfo(dbg_jasmin_info,TDebugInfoJasmin);
  198. end.