dbgllvm.pas 100 KB

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