dbgllvm.pas 97 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474
  1. {
  2. Copyright (c) 2021-2022 by Jonas Maebe,
  3. member of the Free Pascal Compiler development team
  4. This units contains support for LLVM debug info generation
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {
  19. This units contains support for LLVM debug info generation.
  20. LLVM debug information is stored as metadata in the LLVM bitcode, and is
  21. loosely based on DWARF (it also reuses some DWARF constants)
  22. }
  23. unit dbgllvm;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. cclasses,globtype,
  28. cgbase,
  29. aasmbase,aasmtai,aasmdata,aasmcnst,aasmllvm,aasmllvmmetadata,
  30. symbase,symconst,symtype,symdef,symsym,
  31. finput,
  32. DbgBase, dbgdwarfconst;
  33. type
  34. TLLVMMetaDefHashSetItem = record
  35. { HashSetItem.Data: LLVM metadata which other types reference when
  36. referring to this type (usually a typedef) }
  37. HashSetItem: THashSetItem;
  38. { in case of a class, the field layout (since a class itself is just a
  39. pointer }
  40. struct_metadef: tai_llvmspecialisedmetadatanode;
  41. { the metadata actually containing the type definition (usually
  42. referenced by HashSetItem.Data), filled in by appenddef_* }
  43. implmetadef: tai_llvmspecialisedmetadatanode;
  44. end;
  45. PLLVMMetaDefHashSetItem = ^TLLVMMetaDefHashSetItem;
  46. TLLVMMetaDefHashSet = class(THashSet)
  47. class function SizeOfItem: Integer; override;
  48. end;
  49. TDebugInfoLLVM = class(TDebugInfo)
  50. strict private
  51. type
  52. tmembercallbackinfo = record
  53. structnode: tai_llvmspecialisedmetadatanode;
  54. list: tasmlist;
  55. end;
  56. pmembercallbackinfo = ^tmembercallbackinfo;
  57. var
  58. { lookup table for def -> LLVMMeta info }
  59. fdefmeta: TLLVMMetaDefHashSet;
  60. { lookup table for file -> LLVMMeta info (DIFile) }
  61. ffilemeta: THashSet;
  62. { lookup table for line,column,scope -> LLVMMeta info (DILocation) }
  63. flocationmeta: THashSet;
  64. { lookup table for scope,file -> LLVMMeta info (DILexicalBlockFile, for include files) }
  65. flexicalblockfilemeta: THashSet;
  66. { lookup table for tsym -> taillvmdecl }
  67. fsymdecl: THashSet;
  68. fcunode: tai_llvmspecialisedmetadatanode;
  69. fenums: tai_llvmunnamedmetadatanode;
  70. fretainedtypes: tai_llvmunnamedmetadatanode;
  71. function absolute_llvm_path(const s:tcmdstr):tcmdstr;
  72. protected
  73. vardatadef: trecorddef;
  74. procedure try_add_file_metaref(dinode: tai_llvmspecialisedmetadatanode; const fileinfo: tfileposinfo; includescope: boolean);
  75. function add_line_metanode(const fileinfo: tfileposinfo): tai_llvmspecialisedmetadatanode;
  76. function def_meta_impl(def: tdef) : tai_llvmspecialisedmetadatanode;
  77. function def_set_meta_impl(def: tdef; meta_impl: tai_llvmspecialisedmetadatanode): tai_llvmspecialisedmetadatanode;
  78. function def_meta_class_struct(def: tobjectdef) : tai_llvmbasemetadatanode;
  79. function def_meta_node(def: tdef): tai_llvmspecialisedmetadatanode;
  80. function def_meta_ref(def: tdef): tai_simpletypedconst;
  81. function file_getmetanode(moduleindex: tfileposmoduleindex; fileindex: tfileposfileindex): tai_llvmspecialisedmetadatanode;
  82. function filepos_getmetanode(const filepos: tfileposinfo; const functionfileinfo: tfileposinfo; const functionscope: tai_llvmspecialisedmetadatanode; nolineinfo: boolean): tai_llvmspecialisedmetadatanode;
  83. function get_def_metatai(def:tdef): PLLVMMetaDefHashSetItem;
  84. procedure sym_set_decl(sym: tsym; decl: tai);
  85. function sym_get_decl(sym: tsym): taillvmdecl;
  86. procedure appenddef_array_internal(list: TAsmList; fordef: tdef; eledef: tdef; lowrange, highrange: asizeint);
  87. function getabstractprocdeftypes(list: TAsmList; def:tabstractprocdef): tai_llvmbasemetadatanode;
  88. procedure afterappenddef(list: TAsmList; def: tdef); override;
  89. procedure appenddef_ord(list:TAsmList;def:torddef);override;
  90. procedure appenddef_float(list:TAsmList;def:tfloatdef);override;
  91. procedure appenddef_enum(list:TAsmList;def:tenumdef);override;
  92. procedure appenddef_array(list:TAsmList;def:tarraydef);override;
  93. procedure appenddef_record_named(list: TAsmList; fordef: tdef; def: trecorddef; const name: TSymStr);
  94. procedure appenddef_record(list:TAsmList;def:trecorddef);override;
  95. procedure appenddef_pointer(list:TAsmList;def:tpointerdef);override;
  96. procedure appenddef_formal(list:TAsmList;def:tformaldef); override;
  97. procedure appenddef_string(list:TAsmList;def:tstringdef);override;
  98. procedure appenddef_procvar(list:TAsmList;def:tprocvardef);override;
  99. procedure appenddef_file(list:TAsmList;def:tfiledef); override;
  100. procedure appenddef_object(list:TAsmList;def:tobjectdef); override;
  101. procedure appenddef_set(list:TAsmList;def:tsetdef); override;
  102. procedure appenddef_undefined(list:TAsmList;def:tundefineddef); override;
  103. procedure appenddef_classref(list: TAsmList; def: tclassrefdef); override;
  104. procedure appenddef_variant(list:TAsmList;def:tvariantdef); override;
  105. procedure appendprocdef(list:TAsmList;def:tprocdef);override;
  106. function get_symlist_sym_offset(symlist: ppropaccesslistitem; out sym: tabstractvarsym; out offset: pint): boolean;
  107. procedure appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  108. procedure appendsym_var_with_name_type_offset(list:TAsmList; sym:tabstractnormalvarsym; const name: TSymStr; def: tdef; offset: pint(*; const flags: tdwarfvarsymflags*));
  109. { used for fields and properties mapped to fields }
  110. procedure appendsym_fieldvar_with_name_offset(list:TAsmList;sym: tfieldvarsym;const name: string; def: tdef; offset: pint);
  111. procedure appendsym_const_member(list:TAsmList;sym:tconstsym;ismember:boolean);
  112. procedure beforeappendsym(list:TAsmList;sym:tsym);override;
  113. procedure appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);override;
  114. procedure appendsym_paravar(list:TAsmList;sym:tparavarsym);override;
  115. procedure appendsym_localvar(list:TAsmList;sym:tlocalvarsym);override;
  116. procedure appendsym_fieldvar(list:TAsmList;sym:tfieldvarsym);override;
  117. procedure appendsym_const(list:TAsmList;sym:tconstsym);override;
  118. procedure appendsym_type(list:TAsmList;sym:ttypesym);override;
  119. procedure appendsym_label(list:TAsmList;sym:tlabelsym);override;
  120. procedure appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);override;
  121. procedure appendsym_property(list:TAsmList;sym:tpropertysym);override;
  122. function symdebugname(sym:tsym): TSymStr;
  123. function symname(sym: tsym; manglename: boolean): TSymStr; virtual;
  124. function visibilitydiflag(vis: tvisibility): TSymStr;
  125. procedure enum_membersyms_callback(p:TObject;arg:pointer);
  126. procedure ensuremetainit;
  127. procedure resetfornewmodule;
  128. procedure collectglobalsyms;
  129. public
  130. constructor Create;override;
  131. destructor Destroy;override;
  132. procedure insertmoduleinfo;override;
  133. procedure inserttypeinfo;override;
  134. procedure insertlineinfo(list:TAsmList);override;
  135. function dwarf_version: Word; virtual; abstract;
  136. end;
  137. implementation
  138. uses
  139. sysutils,cutils,cfileutl,constexp,
  140. version,globals,verbose,systems,
  141. cpubase,cpuinfo,paramgr,
  142. fmodule,
  143. defutil,symtable,symcpu,ppu,
  144. llvminfo,llvmbase
  145. ;
  146. {$push}
  147. {$scopedenums on}
  148. type
  149. TLLVMDIFlags = (
  150. DIFlagNone = 0,
  151. DIFlagPrivate = 1,
  152. DIFlagProtected = 2,
  153. DIFlagPublic = 3,
  154. DIFlagFwdDecl = 1 shl 2,
  155. DIFlagAppleBlock = 1 shl 3,
  156. DIFlagReservedBit4 = 1 shl 4,
  157. { virtual inheritance at the C++ struct level, not at method level; use the SPFlag for that virtual methods) }
  158. DIFlagVirtual = 1 shl 5,
  159. DIFlagArtificial = 1 shl 6,
  160. DIFlagExplicit = 1 shl 7,
  161. DIFlagPrototyped = 1 shl 8,
  162. DIFlagObjcClassComplete = 1 shl 9,
  163. DIFlagObjectPointer = 1 shl 10,
  164. DIFlagVector = 1 shl 11,
  165. DIFlagStaticMember = 1 shl 12,
  166. DIFlagLValueReference = 1 shl 13,
  167. DIFlagRValueReference = 1 shl 14,
  168. DIFlagReserved = 1 shl 15,
  169. DIFlagSingleInheritance = 1 shl 16,
  170. DIFlagMultipleInheritance = 1 shl 17,
  171. DIFlagVirtualInheritance = 1 shl 18,
  172. DIFlagIntroducedVirtual = 1 shl 19,
  173. DIFlagBitField = 1 shl 20,
  174. DIFlagNoReturn = 1 shl 21,
  175. { at the type level, DWARF 5 DW_CC_pass_by_value }
  176. DIFlagTypePassByValue = 1 shl 22,
  177. { at the type level, DWARF 5 DW_CC_pass_by_reference }
  178. DIFlagTypePassByReference = 1 shl 23,
  179. DIFlagEnumClass = 1 shl 24,
  180. DIFlagThunk = 1 shl 25,
  181. { moved to DISPFlags in LLVM 8.0 }
  182. DIFlagMainSubprogram_Deprecated = 1 shl 21
  183. { introduced/renamed after LLVM 7.0, but nothing we need right now
  184. ,
  185. DIFlagNonTrivial,
  186. DIFlagBigEndian,
  187. DIFlagLittleEndian
  188. }
  189. );
  190. TLLVMDISPFlags = (
  191. DISPFlagVirtual = 1,
  192. DISPFlagPureVirtual = 2,
  193. DISPFlagLocalToUnit = 1 shl 2,
  194. DISPFlagDefinition = 1 shl 3,
  195. DISPFlagOptimized = 1 shl 4,
  196. DISPFlagPure = 1 shl 5,
  197. DISPFlagElemental = 1 shl 6,
  198. DISPFlagRecursive = 1 shl 7,
  199. DISPFlagMainSubprogram = 1 shl 8,
  200. DISPFlagDeleted = 1 shl 9,
  201. DISPFlagObjCDirect = 1 shl 11
  202. );
  203. {$pop}
  204. TLLVMLocationAtom = (
  205. DW_OP_LLVM_fragment = $1000, ///< Only used in LLVM metadata.
  206. DW_OP_LLVM_convert = $1001, ///< Only used in LLVM metadata.
  207. DW_OP_LLVM_tag_offset = $1002, ///< Only used in LLVM metadata.
  208. DW_OP_LLVM_entry_value = $1003, ///< Only used in LLVM metadata.
  209. DW_OP_LLVM_implicit_pointer = $1004, ///< Only used in LLVM metadata.
  210. DW_OP_LLVM_arg = $1005 ///< Only used in LLVM metadata.
  211. );
  212. {****************************************************************************
  213. TLLVMMetaDefHashSet
  214. ****************************************************************************}
  215. class function TLLVMMetaDefHashSet.SizeOfItem: Integer;
  216. begin
  217. Result:=sizeof(TLLVMMetaDefHashSetItem);
  218. end;
  219. {****************************************************************************
  220. TDebugInfoLLVM
  221. ****************************************************************************}
  222. function TDebugInfoLLVM.absolute_llvm_path(const s:tcmdstr):tcmdstr;
  223. begin
  224. { Remove trailing / and ./ prefixes and always use a / }
  225. result:=BsToSlash(ExcludeTrailingPathDelimiter(FixFileName(ExpandFileName(s))));
  226. end;
  227. function TDebugInfoLLVM.get_def_metatai(def:tdef): PLLVMMetaDefHashSetItem;
  228. var
  229. needstructdeflab: boolean;
  230. begin
  231. if def.dbg_state=dbg_state_unused then
  232. def.dbg_state:=dbg_state_used;
  233. { Need a new meta item? }
  234. result:=PLLVMMetaDefHashSetItem(fdefmeta.FindOrAdd(@def,sizeof(def)));
  235. { the other fields besides Data are not initialised }
  236. if not assigned(result^.HashSetItem.Data) then
  237. begin
  238. { will be turned into a pointerdef (in case of Objective-C types) or
  239. typedef later on. We only really need a typedef if this def has
  240. a typesym (to add the name), but it allows us to create a generic
  241. specialised metatype node that can represent any type. Otherwise
  242. we have to duplicate the logic here to determine whether it's a
  243. basic, derived or composite type.
  244. exception: procdefs because we cannot make typedefs for those}
  245. if def.typ<>procdef then
  246. begin
  247. result^.HashSetItem.Data:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType);
  248. if is_implicit_pointer_object_type(def) then
  249. result^.struct_metadef:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType)
  250. else
  251. result^.struct_metadef:=nil;
  252. result^.implmetadef:=nil;
  253. end
  254. else
  255. begin
  256. result^.HashSetItem.Data:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubprogram);
  257. result^.struct_metadef:=nil;
  258. result^.implmetadef:=nil;
  259. end;
  260. if def.dbg_state=dbg_state_used then
  261. deftowritelist.Add(def);
  262. defnumberlist.Add(def);
  263. end;
  264. end;
  265. procedure TDebugInfoLLVM.sym_set_decl(sym: tsym; decl: tai);
  266. var
  267. entry: PHashSetItem;
  268. begin
  269. entry:=fsymdecl.FindOrAdd(@sym,sizeof(sym));
  270. if assigned(entry^.Data) then
  271. internalerror(2022051701);
  272. entry^.Data:=decl;
  273. end;
  274. function TDebugInfoLLVM.sym_get_decl(sym: tsym): taillvmdecl;
  275. var
  276. entry: PHashSetItem;
  277. begin
  278. result:=nil;
  279. entry:=fsymdecl.Find(@sym,sizeof(sym));
  280. if assigned(entry) then
  281. result:=taillvmdecl(entry^.Data);
  282. end;
  283. procedure TDebugInfoLLVM.appenddef_array_internal(list: TAsmList; fordef: tdef; eledef: tdef; lowrange, highrange: asizeint);
  284. var
  285. dinode,
  286. subrangenode,
  287. exprnode: tai_llvmspecialisedmetadatanode;
  288. arrayrangenode: tai_llvmunnamedmetadatanode;
  289. begin
  290. { range of the array }
  291. subrangenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubrange);
  292. { include length }
  293. subrangenode.addqword('lowerBound',lowRange);
  294. if highrange>=0 then
  295. subrangenode.addqword('count',qword(highRange)+1)
  296. else
  297. subrangenode.addint64('count',highRange+1);
  298. list.concat(subrangenode);
  299. { collection containing the one range }
  300. arrayrangenode:=tai_llvmunnamedmetadatanode.create;
  301. arrayrangenode.addvalue(llvm_getmetadatareftypedconst(subrangenode));
  302. list.concat(arrayrangenode);
  303. { the array definition }
  304. dinode:=def_set_meta_impl(fordef,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  305. dinode.addqword('tag',ord(DW_TAG_array_type));
  306. dinode.addmetadatarefto('baseType',def_meta_node(eledef));
  307. dinode.addqword('size',eledef.size*(highrange-lowrange+1)*8);
  308. dinode.addmetadatarefto('elements',arrayrangenode);
  309. list.concat(dinode);
  310. end;
  311. function TDebugInfoLLVM.getabstractprocdeftypes(list: TAsmList; def: tabstractprocdef): tai_llvmbasemetadatanode;
  312. var
  313. types: tai_llvmunnamedmetadatanode;
  314. i: longint;
  315. begin
  316. types:=tai_llvmunnamedmetadatanode.create;
  317. list.concat(types);
  318. { we still need a DISubProgramType in this case, but not the list of types }
  319. if not(cs_debuginfo in current_settings.moduleswitches) then
  320. exit;
  321. if is_void(def.returndef) then
  322. types.addvalue(tai_simpletypedconst.create(llvm_metadatatype,nil))
  323. else
  324. types.addvalue(def_meta_ref(def.returndef));
  325. for i:=0 to def.paras.count-1 do
  326. begin
  327. types.addvalue(def_meta_ref(tparavarsym(def.paras[i]).vardef));
  328. end;
  329. result:=types;
  330. end;
  331. function TDebugInfoLLVM.def_meta_impl(def: tdef): tai_llvmspecialisedmetadatanode;
  332. begin
  333. result:=tai_llvmspecialisedmetadatanode(get_def_metatai(def)^.implmetadef);
  334. end;
  335. function TDebugInfoLLVM.def_set_meta_impl(def: tdef; meta_impl: tai_llvmspecialisedmetadatanode): tai_llvmspecialisedmetadatanode;
  336. begin
  337. tai_llvmspecialisedmetadatanode(get_def_metatai(def)^.implmetadef):=meta_impl;
  338. result:=meta_impl;
  339. end;
  340. function TDebugInfoLLVM.def_meta_class_struct(def: tobjectdef): tai_llvmbasemetadatanode;
  341. begin
  342. result:=tai_llvmbasemetadatanode(get_def_metatai(def)^.struct_metadef);
  343. end;
  344. function TDebugInfoLLVM.def_meta_node(def: tdef): tai_llvmspecialisedmetadatanode;
  345. begin
  346. if not is_void(def) then
  347. result:=tai_llvmspecialisedmetadatanode(get_def_metatai(def)^.HashSetItem.Data)
  348. else
  349. result:=nil;
  350. end;
  351. function TDebugInfoLLVM.def_meta_ref(def: tdef): tai_simpletypedconst;
  352. begin
  353. result:=llvm_getmetadatareftypedconst(def_meta_node(def));
  354. end;
  355. constructor TDebugInfoLLVM.Create;
  356. begin
  357. inherited Create;
  358. fenums:=nil;
  359. fretainedtypes:=nil;
  360. fcunode:=nil;
  361. ffilemeta:=thashset.Create(10000,true,false);
  362. flocationmeta:=thashset.Create(10000,true,false);
  363. flexicalblockfilemeta:=thashset.Create(100,true,false);
  364. fdefmeta:=TLLVMMetaDefHashSet.Create(10000,true,false);
  365. fsymdecl:=thashset.create(10000,true,false);
  366. defnumberlist:=TFPObjectList.create(false);
  367. deftowritelist:=TFPObjectList.create(false);
  368. vardatadef:=nil;
  369. end;
  370. destructor TDebugInfoLLVM.Destroy;
  371. begin
  372. // don't free fenums/fretainedtypes, they get emitted in the assembler list
  373. ffilemeta.free;
  374. ffilemeta:=nil;
  375. flocationmeta.free;
  376. flocationmeta:=nil;
  377. flexicalblockfilemeta.free;
  378. flexicalblockfilemeta:=nil;
  379. fdefmeta.free;
  380. fdefmeta:=nil;
  381. fsymdecl.free;
  382. fsymdecl:=nil;
  383. defnumberlist.free;
  384. defnumberlist:=nil;
  385. deftowritelist.free;
  386. deftowritelist:=nil;
  387. fcunode.free;
  388. fcunode:=nil;
  389. inherited Destroy;
  390. end;
  391. procedure TDebugInfoLLVM.enum_membersyms_callback(p:TObject; arg: pointer);
  392. begin
  393. (*
  394. case tsym(p).typ of
  395. fieldvarsym:
  396. appendsym_fieldvar(pmembercallbackinfo(arg)^.list,pmembercallbackinfo(arg)^.structnode,tfieldvarsym(p));
  397. propertysym:
  398. appendsym_property(pmembercallbackinfo(arg)^.list,pmembercallbackinfo(arg)^.structnode,tpropertysym(p));
  399. constsym:
  400. appendsym_const_member(pmembercallbackinfo(arg)^.list,pmembercallbackinfo(arg)^.structnode,tconstsym(p),true);
  401. else
  402. ;
  403. end;
  404. *)
  405. end;
  406. procedure TDebugInfoLLVM.ensuremetainit;
  407. begin
  408. if not assigned(fenums) then
  409. begin
  410. fenums:=tai_llvmunnamedmetadatanode.create;
  411. fretainedtypes:=tai_llvmunnamedmetadatanode.create;
  412. fcunode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompileUnit);
  413. end;
  414. end;
  415. procedure TDebugInfoLLVM.resetfornewmodule;
  416. var
  417. i: longint;
  418. begin
  419. { for LLVM, we need to generate the procdef type info (or at least
  420. temporary references to it) already during the generation of the line
  421. info (all line info metadata needs a reference to its parent scope,
  422. the procdef). Since the line info is generated per procedure and
  423. the type info only at the end, we can't allocate the type info
  424. structures at the start of the type info generation like for other
  425. debug info producers. Instead, we have to initialise everything in the
  426. constructor, and then reset it at the end of the debug info pass
  427. (inserting the module info) }
  428. ffilemeta.Clear;
  429. flocationmeta.Clear;
  430. flexicalblockfilemeta.Clear;
  431. fdefmeta.free;
  432. fsymdecl.Clear;
  433. { one item per def, plus some extra space in case of nested types,
  434. externally used types etc (it will grow further if necessary) }
  435. i:=current_module.localsymtable.DefList.count*4;
  436. if assigned(current_module.globalsymtable) then
  437. inc(i,current_module.globalsymtable.DefList.count*2);
  438. fdefmeta:=TLLVMMetaDefHashSet.Create(i,true,false);
  439. defnumberlist.Clear;
  440. deftowritelist.Clear;
  441. fcunode:=nil;
  442. fenums:=nil;
  443. fretainedtypes:=nil;
  444. end;
  445. procedure TDebugInfoLLVM.collectglobalsyms;
  446. var
  447. i: TAsmListType;
  448. hp: tai;
  449. begin
  450. for i in globaldataasmlisttypes do
  451. begin
  452. if not assigned(current_asmdata.AsmLists[i]) then
  453. continue;
  454. hp:=tai(current_asmdata.AsmLists[i].First);
  455. while assigned(hp) do
  456. begin
  457. if (hp.typ=ait_llvmdecl) and
  458. assigned(taillvmdecl(hp).sym) then
  459. sym_set_decl(taillvmdecl(hp).sym,hp);
  460. hp:=tai(hp.next);
  461. end;
  462. end;
  463. end;
  464. function TDebugInfoLLVM.file_getmetanode(moduleindex: tfileposmoduleindex; fileindex: tfileposfileindex): tai_llvmspecialisedmetadatanode;
  465. var
  466. infile: tinputfile;
  467. dirname: TSymStr;
  468. item: PHashSetItem;
  469. metaitem: tai_llvmspecialisedmetadatanode;
  470. modfileindex: packed record
  471. moduleindex: tfileposmoduleindex;
  472. fileindex: tfileposfileindex;
  473. end;
  474. begin
  475. modfileindex.moduleindex:=moduleindex;
  476. modfileindex.fileindex:=fileindex;
  477. item:=ffilemeta.FindOrAdd(@modfileindex,sizeof(modfileindex));
  478. if not assigned(item^.Data) then
  479. begin
  480. infile:=get_module(moduleindex).sourcefiles.get_file(fileindex);
  481. if not assigned(infile) then
  482. begin
  483. result:=nil;
  484. exit;
  485. end;
  486. if infile.path = '' then
  487. dirname:=absolute_llvm_path('.')
  488. else
  489. begin
  490. { add the canonical form here already to avoid problems with }
  491. { paths such as './' etc }
  492. dirname:=absolute_llvm_path(infile.path);
  493. end;
  494. if dirname='' then
  495. dirname:='.';
  496. metaitem:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIFile);
  497. metaitem.addstring('filename',infile.name);
  498. metaitem.addstring('directory',dirname);
  499. current_asmdata.AsmLists[al_dwarf_line].concat(metaitem);
  500. item^.Data:=metaitem;
  501. end;
  502. result:=tai_llvmspecialisedmetadatanode(item^.Data);
  503. end;
  504. function TDebugInfoLLVM.filepos_getmetanode(const filepos: tfileposinfo; const functionfileinfo: tfileposinfo; const functionscope: tai_llvmspecialisedmetadatanode; nolineinfo: boolean): tai_llvmspecialisedmetadatanode;
  505. var
  506. item: PHashSetItem;
  507. filemeta,
  508. locationscopemeta: tai_llvmspecialisedmetadatanode;
  509. lexicalblockkey: packed record
  510. scopemeta,
  511. filemeta: tai_llvmspecialisedmetadatanode;
  512. end;
  513. locationkey: packed record
  514. scope: tai_llvmspecialisedmetadatanode;
  515. line: tfileposline;
  516. column: tfileposcolumn;
  517. end;
  518. begin
  519. result:=nil;
  520. if (filepos.fileindex<>0) then
  521. filemeta:=file_getmetanode(filepos.moduleindex,filepos.fileindex)
  522. else
  523. filemeta:=file_getmetanode(functionfileinfo.moduleindex,functionfileinfo.fileindex);
  524. if not assigned(filemeta) then
  525. exit;
  526. if (filepos.fileindex<>0) and
  527. (filepos.fileindex<>functionfileinfo.fileindex) then
  528. begin
  529. lexicalblockkey.scopemeta:=functionscope;
  530. lexicalblockkey.filemeta:=filemeta;
  531. item:=flexicalblockfilemeta.FindOrAdd(@lexicalblockkey,sizeof(lexicalblockkey));
  532. if not assigned(item^.Data) then
  533. begin
  534. locationscopemeta:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILexicalBlockFile);
  535. locationscopemeta.addmetadatarefto('scope',functionscope);
  536. locationscopemeta.addmetadatarefto('file',filemeta);
  537. locationscopemeta.addint64('discriminator',0);
  538. current_asmdata.AsmLists[al_dwarf_line].concat(locationscopemeta);
  539. item^.Data:=locationscopemeta;
  540. end
  541. else
  542. locationscopemeta:=tai_llvmspecialisedmetadatanode(item^.Data);
  543. end
  544. else
  545. locationscopemeta:=functionscope;
  546. locationkey.scope:=locationscopemeta;
  547. if not nolineinfo then
  548. begin
  549. locationkey.line:=filepos.line;
  550. locationkey.column:=filepos.column;
  551. end
  552. else
  553. begin
  554. locationkey.line:=0;
  555. locationkey.column:=0;
  556. end;
  557. item:=flocationmeta.FindOrAdd(@locationkey,sizeof(locationkey));
  558. if not assigned(item^.Data) then
  559. begin
  560. result:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILocation);
  561. if not nolineinfo then
  562. begin
  563. result.addqword('line',filepos.line);
  564. result.addqword('column',filepos.column);
  565. end
  566. else
  567. result.addqword('line',0);
  568. result.addmetadatarefto('scope',locationscopemeta);
  569. current_asmdata.AsmLists[al_dwarf_line].concat(result);
  570. item^.Data:=result;
  571. end
  572. else
  573. result:=tai_llvmspecialisedmetadatanode(item^.Data);
  574. end;
  575. procedure TDebugInfoLLVM.try_add_file_metaref(dinode: tai_llvmspecialisedmetadatanode; const fileinfo: tfileposinfo; includescope: boolean);
  576. var
  577. filemeta: tai_llvmbasemetadatanode;
  578. begin
  579. filemeta:=file_getmetanode(fileinfo.moduleindex,fileinfo.fileindex);
  580. if assigned(filemeta) then
  581. begin
  582. if includescope then
  583. begin
  584. dinode.addmetadatarefto('scope',filemeta);
  585. end;
  586. dinode.addmetadatarefto('file',filemeta);
  587. dinode.addqword('line',fileinfo.line);
  588. end;
  589. end;
  590. function TDebugInfoLLVM.add_line_metanode(const fileinfo: tfileposinfo): tai_llvmspecialisedmetadatanode;
  591. var
  592. filemeta: tai_llvmbasemetadatanode;
  593. begin
  594. filemeta:=file_getmetanode(fileinfo.moduleindex,fileinfo.fileindex);
  595. if not assigned(filemeta) then
  596. internalerror(2022041701);
  597. result:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DILocation);
  598. result.addqword('line',fileinfo.line);
  599. result.addqword('column',fileinfo.column);
  600. result.addmetadatarefto('scope',filemeta);
  601. current_asmdata.AsmLists[al_dwarf_line].concat(result);
  602. end;
  603. procedure TDebugInfoLLVM.appenddef_ord(list:TAsmList;def:torddef);
  604. var
  605. ordtype: tordtype;
  606. dinode: tai_llvmspecialisedmetadatanode;
  607. begin
  608. { nothing, must be referenced as "null" in the using declaration }
  609. if is_void(def) then
  610. exit;
  611. ordtype:=def.ordtype;
  612. if ordtype=customint then
  613. ordtype:=range_to_basetype(def.low,def.high);
  614. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIBasicType));
  615. case ordtype of
  616. s8bit,
  617. s16bit,
  618. s32bit,
  619. u8bit,
  620. u16bit,
  621. u32bit,
  622. u64bit,
  623. s64bit,
  624. u128bit,
  625. s128bit:
  626. begin
  627. dinode.addqword('size',def.size*8);
  628. if def.alignment<>def.size then
  629. dinode.addqword('align',def.alignment*8);
  630. { generate proper signed/unsigned info for types like 0..3 }
  631. { these are s8bit, but should be identified as unsigned }
  632. { because otherwise they are interpreted wrongly when used }
  633. { in a bitpacked record }
  634. if def.low<0 then
  635. dinode.addqword('encoding',ord(DW_ATE_signed))
  636. else
  637. dinode.addqword('encoding',ord(DW_ATE_unsigned));
  638. end;
  639. uvoid :
  640. begin
  641. { checked above }
  642. end;
  643. uchar,
  644. uwidechar :
  645. begin
  646. dinode.addqword('size',def.size*8);
  647. dinode.addint64('encoding',ord(DW_ATE_unsigned_char));
  648. end;
  649. pasbool1,
  650. pasbool8,
  651. bool8bit,
  652. pasbool16,
  653. bool16bit,
  654. pasbool32,
  655. bool32bit,
  656. pasbool64,
  657. bool64bit:
  658. begin
  659. dinode.addqword('size',def.size*8);
  660. dinode.addint64('encoding',ord(DW_ATE_boolean));
  661. end;
  662. scurrency:
  663. begin
  664. { we should use DW_ATE_signed_fixed, however it isn't supported yet by LLVM }
  665. dinode.addqword('size',def.size*8);
  666. dinode.addint64('encoding',ord(DW_ATE_signed));
  667. end;
  668. customint:
  669. internalerror(2021111502);
  670. end;
  671. list.concat(dinode);
  672. end;
  673. procedure TDebugInfoLLVM.appenddef_float(list:TAsmList;def:tfloatdef);
  674. var
  675. dinode: tai_llvmspecialisedmetadatanode;
  676. begin
  677. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIBasicType));
  678. case def.floattype of
  679. s32real,
  680. s64real,
  681. s80real,
  682. sc80real,
  683. s128real:
  684. begin
  685. dinode.addqword('size',def.size*8);
  686. if def.alignment<>def.size then
  687. dinode.addqword('align',def.alignment*8);
  688. dinode.addint64('encoding',ord(DW_ATE_float));
  689. end;
  690. s64currency:
  691. begin
  692. { we should use DW_ATE_signed_fixed, however it isn't supported yet by LLVM }
  693. dinode.addqword('size',def.size*8);
  694. dinode.addint64('encoding',ord(DW_ATE_signed));
  695. end;
  696. s64comp:
  697. begin
  698. { we should use DW_ATE_signed_fixed, however it isn't supported yet by LLVM }
  699. dinode.addqword('size',def.size*8);
  700. dinode.addint64('encoding',ord(DW_ATE_signed));
  701. end;
  702. end;
  703. list.concat(dinode);
  704. end;
  705. procedure TDebugInfoLLVM.appenddef_enum(list:TAsmList;def:tenumdef);
  706. var
  707. hp : tenumsym;
  708. i : longint;
  709. dinode: tai_llvmspecialisedmetadatanode;
  710. enumelem: tai_llvmspecialisedmetadatanode;
  711. enumlist: tai_llvmunnamedmetadatanode;
  712. begin
  713. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  714. dinode.addqword('tag',ord(DW_TAG_enumeration_type));
  715. dinode.addqword('size',def.size*8);
  716. dinode.addstring('identifier',def.mangledparaname);
  717. { register in module's list of enums (to ensure the debug info gets
  718. emitted even if the enum is not used in the current module) }
  719. fenums.addvalue(llvm_getmetadatareftypedconst(dinode));
  720. enumlist:=tai_llvmunnamedmetadatanode.create;
  721. { add enum symbols }
  722. for i:=0 to def.symtable.SymList.Count-1 do
  723. begin
  724. hp:=tenumsym(def.symtable.SymList[i]);
  725. if hp.value<def.minval then
  726. continue
  727. else if hp.value>def.maxval then
  728. break;
  729. enumelem:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIEnumerator);
  730. enumelem.addstring('name',symname(hp, false));
  731. enumelem.addint64('value',hp.value);
  732. list.concat(enumelem);
  733. enumlist.addvalue(llvm_getmetadatareftypedconst(enumelem));
  734. end;
  735. if enumlist.valuecount<>0 then
  736. begin
  737. list.concat(enumlist);
  738. dinode.addmetadatarefto('elements',enumlist);
  739. end
  740. else
  741. begin
  742. enumlist.free;
  743. end;
  744. list.concat(dinode);
  745. end;
  746. procedure TDebugInfoLLVM.appenddef_array(list:TAsmList;def:tarraydef);
  747. var
  748. dinode,
  749. subrangenode,
  750. exprnode: tai_llvmspecialisedmetadatanode;
  751. arrayrangenode: tai_llvmunnamedmetadatanode;
  752. size : qword;
  753. nesteddef: tdef;
  754. power: longint;
  755. flags: TLLVMDIFlags;
  756. begin
  757. if is_dynamic_array(def) { and
  758. not(llvmflag_array_datalocation in llvmversion_properties[current_settings.llvmversion]) } then
  759. begin
  760. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  761. dinode.addqword('tag',ord(DW_TAG_pointer_type));
  762. dinode.addmetadatarefto('baseType',def_meta_node(def.elementdef));
  763. dinode.addqword('size',def.size*8);
  764. list.concat(dinode);
  765. exit;
  766. end;
  767. { open arrays etc need to access the high parameter to define their range,
  768. which is not possible here since we need the parasym rather than the def }
  769. if is_open_array(def) then
  770. begin
  771. (*
  772. if llvmflag_array_datalocation in llvmversion_properties[current_settings.llvmversion] then
  773. begin
  774. dinode:=def_meta_impl(def);
  775. { should be generated as part of the parasym }
  776. if not assigned(dinode) then
  777. internalerror(2021112002);
  778. end
  779. else *)
  780. begin
  781. { no idea about the size, generate an array of 1 element -- although it could be empty }
  782. appenddef_array_internal(list,def,def.elementdef,0,1);
  783. end;
  784. exit;
  785. end;
  786. if is_array_of_const(def) then
  787. begin
  788. { no idea about the size, generate an array of 1 element -- although it could be empty }
  789. appenddef_array_internal(list,def,def.elementdef,0,1);
  790. exit;
  791. end;
  792. if is_special_array(def)
  793. and not((llvmflag_array_datalocation in llvmversion_properties[current_settings.llvmversion]) and
  794. is_dynamic_array(def)) then
  795. internalerror(2021121902);
  796. { todo: proper support for bitpacked arrays }
  797. if is_packed_array(def) and
  798. (((def.elementdef.packedbitsize mod 8)<>0) or
  799. not ispowerof2(def.elementdef.packedbitsize div 8,power)) then
  800. begin
  801. { for now just encode as an array of bytes }
  802. appenddef_array_internal(list,def,u8inttype,0,def.size-1);
  803. exit;
  804. end;
  805. { collection of all ranges of the array (to support multi-dimensional arrays) }
  806. arrayrangenode:=tai_llvmunnamedmetadatanode.create;
  807. list.concat(arrayrangenode);
  808. { range of the array }
  809. subrangenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubrange);
  810. if is_dynamic_array(def) then
  811. begin
  812. exprnode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
  813. exprnode.addint64('',ord(DW_OP_push_object_address));
  814. exprnode.addint64('',ord(DW_OP_constu));
  815. exprnode.addint64('',ord(sizeof(pint)));
  816. exprnode.addint64('',ord(DW_OP_minus));
  817. exprnode.addint64('',ord(DW_OP_deref));
  818. list.concat(exprnode);
  819. subrangenode.addmetadatarefto('upperBound',exprnode);
  820. subrangenode.addint64('lowerBound',def.lowrange);
  821. end
  822. else
  823. begin
  824. subrangenode.addqword('count',def.highrange-def.lowrange+1);
  825. subrangenode.addint64('lowerBound',def.lowrange);
  826. end;
  827. list.concat(subrangenode);
  828. nesteddef:=def.elementdef;
  829. arrayrangenode.addvalue(llvm_getmetadatareftypedconst(subrangenode));
  830. while (nesteddef.typ=arraydef) and
  831. not is_special_array(nesteddef) do
  832. begin
  833. subrangenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubrange);
  834. subrangenode.addqword('count',tarraydef(nesteddef).highrange-tarraydef(nesteddef).lowrange+1);
  835. subrangenode.addint64('lowerBound',tarraydef(nesteddef).lowrange);
  836. list.concat(subrangenode);
  837. arrayrangenode.addvalue(llvm_getmetadatareftypedconst(subrangenode));
  838. nesteddef:=tarraydef(nesteddef).elementdef;
  839. end;
  840. { the array definition }
  841. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  842. dinode.addqword('tag',ord(DW_TAG_array_type));
  843. dinode.addmetadatarefto('baseType',def_meta_node(nesteddef));
  844. dinode.addmetadatarefto('elements',arrayrangenode);
  845. if is_vector(def) then
  846. dinode.addenum('flags','DIFlagVector');
  847. if not is_dynamic_array(def) then
  848. dinode.addqword('size',def.size*8)
  849. else
  850. begin
  851. exprnode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIExpression);
  852. exprnode.addqword('',ord(DW_OP_LLVM_implicit_pointer));
  853. list.concat(exprnode);
  854. dinode.addmetadatarefto('dataLocation',exprnode);
  855. end;
  856. list.concat(dinode);
  857. end;
  858. procedure TDebugInfoLLVM.appenddef_record(list:TAsmList;def:trecorddef);
  859. begin
  860. if assigned(def.objname) then
  861. appenddef_record_named(list,def,def,def.objname^)
  862. else
  863. appenddef_record_named(list,def,def,'');
  864. end;
  865. procedure TDebugInfoLLVM.appenddef_record_named(list:TAsmList; fordef: tdef; def:trecorddef; const name: TSymStr);
  866. var
  867. dinode: tai_llvmspecialisedmetadatanode;
  868. begin
  869. dinode:=def_set_meta_impl(fordef,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  870. dinode.addint64('tag',ord(DW_TAG_structure_type));
  871. if (name<>'') then
  872. dinode.addstring('name',name);
  873. dinode.addqword('size',def.size*8);
  874. list.concat(dinode);
  875. // def.symtable.symList.ForEachCall(@enum_membersyms_callback,dinode);
  876. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.symtable);
  877. end;
  878. procedure TDebugInfoLLVM.appenddef_pointer(list:TAsmList;def:tpointerdef);
  879. var
  880. dinode: tai_llvmspecialisedmetadatanode;
  881. begin
  882. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  883. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  884. if not(is_voidpointer(def)) then
  885. dinode.addmetadatarefto('baseType',def_meta_node(def.pointeddef))
  886. else
  887. dinode.addmetadatarefto('baseType',nil);
  888. list.concat(dinode);
  889. end;
  890. procedure TDebugInfoLLVM.appenddef_formal(list: TAsmList; def: tformaldef);
  891. var
  892. dinode: tai_llvmspecialisedmetadatanode;
  893. begin
  894. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  895. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  896. dinode.addmetadatarefto('baseType',nil);
  897. list.concat(dinode);
  898. end;
  899. procedure TDebugInfoLLVM.appenddef_string(list:TAsmList;def:tstringdef);
  900. procedure addnormalstringdef(const name: TSymStr; lendef: tdef; maxlen: asizeuint);
  901. var
  902. dinode,
  903. subrangenode,
  904. exprnode: tai_llvmspecialisedmetadatanode;
  905. arrayrangenode: tai_aggregatetypedconst;
  906. { maxlen can be > high(int64) }
  907. slen : asizeuint;
  908. arr : tasmlabel;
  909. begin
  910. { fix length of openshortstring }
  911. slen:=aword(def.len);
  912. if (slen=0) or
  913. (slen>maxlen) then
  914. slen:=maxlen;
  915. appenddef_array_internal(list,def,cansichartype,0,slen);
  916. end;
  917. var
  918. dinode: tai_llvmspecialisedmetadatanode;
  919. begin
  920. case def.stringtype of
  921. st_shortstring:
  922. begin
  923. addnormalstringdef('ShortString',u8inttype,255);
  924. end;
  925. st_longstring:
  926. begin
  927. { a) we don't actually support variables of this type currently
  928. b) this type is only used as the type for constant strings
  929. > 255 characters
  930. c) in such a case, gdb will allocate and initialise enough
  931. memory to hold the maximum size for such a string
  932. -> don't use high(qword)/high(cardinal) as maximum, since that
  933. will cause exhausting the VM space, but some "reasonably high"
  934. number that should be enough for most constant strings
  935. }
  936. {$ifdef cpu64bitaddr}
  937. addnormalstringdef('LongString',u64inttype,qword(1024*1024));
  938. {$endif cpu64bitaddr}
  939. {$ifdef cpu32bitaddr}
  940. addnormalstringdef('LongString',u32inttype,cardinal(1024*1024));
  941. {$endif cpu32bitaddr}
  942. {$ifdef cpu16bitaddr}
  943. addnormalstringdef('LongString',u16inttype,cardinal(1024));
  944. {$endif cpu16bitaddr}
  945. end;
  946. st_ansistring:
  947. begin
  948. // Todo: dynamic length "array"
  949. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  950. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  951. dinode.addmetadatarefto('baseType',def_meta_node(cansichartype));
  952. list.concat(dinode);
  953. end;
  954. st_unicodestring,
  955. st_widestring:
  956. begin
  957. // Todo: dynamic length "array"
  958. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  959. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  960. dinode.addmetadatarefto('baseType',def_meta_node(cwidechartype));
  961. list.concat(dinode);
  962. end;
  963. end;
  964. end;
  965. procedure TDebugInfoLLVM.appenddef_procvar(list:TAsmList;def:tprocvardef);
  966. var
  967. dinode: tai_llvmspecialisedmetadatanode;
  968. begin
  969. { plain pointer for now }
  970. if def.is_addressonly then
  971. begin
  972. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  973. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  974. dinode.addmetadatarefto('baseType',nil);
  975. list.concat(dinode);
  976. end
  977. else
  978. begin
  979. appenddef_array_internal(list,def,voidcodepointertype,1,2);
  980. end;
  981. end;
  982. procedure TDebugInfoLLVM.appenddef_file(list: TAsmList; def: tfiledef);
  983. var
  984. dinode: tai_llvmspecialisedmetadatanode;
  985. begin
  986. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  987. dinode.addint64('tag',ord(DW_TAG_structure_type));
  988. if assigned(def.typesym) then
  989. dinode.addstring('name',symname(def.typesym, false));
  990. dinode.addqword('size',def.size*8);
  991. list.concat(dinode);
  992. end;
  993. procedure TDebugInfoLLVM.appenddef_object(list: TAsmList; def: tobjectdef);
  994. var
  995. dinode: tai_llvmspecialisedmetadatanode;
  996. begin
  997. if is_implicit_pointer_object_type(def) then
  998. begin
  999. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1000. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1001. dinode.addmetadatarefto('baseType',nil);
  1002. end
  1003. else
  1004. begin
  1005. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DICompositeType));
  1006. dinode.addint64('tag',ord(DW_TAG_structure_type));
  1007. if assigned(def.typesym) then
  1008. dinode.addstring('name',symname(def.typesym, false));
  1009. dinode.addqword('size',def.size*8);
  1010. end;
  1011. list.concat(dinode);
  1012. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.symtable);
  1013. end;
  1014. procedure TDebugInfoLLVM.appenddef_set(list: TAsmList; def: tsetdef);
  1015. begin
  1016. appenddef_array_internal(list,def,u8inttype,0,def.size-1);
  1017. end;
  1018. procedure TDebugInfoLLVM.appenddef_undefined(list: TAsmList; def: tundefineddef);
  1019. var
  1020. dinode: tai_llvmspecialisedmetadatanode;
  1021. begin
  1022. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1023. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1024. dinode.addmetadatarefto('baseType',nil);
  1025. list.concat(dinode);
  1026. end;
  1027. procedure TDebugInfoLLVM.appenddef_classref(list: TAsmList; def: tclassrefdef);
  1028. var
  1029. dinode: tai_llvmspecialisedmetadatanode;
  1030. begin
  1031. dinode:=def_set_meta_impl(def,tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType));
  1032. dinode.addint64('tag',ord(DW_TAG_pointer_type));
  1033. dinode.addmetadatarefto('baseType',nil);
  1034. list.concat(dinode);
  1035. end;
  1036. procedure TDebugInfoLLVM.appenddef_variant(list: TAsmList; def: tvariantdef);
  1037. begin
  1038. if assigned(vardatadef) then
  1039. appenddef_record_named(list,def,trecorddef(vardatadef),'Variant');
  1040. end;
  1041. procedure TDebugInfoLLVM.afterappenddef(list:TAsmList;def:tdef);
  1042. var
  1043. tempdinode,
  1044. refdinode,
  1045. impldinode: tai_llvmspecialisedmetadatanode;
  1046. begin
  1047. if def.typ=procdef then
  1048. exit;
  1049. if is_void(def) then
  1050. exit;
  1051. refdinode:=def_meta_node(def);
  1052. if is_objc_class_or_protocol(def) then
  1053. begin
  1054. { for Objective-C classes, the named typedef must refer to the
  1055. struct itself, not to the pointer of the struct; Objective-C
  1056. classes are not implicit pointers in Objective-C itself, only
  1057. in FPC. So make the def label point to a pointer to the
  1058. typedef, which in turn refers to the actual struct (for Delphi-
  1059. style classes, the def points to the typedef, which refers to
  1060. a pointer to the actual struct) }
  1061. { implicit pointer }
  1062. tempdinode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DIDerivedType);
  1063. refdinode.addint64('tag',ord(DW_TAG_pointer_type));
  1064. refdinode.addmetadatarefto('baseType',tempdinode);
  1065. list.concat(refdinode);
  1066. { typedef }
  1067. refdinode:=tempdinode;
  1068. end;
  1069. refdinode.addint64('tag',ord(DW_TAG_typedef));
  1070. if assigned(def.typesym) and
  1071. not(df_generic in def.defoptions) then
  1072. begin
  1073. refdinode.addstring('name',symname(def.typesym,false));
  1074. try_add_file_metaref(refdinode,def.typesym.fileinfo,false);
  1075. end;
  1076. impldinode:=def_meta_impl(def);
  1077. if not assigned(impldinode) then
  1078. internalerror(2021120501);
  1079. refdinode.addmetadatarefto('baseType',impldinode);
  1080. list.concat(refdinode);
  1081. end;
  1082. procedure TDebugInfoLLVM.appendprocdef(list:TAsmList; def:tprocdef);
  1083. procedure adddispflags(dinode: tai_llvmspecialisedmetadatanode; is_definition, is_virtual: boolean);
  1084. var
  1085. dispflags: TSymStr;
  1086. begin
  1087. if llvmflag_NoDISPFlags in llvmversion_properties[current_settings.llvmversion] then
  1088. begin
  1089. dinode.addboolean('isDefinition',is_definition);
  1090. if is_definition then
  1091. begin
  1092. dinode.addboolean('isLocal',
  1093. not((po_global in def.procoptions) and
  1094. (def.parast.symtablelevel<=normal_function_level))
  1095. );
  1096. end;
  1097. if is_virtual then
  1098. begin
  1099. if not(po_abstractmethod in def.procoptions) then
  1100. dinode.addenum('virtuality','DW_VIRTUALITY_virtual')
  1101. else
  1102. dinode.addenum('virtuality','DW_VIRTUALITY_pure_virtual');
  1103. end;
  1104. exit;
  1105. end;
  1106. dispflags:='';
  1107. if is_definition then
  1108. begin
  1109. dispflags:='DISPFlagDefinition';
  1110. if not((po_global in def.procoptions) and
  1111. (def.parast.symtablelevel<=normal_function_level)) then
  1112. dispflags:=dispflags+'|DISPFlagLocalToUnit';
  1113. end;
  1114. if is_virtual then
  1115. begin
  1116. if dispflags<>'' then
  1117. dispflags:=dispflags+'|';
  1118. if not(po_abstractmethod in def.procoptions) then
  1119. dispflags:=dispflags+'DISPFlagVirtual'
  1120. else
  1121. dispflags:=dispflags+'DISPFlagPureVirtual';
  1122. end
  1123. else
  1124. begin
  1125. { this one will always be a definition, so no need to check
  1126. whether result is empty }
  1127. if not(llvmflag_NoDISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and
  1128. (def.proctypeoption=potype_proginit) then
  1129. dispflags:=dispflags+'|DISPFlagMainSubprogram';
  1130. end;
  1131. if dispflags<>'' then
  1132. dinode.addenum('spFlags',dispflags);
  1133. end;
  1134. procedure adddiflags(dinode: tai_llvmspecialisedmetadatanode; is_definition: boolean);
  1135. var
  1136. diflags: TSymStr;
  1137. begin
  1138. if (llvmflag_NoDISPFlagMainSubprogram in llvmversion_properties[current_settings.llvmversion]) and
  1139. (def.proctypeoption=potype_proginit) then
  1140. diflags:='DIFlagMainSubprogram'
  1141. else if def.owner.symtabletype in [objectsymtable,recordsymtable] then
  1142. diflags:=visibilitydiflag(def.visibility)
  1143. else
  1144. diflags:='';
  1145. if diflags<>'' then
  1146. dinode.addenum('flags',diflags);
  1147. end;
  1148. var
  1149. dinode,
  1150. ditypenode : tai_llvmspecialisedmetadatanode;
  1151. fileref : tai_simpletypedconst;
  1152. procdeftai : tai;
  1153. st : tsymtable;
  1154. vmtoffset : pint;
  1155. flags : TSymStr;
  1156. in_currentunit,
  1157. is_virtual : boolean;
  1158. begin
  1159. { only write debug info for procedures defined in the current module,
  1160. except in case of methods (clang-compatible)
  1161. }
  1162. in_currentunit:=def.in_currentunit;
  1163. if not in_currentunit and
  1164. not (def.owner.symtabletype in [objectsymtable,recordsymtable]) then
  1165. exit;
  1166. { happens for init procdef of units without init section }
  1167. if in_currentunit and
  1168. not assigned(def.procstarttai) then
  1169. exit;
  1170. { These don't contain a taillvmdecl, they are completely generated
  1171. in native assembly. If we want to add debug information to these,
  1172. we have to do it using the regular debug info generation }
  1173. if po_assembler in def.procoptions then
  1174. exit;
  1175. if df_generic in def.defoptions then
  1176. exit;
  1177. { Procdefs are not handled by the regular def writing code, so
  1178. dbg_state is not set/checked for them. Do it here. }
  1179. if (def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  1180. exit;
  1181. defnumberlist.Add(def);
  1182. def.dbg_state:=dbg_state_writing;
  1183. { difference compared to other kinds of defs: the DISubProgram gets
  1184. created directly in get_def_metatai because a typedef for a
  1185. DISubProgram does not make sense and is not supported by LLVM ->
  1186. don't set the implementation of the metadata def here and just use
  1187. the regular node }
  1188. dinode:=def_meta_node(def);
  1189. list.concat(dinode);
  1190. { we have to attach the debug info to the definition instruction of the
  1191. proc }
  1192. procdeftai:=nil;
  1193. if in_currentunit then
  1194. begin
  1195. procdeftai:=def.procstarttai;
  1196. if (procdeftai.typ<>ait_llvmdecl) or
  1197. (taillvmdecl(procdeftai).def<>def) then
  1198. internalerror(2022022010);
  1199. taillvmdecl(procdeftai).addinsmetadata(tai_llvmmetadatareferenceoperand.createreferenceto('dbg',dinode));
  1200. end;
  1201. dinode.addstring('name',symdebugname(def.procsym));
  1202. try_add_file_metaref(dinode,def.fileinfo,true);
  1203. if not(cs_debuginfo in current_settings.moduleswitches) then
  1204. begin
  1205. def.dbg_state:=dbg_state_written;
  1206. exit;
  1207. end;
  1208. is_virtual:=
  1209. (([po_abstractmethod, po_virtualmethod, po_overridingmethod]*def.procoptions)<>[]) and
  1210. not is_objc_class_or_protocol(def.struct) and
  1211. not is_objectpascal_helper(def.struct);
  1212. adddispflags(dinode,in_currentunit,is_virtual);
  1213. if is_virtual then
  1214. begin
  1215. { the sizeof(pint) is a bit iffy, since vmtmethodoffset() calculates
  1216. using a combination of voidcodepointer.size, voidpointer.size, and
  1217. sizeof(pint). But that's what the debugger will use }
  1218. dinode.addint64('virtualIndex',tobjectdef(def.owner.defowner).vmtmethodoffset(def.extnumber) div sizeof(pint));
  1219. {$ifdef extdebug}
  1220. if (tobjectdef(def.owner.defowner).vmtmethodoffset(def.extnumber) mod sizeof(pint))<>0 then
  1221. internalerror(2022043001);
  1222. {$endif}
  1223. end;
  1224. adddiflags(dinode,in_currentunit);
  1225. dinode.addmetadatarefto('unit',fcunode);
  1226. ditypenode:=tai_llvmspecialisedmetadatanode.create(tspecialisedmetadatanodekind.DISubroutineType);
  1227. ditypenode.addmetadatarefto('types',getabstractprocdeftypes(list,def));
  1228. list.concat(ditypenode);
  1229. dinode.addmetadatarefto('type',ditypenode);
  1230. (*
  1231. if assigned(def.parast) then
  1232. begin
  1233. { First insert self, because gdb uses the fact whether or not the
  1234. first parameter of a method is artificial to distinguish static
  1235. from regular methods. }
  1236. { fortunately, self is the always the first parameter in the
  1237. paralist, since it has the lowest paranr. Note that this is not
  1238. true for Objective-C, but those methods are detected in
  1239. another way (by reading the ObjC run time information) }
  1240. write_symtable_parasyms(current_asmdata.asmlists[al_dwarf_info],def.paras);
  1241. end;
  1242. { local type defs and vars should not be written
  1243. inside the main proc }
  1244. if in_currentunit and
  1245. assigned(def.localst) and
  1246. (def.localst.symtabletype=localsymtable) then
  1247. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],def.localst);
  1248. { last write the types from this procdef }
  1249. if assigned(def.parast) then
  1250. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.parast);
  1251. { only try to write the localst if the routine is implemented here }
  1252. if in_currentunit and
  1253. assigned(def.localst) and
  1254. (def.localst.symtabletype=localsymtable) then
  1255. begin
  1256. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],def.localst);
  1257. { Write nested procedures -- disabled, see scope check at the
  1258. beginning; currently, these are still written in the global
  1259. scope. }
  1260. // write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],def.localst);
  1261. end;
  1262. finish_children;
  1263. *)
  1264. def.dbg_state:=dbg_state_written;
  1265. end;
  1266. function TDebugInfoLLVM.get_symlist_sym_offset(symlist: ppropaccesslistitem; out sym: tabstractvarsym; out offset: pint): boolean;
  1267. (*
  1268. var
  1269. elesize : pint;
  1270. currdef : tdef;
  1271. indirection: boolean;
  1272. *)
  1273. begin
  1274. result:=false;
  1275. (*
  1276. if not assigned(symlist) then
  1277. exit;
  1278. sym:=nil;
  1279. offset:=0;
  1280. currdef:=nil;
  1281. indirection:=false;
  1282. repeat
  1283. case symlist^.sltype of
  1284. sl_load:
  1285. begin
  1286. if assigned(sym) then
  1287. internalerror(2009031203);
  1288. if not(symlist^.sym.typ in [paravarsym,localvarsym,staticvarsym,fieldvarsym]) then
  1289. { can't handle... }
  1290. exit;
  1291. sym:=tabstractvarsym(symlist^.sym);
  1292. currdef:=tabstractvarsym(sym).vardef;
  1293. if ((sym.typ=paravarsym) and
  1294. paramanager.push_addr_param(tparavarsym(sym).varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption)) then
  1295. indirection:=true;
  1296. end;
  1297. sl_subscript:
  1298. begin
  1299. if not assigned(currdef) then
  1300. internalerror(2009031301);
  1301. if (symlist^.sym.typ<>fieldvarsym) then
  1302. internalerror(2009031202);
  1303. { can't handle offsets with indirections yet }
  1304. if indirection then
  1305. exit;
  1306. if is_packed_record_or_object(currdef) then
  1307. begin
  1308. { can't calculate the address of a non-byte aligned field }
  1309. if (tfieldvarsym(symlist^.sym).fieldoffset mod 8) <> 0 then
  1310. exit;
  1311. inc(offset,tfieldvarsym(symlist^.sym).fieldoffset div 8)
  1312. end
  1313. else
  1314. inc(offset,tfieldvarsym(symlist^.sym).fieldoffset);
  1315. currdef:=tfieldvarsym(symlist^.sym).vardef;
  1316. end;
  1317. sl_absolutetype,
  1318. sl_typeconv:
  1319. begin
  1320. currdef:=symlist^.def;
  1321. { ignore, these don't change the address }
  1322. end;
  1323. sl_vec:
  1324. begin
  1325. if not assigned(currdef) or
  1326. (currdef.typ<>arraydef) then
  1327. internalerror(2009031201);
  1328. { can't handle offsets with indirections yet }
  1329. if indirection then
  1330. exit;
  1331. if not is_packed_array(currdef) then
  1332. elesize:=tarraydef(currdef).elesize
  1333. else
  1334. begin
  1335. elesize:=tarraydef(currdef).elepackedbitsize;
  1336. { can't calculate the address of a non-byte aligned element }
  1337. if (elesize mod 8)<>0 then
  1338. exit;
  1339. elesize:=elesize div 8;
  1340. end;
  1341. inc(offset,(symlist^.value.svalue-tarraydef(currdef).lowrange)*elesize);
  1342. currdef:=tarraydef(currdef).elementdef;
  1343. end;
  1344. else
  1345. internalerror(2009031403);
  1346. end;
  1347. symlist:=symlist^.next;
  1348. until not assigned(symlist);
  1349. if not assigned(sym) then
  1350. internalerror(2009031205);
  1351. result:=true;
  1352. *)
  1353. end;
  1354. procedure TDebugInfoLLVM.appendsym_var(list:TAsmList;sym:tabstractnormalvarsym);
  1355. begin
  1356. // appendsym_var_with_name_type_offset(list,sym,symname(sym, false),sym.vardef,0,[]);
  1357. end;
  1358. procedure TDebugInfoLLVM.appendsym_var_with_name_type_offset(list:TAsmList; sym:tabstractnormalvarsym; const name: TSymStr; def: tdef; offset: pint(*; const flags: tdwarfvarsymflags*));
  1359. (*
  1360. var
  1361. templist : TAsmList;
  1362. blocksize,size_of_int : longint;
  1363. tag : tdwarf_tag;
  1364. has_high_reg : boolean;
  1365. dreg,dreghigh : shortint;
  1366. {$ifdef i8086}
  1367. has_segment_sym_name : boolean=false;
  1368. segment_sym_name : TSymStr='';
  1369. segment_reg: TRegister=NR_NO;
  1370. {$endif i8086}
  1371. *)
  1372. begin
  1373. (*
  1374. if vo_is_external in sym.varoptions then
  1375. exit;
  1376. blocksize:=0;
  1377. dreghigh:=0;
  1378. { There is no space allocated for not referenced locals }
  1379. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  1380. exit;
  1381. templist:=TAsmList.create;
  1382. case sym.localloc.loc of
  1383. LOC_REGISTER,
  1384. LOC_CREGISTER,
  1385. LOC_MMREGISTER,
  1386. LOC_CMMREGISTER,
  1387. LOC_FPUREGISTER,
  1388. LOC_CFPUREGISTER :
  1389. begin
  1390. { dwarf_reg_no_error might return -1
  1391. in case the register variable has been optimized out }
  1392. dreg:=dwarf_reg_no_error(sym.localloc.register);
  1393. has_high_reg:=(sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER]) and (sym.localloc.registerhi<>NR_NO);
  1394. if has_high_reg then
  1395. dreghigh:=dwarf_reg_no_error(sym.localloc.registerhi);
  1396. if dreghigh=-1 then
  1397. has_high_reg:=false;
  1398. if (sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER]) and
  1399. (sym.typ=paravarsym) and
  1400. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1401. not(vo_has_local_copy in sym.varoptions) and
  1402. not is_open_string(sym.vardef) and (dreg>=0) then
  1403. begin
  1404. templist.concat(tai_const.create_8bit(ord(DW_OP_bregx)));
  1405. templist.concat(tai_const.create_uleb128bit(dreg));
  1406. templist.concat(tai_const.create_sleb128bit(0));
  1407. blocksize:=1+Lengthuleb128(dreg)+LengthSleb128(0);
  1408. end
  1409. else
  1410. begin
  1411. if has_high_reg then
  1412. begin
  1413. templist.concat(tai_comment.create(strpnew('high:low reg pair variable')));
  1414. size_of_int:=sizeof(aint);
  1415. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1416. templist.concat(tai_const.create_uleb128bit(dreg));
  1417. blocksize:=1+Lengthuleb128(dreg);
  1418. templist.concat(tai_const.create_8bit(ord(DW_OP_piece)));
  1419. templist.concat(tai_const.create_uleb128bit(size_of_int));
  1420. blocksize:=blocksize+1+Lengthuleb128(size_of_int);
  1421. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1422. templist.concat(tai_const.create_uleb128bit(dreghigh));
  1423. blocksize:=blocksize+1+Lengthuleb128(dreghigh);
  1424. templist.concat(tai_const.create_8bit(ord(DW_OP_piece)));
  1425. templist.concat(tai_const.create_uleb128bit(size_of_int));
  1426. blocksize:=blocksize+1+Lengthuleb128(size_of_int);
  1427. end
  1428. else if (dreg>=0) then
  1429. begin
  1430. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1431. templist.concat(tai_const.create_uleb128bit(dreg));
  1432. blocksize:=1+Lengthuleb128(dreg);
  1433. end;
  1434. end;
  1435. end;
  1436. else
  1437. begin
  1438. case sym.typ of
  1439. staticvarsym:
  1440. begin
  1441. if vo_is_thread_var in sym.varoptions then
  1442. begin
  1443. if tf_section_threadvars in target_info.flags then
  1444. begin
  1445. case sizeof(puint) of
  1446. 2:
  1447. templist.concat(tai_const.create_8bit(ord(DW_OP_const2u)));
  1448. 4:
  1449. templist.concat(tai_const.create_8bit(ord(DW_OP_const4u)));
  1450. 8:
  1451. templist.concat(tai_const.create_8bit(ord(DW_OP_const8u)));
  1452. else
  1453. Internalerror(2019100501);
  1454. end;
  1455. {$push}
  1456. {$warn 6018 off} { Unreachable code due to compile time evaluation }
  1457. templist.concat(tai_const.Create_type_name(aitconst_dtpoff,sym.mangledname,0));
  1458. { so far, aitconst_dtpoff is solely 32 bit }
  1459. if (sizeof(puint)=8) and (target_info.endian=endian_little) then
  1460. templist.concat(tai_const.create_32bit(0));
  1461. templist.concat(tai_const.create_8bit(ord(DW_OP_GNU_push_tls_address)));
  1462. if (sizeof(puint)=8) and (target_info.endian=endian_big) then
  1463. templist.concat(tai_const.create_32bit(0));
  1464. {$pop}
  1465. blocksize:=2+sizeof(puint);
  1466. end
  1467. else
  1468. begin
  1469. { TODO: !!! FIXME: dwarf for thread vars !!!}
  1470. { This is only a minimal change to at least be able to get a value
  1471. in only one thread is present PM 2014-11-21, like for stabs format }
  1472. templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
  1473. templist.concat(tai_const.Create_type_name(aitconst_ptr_unaligned,sym.mangledname,
  1474. offset+sizeof(pint)));
  1475. blocksize:=1+sizeof(puint);
  1476. end;
  1477. end
  1478. else
  1479. begin
  1480. templist.concat(tai_const.create_8bit(ord(DW_OP_addr)));
  1481. templist.concat(tai_const.Create_type_name(aitconst_ptr_unaligned,sym.mangledname,offset));
  1482. blocksize:=1+sizeof(puint);
  1483. {$ifdef i8086}
  1484. segment_sym_name:=sym.mangledname;
  1485. has_segment_sym_name:=true;
  1486. {$endif i8086}
  1487. end;
  1488. end;
  1489. paravarsym,
  1490. localvarsym:
  1491. begin
  1492. { Happens when writing debug info for paras of procdefs not
  1493. implemented in the current module. Can't add a general check
  1494. for LOC_INVALID above, because staticvarsyms may also have it.
  1495. }
  1496. if sym.localloc.loc<> LOC_INVALID then
  1497. begin
  1498. if is_fbreg(sym.localloc.reference.base) then
  1499. begin
  1500. templist.concat(tai_const.create_8bit(ord(DW_OP_fbreg)));
  1501. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset+offset));
  1502. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset+offset);
  1503. end
  1504. else
  1505. begin
  1506. dreg:=dwarf_reg(sym.localloc.reference.base);
  1507. if dreg<=31 then
  1508. begin
  1509. templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+dreg));
  1510. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset+offset));
  1511. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset+offset);
  1512. end
  1513. else
  1514. begin
  1515. templist.concat(tai_const.create_8bit(ord(DW_OP_bregx)));
  1516. templist.concat(tai_const.create_uleb128bit(dreg));
  1517. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset+offset));
  1518. blocksize:=1+Lengthuleb128(dreg)+LengthSleb128(sym.localloc.reference.offset+offset);
  1519. end;
  1520. end;
  1521. {$ifdef i8086}
  1522. segment_reg:=sym.localloc.reference.segment;
  1523. {$endif i8086}
  1524. {$ifndef gdb_supports_DW_AT_variable_parameter}
  1525. { Parameters which are passed by reference. (var and the like)
  1526. Hide the reference-pointer and dereference the pointer
  1527. in the DW_AT_location block.
  1528. }
  1529. if (sym.typ=paravarsym) and
  1530. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1531. not(vo_has_local_copy in sym.varoptions) and
  1532. not is_open_string(sym.vardef) then
  1533. begin
  1534. templist.concat(tai_const.create_8bit(ord(DW_OP_deref)));
  1535. inc(blocksize);
  1536. end
  1537. {$endif not gdb_supports_DW_AT_variable_parameter}
  1538. end;
  1539. end
  1540. else
  1541. internalerror(200601288);
  1542. end;
  1543. end;
  1544. end;
  1545. { function results must not be added to the parameter list,
  1546. as they are not part of the signature of the function
  1547. (gdb automatically adds them according to the ABI specifications
  1548. when calling the function)
  1549. }
  1550. if (sym.typ=paravarsym) and
  1551. not(dvf_force_local_var in flags) and
  1552. not(vo_is_funcret in sym.varoptions) then
  1553. tag:=DW_TAG_formal_parameter
  1554. else
  1555. tag:=DW_TAG_variable;
  1556. { must be parasym of externally implemented procdef, but
  1557. the parasymtable can con also contain e.g. absolutevarsyms
  1558. -> check symtabletype}
  1559. if (sym.owner.symtabletype=parasymtable) and
  1560. (sym.localloc.loc=LOC_INVALID) then
  1561. begin
  1562. if (sym.owner.symtabletype<>parasymtable) then
  1563. internalerror(2009101001);
  1564. append_entry(tag,false,[
  1565. DW_AT_name,DW_FORM_string,name+#0
  1566. {
  1567. DW_AT_decl_file,DW_FORM_data1,0,
  1568. DW_AT_decl_line,DW_FORM_data1,
  1569. }
  1570. ])
  1571. end
  1572. else if not(sym.localloc.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_MMREGISTER,
  1573. LOC_CMMREGISTER,LOC_FPUREGISTER,LOC_CFPUREGISTER]) and
  1574. ((sym.owner.symtabletype = globalsymtable) or
  1575. (sp_static in sym.symoptions) or
  1576. (vo_is_public in sym.varoptions)) then
  1577. append_entry(tag,false,[
  1578. DW_AT_name,DW_FORM_string,name+#0,
  1579. {
  1580. DW_AT_decl_file,DW_FORM_data1,0,
  1581. DW_AT_decl_line,DW_FORM_data1,
  1582. }
  1583. DW_AT_external,DW_FORM_flag,true,
  1584. { data continues below }
  1585. DW_AT_location,DW_FORM_block1,blocksize
  1586. ])
  1587. {$ifdef gdb_supports_DW_AT_variable_parameter}
  1588. else if (sym.typ=paravarsym) and
  1589. paramanager.push_addr_param(sym.varspez,sym.vardef,tprocdef(sym.owner.defowner).proccalloption) and
  1590. not(vo_has_local_copy in sym.varoptions) and
  1591. not is_open_string(sym.vardef) then
  1592. append_entry(tag,false,[
  1593. DW_AT_name,DW_FORM_string,name+#0,
  1594. DW_AT_variable_parameter,DW_FORM_flag,true,
  1595. {
  1596. DW_AT_decl_file,DW_FORM_data1,0,
  1597. DW_AT_decl_line,DW_FORM_data1,
  1598. }
  1599. { data continues below }
  1600. DW_AT_location,DW_FORM_block1,blocksize
  1601. ])
  1602. {$endif gdb_supports_DW_AT_variable_parameter}
  1603. else
  1604. append_entry(tag,false,[
  1605. DW_AT_name,DW_FORM_string,name+#0,
  1606. {
  1607. DW_AT_decl_file,DW_FORM_data1,0,
  1608. DW_AT_decl_line,DW_FORM_data1,
  1609. }
  1610. { data continues below }
  1611. DW_AT_location,DW_FORM_block1,blocksize
  1612. ]);
  1613. { append block data }
  1614. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  1615. { Mark self as artificial for methods, because gdb uses the fact
  1616. whether or not the first parameter of a method is artificial to
  1617. distinguish regular from static methods (since there are no
  1618. no vo_is_self parameters for static methods, we don't have to check
  1619. that). }
  1620. if (vo_is_self in sym.varoptions) then
  1621. append_attribute(DW_AT_artificial,DW_FORM_flag,[true]);
  1622. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def));
  1623. {$ifdef i8086}
  1624. if has_segment_sym_name then
  1625. append_seg_name(segment_sym_name)
  1626. else if segment_reg<>NR_NO then
  1627. append_seg_reg(segment_reg);
  1628. {$endif i8086}
  1629. templist.free;
  1630. finish_entry;
  1631. *)
  1632. end;
  1633. procedure TDebugInfoLLVM.appendsym_staticvar(list:TAsmList;sym:tstaticvarsym);
  1634. begin
  1635. appendsym_var(list,sym);
  1636. end;
  1637. procedure TDebugInfoLLVM.appendsym_localvar(list:TAsmList;sym:tlocalvarsym);
  1638. begin
  1639. appendsym_var(list,sym);
  1640. end;
  1641. procedure TDebugInfoLLVM.appendsym_paravar(list:TAsmList;sym:tparavarsym);
  1642. begin
  1643. appendsym_var(list,sym);
  1644. end;
  1645. procedure TDebugInfoLLVM.appendsym_fieldvar(list:TAsmList;sym: tfieldvarsym);
  1646. begin
  1647. appendsym_fieldvar_with_name_offset(list,sym,symname(sym, false),sym.vardef,0);
  1648. end;
  1649. procedure TDebugInfoLLVM.appendsym_fieldvar_with_name_offset(list:TAsmList;sym: tfieldvarsym;const name: string; def: tdef; offset: pint);
  1650. var
  1651. bitoffset,
  1652. fieldoffset,
  1653. fieldnatsize: asizeint;
  1654. begin
  1655. (*
  1656. if (sp_static in sym.symoptions) or
  1657. (sym.visibility=vis_hidden) then
  1658. exit;
  1659. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) or
  1660. { only ordinals are bitpacked }
  1661. not is_ordinal(sym.vardef) then
  1662. begin
  1663. { other kinds of fields can however also appear in a bitpacked }
  1664. { record, and then their offset is also specified in bits rather }
  1665. { than in bytes }
  1666. if (tabstractrecordsymtable(sym.owner).usefieldalignment<>bit_alignment) then
  1667. fieldoffset:=sym.fieldoffset
  1668. else
  1669. fieldoffset:=sym.fieldoffset div 8;
  1670. inc(fieldoffset,offset);
  1671. append_entry(DW_TAG_member,false,[
  1672. DW_AT_name,DW_FORM_string,name+#0,
  1673. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  1674. ]);
  1675. end
  1676. else
  1677. begin
  1678. if (sym.vardef.packedbitsize > 255) then
  1679. internalerror(2007061201);
  1680. { we don't bitpack according to the ABI, but as close as }
  1681. { possible, i.e., equivalent to gcc's }
  1682. { __attribute__((__packed__)), which is also what gpc }
  1683. { does. }
  1684. fieldnatsize:=max(sizeof(pint),sym.vardef.size);
  1685. fieldoffset:=(sym.fieldoffset div (fieldnatsize*8)) * fieldnatsize;
  1686. inc(fieldoffset,offset);
  1687. bitoffset:=sym.fieldoffset mod (fieldnatsize*8);
  1688. if (target_info.endian=endian_little) then
  1689. bitoffset:=(fieldnatsize*8)-bitoffset-sym.vardef.packedbitsize;
  1690. append_entry(DW_TAG_member,false,[
  1691. DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
  1692. { gcc also generates both a bit and byte size attribute }
  1693. { we don't support ordinals >= 256 bits }
  1694. DW_AT_byte_size,DW_FORM_data1,fieldnatsize,
  1695. { nor >= 256 bits (not yet, anyway, see IE above) }
  1696. DW_AT_bit_size,DW_FORM_data1,sym.vardef.packedbitsize,
  1697. { data1 and data2 are unsigned, bitoffset can also be negative }
  1698. DW_AT_bit_offset,DW_FORM_data4,bitoffset,
  1699. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(fieldoffset)
  1700. ]);
  1701. end;
  1702. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1703. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(fieldoffset));
  1704. if (sym.owner.symtabletype in [objectsymtable,recordsymtable]) then
  1705. append_visibility(sym.visibility);
  1706. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def));
  1707. finish_entry;
  1708. *)
  1709. end;
  1710. procedure TDebugInfoLLVM.appendsym_const(list:TAsmList;sym:tconstsym);
  1711. begin
  1712. appendsym_const_member(list,sym,false);
  1713. end;
  1714. procedure TDebugInfoLLVM.appendsym_const_member(list:TAsmList;sym:tconstsym;ismember:boolean);
  1715. var
  1716. i,
  1717. size: aint;
  1718. usedef: tdef;
  1719. begin
  1720. (*
  1721. { These are default values of parameters. These should be encoded
  1722. via DW_AT_default_value, not as a separate sym. Moreover, their
  1723. type is not available when writing the debug info for external
  1724. procedures.
  1725. }
  1726. if (sym.owner.symtabletype=parasymtable) then
  1727. exit;
  1728. if ismember then
  1729. append_entry(DW_TAG_member,false,[
  1730. DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
  1731. { The DW_AT_declaration tag is invalid according to the DWARF specifications.
  1732. But gcc adds this to static const members and gdb checks
  1733. for this flag. So we have to set it also.
  1734. }
  1735. DW_AT_declaration,DW_FORM_flag,true,
  1736. DW_AT_external,DW_FORM_flag,true
  1737. ])
  1738. else
  1739. append_entry(DW_TAG_variable,false,[
  1740. DW_AT_name,DW_FORM_string,symname(sym, false)+#0
  1741. ]);
  1742. { for string constants, constdef isn't set because they have no real type }
  1743. case sym.consttyp of
  1744. conststring:
  1745. begin
  1746. { if DW_FORM_string is used below one day, this usedef should
  1747. probably become nil }
  1748. { note: < 255 instead of <= 255 because we have to store the
  1749. entire length of the string as well, and 256 does not fit in
  1750. a byte }
  1751. if (sym.value.len<255) then
  1752. usedef:=cshortstringtype
  1753. else
  1754. usedef:=clongstringtype;
  1755. end;
  1756. constresourcestring,
  1757. constwstring:
  1758. usedef:=nil;
  1759. else
  1760. usedef:=sym.constdef;
  1761. end;
  1762. if assigned(usedef) then
  1763. append_labelentry_ref(DW_AT_type,def_dwarf_lab(usedef));
  1764. AddConstToAbbrev(ord(DW_AT_const_value));
  1765. case sym.consttyp of
  1766. conststring:
  1767. begin
  1768. { DW_FORM_string isn't supported yet by the Pascal value printer
  1769. -> create a string using raw bytes }
  1770. if (sym.value.len<255) then
  1771. begin
  1772. AddConstToAbbrev(ord(DW_FORM_block1));
  1773. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sym.value.len+1));
  1774. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sym.value.len));
  1775. end
  1776. else
  1777. begin
  1778. AddConstToAbbrev(ord(DW_FORM_block));
  1779. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sym.value.len+sizesinttype.size));
  1780. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.Create_sizeint_unaligned(sym.value.len));
  1781. end;
  1782. i:=0;
  1783. size:=sym.value.len;
  1784. while(i<size) do
  1785. begin
  1786. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit((pbyte(sym.value.valueptr+i)^)));
  1787. inc(i);
  1788. end;
  1789. end;
  1790. constguid,
  1791. constset:
  1792. begin
  1793. AddConstToAbbrev(ord(DW_FORM_block1));
  1794. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(usedef.size));
  1795. i:=0;
  1796. size:=sym.constdef.size;
  1797. while (i<size) do
  1798. begin
  1799. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit((pbyte(sym.value.valueptr+i)^)));
  1800. inc(i);
  1801. end;
  1802. end;
  1803. constwstring,
  1804. constresourcestring:
  1805. begin
  1806. { write dummy for now }
  1807. AddConstToAbbrev(ord(DW_FORM_string));
  1808. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(''));
  1809. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  1810. end;
  1811. constord:
  1812. begin
  1813. if (sym.value.valueord<0) then
  1814. begin
  1815. AddConstToAbbrev(ord(DW_FORM_sdata));
  1816. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(sym.value.valueord.svalue));
  1817. end
  1818. else
  1819. begin
  1820. AddConstToAbbrev(ord(DW_FORM_udata));
  1821. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sym.value.valueord.uvalue));
  1822. end;
  1823. end;
  1824. constnil:
  1825. begin
  1826. {$ifdef cpu64bitaddr}
  1827. AddConstToAbbrev(ord(DW_FORM_data8));
  1828. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit_unaligned(0));
  1829. {$else cpu64bitaddr}
  1830. AddConstToAbbrev(ord(DW_FORM_data4));
  1831. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit_unaligned(0));
  1832. {$endif cpu64bitaddr}
  1833. end;
  1834. constpointer:
  1835. begin
  1836. {$ifdef cpu64bitaddr}
  1837. AddConstToAbbrev(ord(DW_FORM_data8));
  1838. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit_unaligned(int64(sym.value.valueordptr)));
  1839. {$else cpu64bitaddr}
  1840. AddConstToAbbrev(ord(DW_FORM_data4));
  1841. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit_unaligned(longint(sym.value.valueordptr)));
  1842. {$endif cpu64bitaddr}
  1843. end;
  1844. constreal:
  1845. begin
  1846. AddConstToAbbrev(ord(DW_FORM_block1));
  1847. case tfloatdef(sym.constdef).floattype of
  1848. s32real:
  1849. begin
  1850. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(4));
  1851. current_asmdata.asmlists[al_dwarf_info].concat(tai_realconst.create_s32real(pbestreal(sym.value.valueptr)^));
  1852. end;
  1853. s64real:
  1854. begin
  1855. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  1856. current_asmdata.asmlists[al_dwarf_info].concat(tai_realconst.create_s64real(pbestreal(sym.value.valueptr)^));
  1857. end;
  1858. s64comp,
  1859. s64currency:
  1860. begin
  1861. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  1862. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit_unaligned(trunc(pbestreal(sym.value.valueptr)^)));
  1863. end;
  1864. s80real,
  1865. sc80real:
  1866. begin
  1867. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sym.constdef.size));
  1868. current_asmdata.asmlists[al_dwarf_info].concat(tai_realconst.create_s80real(pextended(sym.value.valueptr)^,sym.constdef.size));
  1869. end;
  1870. else
  1871. internalerror(200601291);
  1872. end;
  1873. end;
  1874. else
  1875. internalerror(200601292);
  1876. end;
  1877. finish_entry;
  1878. *)
  1879. end;
  1880. procedure TDebugInfoLLVM.appendsym_label(list:TAsmList;sym: tlabelsym);
  1881. begin
  1882. { ignore label syms for now, the problem is that a label sym
  1883. can have more than one label associated e.g. in case of
  1884. an inline procedure expansion }
  1885. end;
  1886. procedure TDebugInfoLLVM.appendsym_property(list:TAsmList;sym: tpropertysym);
  1887. var
  1888. symlist: ppropaccesslistitem;
  1889. tosym: tabstractvarsym;
  1890. offset: pint;
  1891. begin
  1892. (*
  1893. if assigned(sym.propaccesslist[palt_read]) and
  1894. not assigned(sym.propaccesslist[palt_read].procdef) then
  1895. symlist:=sym.propaccesslist[palt_read].firstsym
  1896. else
  1897. { can't handle }
  1898. exit;
  1899. if not get_symlist_sym_offset(symlist,tosym,offset) then
  1900. exit;
  1901. if not (tosym.owner.symtabletype in [objectsymtable,recordsymtable]) then
  1902. begin
  1903. if (tosym.typ=fieldvarsym) then
  1904. internalerror(2009031404);
  1905. appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym, false),sym.propdef,offset,[])
  1906. end
  1907. else
  1908. appendsym_fieldvar_with_name_offset(list,tfieldvarsym(tosym),symname(sym, false),sym.propdef,offset)
  1909. *)
  1910. end;
  1911. function TDebugInfoLLVM.symdebugname(sym: tsym): TSymStr;
  1912. begin
  1913. result:=sym.RealName;
  1914. if (result<>'') and
  1915. (result[1]='$') then
  1916. delete(result,1,1);
  1917. end;
  1918. procedure TDebugInfoLLVM.appendsym_type(list:TAsmList;sym: ttypesym);
  1919. begin
  1920. { just queue the def if needed, beforeappenddef will
  1921. emit the typedef if necessary }
  1922. get_def_metatai(sym.typedef);
  1923. {
  1924. if FindUnitSymtable(sym.Owner).iscurrentunit then
  1925. fretainedtypes.addvalue(def_meta_ref(sym.typedef));
  1926. }
  1927. end;
  1928. procedure TDebugInfoLLVM.appendsym_absolute(list:TAsmList;sym:tabsolutevarsym);
  1929. (*
  1930. var
  1931. templist : TAsmList;
  1932. blocksize : longint;
  1933. symlist : ppropaccesslistitem;
  1934. tosym: tabstractvarsym;
  1935. offset: pint;
  1936. flags: tdwarfvarsymflags;
  1937. *)
  1938. begin
  1939. (*
  1940. templist:=TAsmList.create;
  1941. case tabsolutevarsym(sym).abstyp of
  1942. toaddr :
  1943. begin
  1944. { MWE: replaced ifdef i368 }
  1945. {
  1946. if target_cpu = cpu_i386 then
  1947. begin
  1948. { in theory, we could write a DW_AT_segment entry here for sym.absseg,
  1949. however I doubt that gdb supports this (FK) }
  1950. end;
  1951. }
  1952. templist.concat(tai_const.create_8bit(3));
  1953. {$ifdef avr}
  1954. // Add $800000 to indicate that the address is in memory space
  1955. templist.concat(tai_const.create_int_dataptr_unaligned(sym.addroffset + $800000, aitconst_ptr_unaligned));
  1956. {$else}
  1957. templist.concat(tai_const.create_int_dataptr_unaligned(sym.addroffset));
  1958. {$endif}
  1959. blocksize:=1+sizeof(puint);
  1960. end;
  1961. toasm :
  1962. begin
  1963. templist.concat(tai_const.create_8bit(3));
  1964. templist.concat(tai_const.create_type_name(aitconst_ptr_unaligned,sym.mangledname,0));
  1965. blocksize:=1+sizeof(puint);
  1966. end;
  1967. tovar:
  1968. begin
  1969. symlist:=tabsolutevarsym(sym).ref.firstsym;
  1970. if get_symlist_sym_offset(symlist,tosym,offset) then
  1971. begin
  1972. if (tosym.typ=fieldvarsym) then
  1973. internalerror(2009031402);
  1974. flags:=[];
  1975. if (sym.owner.symtabletype=localsymtable) then
  1976. include(flags,dvf_force_local_var);
  1977. appendsym_var_with_name_type_offset(list,tabstractnormalvarsym(tosym),symname(sym, false),tabstractvarsym(sym).vardef,offset,flags);
  1978. end;
  1979. templist.free;
  1980. exit;
  1981. end;
  1982. end;
  1983. append_entry(DW_TAG_variable,false,[
  1984. DW_AT_name,DW_FORM_string,symname(sym, false)+#0,
  1985. {
  1986. DW_AT_decl_file,DW_FORM_data1,0,
  1987. DW_AT_decl_line,DW_FORM_data1,
  1988. }
  1989. DW_AT_external,DW_FORM_flag,true,
  1990. { data continues below }
  1991. DW_AT_location,DW_FORM_block1,blocksize
  1992. ]);
  1993. { append block data }
  1994. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  1995. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  1996. templist.free;
  1997. finish_entry;
  1998. *)
  1999. end;
  2000. procedure TDebugInfoLLVM.beforeappendsym(list:TAsmList;sym:tsym);
  2001. begin
  2002. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Symbol '+symname(sym, true))));
  2003. end;
  2004. procedure TDebugInfoLLVM.insertmoduleinfo;
  2005. var
  2006. culist: tai_llvmnamedmetadatanode;
  2007. dwarfversionflag: tai_llvmbasemetadatanode;
  2008. lang: tdwarf_source_language;
  2009. objcruntimeversion: longint;
  2010. begin
  2011. ensuremetainit;
  2012. if (ds_dwarf_cpp in current_settings.debugswitches) then
  2013. lang:=DW_LANG_C_plus_plus
  2014. else
  2015. lang:=DW_LANG_Pascal83;
  2016. { debug info header }
  2017. fcunode.addint64('language',ord(lang));
  2018. fcunode.addmetadatarefto('file',file_getmetanode(current_filepos.moduleindex,current_filepos.fileindex));
  2019. fcunode.addstring('producer','Free Pascal Compiler '+full_version_string);
  2020. fcunode.addboolean('isOptimized',cs_opt_level2 in current_settings.optimizerswitches);
  2021. if target_info.system in systems_objc_supported then
  2022. begin
  2023. if ([m_objectivec1,m_objectivec2]*current_settings.modeswitches)<>[] then
  2024. if target_info.system in systems_objc_nfabi then
  2025. objcruntimeversion:=2
  2026. else
  2027. objcruntimeversion:=1
  2028. else
  2029. objcruntimeversion:=0;
  2030. fcunode.addint64('runtimeVersion',objcruntimeversion);
  2031. end;
  2032. if cs_debuginfo in current_settings.moduleswitches then
  2033. fcunode.addenum('emissionKind','FullDebug')
  2034. else
  2035. fcunode.addenum('emissionKind','LineTablesOnly');
  2036. if fenums.valuecount<>0 then
  2037. begin
  2038. fcunode.addmetadatarefto('enums',fenums);
  2039. current_asmdata.AsmLists[al_dwarf_info].Concat(fenums);
  2040. end
  2041. else
  2042. begin
  2043. fcunode.addmetadatarefto('enums',nil);
  2044. fenums.free;
  2045. fenums:=nil;
  2046. end;
  2047. if fretainedtypes.valuecount<>0 then
  2048. begin
  2049. fcunode.addmetadatarefto('retainedTypes',fretainedtypes);
  2050. current_asmdata.AsmLists[al_dwarf_info].Concat(fretainedtypes);
  2051. end
  2052. else
  2053. begin
  2054. fcunode.addmetadatarefto('retainedTypes',nil);
  2055. fretainedtypes.free;
  2056. fretainedtypes:=nil;
  2057. end;
  2058. if target_info.system in systems_darwin then
  2059. fcunode.addenum('nameTableKind','GNU');
  2060. current_asmdata.AsmLists[al_dwarf_info].Concat(fcunode);
  2061. culist:=tai_llvmnamedmetadatanode.create('llvm.dbg.cu');
  2062. current_asmdata.AsmLists[al_dwarf_info].Concat(culist);
  2063. culist.addvalue(llvm_getmetadatareftypedconst(fcunode));
  2064. resetfornewmodule;
  2065. end;
  2066. procedure TDebugInfoLLVM.inserttypeinfo;
  2067. var
  2068. storefilepos : tfileposinfo;
  2069. i : longint;
  2070. (*
  2071. lenstartlabel,arangestartlabel: tasmlabel;
  2072. *)
  2073. def: tdef;
  2074. (*
  2075. dbgname: string;
  2076. *)
  2077. vardatatype: ttypesym;
  2078. begin
  2079. storefilepos:=current_filepos;
  2080. current_filepos:=current_module.mainfilepos;
  2081. vardatatype:=try_search_system_type('TVARDATA');
  2082. if assigned(vardatatype) then
  2083. vardatadef:=trecorddef(vardatatype.typedef);
  2084. collectglobalsyms;
  2085. { write all global/local variables. This will flag all required tdefs }
  2086. if assigned(current_module.globalsymtable) then
  2087. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  2088. if assigned(current_module.localsymtable) then
  2089. write_symtable_syms(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  2090. { write all procedures and methods. This will flag all required tdefs }
  2091. if assigned(current_module.globalsymtable) then
  2092. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  2093. if assigned(current_module.localsymtable) then
  2094. write_symtable_procdefs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  2095. { reset unit type info flag }
  2096. reset_unit_type_info;
  2097. { write used types from the used units }
  2098. write_used_unit_type_info(current_asmdata.asmlists[al_dwarf_info],current_module);
  2099. { last write the types from this unit }
  2100. if assigned(current_module.globalsymtable) then
  2101. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  2102. if assigned(current_module.localsymtable) then
  2103. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  2104. { write defs not written yet }
  2105. write_remaining_defs_to_write(current_asmdata.asmlists[al_dwarf_info]);
  2106. { reset all def debug states for LLVMTypeInfo (which also uses this
  2107. field, to track for which types type info has been inserted already }
  2108. for i:=0 to defnumberlist.count-1 do
  2109. begin
  2110. def := tdef(defnumberlist[i]);
  2111. if assigned(def) then
  2112. def.dbg_state:=dbg_state_unused;
  2113. end;
  2114. current_filepos:=storefilepos;
  2115. end;
  2116. function TDebugInfoLLVM.symname(sym: tsym; manglename: boolean): TSymStr;
  2117. begin
  2118. if (sym.typ=paravarsym) and
  2119. (vo_is_self in tparavarsym(sym).varoptions) then
  2120. { We use 'this' for regular methods because that's what gdb triggers
  2121. on to automatically search fields. Don't do this for class methods,
  2122. because search class fields is not supported, and gdb 7.0+ fails
  2123. in this case because "this" is not a record in that case (it's a
  2124. pointer to a vmt) }
  2125. if not is_objc_class_or_protocol(tdef(sym.owner.defowner.owner.defowner)) and
  2126. not(po_classmethod in tabstractprocdef(sym.owner.defowner).procoptions) then
  2127. result:='this'
  2128. else
  2129. result:='self'
  2130. else if (sym.typ=typesym) and
  2131. is_objc_class_or_protocol(ttypesym(sym).typedef) then
  2132. result:=tobjectdef(ttypesym(sym).typedef).objextname^
  2133. else if (ds_dwarf_method_class_prefix in current_settings.debugswitches) and
  2134. (sym.typ=procsym) and
  2135. (tprocsym(sym).owner.symtabletype in [objectsymtable,recordsymtable]) then
  2136. begin
  2137. result:=tprocsym(sym).owner.name^+'__';
  2138. if manglename then
  2139. result := result + sym.name
  2140. else
  2141. result := result + symdebugname(sym);
  2142. end
  2143. else
  2144. begin
  2145. if manglename then
  2146. result := sym.name
  2147. else
  2148. result := symdebugname(sym);
  2149. end;
  2150. end;
  2151. function TDebugInfoLLVM.visibilitydiflag(vis: tvisibility): TSymStr;
  2152. begin
  2153. case vis of
  2154. vis_hidden,
  2155. vis_private,
  2156. vis_strictprivate:
  2157. result:='DIFlagPrivate';
  2158. vis_protected,
  2159. vis_strictprotected:
  2160. result:='DIFlagProtected';
  2161. vis_published,
  2162. vis_public:
  2163. result:='DIFlagPublic';
  2164. vis_none:
  2165. internalerror(2022050101);
  2166. end;
  2167. end;
  2168. procedure TDebugInfoLLVM.insertlineinfo(list:TAsmList);
  2169. var
  2170. hp: tai;
  2171. functionscope,
  2172. positionmeta: tai_llvmspecialisedmetadatanode;
  2173. procdeffileinfo: tfileposinfo;
  2174. nolineinfolevel : longint;
  2175. firstline: boolean;
  2176. begin
  2177. ensuremetainit;
  2178. hp:=tai(list.first);
  2179. while assigned(hp) and
  2180. ((hp.typ<>ait_llvmdecl) or
  2181. (taillvmdecl(hp).def.typ<>procdef)) do
  2182. begin
  2183. hp:=tai(hp.next);
  2184. end;
  2185. if not assigned(hp) then
  2186. exit;
  2187. procdeffileinfo:=tprocdef(taillvmdecl(hp).def).fileinfo;
  2188. { might trigger for certain kinds of internally generated code }
  2189. if procdeffileinfo.fileindex=0 then
  2190. exit;
  2191. functionscope:=def_meta_node(taillvmdecl(hp).def);
  2192. nolineinfolevel:=0;
  2193. hp:=tai(hp.next);
  2194. firstline:=true;
  2195. while assigned(hp) do
  2196. begin
  2197. case hp.typ of
  2198. ait_marker:
  2199. begin
  2200. case tai_marker(hp).kind of
  2201. mark_NoLineInfoStart:
  2202. inc(nolineinfolevel);
  2203. mark_NoLineInfoEnd:
  2204. dec(nolineinfolevel);
  2205. else
  2206. ;
  2207. end;
  2208. end;
  2209. else
  2210. ;
  2211. end;
  2212. if (hp.typ=ait_llvmins) and
  2213. ((nolineinfolevel=0) or
  2214. (taillvm(hp).llvmopcode=la_call)) then
  2215. begin
  2216. positionmeta:=nil;
  2217. { valid file -> add info }
  2218. if (tailineinfo(hp).fileinfo.fileindex<>0) then
  2219. begin
  2220. if firstline and
  2221. (nolineinfolevel=0) then
  2222. begin
  2223. functionscope.addint64('scopeLine',tailineinfo(hp).fileinfo.line);
  2224. firstline:=false;
  2225. end;
  2226. positionmeta:=filepos_getmetanode(tailineinfo(hp).fileinfo,procdeffileinfo,functionscope,nolineinfolevel<>0);
  2227. end
  2228. { LLVM requires line info for call instructions that may
  2229. potentially be inlined }
  2230. else if taillvm(hp).llvmopcode=la_call then
  2231. begin
  2232. positionmeta:=filepos_getmetanode(tailineinfo(hp).fileinfo,procdeffileinfo,functionscope,true);
  2233. end;
  2234. if assigned(positionmeta) then
  2235. taillvm(hp).addinsmetadata(tai_llvmmetadatareferenceoperand.createreferenceto('dbg',positionmeta));
  2236. end;
  2237. hp:=tai(hp.next);
  2238. end;
  2239. end;
  2240. {****************************************************************************
  2241. ****************************************************************************}
  2242. const
  2243. dbg_llvm_info : tdbginfo =
  2244. (
  2245. id : dbg_llvm;
  2246. idtxt : 'LLVM';
  2247. );
  2248. initialization
  2249. RegisterDebugInfo(dbg_llvm_info,TDebugInfoLLVM);
  2250. end.