dbgllvm.pas 103 KB

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