dbgllvm.pas 117 KB

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