llvmdef.pas 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. {
  2. Copyright (c) 2008 by Peter Vreman, Florian Klaempfl and Jonas Maebe
  3. This units contains support for generating LLVM type info
  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. {
  18. This units contains support for LLVM type info generation.
  19. It's based on the debug info system, since it's quite similar
  20. }
  21. unit llvmdef;
  22. {$i fpcdefs.inc}
  23. {$h+}
  24. interface
  25. uses
  26. cclasses,globtype,
  27. aasmbase,aasmtai,aasmdata,
  28. symbase,symtype,symdef,symsym,
  29. finput,
  30. dbgbase;
  31. { TLLVMDefInfo }
  32. type
  33. TLLVMDefInfo = class(TDebugInfo)
  34. { collect all defs in one list so we can reset them easily }
  35. defnumberlist,
  36. deftowritelist : TFPObjectList;
  37. function def_llvm_name(def:tdef) : tasmsymbol;
  38. function def_llvm_class_struct_name(def:tobjectdef) : tasmsymbol;
  39. protected
  40. vardatadef: trecorddef;
  41. procedure record_def(def:tdef);
  42. procedure beforeappenddef(list:TAsmList;def:tdef);override;
  43. procedure afterappenddef(list:TAsmList;def:tdef);override;
  44. procedure appenddef_ord(list:TAsmList;def:torddef);override;
  45. procedure appenddef_float(list:TAsmList;def:tfloatdef);override;
  46. procedure appenddef_enum(list:TAsmList;def:tenumdef);override;
  47. procedure appenddef_array(list:TAsmList;def:tarraydef);override;
  48. procedure appenddef_abstractrecord(list:TAsmList;def:tabstractrecorddef);
  49. procedure appenddef_record(list:TAsmList;def:trecorddef);override;
  50. procedure appenddef_pointer(list:TAsmList;def:tpointerdef);override;
  51. procedure appenddef_classref(list:TAsmList;def: tclassrefdef);override;
  52. procedure appenddef_string(list:TAsmList;def:tstringdef);override;
  53. procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
  54. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  55. procedure appendprocdef_implicit(list:TAsmList;def:tprocdef);override;
  56. procedure appenddef_formal(list:TAsmList;def: tformaldef);override;
  57. procedure appenddef_object(list:TAsmList;def: tobjectdef);override;
  58. procedure appenddef_set(list:TAsmList;def: tsetdef);override;
  59. procedure appenddef_undefined(list:TAsmList;def: tundefineddef);override;
  60. procedure appenddef_variant(list:TAsmList;def: tvariantdef);override;
  61. procedure appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  62. procedure beforeappendsym(list:TAsmList;sym:tsym);override;
  63. procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
  64. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  65. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  66. procedure appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);override;
  67. procedure appendsym_const(list:TAsmList;sym:tconstsym);override;
  68. procedure appendsym_type(list:TAsmList;sym:ttypesym);override;
  69. procedure appendsym_label(list:TAsmList;sym:tlabelsym);override;
  70. procedure appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);override;
  71. procedure appendsym_property(list:TAsmList;sym:tpropertysym);override;
  72. function getabstractprocdefstr(def:tabstractprocdef): ansistring;
  73. function symname(sym:tsym): String;
  74. procedure enum_membersyms_callback(p:TObject;arg:pointer);
  75. public
  76. constructor Create;override;
  77. destructor Destroy;override;
  78. procedure insertmoduleinfo;override;
  79. procedure inserttypeinfo;override;
  80. procedure referencesections(list:TAsmList);override;
  81. end;
  82. implementation
  83. uses
  84. sysutils,cutils,cfileutl,constexp,
  85. version,globals,verbose,systems,
  86. cpubase,cgbase,paramgr,
  87. fmodule,nobj,
  88. defutil,symconst,symtable,
  89. llvmbase, aasmllvm;
  90. {****************************************************************************
  91. TDebugInfoDwarf
  92. ****************************************************************************}
  93. procedure TLLVMDefInfo.record_def(def:tdef);
  94. begin
  95. if (def.dbg_state <> dbg_state_unused) then
  96. exit;
  97. { the name syms are set automatically when requested }
  98. def.dbg_state:=dbg_state_used;
  99. deftowritelist.Add(def);
  100. defnumberlist.Add(def);
  101. end;
  102. function TLLVMDefInfo.def_llvm_name(def: tdef): tasmsymbol;
  103. begin
  104. record_def(def);
  105. result:=def.llvm_name_sym;
  106. end;
  107. function TLLVMDefInfo.def_llvm_class_struct_name(def: tobjectdef): tasmsymbol;
  108. begin
  109. record_def(def);
  110. result:=def.llvm_class_struct_name_sym;
  111. end;
  112. constructor TLLVMDefInfo.Create;
  113. begin
  114. inherited Create;
  115. end;
  116. destructor TLLVMDefInfo.Destroy;
  117. begin
  118. inherited destroy;
  119. end;
  120. procedure TLLVMDefInfo.enum_membersyms_callback(p:TObject; arg: pointer);
  121. begin
  122. case tsym(p).typ of
  123. fieldvarsym:
  124. appendsym_fieldvar(TAsmList(arg),tfieldvarsym(p));
  125. end;
  126. end;
  127. procedure TLLVMDefInfo.appenddef_ord(list:TAsmList;def:torddef);
  128. begin
  129. case def.ordtype of
  130. s8bit,
  131. s16bit,
  132. s32bit,
  133. s64bit,
  134. u8bit,
  135. u16bit,
  136. u32bit,
  137. u64bit,
  138. uchar,
  139. uwidechar,
  140. pasbool,
  141. bool8bit,
  142. bool16bit,
  143. bool32bit,
  144. bool64bit,
  145. scurrency:
  146. begin
  147. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'i'+tostr(def.size*8)));
  148. end;
  149. uvoid :
  150. begin
  151. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'void'));
  152. end
  153. else
  154. internalerror(2008032901);
  155. end;
  156. end;
  157. procedure TLLVMDefInfo.appenddef_float(list:TAsmList;def:tfloatdef);
  158. begin
  159. case def.floattype of
  160. s32real:
  161. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'float'));
  162. s64real:
  163. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'double'));
  164. s80real:
  165. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'x86_fp80'));
  166. s64currency,
  167. s64comp:
  168. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'i64'));
  169. else
  170. internalerror(200601289);
  171. end;
  172. end;
  173. procedure TLLVMDefInfo.appenddef_enum(list:TAsmList;def:tenumdef);
  174. begin
  175. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'i'+tostr(def.size*8)));
  176. end;
  177. procedure TLLVMDefInfo.appenddef_array(list:TAsmList;def:tarraydef);
  178. var
  179. typename: ansistring;
  180. endstr: ansistring;
  181. indexrange: aint;
  182. {$ifndef llvm_has_packed_arrays}
  183. begin
  184. if is_packed_array(def) then
  185. begin
  186. { have to use an array of byte of the appropriate size, }
  187. { since llvm doesn't support packed arrays yet natively }
  188. typename:=def_llvm_name(s8inttype).name;
  189. indexrange:=def.size;
  190. end
  191. else
  192. begin
  193. typename:=def_llvm_name(def.elementdef).name;
  194. if not is_open_array(def) and
  195. not is_dynamic_array(def) then
  196. indexrange:=def.highrange-def.lowrange+1
  197. else
  198. indexrange:=0;
  199. end;
  200. if not is_dynamic_array(def) then
  201. endstr:=']'
  202. else
  203. endstr:=']*';
  204. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'['+tostr(indexrange)+' x '+typename+endstr))
  205. {$else not llvm_has_packed_arrays}
  206. var
  207. arrstart, arrend, typename: ansistring;
  208. begin
  209. typename:='';
  210. if not is_packed_array(def) then
  211. begin
  212. { regular array: '[' nritems 'x' type ']' }
  213. arrstart:='[';
  214. arrend:=']'
  215. end
  216. else
  217. begin
  218. { packed array: '<' nritems 'x' type '>' }
  219. arrstart:='< [';
  220. arrend:='] >';
  221. if is_ordinal(def.elementdef) then
  222. typename:='i'+tostr(def.elepackedbitsize);
  223. end;
  224. if (typename='') then
  225. typename:=def_llvm_name(def.elementdef).name
  226. if is_open_array(def) then
  227. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),arrstart+'0 x '+typename+arrend))
  228. else if is_dynamic_array(def) then
  229. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'[0 x '+typename+']'+'*'))
  230. else
  231. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),arrstart+tostr(def.highrange-def.lowrange+1)+' x '+typename+arrend))
  232. {$endif not llvm_has_packed_arrays}
  233. end;
  234. procedure TLLVMDefInfo.appenddef_abstractrecord(list:TAsmList;def:tabstractrecorddef);
  235. var
  236. defstr, endstr: ansistring;
  237. symdeflist: tfpobjectlist;
  238. i: longint;
  239. begin
  240. if (tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment) then
  241. begin
  242. { we handle the alignment/padding ourselves }
  243. defstr:='< ';
  244. endstr:=' >'
  245. end
  246. else
  247. begin
  248. { let llvm do everything }
  249. defstr:= '{ ';
  250. endstr:= ' }'
  251. end;
  252. if not assigned(tabstractrecordsymtable(def.symtable).llvmst) then
  253. tabstractrecordsymtable(def.symtable).llvmst:=tllvmshadowsymtable.create(tabstractrecordsymtable(def.symtable));
  254. symdeflist:=tabstractrecordsymtable(def.symtable).llvmst.symdeflist;
  255. i:=0;
  256. if (def.typ=objectdef) and
  257. assigned(tobjectdef(def).childof) and
  258. is_class(tllvmshadowsymtableentry(symdeflist[0]).def) then
  259. begin
  260. { insert the struct for the class rather than a pointer to the struct }
  261. if (tllvmshadowsymtableentry(symdeflist[0]).def.typ<>objectdef) then
  262. internalerror(2008070601);
  263. defstr:=defstr+def_llvm_class_struct_name(tobjectdef(tllvmshadowsymtableentry(symdeflist[0]).def)).name+', ';
  264. inc(i);
  265. end;
  266. while i< symdeflist.count do
  267. begin
  268. defstr:=defstr+def_llvm_name(tllvmshadowsymtableentry(symdeflist[i]).def).name+', ';
  269. inc(i);
  270. end;
  271. { remove last ', ' }
  272. setlength(defstr,length(defstr)-2);
  273. defstr:=defstr+endstr;
  274. if (def.typ <> objectdef) or
  275. not(tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba,odt_dispinterface,odt_class]) then
  276. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),defstr))
  277. else
  278. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_class_struct_name(tobjectdef(def)),defstr))
  279. end;
  280. procedure TLLVMDefInfo.appenddef_record(list:TAsmList;def:trecorddef);
  281. begin
  282. appenddef_abstractrecord(list,def);
  283. end;
  284. procedure TLLVMDefInfo.appenddef_pointer(list:TAsmList;def:tpointerdef);
  285. begin
  286. { to avoid cluttering the source with pointer types, }
  287. { pointer type names directly are "pointeddef.name+'*'". }
  288. { So only register the pointeddef so it gets printed }
  289. record_def(def.pointeddef);
  290. end;
  291. procedure TLLVMDefInfo.appenddef_classref(list:TAsmList;def: tclassrefdef);
  292. var
  293. defstr: ansistring;
  294. i: longint;
  295. begin
  296. { a pointer to the VMT. Structure of the VMT: }
  297. { InstanceSize : ptrint }
  298. { -InstanceSize : ptrint }
  299. { Parent : ^parent }
  300. { ClassName : pointer }
  301. { DynamicTable : pointer }
  302. { MethodTable : pointer }
  303. { FieldTable : pointer }
  304. { TypeInfo : pointer }
  305. { InitTable : pointer }
  306. { AutoTable : pointer }
  307. { IntfTable : pointer }
  308. { MsgStrTable : pointer }
  309. { Methods : X times procvar }
  310. defstr:=def_llvm_name(ptrsinttype).name+', ';
  311. defstr:='< '+defstr+defstr;
  312. { needs to be pointer to the parent class' vmt!
  313. if assigned(tobjectdef(def.pointeddef).childof) then
  314. defstr:=defstr+def_llvm_name(tobjectdef(def.pointeddef).childof).name+'*,'
  315. else
  316. }
  317. defstr:=defstr+'void*, ';
  318. { class name (length+string) }
  319. defstr:=defstr+'['+tostr(length(tobjectdef(def.pointeddef).objrealname^)+1)+' x i8]*, ';
  320. { the other fields }
  321. for i:=1 to 8 do
  322. defstr:=defstr+'void*, ';
  323. if not assigned(tobjectdef(def.pointeddef).VMTEntries) then
  324. with TVMTBuilder.Create(tobjectdef(def.pointeddef)) do
  325. begin
  326. generate_vmt;
  327. free;
  328. end;
  329. for i:= 0 to tobjectdef(def.pointeddef).VMTEntries.Count-1 do
  330. defstr:=defstr+def_llvm_name(tprocdef(tobjectdef(def.pointeddef).VMTEntries[i])).name+'*, ';
  331. setlength(defstr,length(defstr)-2);
  332. defstr:=defstr+' >*';
  333. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),defstr));
  334. end;
  335. procedure TLLVMDefInfo.appenddef_string(list:TAsmList;def:tstringdef);
  336. procedure addnormalstringdef(lendef: tdef);
  337. var
  338. defstr: ansistring;
  339. begin
  340. { record with length and array [maxlen x i8 ] }
  341. { (also ok for openstrings, as [0 x i8] means }
  342. { "array of unspecified size" in llvm) }
  343. defstr:='< '+def_llvm_name(lendef).name+', ['+tostr(def.len)+' x i8] >';
  344. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),defstr));
  345. end;
  346. begin
  347. case def.stringtype of
  348. st_shortstring:
  349. begin
  350. addnormalstringdef(u8inttype);
  351. end;
  352. st_longstring:
  353. begin
  354. {$ifdef cpu64bitaddr}
  355. addnormalstringdef(u64inttype);
  356. {$else cpu64bitaddr}
  357. addnormalstringdef(u32inttype);
  358. {$endif cpu64bitaddr}
  359. end;
  360. st_ansistring:
  361. begin
  362. { looks like a pchar }
  363. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'i8*'));
  364. end;
  365. st_unicodestring,
  366. st_widestring:
  367. begin
  368. { looks like a pwidechar }
  369. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'i16*'));
  370. end;
  371. end;
  372. end;
  373. procedure TLLVMDefInfo.appenddef_procvar(list:TAsmList;def:tprocvardef);
  374. begin
  375. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),getabstractprocdefstr(def)+'*'));
  376. end;
  377. procedure TLLVMDefInfo.beforeappenddef(list:TAsmList;def:tdef);
  378. var
  379. labsym : tasmsymbol;
  380. begin
  381. list.concat(tai_comment.Create(strpnew('LLVM definition '+def.typename)));
  382. end;
  383. procedure TLLVMDefInfo.afterappenddef(list:TAsmList;def:tdef);
  384. begin
  385. end;
  386. function TLLVMDefInfo.getabstractprocdefstr(def:tabstractprocdef): ansistring;
  387. var
  388. i : longint;
  389. begin
  390. { function result-by-reference is handled as a parameter }
  391. if (def.proctypeoption in [potype_constructor,potype_destructor]) or
  392. not paramanager.ret_in_param(def.returndef,def.proccalloption) then
  393. result:=def_llvm_name(def.returndef).name
  394. else
  395. result:='void';
  396. result:=result+' ( ';
  397. for i:=0 to def.paras.count-1 do
  398. with tparavarsym(def.paras[i]) do
  399. begin
  400. result:=result+def_llvm_name(vardef).name;
  401. if paramanager.push_addr_param(varspez,vardef,def.proccalloption) then
  402. begin
  403. result:=result+'*';
  404. if (vo_has_local_copy in varoptions) then
  405. result:=result+' byval'
  406. else if (vo_is_funcret in varoptions) then
  407. result:=result+' sret';
  408. end;
  409. result:=result+', '
  410. end;
  411. result[length(result)-1]:=')';
  412. end;
  413. procedure TLLVMDefInfo.appendprocdef_implicit(list:TAsmList;def:tprocdef);
  414. begin
  415. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),getabstractprocdefstr(def)));
  416. end;
  417. procedure TLLVMDefInfo.appendprocdef(list:TAsmList;def:tprocdef);
  418. var
  419. defstr : ansistring;
  420. i : longint;
  421. begin
  422. { the procdef itself is already written by appendprocdef_implicit }
  423. { last write the types from this procdef }
  424. if assigned(def.parast) then
  425. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
  426. if assigned(def.localst) and
  427. (def.localst.symtabletype=localsymtable) then
  428. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.localst);
  429. end;
  430. procedure TLLVMDefInfo.appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  431. var
  432. templist : TAsmList;
  433. blocksize : longint;
  434. dreg : byte;
  435. begin
  436. { external symbols can't be resolved at link time, so we
  437. can't generate stabs for them
  438. not sure if this applies to dwarf as well (FK)
  439. }
  440. if vo_is_external in sym.varoptions then
  441. exit;
  442. def_llvm_name(sym.vardef);
  443. { There is no space allocated for not referenced locals }
  444. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  445. exit;
  446. (*
  447. templist:=TAsmList.create;
  448. case sym.localloc.loc of
  449. LOC_REGISTER,
  450. LOC_CREGISTER,
  451. LOC_MMREGISTER,
  452. LOC_CMMREGISTER,
  453. LOC_FPUREGISTER,
  454. LOC_CFPUREGISTER :
  455. begin
  456. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  457. dreg:=dwarf_reg(sym.localloc.register);
  458. templist.concat(tai_const.create_uleb128bit(dreg));
  459. blocksize:=1+Lengthuleb128(dreg);
  460. end;
  461. else
  462. begin
  463. case sym.typ of
  464. staticvarsym:
  465. begin
  466. if (vo_is_thread_var in sym.varoptions) then
  467. begin
  468. {$warning !!! FIXME: dwarf for thread vars !!!
  469. }
  470. blocksize:=0;
  471. end
  472. else
  473. begin
  474. templist.concat(tai_const.create_8bit(3));
  475. templist.concat(tai_const.createname(sym.mangledname,0));
  476. blocksize:=1+sizeof(puint);
  477. end;
  478. end;
  479. paravarsym,
  480. localvarsym:
  481. begin
  482. dreg:=dwarf_reg(sym.localloc.reference.base);
  483. templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+dreg));
  484. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset));
  485. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset);
  486. end
  487. else
  488. internalerror(200601288);
  489. end;
  490. end;
  491. end;
  492. if sym.typ=paravarsym then
  493. tag:=DW_TAG_formal_parameter
  494. else
  495. tag:=DW_TAG_variable;
  496. if not(sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_MMREGISTER,
  497. LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
  498. ((sym.owner.symtabletype = globalsymtable) or
  499. (sp_static in sym.symoptions) or
  500. (vo_is_public in sym.varoptions)) then
  501. append_entry(tag,false,[
  502. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  503. {
  504. DW_AT_decl_file,DW_FORM_data1,0,
  505. DW_AT_decl_line,DW_FORM_data1,
  506. }
  507. DW_AT_external,DW_FORM_flag,true,
  508. { data continues below }
  509. DW_AT_location,DW_FORM_block1,blocksize
  510. ])
  511. {$ifdef gdb_supports_DW_AT_variable_parameter}
  512. else if (sym.typ=paravarsym) and
  513. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  514. not(vo_has_local_copy in sym.varoptions) and
  515. not is_open_string(sym.vardef) then
  516. append_entry(tag,false,[
  517. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  518. DW_AT_variable_parameter,DW_FORM_flag,true,
  519. {
  520. DW_AT_decl_file,DW_FORM_data1,0,
  521. DW_AT_decl_line,DW_FORM_data1,
  522. }
  523. { data continues below }
  524. DW_AT_location,DW_FORM_block1,blocksize
  525. ])
  526. {$endif gdb_supports_DW_AT_variable_parameter}
  527. else
  528. append_entry(tag,false,[
  529. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  530. {
  531. DW_AT_decl_file,DW_FORM_data1,0,
  532. DW_AT_decl_line,DW_FORM_data1,
  533. }
  534. { data continues below }
  535. DW_AT_location,DW_FORM_block1,blocksize
  536. ]);
  537. { append block data }
  538. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  539. {$ifndef gdb_supports_DW_AT_variable_parameter}
  540. if (sym.typ=paravarsym) and
  541. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  542. not(vo_has_local_copy in sym.varoptions) and
  543. not is_open_string(sym.vardef) then
  544. append_labelentry_ref(DW_AT_type,def_dwarf_ref_lab(sym.vardef))
  545. else
  546. {$endif not gdb_supports_DW_AT_variable_parameter}
  547. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  548. templist.free;
  549. finish_entry;
  550. *)
  551. end;
  552. procedure TLLVMDefInfo.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
  553. begin
  554. appendsym_var(list,sym);
  555. end;
  556. procedure TLLVMDefInfo.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
  557. begin
  558. appendsym_var(list,sym);
  559. end;
  560. procedure TLLVMDefInfo.appendsym_paravar(list:TAsmList;sym:tparavarsym);
  561. begin
  562. appendsym_var(list,sym);
  563. end;
  564. procedure TLLVMDefInfo.appendsym_fieldvar(list:TAsmList;sym: tfieldvarsym);
  565. var
  566. bitoffset,
  567. fieldoffset,
  568. fieldnatsize: aint;
  569. begin
  570. // list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE),'fieldvasym');
  571. (*
  572. if sp_static in sym.symoptions then
  573. exit;
  574. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) or
  575. { only ordinals are bitpacked }
  576. not is_ordinal(sym.vardef) then
  577. begin
  578. { other kinds of fields can however also appear in a bitpacked }
  579. { record, and then their offset is also specified in bits rather }
  580. { than in bytes }
  581. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) then
  582. fieldoffset:=sym.fieldoffset
  583. else
  584. fieldoffset:=sym.fieldoffset div 8;
  585. append_entry(DW_TAG_member,false,[
  586. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  587. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  588. ]);
  589. end
  590. else
  591. begin
  592. if (sym.vardef.packedbitsize > 255) then
  593. internalerror(2007061201);
  594. { we don't bitpack according to the ABI, but as close as }
  595. { possible, i.e., equivalent to gcc's }
  596. { __attribute__((__packed__)), which is also what gpc }
  597. { does. }
  598. fieldnatsize:=max(sizeof(pint),sym.vardef.size);
  599. fieldoffset:=(sym.fieldoffset div (fieldnatsize*8)) * fieldnatsize;
  600. bitoffset:=sym.fieldoffset mod (fieldnatsize*8);
  601. if (target_info.endian=endian_little) then
  602. bitoffset:=(fieldnatsize*8)-bitoffset-sym.vardef.packedbitsize;
  603. append_entry(DW_TAG_member,false,[
  604. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  605. { gcc also generates both a bit and byte size attribute }
  606. { we don't support ordinals >= 256 bits }
  607. DW_AT_byte_size,DW_FORM_data1,fieldnatsize,
  608. { nor >= 256 bits (not yet, anyway, see IE above) }
  609. DW_AT_bit_size,DW_FORM_data1,sym.vardef.packedbitsize,
  610. { data1 and data2 are unsigned, bitoffset can also be negative }
  611. DW_AT_bit_offset,DW_FORM_data4,bitoffset,
  612. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  613. ]);
  614. end;
  615. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  616. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(fieldoffset));
  617. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  618. finish_entry;
  619. *)
  620. end;
  621. procedure TLLVMDefInfo.appendsym_const(list:TAsmList;sym:tconstsym);
  622. begin
  623. // list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE),'constsym');
  624. (*
  625. append_entry(DW_TAG_constant,false,[
  626. DW_AT_name,DW_FORM_string,symname(sym)+#0
  627. ]);
  628. { for string constants, constdef isn't set because they have no real type }
  629. if not(sym.consttyp in [conststring,constresourcestring,constwstring]) then
  630. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.constdef));
  631. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_AT_const_value)));
  632. case sym.consttyp of
  633. conststring:
  634. begin
  635. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_string)));
  636. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(strpas(pchar(sym.value.valueptr))));
  637. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  638. end;
  639. constset,
  640. constwstring,
  641. constguid,
  642. constresourcestring:
  643. begin
  644. { write dummy for now }
  645. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_string)));
  646. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(''));
  647. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  648. end;
  649. constord:
  650. begin
  651. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_sdata)));
  652. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(sym.value.valueord.svalue));
  653. end;
  654. constnil:
  655. begin
  656. {$ifdef cpu64bitaddr}
  657. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  658. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(0));
  659. {$else cpu64bitaddr}
  660. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  661. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(0));
  662. {$endif cpu64bitaddr}
  663. end;
  664. constpointer:
  665. begin
  666. {$ifdef cpu64bitaddr}
  667. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  668. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(int64(sym.value.valueordptr)));
  669. {$else cpu64bitaddr}
  670. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  671. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(sym.value.valueordptr));
  672. {$endif cpu64bitaddr}
  673. end;
  674. constreal:
  675. begin
  676. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_block1)));
  677. case tfloatdef(sym.constdef).floattype of
  678. s32real:
  679. begin
  680. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(4));
  681. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_32bit.create(psingle(sym.value.valueptr)^));
  682. end;
  683. s64comp,
  684. s64currency,
  685. s64real:
  686. begin
  687. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  688. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_64bit.create(pdouble(sym.value.valueptr)^));
  689. end;
  690. s80real:
  691. begin
  692. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(10));
  693. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_80bit.create(pextended(sym.value.valueptr)^));
  694. end;
  695. else
  696. internalerror(200601291);
  697. end;
  698. end;
  699. else
  700. internalerror(200601292);
  701. end;
  702. finish_entry;
  703. *)
  704. end;
  705. procedure TLLVMDefInfo.appendsym_label(list:TAsmList;sym: tlabelsym);
  706. begin
  707. { ignore label syms for now, the problem is that a label sym
  708. can have more than one label associated e.g. in case of
  709. an inline procedure expansion }
  710. end;
  711. procedure TLLVMDefInfo.appendsym_property(list:TAsmList;sym: tpropertysym);
  712. begin
  713. { ignored for now }
  714. end;
  715. procedure TLLVMDefInfo.appendsym_type(list:TAsmList;sym: ttypesym);
  716. begin
  717. // list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,'typesym');
  718. record_def(sym.typedef);
  719. end;
  720. procedure TLLVMDefInfo.appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);
  721. var
  722. templist : TAsmList;
  723. blocksize : longint;
  724. symlist : ppropaccesslistitem;
  725. begin
  726. // list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE),'absolutesym'));
  727. end;
  728. procedure TLLVMDefInfo.beforeappendsym(list:TAsmList;sym:tsym);
  729. begin
  730. end;
  731. procedure TLLVMDefInfo.insertmoduleinfo;
  732. begin
  733. end;
  734. procedure TLLVMDefInfo.inserttypeinfo;
  735. procedure write_defs_to_write;
  736. var
  737. n : integer;
  738. looplist,
  739. templist: TFPObjectList;
  740. def : tdef;
  741. begin
  742. templist := TFPObjectList.Create(False);
  743. looplist := deftowritelist;
  744. while looplist.count > 0 do
  745. begin
  746. deftowritelist := templist;
  747. for n := 0 to looplist.count - 1 do
  748. begin
  749. def := tdef(looplist[n]);
  750. case def.dbg_state of
  751. dbg_state_written:
  752. continue;
  753. dbg_state_writing:
  754. internalerror(200610052);
  755. dbg_state_unused:
  756. internalerror(200610053);
  757. dbg_state_used:
  758. appenddef(current_asmdata.asmlists[al_dwarf_info],def)
  759. else
  760. internalerror(200610054);
  761. end;
  762. end;
  763. looplist.clear;
  764. templist := looplist;
  765. looplist := deftowritelist;
  766. end;
  767. templist.free;
  768. end;
  769. var
  770. storefilepos : tfileposinfo;
  771. lenstartlabel : tasmlabel;
  772. i : longint;
  773. def: tdef;
  774. begin
  775. storefilepos:=current_filepos;
  776. current_filepos:=current_module.mainfilepos;
  777. defnumberlist:=TFPObjectList.create(false);
  778. deftowritelist:=TFPObjectList.create(false);
  779. { not exported (FK)
  780. FILEREC
  781. TEXTREC
  782. }
  783. vardatadef:=trecorddef(search_system_type('TVARDATA').typedef);
  784. { write all global/local variables. This will flag all required tdefs }
  785. if assigned(current_module.globalsymtable) then
  786. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  787. if assigned(current_module.localsymtable) then
  788. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  789. { write all procedures and methods. This will flag all required tdefs }
  790. if assigned(current_module.globalsymtable) then
  791. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  792. if assigned(current_module.localsymtable) then
  793. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  794. { reset unit type info flag }
  795. reset_unit_type_info;
  796. { write used types from the used units }
  797. write_used_unit_type_info(current_asmdata.asmlists[al_dwarf_info],current_module);
  798. { last write the types from this unit }
  799. if assigned(current_module.globalsymtable) then
  800. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  801. if assigned(current_module.localsymtable) then
  802. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  803. { write defs not written yet }
  804. write_defs_to_write;
  805. { reset all def labels }
  806. for i:=0 to defnumberlist.count-1 do
  807. begin
  808. def := tdef(defnumberlist[i]);
  809. if assigned(def) then
  810. begin
  811. def.dwarf_lab:=nil;
  812. def.dbg_state:=dbg_state_unused;
  813. end;
  814. end;
  815. defnumberlist.free;
  816. defnumberlist:=nil;
  817. deftowritelist.free;
  818. deftowritelist:=nil;
  819. current_filepos:=storefilepos;
  820. end;
  821. procedure TLLVMDefInfo.referencesections(list:TAsmList);
  822. begin
  823. end;
  824. function TLLVMDefInfo.symname(sym: tsym): String;
  825. begin
  826. if (sym.typ=paravarsym) and
  827. (vo_is_self in tparavarsym(sym).varoptions) then
  828. result:='this'
  829. else
  830. result := sym.Name;
  831. end;
  832. procedure TLLVMDefInfo.appenddef_formal(list:TAsmList;def: tformaldef);
  833. begin
  834. { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
  835. replace it with a unsigned type with size 0 (FK)
  836. }
  837. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'undef*'));
  838. end;
  839. procedure TLLVMDefInfo.appenddef_object(list:TAsmList;def: tobjectdef);
  840. procedure doappend;
  841. begin
  842. appenddef_abstractrecord(list,def);
  843. end;
  844. begin
  845. case def.objecttype of
  846. odt_cppclass,
  847. odt_object:
  848. doappend;
  849. odt_interfacecom,
  850. odt_interfacecorba,
  851. odt_dispinterface,
  852. odt_class:
  853. begin
  854. { implicit pointer }
  855. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),def_llvm_class_struct_name(def).name+'*'));
  856. doappend;
  857. end;
  858. else
  859. internalerror(200602041);
  860. end;
  861. end;
  862. procedure TLLVMDefInfo.appenddef_set(list:TAsmList;def: tsetdef);
  863. begin
  864. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'[ '+tostr(def.size)+ 'x i8 ]'));
  865. end;
  866. procedure TLLVMDefInfo.appenddef_undefined(list:TAsmList;def: tundefineddef);
  867. begin
  868. { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
  869. replace it with a unsigned type with size 0 (FK)
  870. }
  871. list.concat(tai_llvmcpu.op_ressym_string(LA_TYPE,def_llvm_name(def),'undef'));
  872. end;
  873. procedure TLLVMDefInfo.appenddef_variant(list:TAsmList;def: tvariantdef);
  874. begin
  875. { variants aren't known to dwarf2 but writting tvardata should be enough }
  876. appenddef_record(list,trecorddef(vardatadef));
  877. end;
  878. end.