dbgllvm.pas 101 KB

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