dbgllvm.pas 118 KB

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