gdb.pas 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This units contains special support for the GDB
  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 gdb;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. {$ifdef delphi}
  23. sysutils,
  24. {$else}
  25. strings,
  26. {$endif}
  27. globtype,cpubase,
  28. globals,aasmtai;
  29. {stab constants }
  30. Const
  31. N_GSYM = $20;
  32. N_STSYM = 38; {initialized const }
  33. N_LCSYM = 40; {non initialized variable}
  34. N_Function = $24; {function or const }
  35. N_TextLine = $44;
  36. N_DataLine = $46;
  37. N_BssLine = $48;
  38. N_RSYM = $40; { register variable }
  39. N_LSYM = $80;
  40. N_tsym = 160;
  41. N_SourceFile = $64;
  42. N_IncludeFile = $84;
  43. N_BINCL = $82;
  44. N_EINCL = $A2;
  45. N_EXCL = $C2;
  46. type
  47. tai_stabs = class(tai)
  48. str : pchar;
  49. constructor Create(_str : pchar);
  50. destructor Destroy;override;
  51. end;
  52. tai_stabn = class(tai)
  53. str : pchar;
  54. constructor Create(_str : pchar);
  55. destructor Destroy;override;
  56. end;
  57. { insert a cut to split into several smaller files }
  58. tai_force_line = class(tai)
  59. constructor Create;
  60. end;
  61. tai_stab_function_name = class(tai)
  62. str : pchar;
  63. constructor create(_str : pchar);
  64. destructor destroy;override;
  65. end;
  66. const
  67. DBX_counter : plongint = nil;
  68. do_count_dbx : boolean = false;
  69. {$ifdef i386}
  70. { this is the register order for GDB }
  71. { this is indeed the internal order of
  72. registers in GDB, but as we use STABS,
  73. the values are converted using
  74. i386_stab_reg_to_regnum from i386_tdep.c PM }
  75. { 0 "eax", "ecx", "edx", "ebx", \
  76. 4 "esp", "ebp", "esi", "edi", \
  77. 8 "eip", "eflags", "cs", "ss", \
  78. 12 "ds", "es", "fs", "gs", \
  79. 16 "st0", "st1", "st2", "st3", \
  80. 20 "st4", "st5", "st6", "st7", \
  81. 24 "fctrl", "fstat", "ftag", "fiseg", \
  82. 28 "fioff", "foseg", "fooff", "fop", \
  83. 32 "xmm0", "xmm1", "xmm2", "xmm3", \
  84. 36 "xmm4", "xmm5", "xmm6", "xmm7", \
  85. 40 "mxcsr" \
  86. }
  87. { tregister = (R_NO,
  88. R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI,
  89. R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI,
  90. R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_BH,R_DH,
  91. R_CS,R_DS,R_ES,R_SS,R_FS,R_GS,
  92. R_ST,R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7,
  93. R_DR0,R_DR1,R_DR2,R_DR3,R_DR6,R_DR7,
  94. R_CR0,R_CR2,R_CR3,R_CR4,
  95. R_TR3,R_TR4,R_TR5,R_TR6,R_TR7,
  96. R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7,
  97. R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7
  98. ); }
  99. { So here we need to use the stabs numbers PM }
  100. GDB_i386index : array[tregister] of shortint =(-1,
  101. 0,1,2,3,4,5,6,7,
  102. 0,1,2,3,4,5,6,7,
  103. 0,1,2,3,0,1,2,3,
  104. -1,-1,-1,-1,-1,-1,
  105. 12,12,13,14,15,16,17,18,19,
  106. -1,-1,-1,-1,-1,-1,
  107. -1,-1,-1,-1,
  108. -1,-1,-1,-1,-1,
  109. { I think, GDB doesn't know MMX (FK)
  110. GDB does not, but stabs does PM }
  111. 29,30,31,32,33,34,35,36,
  112. 21,22,23,24,25,26,27,28
  113. );
  114. {$endif i386}
  115. {$ifdef m68k}
  116. { "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  117. "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp",
  118. "ps", "pc", "fp0", "fp1", "fp2", "fp3", "fp4" ,
  119. "fp5", "fp6", "fp7", "fpcontrol", "fpstatus",
  120. "fpiaddr","fpcode","fpflags"
  121. }
  122. { this is the register order for GDB }
  123. GDB_m68kindex : array[tregister] of shortint =
  124. (-1, { R_NO }
  125. 0,1,2,3,4,5,6,7, { R_D0..R_D7 }
  126. 8,9,10,11,12,13,14,15, { R_A0..R_A7 }
  127. -1,-1,-1, { R_SPPUSH, R_SPPULL, R_CCR }
  128. 18,19,20,21,22,23,24,25, { R_FP0..R_FP7 }
  129. -1,-1,-1,-1,-1,-1,-1,-1
  130. );
  131. {$endif}
  132. {$IFDEF SPARC}
  133. GDB_SPARC_index:ARRAY[tregister]OF ShortInt=(0,0,0,0,0,0,0,0,0,0,0,0,0,
  134. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  135. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  136. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  137. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  138. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  139. {$ENDIF SPARC}
  140. implementation
  141. { to use N_EXCL we have to count the character in the stabs for
  142. N_BINCL to N_EINCL
  143. Code comes from stabs.c for ld
  144. if (type == N_BINCL)
  145. (
  146. bfd_vma val;
  147. int nest;
  148. bfd_byte *incl_sym;
  149. struct stab_link_includes_entry *incl_entry;
  150. struct stab_link_includes_totals *t;
  151. struct stab_excl_list *ne;
  152. val = 0;
  153. nest = 0;
  154. for (incl_sym = sym + STABSIZE;
  155. incl_sym < symend;
  156. incl_sym += STABSIZE)
  157. (
  158. int incl_type;
  159. incl_type = incl_sym[TYPEOFF];
  160. if (incl_type == 0)
  161. break;
  162. else if (incl_type == N_EINCL)
  163. (
  164. if (nest == 0)
  165. break;
  166. --nest;
  167. )
  168. else if (incl_type == N_BINCL)
  169. ++nest;
  170. else if (nest == 0)
  171. (
  172. const char *str;
  173. str = ((char *) stabstrbuf
  174. + stroff
  175. + bfd_get_32 (abfd, incl_sym + STRDXOFF));
  176. for (; *str != '\0'; str++)
  177. (
  178. val += *str;
  179. if *str == '('
  180. (
  181. Skip the file number.
  182. ++str;
  183. while (isdigit ((unsigned char) *str))
  184. ++str;
  185. --str;
  186. )
  187. )
  188. )
  189. ) }
  190. procedure count_dbx(st : pchar);
  191. var i : longint;
  192. do_count : boolean;
  193. begin
  194. do_count := false;
  195. if assigned(dbx_counter) then
  196. begin
  197. {$IfDef ExtDebugDbx }
  198. Comment(V_Info,'Counting '+st);
  199. Comment(V_Info,'count = '+tostr(dbx_counter^));
  200. Comment(V_Info,'addr = '+tostr(longint(dbx_counter)));
  201. {$EndIf ExtDebugDbx }
  202. i:=0;
  203. while i<=strlen(st) do
  204. begin
  205. if st[i] = '"' then
  206. if do_count then exit
  207. else do_count := true
  208. else
  209. if do_count then
  210. begin
  211. dbx_counter^ := dbx_counter^+byte(st[i]);
  212. { skip file number }
  213. if st[i] = '(' then
  214. begin
  215. inc(i);
  216. while st[i] in ['0'..'9'] do inc(i);
  217. dec(i);
  218. end;
  219. end;
  220. inc(i);
  221. end;
  222. end;
  223. end;
  224. constructor tai_stabs.create(_str : pchar);
  225. begin
  226. inherited create;
  227. typ:=ait_stabs;
  228. str:=_str;
  229. if do_count_dbx then
  230. begin
  231. count_dbx(str);
  232. end;
  233. end;
  234. destructor tai_stabs.destroy;
  235. begin
  236. strdispose(str);
  237. inherited destroy;
  238. end;
  239. constructor tai_stabn.create(_str : pchar);
  240. begin
  241. inherited create;
  242. typ:=ait_stabn;
  243. str:=_str;
  244. end;
  245. destructor tai_stabn.destroy;
  246. begin
  247. strdispose(str);
  248. inherited destroy;
  249. end;
  250. constructor tai_force_line.create;
  251. begin
  252. inherited create;
  253. typ:=ait_force_line;
  254. end;
  255. constructor tai_stab_function_name.create(_str : pchar);
  256. begin
  257. inherited create;
  258. typ:=ait_stab_function_name;
  259. str:=_str;
  260. end;
  261. destructor tai_stab_function_name.destroy;
  262. begin
  263. strdispose(str);
  264. inherited destroy;
  265. end;
  266. end.
  267. {
  268. $Log$
  269. Revision 1.14 2002-07-01 18:46:22 peter
  270. * internal linker
  271. * reorganized aasm layer
  272. Revision 1.13 2002/05/18 13:34:08 peter
  273. * readded missing revisions
  274. Revision 1.12 2002/05/16 19:46:36 carl
  275. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  276. + try to fix temp allocation (still in ifdef)
  277. + generic constructor calls
  278. + start of tassembler / tmodulebase class cleanup
  279. Revision 1.10 2002/05/06 19:49:26 carl
  280. + added more patches from Mazen for SPARC port
  281. }