dbgllvm.pas 118 KB

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