dbgstabs.pas 66 KB

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