2
0

dbgjasm.pas 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. instrcount : longint;
  85. begin
  86. { insert debug information for local variables and parameters, but only
  87. for routines implemented in the Pascal code }
  88. if not assigned(def.procstarttai) then
  89. exit;
  90. current_asmdata.getlabel(procstartlabel,alt_dbgtype);
  91. current_asmdata.getlabel(procendlabel,alt_dbgtype);
  92. tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(procstartlabel),def.procstarttai);
  93. tcpuprocdef(def).exprasmlist.insertbefore(tai_label.create(procendlabel),def.procendtai);
  94. fcurrprocstart:=procstartlabel;
  95. { set the start label for local variables after the first instruction,
  96. because javac's code completion support assumes that all info at
  97. bytecode position 0 is for parameters }
  98. instrcount:=0;
  99. afterproccodestart:=def.procstarttai;
  100. while assigned(afterproccodestart.next) do
  101. begin
  102. afterproccodestart:=tai(afterproccodestart.next);
  103. if (afterproccodestart.typ=ait_instruction) then
  104. break;
  105. end;
  106. { must be followed by at least one more instruction }
  107. hp:=tai(afterproccodestart.next);
  108. while assigned(hp) do
  109. begin
  110. if hp.typ=ait_instruction then
  111. break;
  112. hp:=tai(hp.next);
  113. end;
  114. if assigned(hp) then
  115. begin
  116. current_asmdata.getlabel(afterprocstartlabel,alt_dbgtype);
  117. tcpuprocdef(def).exprasmlist.insertafter(tai_label.create(afterprocstartlabel),afterproccodestart);
  118. fcurrprocafterstart:=afterprocstartlabel;
  119. end
  120. else
  121. fcurrprocafterstart:=procstartlabel;
  122. fcurrprocend:=procendlabel;
  123. write_symtable_parasyms(list,def.paras);
  124. { not assigned for unit init }
  125. if assigned(def.localst) then
  126. write_symtable_syms(list,def.localst);
  127. end;
  128. procedure TDebugInfoJasmin.inserttypeinfo;
  129. begin
  130. { write all procedures and methods }
  131. if assigned(current_module.globalsymtable) then
  132. write_symtable_procdefs(nil,current_module.globalsymtable);
  133. if assigned(current_module.localsymtable) then
  134. write_symtable_procdefs(nil,current_module.localsymtable);
  135. end;
  136. procedure TDebugInfoJasmin.insertlineinfo(list: TAsmList);
  137. var
  138. currfileinfo,
  139. lastfileinfo : tfileposinfo;
  140. nolineinfolevel : Integer;
  141. currfuncname : pshortstring;
  142. hp : tai;
  143. begin
  144. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  145. hp:=Tai(list.first);
  146. nolineinfolevel:=0;
  147. while assigned(hp) do
  148. begin
  149. case hp.typ of
  150. ait_function_name :
  151. begin
  152. currfuncname:=tai_function_name(hp).funcname;
  153. list.concat(tai_comment.Create(strpnew('function: '+currfuncname^)));
  154. end;
  155. ait_force_line :
  156. begin
  157. lastfileinfo.line:=-1;
  158. end;
  159. ait_marker :
  160. begin
  161. case tai_marker(hp).kind of
  162. mark_NoLineInfoStart:
  163. inc(nolineinfolevel);
  164. mark_NoLineInfoEnd:
  165. dec(nolineinfolevel);
  166. end;
  167. end;
  168. end;
  169. { Java does not support multiple source files }
  170. if (hp.typ=ait_instruction) and
  171. (nolineinfolevel=0) and
  172. (tailineinfo(hp).fileinfo.fileindex=main_module.unit_index) then
  173. begin
  174. currfileinfo:=tailineinfo(hp).fileinfo;
  175. { line changed ? }
  176. if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
  177. begin
  178. { line directive }
  179. list.insertbefore(tai_directive.Create(asd_jline,tostr(currfileinfo.line)),hp);
  180. end;
  181. lastfileinfo:=currfileinfo;
  182. end;
  183. hp:=tai(hp.next);
  184. end;
  185. end;
  186. {****************************************************************************
  187. ****************************************************************************}
  188. const
  189. dbg_jasmin_info : tdbginfo =
  190. (
  191. id : dbg_jasmin;
  192. idtxt : 'JASMIN';
  193. );
  194. initialization
  195. RegisterDebugInfo(dbg_jasmin_info,TDebugInfoJasmin);
  196. end.