dbgllvm.pas 113 KB

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