dbgllvm.pas 100 KB

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