dbgllvm.pas 118 KB

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