dbgllvm.pas 114 KB

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