dbgllvm.pas 95 KB

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