dbgstabs.pas 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887
  1. {
  2. Copyright (c) 2003-2004 by Peter Vreman and Florian Klaempfl
  3. This units contains support for STABS 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 dbgstabs;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. cclasses,
  22. systems,dbgbase,cgbase,
  23. symconst,symtype,symdef,symsym,symtable,symbase,
  24. aasmtai,aasmdata;
  25. const
  26. { stab types }
  27. STABS_N_GSYM = $20;
  28. STABS_N_STSYM = 38; { initialized const }
  29. STABS_N_LCSYM = 40; { non initialized variable}
  30. STABS_N_Function = $24; { function or const }
  31. STABS_N_TextLine = $44;
  32. STABS_N_DataLine = $46;
  33. STABS_N_BssLine = $48;
  34. STABS_N_RSYM = $40; { register variable }
  35. STABS_N_LSYM = $80;
  36. STABS_N_DECL = $8c;
  37. STABS_N_RPSYM = $8e;
  38. STABS_N_tsym = 160;
  39. STABS_N_SourceFile = $64;
  40. { APPLE LOCAL N_OSO: This is the stab that associated the .o file with the
  41. N_SO stab, in the case where debug info is mostly stored in the .o file. }
  42. STABS_N_OSO = $66;
  43. STABS_N_IncludeFile = $84;
  44. STABS_N_BINCL = $82;
  45. STABS_N_EINCL = $A2;
  46. STABS_N_LBRAC = $C0;
  47. STABS_N_EXCL = $C2;
  48. STABS_N_RBRAC = $E0;
  49. type
  50. TDebugInfoStabs=class(TDebugInfo)
  51. protected
  52. dbgtype: tdbg;
  53. stabsdir: TStabType;
  54. def_stab,
  55. regvar_stab,
  56. procdef_stab,
  57. constsym_stab,
  58. typesym_stab,
  59. globalvarsym_uninited_stab,
  60. globalvarsym_inited_stab,
  61. staticvarsym_uninited_stab,
  62. staticvarsym_inited_stab,
  63. localvarsymref_stab,
  64. paravarsymref_stab: byte;
  65. writing_def_stabs : boolean;
  66. global_stab_number : word;
  67. vardatadef: trecorddef;
  68. tagtypeprefix: ansistring;
  69. { tsym writing }
  70. function sym_var_value(const s:string;arg:pointer):string;
  71. function sym_stabstr_evaluate(sym:tsym;const s:string;const vars:array of string):ansistring;
  72. procedure write_sym_stabstr(list:TAsmList;sym:tsym;const ss:ansistring);
  73. function staticvarsym_mangled_name(sym: tstaticvarsym):string;virtual;
  74. procedure maybe_add_vmt_sym(list:TAsmList;def: tobjectdef);virtual;
  75. { tdef writing }
  76. function def_stab_number(def:tdef):string;
  77. function def_stab_classnumber(def:tabstractrecorddef):string;
  78. function def_var_value(const s:string;arg:pointer):string;
  79. function def_stabstr_evaluate(def:tdef;const s:string;const vars:array of string):ansistring;
  80. procedure write_def_stabstr(list:TAsmList;def:tdef;const ss:ansistring);virtual;
  81. procedure field_add_stabstr(p:TObject;arg:pointer);
  82. procedure method_add_stabstr(p:TObject;arg:pointer);
  83. procedure field_write_defs(p:TObject;arg:pointer);
  84. function get_enum_defstr(def: tenumdef; lowerbound: longint): ansistring;
  85. function get_appendsym_paravar_reg(sym:tparavarsym;const typ,stabstr:string;reg: tregister): ansistring;
  86. function base_stabs_str(typ: longint; const other, desc, value: ansistring): ansistring;overload;
  87. function base_stabs_str(const typ, other, desc, value: ansistring): ansistring;overload;virtual;
  88. function gen_procdef_startsym_stabs(def: tprocdef): TAsmList;virtual;
  89. function gen_procdef_endsym_stabs(def: tprocdef): TAsmList;virtual;
  90. protected
  91. procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
  92. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  93. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  94. procedure appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);override;
  95. procedure appendsym_const(list:TAsmList;sym:tconstsym);override;
  96. procedure appendsym_type(list:TAsmList;sym:ttypesym);override;
  97. procedure appendsym_label(list:TAsmList;sym:tlabelsym);override;
  98. procedure beforeappenddef(list:TAsmList;def:tdef);override;
  99. procedure appenddef_ord(list:TAsmList;def:torddef);override;
  100. procedure appenddef_float(list:TAsmList;def:tfloatdef);override;
  101. procedure appenddef_file(list:TAsmList;def:tfiledef);override;
  102. procedure appenddef_enum(list:TAsmList;def:tenumdef);override;
  103. procedure appenddef_array(list:TAsmList;def:tarraydef);override;
  104. procedure appenddef_record(list:TAsmList;def:trecorddef);override;
  105. procedure appenddef_object(list:TAsmList;def:tobjectdef);override;
  106. procedure appenddef_pointer(list:TAsmList;def:tpointerdef);override;
  107. procedure appenddef_string(list:TAsmList;def:tstringdef);override;
  108. procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
  109. procedure appenddef_variant(list:TAsmList;def:tvariantdef);override;
  110. procedure appenddef_set(list:TAsmList;def:tsetdef);override;
  111. procedure appenddef_formal(list:TAsmList;def:tformaldef);override;
  112. procedure appenddef_undefined(list:TAsmList;def: tundefineddef);override;
  113. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  114. public
  115. procedure inserttypeinfo;override;
  116. procedure insertmoduleinfo;override;
  117. procedure insertlineinfo(list:TAsmList);override;
  118. procedure referencesections(list:TAsmList);override;
  119. constructor Create;override;
  120. end;
  121. function GetSymTableName(SymTable : TSymTable) : string;
  122. const
  123. tagtypes = [
  124. recorddef,
  125. variantdef,
  126. enumdef,
  127. stringdef,
  128. filedef,
  129. objectdef
  130. ];
  131. implementation
  132. uses
  133. SysUtils,cutils,cfileutl,
  134. globals,globtype,verbose,constexp,
  135. defutil, cgutils, parabase,
  136. cpuinfo,cpubase,cpupi,paramgr,
  137. aasmbase,procinfo,
  138. finput,fmodule,ppu;
  139. const
  140. current_procdef : tprocdef = nil;
  141. function GetOffsetStr(reference : TReference) : string;
  142. begin
  143. {$ifdef MIPS}
  144. if (reference.index=NR_STACK_POINTER_REG) or
  145. (reference.base=NR_STACK_POINTER_REG) then
  146. GetOffsetStr:=tostr(reference.offset
  147. - mips_extra_offset(current_procdef))
  148. else
  149. {$endif MIPS}
  150. GetOffsetStr:=tostr(reference.offset);
  151. end;
  152. function GetParaOffsetStr(reference : TCGParaReference) : string;
  153. begin
  154. {$ifdef MIPS}
  155. if reference.index=NR_STACK_POINTER_REG then
  156. GetParaOffsetStr:=tostr(reference.offset
  157. - mips_extra_offset(current_procdef))
  158. else
  159. {$endif MIPS}
  160. GetParaOffsetStr:=tostr(reference.offset);
  161. end;
  162. function GetSymName(Sym : TSymEntry) : string;
  163. begin
  164. if Not (cs_stabs_preservecase in current_settings.globalswitches) then
  165. result := Sym.Name
  166. else
  167. result := Sym.RealName;
  168. if target_asm.dollarsign<>'$' then
  169. result:=ReplaceForbiddenAsmSymbolChars(result);
  170. end;
  171. function GetSymTableName(SymTable : TSymTable) : string;
  172. begin
  173. if Not (cs_stabs_preservecase in current_settings.globalswitches) then
  174. result := SymTable.Name^
  175. else
  176. result := SymTable.RealName^;
  177. if target_asm.dollarsign<>'$' then
  178. result:=ReplaceForbiddenAsmSymbolChars(result);
  179. end;
  180. const
  181. memsizeinc = 512;
  182. type
  183. get_var_value_proc=function(const s:string;arg:pointer):string of object;
  184. function string_evaluate(s:string;get_var_value:get_var_value_proc;get_var_value_arg:pointer;const vars:array of string):ansistring;
  185. (*
  186. S contains a prototype of a result. Stabstr_evaluate will expand
  187. variables and parameters.
  188. Output is s in ASCIIZ format, with the following expanded:
  189. ${varname} - The variable name is expanded.
  190. $n - The parameter n is expanded.
  191. $$ - Is expanded to $
  192. *)
  193. const maxvalue=9;
  194. maxdata=1023;
  195. var i,j:byte;
  196. varname:string[63];
  197. varno,varcounter:byte;
  198. varvalues:array[0..9] of pshortstring;
  199. {1 kb of parameters is the limit. 256 extra bytes are allocated to
  200. ensure buffer integrity.}
  201. varvaluedata:array[0..maxdata+256] of char;
  202. varptr:Pchar;
  203. varidx : byte;
  204. len:longint;
  205. r:Pchar;
  206. begin
  207. {Two pass approach, first, calculate the length and receive variables.}
  208. i:=1;
  209. len:=0;
  210. varcounter:=0;
  211. varptr:=@varvaluedata[0];
  212. varvalues[0]:=nil;
  213. while i<=length(s) do
  214. begin
  215. if (s[i]='$') and (i<length(s)) then
  216. begin
  217. if s[i+1]='$' then
  218. begin
  219. inc(len);
  220. inc(i);
  221. end
  222. else if (s[i+1]='{') and (length(s)>2) and (i<length(s)-2) then
  223. begin
  224. varname:='';
  225. inc(i,2);
  226. repeat
  227. inc(varname[0]);
  228. varname[length(varname)]:=s[i];
  229. s[i]:=char(varcounter);
  230. inc(i);
  231. until s[i]='}';
  232. varvalues[varcounter]:=pshortstring(varptr);
  233. if varptr>@varvaluedata[maxdata] then
  234. internalerrorproc(200411152);
  235. pshortstring(varptr)^:=get_var_value(varname,get_var_value_arg);
  236. inc(len,length(pshortstring(varptr)^));
  237. inc(varptr,length(pshortstring(varptr)^)+1);
  238. inc(varcounter);
  239. end
  240. else if s[i+1] in ['1'..'9'] then
  241. begin
  242. varidx:=byte(s[i+1])-byte('1');
  243. if varidx>high(vars) then
  244. internalerror(200509263);
  245. inc(len,length(vars[varidx]));
  246. inc(i);
  247. end;
  248. end
  249. else
  250. inc(len);
  251. inc(i);
  252. end;
  253. {Second pass, writeout result.}
  254. setlength(result,len);
  255. r:=pchar(result);
  256. i:=1;
  257. while i<=length(s) do
  258. begin
  259. if (s[i]='$') and (i<length(s)) then
  260. begin
  261. if s[i+1]='$' then
  262. begin
  263. r^:='$';
  264. inc(r);
  265. inc(i);
  266. end
  267. else if (s[i+1]='{') and (length(s)>2) and (i<length(s)-2) then
  268. begin
  269. varname:='';
  270. inc(i,2);
  271. varno:=byte(s[i]);
  272. repeat
  273. inc(i);
  274. until s[i]='}';
  275. for j:=1 to length(varvalues[varno]^) do
  276. begin
  277. r^:=varvalues[varno]^[j];
  278. inc(r);
  279. end;
  280. end
  281. else if s[i+1] in ['0'..'9'] then
  282. begin
  283. for j:=1 to length(vars[byte(s[i+1])-byte('1')]) do
  284. begin
  285. r^:=vars[byte(s[i+1])-byte('1')][j];
  286. inc(r);
  287. end;
  288. inc(i);
  289. end
  290. end
  291. else
  292. begin
  293. r^:=s[i];
  294. inc(r);
  295. end;
  296. inc(i);
  297. end;
  298. { verify that the length was correct }
  299. if r^<>#0 then
  300. internalerror(200802031);
  301. end;
  302. {****************************************************************************
  303. TDef support
  304. ****************************************************************************}
  305. function TDebugInfoStabs.def_stab_number(def:tdef):string;
  306. begin
  307. { procdefs only need a number, mark them as already written
  308. so they won't be written implicitly }
  309. if (def.typ=procdef) then
  310. def.dbg_state:=dbg_state_written;
  311. { Stab must already be written, or we must be busy writing it }
  312. if writing_def_stabs and
  313. not(def.dbg_state in [dbg_state_writing,dbg_state_written,dbg_state_queued]) then
  314. internalerror(200403091);
  315. { Keep track of used stabs, this info is only useful for stabs
  316. referenced by the symbols. Definitions will always include all
  317. required stabs }
  318. if def.dbg_state=dbg_state_unused then
  319. begin
  320. def.dbg_state:=dbg_state_used;
  321. deftowritelist.Add(def);
  322. end;
  323. { Need a new number? }
  324. if def.stab_number=0 then
  325. begin
  326. inc(global_stab_number);
  327. { classes require 2 numbers }
  328. if is_class(def) then
  329. inc(global_stab_number);
  330. def.stab_number:=global_stab_number;
  331. if global_stab_number>=defnumberlist.count then
  332. defnumberlist.count:=global_stab_number+250;
  333. defnumberlist[global_stab_number]:=def;
  334. end;
  335. result:=tostr(def.stab_number);
  336. end;
  337. function TDebugInfoStabs.def_stab_classnumber(def:tabstractrecorddef):string;
  338. begin
  339. if def.stab_number=0 then
  340. def_stab_number(def);
  341. if (def.typ=objectdef) and (tobjectdef(def).objecttype=odt_class) then
  342. result:=tostr(def.stab_number-1)
  343. else
  344. result:=tostr(def.stab_number);
  345. end;
  346. function TDebugInfoStabs.def_var_value(const s:string;arg:pointer):string;
  347. var
  348. def : tdef;
  349. begin
  350. def:=tdef(arg);
  351. result:='';
  352. if s='numberstring' then
  353. result:=def_stab_number(def)
  354. else if s='sym_name' then
  355. begin
  356. if assigned(def.typesym) then
  357. result:=GetSymName(Ttypesym(def.typesym));
  358. end
  359. else if s='savesize' then
  360. result:=tostr(def.size);
  361. end;
  362. function TDebugInfoStabs.def_stabstr_evaluate(def:tdef;const s:string;const vars:array of string):ansistring;
  363. begin
  364. result:=string_evaluate(s,@def_var_value,def,vars);
  365. end;
  366. procedure TDebugInfoStabs.field_add_stabstr(p:TObject;arg:pointer);
  367. var
  368. spec : string[3];
  369. varsize : asizeint;
  370. newss : ansistring;
  371. ss : pansistring absolute arg;
  372. begin
  373. if (tsym(p).visibility=vis_hidden) then
  374. exit;
  375. { static variables from objects are like global objects }
  376. if (Tsym(p).typ=fieldvarsym) and
  377. not(sp_static in Tsym(p).symoptions) then
  378. begin
  379. case tsym(p).visibility of
  380. vis_private,
  381. vis_strictprivate :
  382. spec:='/0';
  383. vis_protected,
  384. vis_strictprotected :
  385. spec:='/1';
  386. else
  387. spec:='';
  388. end;
  389. if (tabstractrecordsymtable(tsym(p).owner).usefieldalignment<>bit_alignment) then
  390. begin
  391. varsize:=tfieldvarsym(p).vardef.size;
  392. { open arrays made overflows !! }
  393. { how can a record/object/class contain an open array? (JM) }
  394. {$ifdef cpu16bitaddr}
  395. if varsize>$fff then
  396. varsize:=$fff;
  397. {$else cpu16bitaddr}
  398. if varsize>$fffffff then
  399. varsize:=$fffffff;
  400. {$endif cpu16bitaddr}
  401. newss:=def_stabstr_evaluate(nil,'$1:$2,$3,$4;',[GetSymName(tfieldvarsym(p)),
  402. spec+def_stab_number(tfieldvarsym(p).vardef),
  403. tostr(TConstExprInt(tfieldvarsym(p).fieldoffset)*8),tostr(varsize*8)])
  404. end
  405. else
  406. newss:=def_stabstr_evaluate(nil,'$1:$2,$3,$4;',[GetSymName(tfieldvarsym(p)),
  407. spec+def_stab_number(tfieldvarsym(p).vardef),
  408. tostr(TConstExprInt(tfieldvarsym(p).fieldoffset)),tostr(tfieldvarsym(p).vardef.packedbitsize)]);
  409. ss^:=ss^+newss;
  410. end;
  411. end;
  412. procedure TDebugInfoStabs.method_add_stabstr(p:TObject;arg:pointer);
  413. var
  414. virtualind,argnames : string;
  415. pd : tprocdef;
  416. lindex : longint;
  417. arglength : byte;
  418. sp : char;
  419. i : integer;
  420. parasym : tparavarsym;
  421. newss : ansistring;
  422. ss : pansistring absolute arg;
  423. begin
  424. if tsym(p).typ = procsym then
  425. begin
  426. pd :=tprocdef(tprocsym(p).ProcdefList[0]);
  427. if (po_virtualmethod in pd.procoptions) and
  428. not is_objectpascal_helper(pd.struct) then
  429. begin
  430. lindex := pd.extnumber;
  431. {doesnt seem to be necessary
  432. lindex := lindex or $80000000;}
  433. virtualind := '*'+tostr(lindex)+';'+def_stab_classnumber(pd.struct)+';'
  434. end
  435. else
  436. virtualind := '.';
  437. { used by gdbpas to recognize constructor and destructors }
  438. if (pd.proctypeoption=potype_constructor) then
  439. argnames:='__ct__'
  440. else if (pd.proctypeoption=potype_destructor) then
  441. argnames:='__dt__'
  442. else
  443. argnames := '';
  444. { arguments are not listed here }
  445. {we don't need another definition}
  446. for i:=0 to pd.paras.count-1 do
  447. begin
  448. parasym:=tparavarsym(pd.paras[i]);
  449. if Parasym.vardef.typ = formaldef then
  450. begin
  451. case Parasym.varspez of
  452. vs_var :
  453. argnames := argnames+'3var';
  454. vs_const :
  455. argnames:=argnames+'5const';
  456. vs_out :
  457. argnames:=argnames+'3out';
  458. vs_constref :
  459. argnames:=argnames+'8constref';
  460. end;
  461. end
  462. else
  463. begin
  464. { if the arg definition is like (v: ^byte;..
  465. there is no sym attached to data !!! }
  466. if assigned(Parasym.vardef.typesym) then
  467. begin
  468. arglength := length(GetSymName(Parasym.vardef.typesym));
  469. argnames := argnames + tostr(arglength)+GetSymName(Parasym.vardef.typesym);
  470. end
  471. else
  472. argnames:=argnames+'11unnamedtype';
  473. end;
  474. end;
  475. { here 2A must be changed for private and protected }
  476. { 0 is private 1 protected and 2 public }
  477. case tsym(p).visibility of
  478. vis_private,
  479. vis_strictprivate :
  480. sp:='0';
  481. vis_protected,
  482. vis_strictprotected :
  483. sp:='1'
  484. else
  485. sp:='2';
  486. end;
  487. newss:=def_stabstr_evaluate(nil,'$1::$2=##$3;:$4;$5A$6;',[GetSymName(tsym(p)),def_stab_number(pd),
  488. def_stab_number(pd.returndef),argnames,sp,
  489. virtualind]);
  490. ss^:=ss^+newss;
  491. end;
  492. end;
  493. procedure TDebugInfoStabs.field_write_defs(p:TObject;arg:pointer);
  494. begin
  495. if (Tsym(p).typ=fieldvarsym) and
  496. not(sp_static in Tsym(p).symoptions) then
  497. appenddef(TAsmList(arg),tfieldvarsym(p).vardef);
  498. end;
  499. procedure TDebugInfoStabs.write_def_stabstr(list:TAsmList;def:tdef;const ss:ansistring);
  500. var
  501. stabchar : string[2];
  502. symname : string[20];
  503. st : ansistring;
  504. begin
  505. { type prefix }
  506. if def.typ in tagtypes then
  507. stabchar := tagtypeprefix
  508. else
  509. stabchar := 't';
  510. { in case of writing the class record structure, we always have to
  511. use the class name (so it refers both to the struct and the
  512. pointer to the struct), otherwise gdb crashes (see tests/webtbs/tw9766.pp) }
  513. if is_class(def) and
  514. tobjectdef(def).writing_class_record_dbginfo then
  515. st:=def_stabstr_evaluate(def,'"${sym_name}:$1$2=',[stabchar,def_stab_classnumber(tobjectdef(def))])
  516. else
  517. begin
  518. { Type names for types defined in the current unit are already written in
  519. the typesym }
  520. if (def.owner.symtabletype=globalsymtable) and
  521. not(def.owner.iscurrentunit) then
  522. symname:='${sym_name}'
  523. else
  524. symname:='';
  525. st:=def_stabstr_evaluate(def,'"'+symname+':$1$2=',[stabchar,def_stab_number(def)]);
  526. end;
  527. st:=st+ss;
  528. { line info is set to 0 for all defs, because the def can be in another
  529. unit and then the linenumber is invalid in the current sourcefile }
  530. st:=st+def_stabstr_evaluate(def,'",'+base_stabs_str(def_stab,'0','0','0'),[]);
  531. { add to list }
  532. list.concat(Tai_stab.create_ansistr(stabsdir,st));
  533. end;
  534. procedure TDebugInfoStabs.appenddef_string(list:TAsmList;def:tstringdef);
  535. var
  536. bytest,charst,longst : string;
  537. ss : ansistring;
  538. slen : longint;
  539. begin
  540. ss:='';
  541. case def.stringtype of
  542. st_shortstring:
  543. begin
  544. { fix length of openshortstring }
  545. slen:=def.len;
  546. if slen=0 then
  547. slen:=255;
  548. charst:=def_stab_number(cansichartype);
  549. bytest:=def_stab_number(u8inttype);
  550. ss:=def_stabstr_evaluate(def,'s$1length:$2,0,8;st:ar$2;1;$3;$4,8,$5;;',
  551. [tostr(slen+1),bytest,tostr(slen),charst,tostr(slen*8)]);
  552. end;
  553. st_longstring:
  554. begin
  555. charst:=def_stab_number(cansichartype);
  556. bytest:=def_stab_number(u8inttype);
  557. longst:=def_stab_number(u32inttype);
  558. ss:=def_stabstr_evaluate(def,'s$1length:$2,0,32;dummy:$6,32,8;st:ar$2;1;$3;$4,40,$5;;',
  559. [tostr(def.len+5),longst,tostr(def.len),charst,tostr(def.len*8),bytest]);
  560. end;
  561. st_ansistring:
  562. begin
  563. { looks like a pchar }
  564. ss:='*'+def_stab_number(cansichartype);
  565. end;
  566. st_unicodestring,
  567. st_widestring:
  568. begin
  569. { looks like a pwidechar }
  570. ss:='*'+def_stab_number(cwidechartype);
  571. end;
  572. end;
  573. write_def_stabstr(list,def,ss);
  574. end;
  575. function TDebugInfoStabs.get_enum_defstr(def: tenumdef; lowerbound: longint): ansistring;
  576. var
  577. i: longint;
  578. p: tenumsym;
  579. begin
  580. { we can specify the size with @s<size>; prefix PM }
  581. if def.size <> std_param_align then
  582. result:='@s'+tostr(def.size*8)+';e'
  583. else
  584. result:='e';
  585. { the if-test is required because pred(def.minval) might overflow;
  586. the longint() typecast should be safe because stabs is not
  587. supported for 64 bit targets }
  588. if (def.minval<>lowerbound) then
  589. for i:=lowerbound to pred(longint(def.minval)) do
  590. result:=result+'<invalid>:'+tostr(i)+',';
  591. for i := 0 to def.symtable.SymList.Count - 1 do
  592. begin
  593. p := tenumsym(def.symtable.SymList[i]);
  594. if p.value<def.minval then
  595. continue
  596. else
  597. if p.value>def.maxval then
  598. break;
  599. result:=result+GetSymName(p)+':'+tostr(p.value)+',';
  600. end;
  601. { the final ',' is required to have a valid stabs }
  602. result:=result+';';
  603. end;
  604. procedure TDebugInfoStabs.appenddef_enum(list:TAsmList;def:tenumdef);
  605. begin
  606. write_def_stabstr(list,def,get_enum_defstr(def,def.minval));
  607. end;
  608. procedure TDebugInfoStabs.appenddef_ord(list:TAsmList;def:torddef);
  609. var
  610. ss : ansistring;
  611. begin
  612. ss:='';
  613. if cs_gdb_valgrind in current_settings.globalswitches then
  614. begin
  615. case def.ordtype of
  616. uvoid :
  617. ss:=def_stab_number(def);
  618. pasbool8,
  619. pasbool16,
  620. pasbool32,
  621. pasbool64,
  622. bool8bit,
  623. bool16bit,
  624. bool32bit,
  625. bool64bit :
  626. ss:=def_stabstr_evaluate(def,'r${numberstring};0;255;',[]);
  627. u32bit,
  628. s64bit,
  629. u64bit :
  630. ss:=def_stabstr_evaluate(def,'r${numberstring};0;-1;',[]);
  631. else
  632. ss:=def_stabstr_evaluate(def,'r${numberstring};$1;$2;',[tostr(longint(def.low.svalue)),tostr(longint(def.high.svalue))]);
  633. end;
  634. end
  635. else
  636. begin
  637. case def.ordtype of
  638. uvoid :
  639. ss:=def_stab_number(def);
  640. uchar :
  641. ss:='-20;';
  642. uwidechar :
  643. ss:='-30;';
  644. pasbool8,
  645. bool8bit :
  646. ss:='-21;';
  647. pasbool16,
  648. bool16bit :
  649. ss:='-22;';
  650. pasbool32,
  651. bool32bit :
  652. ss:='-23;';
  653. pasbool64,
  654. bool64bit :
  655. { no clue if this is correct (FK) }
  656. ss:='-23;';
  657. u64bit :
  658. ss:='-32;';
  659. s64bit :
  660. ss:='-31;';
  661. {u32bit : result:=def_stab_number(s32inttype)+';0;-1;'); }
  662. else
  663. begin
  664. if def.size <> std_param_align then
  665. ss:='@s'+tostr(def.size*8)+';'
  666. else
  667. ss:='';
  668. ss:=ss+def_stabstr_evaluate(def,'r${numberstring};$1;$2;',[tostr(longint(def.low.svalue)),tostr(longint(def.high.svalue))]);
  669. end;
  670. end;
  671. end;
  672. write_def_stabstr(list,def,ss);
  673. end;
  674. procedure TDebugInfoStabs.appenddef_float(list:TAsmList;def:tfloatdef);
  675. var
  676. ss : ansistring;
  677. begin
  678. ss:='';
  679. case def.floattype of
  680. s32real,
  681. s64real,
  682. s80real,
  683. sc80real:
  684. ss:=def_stabstr_evaluate(def,'r$1;${savesize};0;',[def_stab_number(s32inttype)]);
  685. s64currency,
  686. s64comp:
  687. ss:=def_stabstr_evaluate(def,'r$1;-${savesize};0;',[def_stab_number(s32inttype)]);
  688. else
  689. internalerror(200509261);
  690. end;
  691. write_def_stabstr(list,def,ss);
  692. end;
  693. procedure TDebugInfoStabs.appenddef_file(list:TAsmList;def:tfiledef);
  694. var
  695. ss : ansistring;
  696. begin
  697. {$ifdef cpu64bitaddr}
  698. ss:=def_stabstr_evaluate(def,'s${savesize}HANDLE:$1,0,32;MODE:$1,32,32;RECSIZE:$2,64,64;'+
  699. '_PRIVATE:ar$1;1;64;$3,128,256;USERDATA:ar$1;1;32;$3,384,256;'+
  700. 'NAME:ar$1;0;255;$4,640,2048;;',[def_stab_number(s32inttype),
  701. def_stab_number(s64inttype),
  702. def_stab_number(u8inttype),
  703. def_stab_number(cansichartype)]);
  704. {$else cpu64bitaddr}
  705. ss:=def_stabstr_evaluate(def,'s${savesize}HANDLE:$1,0,32;MODE:$1,32,32;RECSIZE:$1,64,32;'+
  706. '_PRIVATE:ar$1;1;32;$3,96,256;USERDATA:ar$1;1;32;$2,352,256;'+
  707. 'NAME:ar$1;0;255;$3,608,2048;;',[def_stab_number(s32inttype),
  708. def_stab_number(u8inttype),
  709. def_stab_number(cansichartype)]);
  710. {$endif cpu64bitaddr}
  711. write_def_stabstr(list,def,ss);
  712. end;
  713. procedure TDebugInfoStabs.appenddef_record(list:TAsmList;def:trecorddef);
  714. var
  715. ss : ansistring;
  716. begin
  717. ss:='s'+tostr(def.size);
  718. def.symtable.SymList.ForEachCall(@field_add_stabstr,@ss);
  719. ss[length(ss)]:=';';
  720. write_def_stabstr(list,def,ss);
  721. end;
  722. procedure TDebugInfoStabs.appenddef_object(list:TAsmList;def:tobjectdef);
  723. procedure do_write_object(list:TAsmList;def:tobjectdef);
  724. var
  725. ss : ansistring;
  726. anc : tobjectdef;
  727. begin
  728. ss:='';
  729. { Write the invisible pointer for the class? }
  730. if (def.objecttype=odt_class) and
  731. (not def.writing_class_record_dbginfo) then
  732. begin
  733. ss:='*'+def_stab_classnumber(def);
  734. write_def_stabstr(list,def,ss);
  735. exit;
  736. end;
  737. ss:='s'+tostr(tobjecTSymtable(def.symtable).datasize);
  738. if assigned(def.childof) then
  739. begin
  740. {only one ancestor not virtual, public, at base offset 0 }
  741. { !1 , 0 2 0 , }
  742. ss:=ss+'!1,020,'+def_stab_classnumber(def.childof)+';';
  743. end;
  744. {virtual table to implement yet}
  745. def.symtable.symList.ForEachCall(@field_add_stabstr,@ss);
  746. if (oo_has_vmt in def.objectoptions) and
  747. (
  748. not assigned(def.childof) or
  749. not(oo_has_vmt in def.childof.objectoptions)
  750. ) then
  751. ss:=ss+'$vf'+def_stab_classnumber(def)+':'+def_stab_number(vmtarraytype)+','+tostr(def.vmt_offset*8)+';';
  752. def.symtable.symList.ForEachCall(@method_add_stabstr,@ss);
  753. if (oo_has_vmt in def.objectoptions) then
  754. begin
  755. anc := def;
  756. while assigned(anc.childof) and (oo_has_vmt in anc.childof.objectoptions) do
  757. anc := anc.childof;
  758. { just in case anc = self }
  759. ss:=ss+';~%'+def_stab_classnumber(anc)+';';
  760. end
  761. else
  762. ss:=ss+';';
  763. write_def_stabstr(list,def,ss);
  764. end;
  765. var
  766. oldtypesym : tsym;
  767. begin
  768. tobjectdef(def).symtable.symList.ForEachCall(@field_write_defs,list);
  769. { classes require special code to write the record and the invisible pointer }
  770. if is_class(def) then
  771. begin
  772. { Write the record class itself }
  773. tobjectdef(def).writing_class_record_dbginfo:=true;
  774. do_write_object(list,def);
  775. tobjectdef(def).writing_class_record_dbginfo:=false;
  776. { Write the invisible pointer class }
  777. oldtypesym:=def.typesym;
  778. def.typesym:=nil;
  779. do_write_object(list,def);
  780. def.typesym:=oldtypesym;
  781. end
  782. else
  783. do_write_object(list,def);
  784. { VMT symbol }
  785. maybe_add_vmt_sym(list,def);
  786. end;
  787. procedure TDebugInfoStabs.appenddef_variant(list:TAsmList;def:tvariantdef);
  788. var
  789. ss : ansistring;
  790. begin
  791. if not assigned(vardatadef) then
  792. exit;
  793. ss:='s'+tostr(vardatadef.size);
  794. vardatadef.symtable.SymList.ForEachCall(@field_add_stabstr,@ss);
  795. ss[length(ss)]:=';';
  796. write_def_stabstr(list,def,ss);
  797. end;
  798. procedure TDebugInfoStabs.appenddef_pointer(list:TAsmList;def:tpointerdef);
  799. var
  800. ss : ansistring;
  801. begin
  802. ss:='*'+def_stab_number(tpointerdef(def).pointeddef);
  803. write_def_stabstr(list,def,ss);
  804. end;
  805. procedure TDebugInfoStabs.appenddef_set(list:TAsmList;def:tsetdef);
  806. var
  807. st,
  808. ss : ansistring;
  809. elementdefstabnr: string;
  810. begin
  811. { ugly hack: create a temporary subrange type if the lower bound of
  812. the set's element type is not a multiple of 8 (because we store them
  813. as if the lower bound is a multiple of 8) }
  814. if (def.setbase<>get_min_value(def.elementdef)) then
  815. begin
  816. { allocate a def number }
  817. inc(global_stab_number);
  818. elementdefstabnr:=tostr(global_stab_number);
  819. { anonymous subrange def }
  820. st:='":t'+elementdefstabnr+'=';
  821. if (def.elementdef.typ = enumdef) then
  822. st:=st+get_enum_defstr(tenumdef(def.elementdef),def.setbase)
  823. else
  824. st:=st+def_stabstr_evaluate(def.elementdef,'r'+elementdefstabnr+';$1;$2;',[tostr(longint(def.setbase)),tostr(longint(get_max_value(def.elementdef).svalue))]);
  825. st:=st+'",'+base_stabs_str(def_stab,'0','0','0');
  826. { add to list }
  827. list.concat(Tai_stab.create_ansistr(stabsdir,st));
  828. end
  829. else
  830. elementdefstabnr:=def_stab_number(def.elementdef);
  831. ss:=def_stabstr_evaluate(def,'@s$1;S$2',[tostr(def.size*8),elementdefstabnr]);
  832. write_def_stabstr(list,def,ss);
  833. end;
  834. procedure TDebugInfoStabs.appenddef_formal(list:TAsmList;def:tformaldef);
  835. var
  836. ss : ansistring;
  837. begin
  838. ss:=def_stabstr_evaluate(def,'${numberstring};',[]);
  839. write_def_stabstr(list,def,ss);
  840. end;
  841. procedure TDebugInfoStabs.appenddef_array(list:TAsmList;def:tarraydef);
  842. var
  843. tempstr: shortstring;
  844. ss : ansistring;
  845. begin
  846. if not is_packed_array(def) then
  847. begin
  848. { Try to used P if ememlent size is smaller than
  849. usual integer }
  850. if def.elesize <> std_param_align then
  851. tempstr:='ar@s'+tostr(def.elesize*8)+';$1;$2;$3;$4'
  852. else
  853. tempstr:='ar$1;$2;$3;$4';
  854. if is_dynamic_array(def) then
  855. tempstr:='*'+tempstr;
  856. ss:=def_stabstr_evaluate(def,tempstr,[def_stab_number(tarraydef(def).rangedef),
  857. tostr(tarraydef(def).lowrange),tostr(tarraydef(def).highrange),def_stab_number(tarraydef(def).elementdef)])
  858. end
  859. else
  860. begin
  861. // the @P seems to be ignored by gdb
  862. tempstr:=def_stabstr_evaluate(tarraydef(def).rangedef,'r${numberstring};$1;$2;',
  863. [tostr(tarraydef(def).lowrange),tostr(tarraydef(def).highrange)]);
  864. // will only show highrange-lowrange+1 bits in gdb
  865. ss:=def_stabstr_evaluate(def,'@s$1;@S;S$2',
  866. [tostr(TConstExprInt(tarraydef(def).elepackedbitsize) * tarraydef(def).elecount),tempstr]);
  867. end;
  868. write_def_stabstr(list,def,ss);
  869. end;
  870. procedure TDebugInfoStabs.appenddef_procvar(list:TAsmList;def:tprocvardef);
  871. var
  872. ss : ansistring;
  873. begin
  874. ss:='*f'+def_stab_number(tprocvardef(def).returndef);
  875. write_def_stabstr(list,def,ss);
  876. end;
  877. procedure TDebugInfoStabs.appenddef_undefined(list:TAsmList;def:tundefineddef);
  878. var
  879. ss : ansistring;
  880. begin
  881. ss:=def_stabstr_evaluate(def,'${numberstring};',[]);
  882. write_def_stabstr(list,def,ss);
  883. end;
  884. procedure TDebugInfoStabs.beforeappenddef(list:TAsmList;def:tdef);
  885. var
  886. anc : tobjectdef;
  887. i : longint;
  888. begin
  889. { write dependencies first }
  890. case def.typ of
  891. stringdef :
  892. begin
  893. if tstringdef(def).stringtype in [st_widestring,st_unicodestring] then
  894. appenddef(list,cwidechartype)
  895. else
  896. begin
  897. appenddef(list,cansichartype);
  898. appenddef(list,u8inttype);
  899. end;
  900. end;
  901. floatdef :
  902. appenddef(list,s32inttype);
  903. filedef :
  904. begin
  905. appenddef(list,s32inttype);
  906. {$ifdef cpu64bitaddr}
  907. appenddef(list,s64inttype);
  908. {$endif cpu64bitaddr}
  909. appenddef(list,u8inttype);
  910. appenddef(list,cansichartype);
  911. end;
  912. classrefdef :
  913. appenddef(list,pvmttype);
  914. pointerdef :
  915. appenddef(list,tpointerdef(def).pointeddef);
  916. setdef :
  917. appenddef(list,tsetdef(def).elementdef);
  918. procvardef :
  919. begin
  920. appenddef(list,tprocvardef(def).returndef);
  921. if assigned(tprocvardef(def).parast) then
  922. write_symtable_defs(list,tprocvardef(def).parast);
  923. end;
  924. procdef :
  925. begin
  926. appenddef(list,tprocdef(def).returndef);
  927. if assigned(tprocdef(def).parast) then
  928. write_symtable_defs(list,tprocdef(def).parast);
  929. if assigned(tprocdef(def).localst) and
  930. (tprocdef(def).localst.symtabletype=localsymtable) then
  931. write_symtable_defs(list,tprocdef(def).localst);
  932. end;
  933. arraydef :
  934. begin
  935. appenddef(list,tarraydef(def).rangedef);
  936. appenddef(list,tarraydef(def).elementdef);
  937. end;
  938. recorddef :
  939. trecorddef(def).symtable.symList.ForEachCall(@field_write_defs,list);
  940. enumdef :
  941. if assigned(tenumdef(def).basedef) then
  942. appenddef(list,tenumdef(def).basedef);
  943. objectdef :
  944. begin
  945. { make sure we don't write child classdefs before their parent }
  946. { classdefs, because this crashes gdb }
  947. anc:=tobjectdef(def);
  948. while assigned(anc.childof) do
  949. begin
  950. anc:=anc.childof;
  951. case anc.dbg_state of
  952. dbg_state_writing:
  953. { happens in case a field of a parent is of the (forward
  954. defined) child type
  955. }
  956. begin
  957. { We don't explicitly requeue it, but the fact that
  958. a child type was used in a parent before the child
  959. type was fully defined means that it was forward
  960. declared, and will still be encountered later.
  961. Setting the state to queued however allows us to
  962. get the def number already without an IE
  963. }
  964. def.dbg_state:=dbg_state_queued;
  965. break;
  966. end;
  967. end;
  968. end;
  969. appenddef(list,vmtarraytype);
  970. if assigned(tobjectdef(def).ImplementedInterfaces) then
  971. for i:=0 to tobjectdef(def).ImplementedInterfaces.Count-1 do
  972. appenddef(list,TImplementedInterface(tobjectdef(def).ImplementedInterfaces[i]).IntfDef);
  973. { first the parents }
  974. anc:=tobjectdef(def);
  975. while assigned(anc.childof) do
  976. begin
  977. anc:=anc.childof;
  978. { in case this is an object family declared in another unit
  979. that was compiled without debug info, this ancestor may not
  980. yet have a stabs number and not yet be added to defstowrite
  981. -> take care of that now, while its dbg_state is still
  982. dbg_state_unused in case the aforementioned things haven't
  983. happened yet (afterwards it will become dbg_state_writing,
  984. and then def_stab_number() won't do anything anymore because
  985. it assumes it's already happened
  986. }
  987. def_stab_number(anc);
  988. appenddef(list,anc);
  989. if assigned(anc.ImplementedInterfaces) then
  990. for i:=0 to anc.ImplementedInterfaces.Count-1 do
  991. appenddef(list,TImplementedInterface(anc.ImplementedInterfaces[i]).IntfDef);
  992. end;
  993. end;
  994. end;
  995. end;
  996. procedure TDebugInfoStabs.appendprocdef(list:TAsmList;def:tprocdef);
  997. var
  998. hs : ansistring;
  999. templist : TAsmList;
  1000. prev_procdef : tprocdef;
  1001. begin
  1002. if not(def.in_currentunit) or
  1003. { happens for init procdef of units without init section }
  1004. not assigned(def.procstarttai) then
  1005. exit;
  1006. { mark as used so the local type defs also be written }
  1007. def.dbg_state:=dbg_state_used;
  1008. prev_procdef:=current_procdef;
  1009. current_procdef:=def;
  1010. templist:=gen_procdef_endsym_stabs(def);
  1011. current_asmdata.asmlists[al_procedures].insertlistafter(def.procendtai,templist);
  1012. { FUNC stabs }
  1013. templist.free;
  1014. templist:=gen_procdef_startsym_stabs(def);
  1015. current_asmdata.asmlists[al_procedures].insertlistbefore(def.procstarttai,templist);
  1016. { para types }
  1017. if assigned(def.parast) then
  1018. write_symtable_syms(templist,def.parast);
  1019. { local type defs and vars should not be written
  1020. inside the main proc stab }
  1021. if assigned(def.localst) and
  1022. (def.localst.symtabletype=localsymtable) then
  1023. write_symtable_syms(templist,def.localst);
  1024. if assigned(def.funcretsym) and
  1025. (tabstractnormalvarsym(def.funcretsym).refs>0) then
  1026. begin
  1027. if tabstractnormalvarsym(def.funcretsym).localloc.loc=LOC_REFERENCE then
  1028. begin
  1029. { TODO: Need to add gdb support for ret in param register calling}
  1030. if paramanager.ret_in_param(def.returndef,def) then
  1031. hs:='X*'
  1032. else
  1033. hs:='X';
  1034. templist.concat(Tai_stab.create(stabsdir,strpnew(
  1035. '"'+GetSymName(def.procsym)+':'+hs+def_stab_number(def.returndef)+'",'+
  1036. base_stabs_str(localvarsymref_stab,'0','0',getoffsetstr(tabstractnormalvarsym(def.funcretsym).localloc.reference)))));
  1037. if (m_result in current_settings.modeswitches) then
  1038. templist.concat(Tai_stab.create(stabsdir,strpnew(
  1039. '"RESULT:'+hs+def_stab_number(def.returndef)+'",'+
  1040. base_stabs_str(localvarsymref_stab,'0','0',getoffsetstr(tabstractnormalvarsym(def.funcretsym).localloc.reference)))));
  1041. end;
  1042. end;
  1043. current_asmdata.asmlists[al_procedures].insertlistbefore(def.procstarttai,templist);
  1044. templist.free;
  1045. current_procdef:=prev_procdef;
  1046. end;
  1047. {****************************************************************************
  1048. TSym support
  1049. ****************************************************************************}
  1050. function TDebugInfoStabs.sym_var_value(const s:string;arg:pointer):string;
  1051. var
  1052. sym : tsym absolute arg;
  1053. begin
  1054. result:='';
  1055. if s='name' then
  1056. result:=GetSymName(sym)
  1057. else if s='mangledname' then
  1058. result:=ReplaceForbiddenAsmSymbolChars(sym.mangledname)
  1059. else if s='ownername' then
  1060. result:=GetSymTableName(sym.owner)
  1061. else if s='line' then
  1062. result:=tostr(sym.fileinfo.line)
  1063. else
  1064. internalerror(200401152);
  1065. end;
  1066. function TDebugInfoStabs.sym_stabstr_evaluate(sym:tsym;const s:string;const vars:array of string):ansistring;
  1067. begin
  1068. result:=string_evaluate(s,@sym_var_value,sym,vars);
  1069. end;
  1070. procedure TDebugInfoStabs.write_sym_stabstr(list:TAsmList;sym:tsym;const ss:ansistring);
  1071. begin
  1072. if ss='' then
  1073. exit;
  1074. { add to list }
  1075. list.concat(Tai_stab.create_ansistr(stabsdir,ss));
  1076. end;
  1077. function TDebugInfoStabs.staticvarsym_mangled_name(sym: tstaticvarsym): string;
  1078. begin
  1079. result:=ReplaceForbiddenAsmSymbolChars(sym.mangledname);
  1080. end;
  1081. procedure TDebugInfoStabs.maybe_add_vmt_sym(list: TAsmList; def: tobjectdef);
  1082. begin
  1083. if (oo_has_vmt in def.objectoptions) and
  1084. assigned(def.owner) and
  1085. assigned(def.owner.name) then
  1086. list.concat(Tai_stab.create_ansistr(stabsdir,ansistring('"vmt_')+GetSymTableName(def.owner)+tobjectdef(def).objname^+':S'+
  1087. def_stab_number(vmttype)+'",'+
  1088. base_stabs_str(globalvarsym_inited_stab,'0','0',ReplaceForbiddenAsmSymbolChars(tobjectdef(def).vmt_mangledname))));
  1089. end;
  1090. procedure TDebugInfoStabs.appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);
  1091. var
  1092. ss : ansistring;
  1093. begin
  1094. ss:='';
  1095. if (sym.owner.symtabletype in [ObjectSymtable,recordsymtable]) and
  1096. (sp_static in sym.symoptions) then
  1097. ss:=sym_stabstr_evaluate(sym,'"${ownername}__${name}:S$1",'+base_stabs_str(globalvarsym_uninited_stab,'0','${line}','${mangledname}'),
  1098. [def_stab_number(sym.vardef)]);
  1099. write_sym_stabstr(list,sym,ss);
  1100. end;
  1101. procedure TDebugInfoStabs.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
  1102. var
  1103. ss : ansistring;
  1104. st : string;
  1105. threadvaroffset : string;
  1106. regidx : Tregisterindex;
  1107. nsym : byte;
  1108. begin
  1109. { external symbols can't be resolved at link time, so we
  1110. can't generate stabs for them }
  1111. if vo_is_external in sym.varoptions then
  1112. exit;
  1113. ss:='';
  1114. st:=def_stab_number(sym.vardef);
  1115. case sym.localloc.loc of
  1116. LOC_REGISTER,
  1117. LOC_CREGISTER,
  1118. LOC_MMREGISTER,
  1119. LOC_CMMREGISTER,
  1120. LOC_FPUREGISTER,
  1121. LOC_CFPUREGISTER :
  1122. begin
  1123. regidx:=findreg_by_number(sym.localloc.register);
  1124. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1125. { this is the register order for GDB}
  1126. if regidx<>0 then
  1127. ss:=sym_stabstr_evaluate(sym,'"${name}:r$1",'+base_stabs_str(regvar_stab,'0','${line}','$2'),[st,tostr(regstabs_table[regidx])]);
  1128. end;
  1129. else
  1130. begin
  1131. if (vo_is_thread_var in sym.varoptions) then
  1132. threadvaroffset:='+'+tostr(sizeof(pint))
  1133. else
  1134. threadvaroffset:='';
  1135. if (vo_is_typed_const in sym.varoptions) then
  1136. if vo_is_public in sym.varoptions then
  1137. nsym:=globalvarsym_inited_stab
  1138. else
  1139. nsym:=staticvarsym_inited_stab
  1140. else if vo_is_public in sym.varoptions then
  1141. nsym:=globalvarsym_uninited_stab
  1142. else
  1143. nsym:=staticvarsym_uninited_stab;
  1144. { Here we used S instead of
  1145. because with G GDB doesn't look at the address field
  1146. but searches the same name or with a leading underscore
  1147. but these names don't exist in pascal !}
  1148. st:='S'+st;
  1149. ss:=sym_stabstr_evaluate(sym,'"${name}:$1",'+base_stabs_str(nsym,'0','${line}','$2$3'),[st,staticvarsym_mangled_name(sym),threadvaroffset]);
  1150. end;
  1151. end;
  1152. write_sym_stabstr(list,sym,ss);
  1153. end;
  1154. procedure TDebugInfoStabs.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
  1155. var
  1156. ss : ansistring;
  1157. st : string;
  1158. regidx : Tregisterindex;
  1159. begin
  1160. { There is no space allocated for not referenced locals }
  1161. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  1162. exit;
  1163. ss:='';
  1164. st:=def_stab_number(sym.vardef);
  1165. case sym.localloc.loc of
  1166. LOC_REGISTER,
  1167. LOC_CREGISTER,
  1168. LOC_MMREGISTER,
  1169. LOC_CMMREGISTER,
  1170. LOC_FPUREGISTER,
  1171. LOC_CFPUREGISTER :
  1172. begin
  1173. regidx:=findreg_by_number(sym.localloc.register);
  1174. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1175. { this is the register order for GDB}
  1176. if regidx<>0 then
  1177. ss:=sym_stabstr_evaluate(sym,'"${name}:r$1",'+base_stabs_str(regvar_stab,'0','${line}','$2'),[st,tostr(regstabs_table[regidx])]);
  1178. end;
  1179. LOC_REFERENCE :
  1180. { offset to ebp => will not work if the framepointer is esp
  1181. so some optimizing will make things harder to debug }
  1182. ss:=sym_stabstr_evaluate(sym,'"${name}:$1",'+base_stabs_str(localvarsymref_stab,'0','${line}','$2'),[st,getoffsetstr(sym.localloc.reference)])
  1183. else
  1184. internalerror(2003091814);
  1185. end;
  1186. write_sym_stabstr(list,sym,ss);
  1187. end;
  1188. function TDebugInfoStabs.get_appendsym_paravar_reg(sym:tparavarsym;const typ,stabstr:string;reg: tregister): ansistring;
  1189. var
  1190. ltyp: string[1];
  1191. regidx : Tregisterindex;
  1192. begin
  1193. result:='';
  1194. if typ='p' then
  1195. ltyp:='R'
  1196. else
  1197. ltyp:='a';
  1198. regidx:=findreg_by_number(reg);
  1199. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1200. { this is the register order for GDB}
  1201. if regidx<>0 then
  1202. result:=sym_stabstr_evaluate(sym,'"${name}:$1",'+base_stabs_str(regvar_stab,'0','${line}','$2'),[ltyp+stabstr,tostr(longint(regstabs_table[regidx]))]);
  1203. end;
  1204. function TDebugInfoStabs.base_stabs_str(typ: longint; const other, desc, value: ansistring): ansistring;
  1205. begin
  1206. result:=base_stabs_str(tostr(typ),other,desc,value);
  1207. end;
  1208. function TDebugInfoStabs.base_stabs_str(const typ, other, desc, value: ansistring): ansistring;
  1209. begin
  1210. result:=typ+','+other+','+desc+','+value
  1211. end;
  1212. function TDebugInfoStabs.gen_procdef_startsym_stabs(def: tprocdef): TAsmList;
  1213. var
  1214. RType : Char;
  1215. Obj,Info,
  1216. mangledname: ansistring;
  1217. begin
  1218. result:=TAsmList.create;
  1219. { "The stab representing a procedure is located immediately
  1220. following the code of the procedure. This stab is in turn
  1221. directly followed by a group of other stabs describing
  1222. elements of the procedure. These other stabs describe the
  1223. procedure's parameters, its block local variables, and its
  1224. block structure." (stab docs) }
  1225. { this is however incorrect in case "include source" statements }
  1226. { appear in the block, in that case the procedure stab must }
  1227. { appear before this include stabs (and we generate such an }
  1228. { stabs for all functions) (JM) }
  1229. obj := GetSymName(def.procsym);
  1230. info := '';
  1231. if (po_global in def.procoptions) then
  1232. RType := 'F'
  1233. else
  1234. RType := 'f';
  1235. if assigned(def.owner) then
  1236. begin
  1237. if (def.owner.symtabletype in [ObjectSymtable,recordsymtable]) then
  1238. obj := GetSymTableName(def.owner)+'__'+GetSymName(def.procsym);
  1239. if not(cs_gdb_valgrind in current_settings.globalswitches) and
  1240. (def.owner.symtabletype=localsymtable) and
  1241. assigned(def.owner.defowner) and
  1242. assigned(tprocdef(def.owner.defowner).procsym) then
  1243. info := ','+GetSymName(def.procsym)+','+GetSymName(tprocdef(def.owner.defowner).procsym);
  1244. end;
  1245. mangledname:=ReplaceForbiddenAsmSymbolChars(def.mangledname);
  1246. if target_info.system in systems_dotted_function_names then
  1247. mangledname:='.'+mangledname;
  1248. result.concat(Tai_stab.Create_ansistr(stabsdir,'"'+obj+':'+RType+def_stab_number(def.returndef)+info+'",'+
  1249. base_stabs_str(procdef_stab,'0',tostr(def.fileinfo.line),mangledname)));
  1250. end;
  1251. function TDebugInfoStabs.gen_procdef_endsym_stabs(def: tprocdef): TAsmList;
  1252. var
  1253. ss, mangledname: ansistring;
  1254. stabsendlabel: tasmlabel;
  1255. begin
  1256. result:=TAsmList.create;
  1257. { end of procedure }
  1258. current_asmdata.getlabel(stabsendlabel,alt_dbgtype);
  1259. if dbgtype<>dbg_stabx then
  1260. begin
  1261. mangledname:=def.mangledname;
  1262. if target_info.system in systems_dotted_function_names then
  1263. mangledname:='.'+mangledname;
  1264. // LBRAC
  1265. ss:=tostr(STABS_N_LBRAC)+',0,0,'+mangledname;
  1266. if not(af_stabs_use_function_absolute_addresses in target_asm.flags) then
  1267. begin
  1268. ss:=ss+'-';
  1269. ss:=ss+mangledname;
  1270. end;
  1271. result.concat(Tai_stab.Create_ansistr(stab_stabn,ss));
  1272. // RBRAC
  1273. ss:=tostr(STABS_N_RBRAC)+',0,0,'+stabsendlabel.name;
  1274. if not(af_stabs_use_function_absolute_addresses in target_asm.flags) then
  1275. begin
  1276. ss:=ss+'-';
  1277. ss:=ss+mangledname;
  1278. end;
  1279. result.concat(Tai_stab.Create_ansistr(stab_stabn,ss));
  1280. { the stabsendlabel must come after all other stabs for this }
  1281. { function }
  1282. result.concat(tai_label.create(stabsendlabel));
  1283. { Add a "size" stab as described in the last paragraph of 2.5 at }
  1284. { http://sourceware.org/gdb/current/onlinedocs/stabs_2.html#SEC12 }
  1285. { This works at least on Darwin (and is needed on Darwin to get }
  1286. { correct smartlinking of stabs), but I don't know which binutils }
  1287. { version is required on other platforms }
  1288. { This stab must come after all other stabs for the procedure, }
  1289. { including the LBRAC/RBRAC ones }
  1290. if (target_info.system in systems_darwin) then
  1291. result.concat(Tai_stab.create(stabsdir,
  1292. strpnew('"",'+base_stabs_str(procdef_stab,'0','0',stabsendlabel.name+'-'+mangledname))));
  1293. end;
  1294. end;
  1295. procedure TDebugInfoStabs.appendsym_paravar(list:TAsmList;sym:tparavarsym);
  1296. var
  1297. ss : ansistring;
  1298. c : string[1];
  1299. st : string;
  1300. regidx : Tregisterindex;
  1301. begin
  1302. ss:='';
  1303. { set loc to LOC_REFERENCE to get somewhat usable debugging info for -Or }
  1304. { while stabs aren't adapted for regvars yet }
  1305. if (vo_is_self in sym.varoptions) then
  1306. begin
  1307. case sym.localloc.loc of
  1308. LOC_REGISTER,
  1309. LOC_CREGISTER:
  1310. regidx:=findreg_by_number(sym.localloc.register);
  1311. LOC_REFERENCE: ;
  1312. else
  1313. internalerror(2003091815);
  1314. end;
  1315. if (po_classmethod in tabstractprocdef(sym.owner.defowner).procoptions) or
  1316. (po_staticmethod in tabstractprocdef(sym.owner.defowner).procoptions) then
  1317. begin
  1318. if (sym.localloc.loc=LOC_REFERENCE) then
  1319. ss:=sym_stabstr_evaluate(sym,'"pvmt:p$1",'+base_stabs_str(localvarsymref_stab,'0','0','$2'),
  1320. [def_stab_number(pvmttype),getoffsetstr(sym.localloc.reference)])
  1321. else
  1322. begin
  1323. regidx:=findreg_by_number(sym.localloc.register);
  1324. ss:=sym_stabstr_evaluate(sym,'"pvmt:r$1",'+base_stabs_str(regvar_stab,'0','0','$2'),
  1325. [def_stab_number(pvmttype),tostr(regstabs_table[regidx])]);
  1326. end
  1327. end
  1328. else
  1329. begin
  1330. if not(is_class(tprocdef(sym.owner.defowner).struct)) then
  1331. c:='v'
  1332. else
  1333. c:='p';
  1334. if (sym.localloc.loc=LOC_REFERENCE) then
  1335. ss:=sym_stabstr_evaluate(sym,'"$$t:$1",'+base_stabs_str(localvarsymref_stab,'0','0','$2'),
  1336. [c+def_stab_number(tprocdef(sym.owner.defowner).struct),getoffsetstr(sym.localloc.reference)])
  1337. else
  1338. begin
  1339. if (c='p') then
  1340. c:='R'
  1341. else
  1342. c:='a';
  1343. regidx:=findreg_by_number(sym.localloc.register);
  1344. ss:=sym_stabstr_evaluate(sym,'"$$t:$1",'+base_stabs_str(regvar_stab,'0','0','$2'),
  1345. [c+def_stab_number(tprocdef(sym.owner.defowner).struct),tostr(regstabs_table[regidx])]);
  1346. end
  1347. end;
  1348. end
  1349. else
  1350. begin
  1351. st:=def_stab_number(sym.vardef);
  1352. if paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1353. not(vo_has_local_copy in sym.varoptions) and
  1354. not is_open_string(sym.vardef) then
  1355. c:='v' { should be 'i' but 'i' doesn't work }
  1356. else
  1357. c:='p';
  1358. case sym.localloc.loc of
  1359. LOC_REGISTER,
  1360. LOC_CREGISTER,
  1361. LOC_MMREGISTER,
  1362. LOC_CMMREGISTER,
  1363. LOC_FPUREGISTER,
  1364. LOC_CFPUREGISTER :
  1365. begin
  1366. ss:=get_appendsym_paravar_reg(sym,c,st,sym.localloc.register);
  1367. end;
  1368. LOC_REFERENCE :
  1369. begin
  1370. { When the *value* of a parameter (so not its address!) is
  1371. copied into a local variable, you have to generate two
  1372. stabs: one for the parmeter, and one for the local copy.
  1373. Not doing this breaks debugging under e.g. SPARC. Doc:
  1374. http://sourceware.org/gdb/current/onlinedocs/stabs_4.html#SEC26
  1375. }
  1376. if (target_dbg.id<>dbg_stabx) and
  1377. (c='p') and
  1378. not is_open_string(sym.vardef) and
  1379. ((sym.paraloc[calleeside].location^.loc<>sym.localloc.loc) or
  1380. ((sym.localloc.loc in [LOC_REFERENCE,LOC_CREFERENCE]) and
  1381. ((sym.paraloc[calleeside].location^.reference.index<>sym.localloc.reference.base) or
  1382. (sym.paraloc[calleeside].location^.reference.offset<>sym.localloc.reference.offset))) or
  1383. ((sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_MMREGISTER,LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
  1384. (sym.localloc.register<>sym.paraloc[calleeside].location^.register))) then
  1385. begin
  1386. if not(sym.paraloc[calleeside].location^.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
  1387. ss:=get_appendsym_paravar_reg(sym,c,st,sym.paraloc[calleeside].location^.register)
  1388. else
  1389. ss:=sym_stabstr_evaluate(sym,'"${name}:$1",'+base_stabs_str(localvarsymref_stab,'0','${line}','$2'),
  1390. [c+st,getparaoffsetstr(sym.paraloc[calleeside].location^.reference)]);
  1391. write_sym_stabstr(list,sym,ss);
  1392. { second stab has no parameter specifier }
  1393. c:='';
  1394. end;
  1395. { offset to ebp => will not work if the framepointer is esp
  1396. so some optimizing will make things harder to debug }
  1397. ss:=sym_stabstr_evaluate(sym,'"${name}:$1",'+base_stabs_str(paravarsymref_stab,'0','${line}','$2'),[c+st,getoffsetstr(sym.localloc.reference)])
  1398. end;
  1399. else
  1400. internalerror(2003091814);
  1401. end;
  1402. end;
  1403. write_sym_stabstr(list,sym,ss);
  1404. end;
  1405. function stabx_quote_const(const s: string): string;
  1406. var
  1407. i:byte;
  1408. begin
  1409. stabx_quote_const:='';
  1410. for i:=1 to length(s) do
  1411. begin
  1412. case s[i] of
  1413. #10:
  1414. stabx_quote_const:=stabx_quote_const+'\n';
  1415. #13:
  1416. stabx_quote_const:=stabx_quote_const+'\r';
  1417. { stabx strings cannot deal with embedded quotes }
  1418. '"':
  1419. stabx_quote_const:=stabx_quote_const+' ';
  1420. else
  1421. stabx_quote_const:=stabx_quote_const+s[i];
  1422. end;
  1423. end;
  1424. end;
  1425. procedure TDebugInfoStabs.appendsym_const(list:TAsmList;sym:tconstsym);
  1426. var
  1427. st : string;
  1428. ss : ansistring;
  1429. begin
  1430. ss:='';
  1431. { Don't write info for default parameter values, the N_Func breaks
  1432. the N_Func for the function itself.
  1433. Valgrind does not support constants }
  1434. if (sym.owner.symtabletype=parasymtable) or
  1435. (cs_gdb_valgrind in current_settings.globalswitches) then
  1436. exit;
  1437. case sym.consttyp of
  1438. conststring:
  1439. begin
  1440. if sym.value.len<200 then
  1441. if target_dbg.id=dbg_stabs then
  1442. st:='s'''+backspace_quote(octal_quote(strpas(pchar(sym.value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+''''
  1443. else
  1444. st:='s'''+stabx_quote_const(octal_quote(strpas(pchar(sym.value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']))
  1445. else
  1446. st:='<constant string too long>';
  1447. end;
  1448. constord:
  1449. st:='i'+tostr(sym.value.valueord);
  1450. constpointer:
  1451. st:='i'+tostr(sym.value.valueordptr);
  1452. constreal:
  1453. begin
  1454. system.str(pbestreal(sym.value.valueptr)^,st);
  1455. st := 'r'+st;
  1456. end;
  1457. else
  1458. begin
  1459. { if we don't know just put zero !! }
  1460. st:='i0';
  1461. end;
  1462. end;
  1463. ss:=sym_stabstr_evaluate(sym,'"${name}:c=$1;",'+base_stabs_str(constsym_stab,'0','${line}','0'),[st]);
  1464. write_sym_stabstr(list,sym,ss);
  1465. end;
  1466. procedure TDebugInfoStabs.appendsym_type(list:TAsmList;sym:ttypesym);
  1467. var
  1468. ss : ansistring;
  1469. stabchar : string[2];
  1470. begin
  1471. ss:='';
  1472. if not assigned(sym.typedef) then
  1473. internalerror(200509262);
  1474. if sym.typedef.typ in tagtypes then
  1475. stabchar:=tagtypeprefix
  1476. else
  1477. stabchar:='t';
  1478. ss:=sym_stabstr_evaluate(sym,'"${name}:$1$2",'+base_stabs_str(typesym_stab,'0','${line}','0'),[stabchar,def_stab_number(sym.typedef)]);
  1479. write_sym_stabstr(list,sym,ss);
  1480. end;
  1481. procedure TDebugInfoStabs.appendsym_label(list:TAsmList;sym:tlabelsym);
  1482. var
  1483. ss : ansistring;
  1484. begin
  1485. ss:=sym_stabstr_evaluate(sym,'"${name}",'+base_stabs_str(localvarsymref_stab,'0','${line}','0'),[]);
  1486. write_sym_stabstr(list,sym,ss);
  1487. end;
  1488. {****************************************************************************
  1489. Proc/Module support
  1490. ****************************************************************************}
  1491. procedure TDebugInfoStabs.inserttypeinfo;
  1492. var
  1493. stabsvarlist,
  1494. stabstypelist : TAsmList;
  1495. storefilepos : tfileposinfo;
  1496. i : longint;
  1497. vardatatype : ttypesym;
  1498. begin
  1499. storefilepos:=current_filepos;
  1500. current_filepos:=current_module.mainfilepos;
  1501. global_stab_number:=0;
  1502. defnumberlist:=TFPObjectlist.create(false);
  1503. deftowritelist:=TFPObjectlist.create(false);
  1504. stabsvarlist:=TAsmList.create;
  1505. stabstypelist:=TAsmList.create;
  1506. vardatatype:=try_search_system_type('TVARDATA');
  1507. if assigned(vardatatype) then
  1508. vardatadef:=trecorddef(vardatatype.typedef);
  1509. { include symbol that will be referenced from the main to be sure to
  1510. include this debuginfo .o file }
  1511. current_module.flags:=current_module.flags or uf_has_stabs_debuginfo;
  1512. if not(target_info.system in systems_darwin) then
  1513. begin
  1514. new_section(current_asmdata.asmlists[al_stabs],sec_data,GetSymTableName(current_module.localsymtable),sizeof(pint));
  1515. current_asmdata.asmlists[al_stabs].concat(tai_symbol.Createname_global(make_mangledname('DEBUGINFO',current_module.localsymtable,''),AT_DATA,0));
  1516. end
  1517. else
  1518. new_section(current_asmdata.asmlists[al_stabs],sec_code,GetSymTableName(current_module.localsymtable),sizeof(pint));
  1519. { write all global/local variables. This will flag all required tdefs }
  1520. if assigned(current_module.globalsymtable) then
  1521. write_symtable_syms(stabsvarlist,current_module.globalsymtable);
  1522. if assigned(current_module.localsymtable) then
  1523. write_symtable_syms(stabsvarlist,current_module.localsymtable);
  1524. { write all procedures and methods. This will flag all required tdefs }
  1525. if assigned(current_module.globalsymtable) then
  1526. write_symtable_procdefs(stabsvarlist,current_module.globalsymtable);
  1527. if assigned(current_module.localsymtable) then
  1528. write_symtable_procdefs(stabsvarlist,current_module.localsymtable);
  1529. { reset unit type info flag }
  1530. reset_unit_type_info;
  1531. { write used types from the used units }
  1532. write_used_unit_type_info(stabstypelist,current_module);
  1533. { last write the types from this unit }
  1534. if assigned(current_module.globalsymtable) then
  1535. write_symtable_defs(stabstypelist,current_module.globalsymtable);
  1536. if assigned(current_module.localsymtable) then
  1537. write_symtable_defs(stabstypelist,current_module.localsymtable);
  1538. write_remaining_defs_to_write(stabstypelist);
  1539. current_asmdata.asmlists[al_stabs].concatlist(stabstypelist);
  1540. current_asmdata.asmlists[al_stabs].concatlist(stabsvarlist);
  1541. { reset stab numbers }
  1542. for i:=0 to defnumberlist.count-1 do
  1543. begin
  1544. if assigned(defnumberlist[i]) then
  1545. begin
  1546. tdef(defnumberlist[i]).stab_number:=0;
  1547. tdef(defnumberlist[i]).dbg_state:=dbg_state_unused;
  1548. end;
  1549. end;
  1550. defnumberlist.free;
  1551. defnumberlist:=nil;
  1552. deftowritelist.free;
  1553. deftowritelist:=nil;
  1554. stabsvarlist.free;
  1555. stabstypelist.free;
  1556. current_filepos:=storefilepos;
  1557. end;
  1558. procedure TDebugInfoStabs.insertlineinfo(list: TAsmList);
  1559. var
  1560. currfileinfo,
  1561. lastfileinfo : tfileposinfo;
  1562. currfuncname : pshortstring;
  1563. currsectype : TAsmSectiontype;
  1564. hlabel : tasmlabel;
  1565. hp : tai;
  1566. infile : tinputfile;
  1567. begin
  1568. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  1569. currfuncname:=nil;
  1570. currsectype:=sec_code;
  1571. hp:=Tai(list.first);
  1572. while assigned(hp) do
  1573. begin
  1574. case hp.typ of
  1575. ait_section :
  1576. currsectype:=tai_section(hp).sectype;
  1577. ait_function_name :
  1578. currfuncname:=tai_function_name(hp).funcname;
  1579. ait_force_line :
  1580. lastfileinfo.line:=-1;
  1581. end;
  1582. if (currsectype=sec_code) and
  1583. (hp.typ=ait_instruction) then
  1584. begin
  1585. currfileinfo:=tailineinfo(hp).fileinfo;
  1586. { file changed ? (must be before line info) }
  1587. if (currfileinfo.fileindex<>0) and
  1588. ((lastfileinfo.fileindex<>currfileinfo.fileindex) or
  1589. (lastfileinfo.moduleindex<>currfileinfo.moduleindex)) then
  1590. begin
  1591. infile:=get_module(currfileinfo.moduleindex).sourcefiles.get_file(currfileinfo.fileindex);
  1592. if assigned(infile) then
  1593. begin
  1594. current_asmdata.getlabel(hlabel,alt_dbgfile);
  1595. { emit stabs }
  1596. if not(ds_stabs_abs_include_files in current_settings.debugswitches) or
  1597. path_absolute(infile.path) then
  1598. list.insertbefore(Tai_stab.Create_str(stabsdir,'"'+BsToSlash(FixPath(infile.path,false))+FixFileName(infile.name)+'",'+tostr(stabs_n_includefile)+
  1599. ',0,0,'+hlabel.name),hp)
  1600. else
  1601. list.insertbefore(Tai_stab.Create_str(stabsdir,'"'+BsToSlash(FixPath(getcurrentdir,false)+FixPath(infile.path,false))+FixFileName(infile.name)+'",'+tostr(stabs_n_includefile)+
  1602. ',0,0,'+hlabel.name),hp);
  1603. list.insertbefore(tai_label.create(hlabel),hp);
  1604. { force new line info }
  1605. lastfileinfo.line:=-1;
  1606. end;
  1607. end;
  1608. { line changed ? }
  1609. if (currfileinfo.line>lastfileinfo.line) and (currfileinfo.line<>0) then
  1610. begin
  1611. if assigned(currfuncname) and
  1612. not(af_stabs_use_function_absolute_addresses in target_asm.flags) then
  1613. begin
  1614. current_asmdata.getlabel(hlabel,alt_dbgline);
  1615. list.insertbefore(Tai_stab.Create_str(stab_stabn,tostr(stabs_n_textline)+',0,'+tostr(currfileinfo.line)+','+
  1616. hlabel.name+' - '+{$IFDEF POWERPC64}'.'+{$ENDIF POWERPC64}currfuncname^),hp);
  1617. list.insertbefore(tai_label.create(hlabel),hp);
  1618. end
  1619. else
  1620. list.insertbefore(Tai_stab.Create_str(stab_stabd,tostr(stabs_n_textline)+',0,'+tostr(currfileinfo.line)),hp);
  1621. end;
  1622. lastfileinfo:=currfileinfo;
  1623. end;
  1624. hp:=tai(hp.next);
  1625. end;
  1626. end;
  1627. procedure TDebugInfoStabs.insertmoduleinfo;
  1628. var
  1629. hlabel : tasmlabel;
  1630. infile : tinputfile;
  1631. begin
  1632. { emit main source n_sourcefile for start of module }
  1633. current_asmdata.getlabel(hlabel,alt_dbgfile);
  1634. infile:=current_module.sourcefiles.get_file(1);
  1635. new_section(current_asmdata.asmlists[al_start],sec_code,make_mangledname('DEBUGSTART',current_module.localsymtable,''),sizeof(pint),secorder_begin);
  1636. if not(target_info.system in systems_darwin) then
  1637. current_asmdata.asmlists[al_start].concat(tai_symbol.Createname_global(make_mangledname('DEBUGSTART',current_module.localsymtable,''),AT_DATA,0));
  1638. current_asmdata.asmlists[al_start].concat(Tai_stab.Create_str(stabsdir,'"'+BsToSlash(FixPath(getcurrentdir,false))+'",'+
  1639. base_stabs_str(stabs_n_sourcefile,'0','0',hlabel.name)));
  1640. current_asmdata.asmlists[al_start].concat(Tai_stab.Create_str(stabsdir,'"'+BsToSlash(FixPath(infile.path,false))+FixFileName(infile.name)+'",'+
  1641. base_stabs_str(stabs_n_sourcefile,'0','0',hlabel.name)));
  1642. current_asmdata.asmlists[al_start].concat(tai_label.create(hlabel));
  1643. { for darwin, you need a "module marker" too to work around }
  1644. { either some assembler or gdb bug (radar 4386531 according to a }
  1645. { comment in dbxout.c of Apple's gcc) }
  1646. if (target_info.system in systems_darwin) then
  1647. current_asmdata.asmlists[al_end].concat(Tai_stab.Create_str(stabsdir,'"",'+base_stabs_str(STABS_N_OSO,'0','0','0')));
  1648. { emit empty n_sourcefile for end of module }
  1649. current_asmdata.getlabel(hlabel,alt_dbgfile);
  1650. new_section(current_asmdata.asmlists[al_end],sec_code,make_mangledname('DEBUGEND',current_module.localsymtable,''),sizeof(pint),secorder_end);
  1651. if not(target_info.system in systems_darwin) then
  1652. current_asmdata.asmlists[al_end].concat(tai_symbol.Createname_global(make_mangledname('DEBUGEND',current_module.localsymtable,''),AT_DATA,0));
  1653. current_asmdata.asmlists[al_end].concat(Tai_stab.Create_str(stabsdir,'"",'+base_stabs_str(stabs_n_sourcefile,'0','0',hlabel.name)));
  1654. current_asmdata.asmlists[al_end].concat(tai_label.create(hlabel));
  1655. end;
  1656. procedure TDebugInfoStabs.referencesections(list: TAsmList);
  1657. var
  1658. hp : tmodule;
  1659. dbgtable : tai_symbol;
  1660. begin
  1661. { Reference all DEBUGINFO sections from the main .fpc section }
  1662. if (target_info.system in ([system_powerpc_macos]+systems_darwin)) then
  1663. exit;
  1664. new_section(list,sec_fpc,'links',0);
  1665. { make sure the debuginfo doesn't get stripped out }
  1666. if (target_info.system in systems_darwin) then
  1667. begin
  1668. dbgtable:=tai_symbol.createname('DEBUGINFOTABLE',AT_DATA,0);
  1669. list.concat(tai_directive.create(asd_no_dead_strip,dbgtable.sym.name));
  1670. list.concat(dbgtable);
  1671. end;
  1672. { include reference to all debuginfo sections of used units }
  1673. hp:=tmodule(loaded_units.first);
  1674. while assigned(hp) do
  1675. begin
  1676. If (hp.flags and uf_has_stabs_debuginfo)=uf_has_stabs_debuginfo then
  1677. begin
  1678. list.concat(Tai_const.Createname(make_mangledname('DEBUGINFO',hp.localsymtable,''),0));
  1679. list.concat(Tai_const.Createname(make_mangledname('DEBUGSTART',hp.localsymtable,''),0));
  1680. list.concat(Tai_const.Createname(make_mangledname('DEBUGEND',hp.localsymtable,''),0));
  1681. end;
  1682. hp:=tmodule(hp.next);
  1683. end;
  1684. end;
  1685. constructor TDebugInfoStabs.Create;
  1686. begin
  1687. inherited Create;
  1688. dbgtype:=dbg_stabs;
  1689. stabsdir:=stab_stabs;
  1690. def_stab:=STABS_N_LSYM;
  1691. regvar_stab:=STABS_N_RSYM;
  1692. procdef_stab:=STABS_N_Function;
  1693. constsym_stab:=STABS_N_Function;
  1694. typesym_stab:=STABS_N_LSYM;
  1695. globalvarsym_uninited_stab:=STABS_N_STSYM;
  1696. globalvarsym_inited_stab:=STABS_N_LCSYM;
  1697. staticvarsym_uninited_stab:=STABS_N_STSYM;
  1698. staticvarsym_inited_stab:=STABS_N_LCSYM;
  1699. localvarsymref_stab:=STABS_N_TSYM;
  1700. paravarsymref_stab:=STABS_N_TSYM;
  1701. tagtypeprefix:='Tt';
  1702. vardatadef:=nil;
  1703. end;
  1704. const
  1705. dbg_stabs_info : tdbginfo =
  1706. (
  1707. id : dbg_stabs;
  1708. idtxt : 'STABS';
  1709. );
  1710. initialization
  1711. RegisterDebugInfo(dbg_stabs_info,TDebugInfoStabs);
  1712. end.