llvmdef.pas 36 KB

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