dbgllvm.pas 99 KB

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