dbgllvm.pas 95 KB

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