dbgdwarf.pas 104 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808
  1. {
  2. Copyright (c) 2003-2006 by Peter Vreman and Florian Klaempfl
  3. This units contains support for DWARF debug info generation
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. {
  18. This units contains support for DWARF debug info generation.
  19. Currently a lot of code looks like being mergable with dbgstabs. This might
  20. change however when improved dwarf info is generated, so the stuff shouldn't be
  21. merged yet. (FK)
  22. The easiest way to debug dwarf debug info generation is the usage of
  23. readelf --debug-dump <executable>
  24. This works only with elf targets though.
  25. }
  26. unit dbgdwarf;
  27. {$i fpcdefs.inc}
  28. interface
  29. uses
  30. cclasses,
  31. aasmbase,aasmtai,aasmdata,
  32. symbase,symtype,symdef,symsym,
  33. finput,
  34. DbgBase;
  35. type
  36. { Tag names and codes. }
  37. tdwarf_tag = (DW_TAG_padding := $00,DW_TAG_array_type := $01,
  38. DW_TAG_class_type := $02,DW_TAG_entry_point := $03,
  39. DW_TAG_enumeration_type := $04,DW_TAG_formal_parameter := $05,
  40. DW_TAG_imported_declaration := $08,DW_TAG_label := $0a,
  41. DW_TAG_lexical_block := $0b,DW_TAG_member := $0d,
  42. DW_TAG_pointer_type := $0f,DW_TAG_reference_type := $10,
  43. DW_TAG_compile_unit := $11,DW_TAG_string_type := $12,
  44. DW_TAG_structure_type := $13,DW_TAG_subroutine_type := $15,
  45. DW_TAG_typedef := $16,DW_TAG_union_type := $17,
  46. DW_TAG_unspecified_parameters := $18,
  47. DW_TAG_variant := $19,DW_TAG_common_block := $1a,
  48. DW_TAG_common_inclusion := $1b,DW_TAG_inheritance := $1c,
  49. DW_TAG_inlined_subroutine := $1d,DW_TAG_module := $1e,
  50. DW_TAG_ptr_to_member_type := $1f,DW_TAG_set_type := $20,
  51. DW_TAG_subrange_type := $21,DW_TAG_with_stmt := $22,
  52. DW_TAG_access_declaration := $23,DW_TAG_base_type := $24,
  53. DW_TAG_catch_block := $25,DW_TAG_const_type := $26,
  54. DW_TAG_constant := $27,DW_TAG_enumerator := $28,
  55. DW_TAG_file_type := $29,DW_TAG_friend := $2a,
  56. DW_TAG_namelist := $2b,DW_TAG_namelist_item := $2c,
  57. DW_TAG_packed_type := $2d,DW_TAG_subprogram := $2e,
  58. DW_TAG_template_type_param := $2f,DW_TAG_template_value_param := $30,
  59. DW_TAG_thrown_type := $31,DW_TAG_try_block := $32,
  60. DW_TAG_variant_part := $33,DW_TAG_variable := $34,
  61. DW_TAG_volatile_type := $35,
  62. { DWARF 3. }
  63. DW_TAG_dwarf_procedure := $36,
  64. DW_TAG_restrict_type := $37,DW_TAG_interface_type := $38,
  65. DW_TAG_namespace := $39,DW_TAG_imported_module := $3a,
  66. DW_TAG_unspecified_type := $3b,DW_TAG_partial_unit := $3c,
  67. DW_TAG_imported_unit := $3d,
  68. { SGI/MIPS Extensions. }
  69. DW_TAG_MIPS_loop := $4081,
  70. { HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . }
  71. DW_TAG_HP_array_descriptor := $4090,
  72. { GNU extensions. }
  73. { For FORTRAN 77 and Fortran 90. }
  74. DW_TAG_format_label := $4101,
  75. { For C++. }
  76. DW_TAG_function_template := $4102,DW_TAG_class_template := $4103,
  77. DW_TAG_GNU_BINCL := $4104,DW_TAG_GNU_EINCL := $4105,
  78. { Extensions for UPC. See: http://upc.gwu.edu/~upc. }
  79. DW_TAG_upc_shared_type := $8765,DW_TAG_upc_strict_type := $8766,
  80. DW_TAG_upc_relaxed_type := $8767,
  81. { PGI (STMicroelectronics) extensions. No documentation available. }
  82. DW_TAG_PGI_kanji_type := $A000,
  83. DW_TAG_PGI_interface_block := $A020);
  84. { Attribute names and codes. }
  85. tdwarf_attribute = (DW_AT_sibling := $01,DW_AT_location := $02,
  86. DW_AT_name := $03,DW_AT_ordering := $09,
  87. DW_AT_subscr_data := $0a,DW_AT_byte_size := $0b,
  88. DW_AT_bit_offset := $0c,DW_AT_bit_size := $0d,
  89. DW_AT_element_list := $0f,DW_AT_stmt_list := $10,
  90. DW_AT_low_pc := $11,DW_AT_high_pc := $12,
  91. DW_AT_language := $13,DW_AT_member := $14,
  92. DW_AT_discr := $15,DW_AT_discr_value := $16,
  93. DW_AT_visibility := $17,DW_AT_import := $18,
  94. DW_AT_string_length := $19,DW_AT_common_reference := $1a,
  95. DW_AT_comp_dir := $1b,DW_AT_const_value := $1c,
  96. DW_AT_containing_type := $1d,DW_AT_default_value := $1e,
  97. DW_AT_inline := $20,DW_AT_is_optional := $21,
  98. DW_AT_lower_bound := $22,DW_AT_producer := $25,
  99. DW_AT_prototyped := $27,DW_AT_return_addr := $2a,
  100. DW_AT_start_scope := $2c,DW_AT_stride_size := $2e,
  101. DW_AT_upper_bound := $2f,DW_AT_abstract_origin := $31,
  102. DW_AT_accessibility := $32,DW_AT_address_class := $33,
  103. DW_AT_artificial := $34,DW_AT_base_types := $35,
  104. DW_AT_calling_convention := $36,DW_AT_count := $37,
  105. DW_AT_data_member_location := $38,DW_AT_decl_column := $39,
  106. DW_AT_decl_file := $3a,DW_AT_decl_line := $3b,
  107. DW_AT_declaration := $3c,DW_AT_discr_list := $3d,
  108. DW_AT_encoding := $3e,DW_AT_external := $3f,
  109. DW_AT_frame_base := $40,DW_AT_friend := $41,
  110. DW_AT_identifier_case := $42,DW_AT_macro_info := $43,
  111. DW_AT_namelist_items := $44,DW_AT_priority := $45,
  112. DW_AT_segment := $46,DW_AT_specification := $47,
  113. DW_AT_static_link := $48,DW_AT_type := $49,
  114. DW_AT_use_location := $4a,DW_AT_variable_parameter := $4b,
  115. DW_AT_virtuality := $4c,DW_AT_vtable_elem_location := $4d,
  116. { DWARF 3 values. }
  117. DW_AT_allocated := $4e,DW_AT_associated := $4f,
  118. DW_AT_data_location := $50,DW_AT_stride := $51,
  119. DW_AT_entry_pc := $52,DW_AT_use_UTF8 := $53,
  120. DW_AT_extension := $54,DW_AT_ranges := $55,
  121. DW_AT_trampoline := $56,DW_AT_call_column := $57,
  122. DW_AT_call_file := $58,DW_AT_call_line := $59,
  123. { SGI/MIPS extensions. }
  124. DW_AT_MIPS_fde := $2001,DW_AT_MIPS_loop_begin := $2002,
  125. DW_AT_MIPS_tail_loop_begin := $2003,DW_AT_MIPS_epilog_begin := $2004,
  126. DW_AT_MIPS_loop_unroll_factor := $2005,
  127. DW_AT_MIPS_software_pipeline_depth := $2006,
  128. DW_AT_MIPS_linkage_name := $2007,DW_AT_MIPS_stride := $2008,
  129. DW_AT_MIPS_abstract_name := $2009,DW_AT_MIPS_clone_origin := $200a,
  130. DW_AT_MIPS_has_inlines := $200b,
  131. { HP extensions. }
  132. DW_AT_HP_block_index := $2000,
  133. DW_AT_HP_unmodifiable := $2001,DW_AT_HP_actuals_stmt_list := $2010,
  134. DW_AT_HP_proc_per_section := $2011,DW_AT_HP_raw_data_ptr := $2012,
  135. DW_AT_HP_pass_by_reference := $2013,DW_AT_HP_opt_level := $2014,
  136. DW_AT_HP_prof_version_id := $2015,DW_AT_HP_opt_flags := $2016,
  137. DW_AT_HP_cold_region_low_pc := $2017,DW_AT_HP_cold_region_high_pc := $2018,
  138. DW_AT_HP_all_variables_modifiable := $2019,
  139. DW_AT_HP_linkage_name := $201a,DW_AT_HP_prof_flags := $201b,
  140. { GNU extensions. }
  141. DW_AT_sf_names := $2101,DW_AT_src_info := $2102,
  142. DW_AT_mac_info := $2103,DW_AT_src_coords := $2104,
  143. DW_AT_body_begin := $2105,DW_AT_body_end := $2106,
  144. DW_AT_GNU_vector := $2107,
  145. { VMS extensions. }
  146. DW_AT_VMS_rtnbeg_pd_address := $2201,
  147. { UPC extension. }
  148. DW_AT_upc_threads_scaled := $3210,
  149. { PGI (STMicroelectronics) extensions. }
  150. DW_AT_PGI_lbase := $3a00,
  151. DW_AT_PGI_soffset := $3a01,DW_AT_PGI_lstride := $3a02
  152. );
  153. { Form names and codes. }
  154. Tdwarf_form = (DW_FORM_addr := $01,DW_FORM_block2 := $03,
  155. DW_FORM_block4 := $04,DW_FORM_data2 := $05,
  156. DW_FORM_data4 := $06,DW_FORM_data8 := $07,
  157. DW_FORM_string := $08,DW_FORM_block := $09,
  158. DW_FORM_block1 := $0a,DW_FORM_data1 := $0b,
  159. DW_FORM_flag := $0c,DW_FORM_sdata := $0d,
  160. DW_FORM_strp := $0e,DW_FORM_udata := $0f,
  161. DW_FORM_ref_addr := $10,DW_FORM_ref1 := $11,
  162. DW_FORM_ref2 := $12,DW_FORM_ref4 := $13,
  163. DW_FORM_ref8 := $14,DW_FORM_ref_udata := $15,
  164. DW_FORM_indirect := $16);
  165. TDwarfFile = record
  166. Index: integer;
  167. Name: PChar;
  168. end;
  169. { TDebugInfoDwarf }
  170. TDebugInfoDwarf = class(TDebugInfo)
  171. private
  172. currabbrevnumber : longint;
  173. { collect all defs in one list so we can reset them easily }
  174. { not used (MWE)
  175. nextdefnumber : longint;
  176. }
  177. defnumberlist,
  178. deftowritelist : TFPObjectList;
  179. writing_def_dwarf : boolean;
  180. { use this defs to create info for variants and file handles }
  181. { unused (MWE)
  182. filerecdef,
  183. textrecdef : tdef;
  184. }
  185. dirlist: TFPHashObjectList;
  186. filesequence: Integer;
  187. loclist: tdynamicarray;
  188. asmline: TAsmList;
  189. function def_dwarf_lab(def:tdef) : tasmsymbol;
  190. function get_file_index(afile: tinputfile): Integer;
  191. procedure write_symtable_syms(st:tsymtable);
  192. protected
  193. isdwarf64: Boolean;
  194. vardatadef: trecorddef;
  195. procedure append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const);
  196. procedure append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
  197. procedure append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
  198. procedure append_labelentry_data(attr : tdwarf_attribute;sym : tasmsymbol);
  199. procedure appenddef(def:tdef);
  200. procedure appenddef_ord(def:torddef); virtual;
  201. procedure appenddef_float(def:tfloatdef); virtual;
  202. procedure appenddef_file(def:tfiledef); virtual;
  203. procedure appenddef_enum(def:tenumdef); virtual;
  204. procedure appenddef_array(def:tarraydef); virtual;
  205. procedure appenddef_record(def:trecorddef); virtual;
  206. procedure appenddef_object(def:tobjectdef); virtual; abstract;
  207. procedure appenddef_pointer(def:tpointerdef); virtual;
  208. procedure appenddef_string(def:tstringdef); virtual;
  209. procedure appenddef_procvar(def:tprocvardef); virtual;
  210. procedure appenddef_variant(def:tvariantdef); virtual; abstract;
  211. procedure appenddef_set(def:tsetdef); virtual; abstract;
  212. procedure appenddef_formal(def:tformaldef); virtual;
  213. procedure appenddef_unineddef(def:tundefineddef); virtual; abstract;
  214. procedure appendprocdef(pd:tprocdef); virtual;
  215. procedure appendsym(sym:tsym);
  216. procedure appendsym_var(sym:tabstractnormalvarsym); virtual;
  217. procedure appendsym_fieldvar(sym:tfieldvarsym); virtual;
  218. procedure appendsym_unit(sym:tunitsym); virtual;
  219. procedure appendsym_const(sym:tconstsym); virtual;
  220. procedure appendsym_type(sym:ttypesym); virtual;
  221. procedure appendsym_typedconst(sym:ttypedconstsym); virtual;
  222. procedure appendsym_label(sym:tlabelsym); virtual;
  223. procedure appendsym_absolute(sym:tabsolutevarsym); virtual;
  224. procedure appendsym_property(sym:tpropertysym); virtual;
  225. procedure appendsym_proc(sym:tprocsym); virtual;
  226. function symname(sym:tsym): String; virtual;
  227. procedure enum_membersyms_callback(p:Tnamedindexitem;arg:pointer);
  228. procedure finish_children;
  229. procedure finish_entry;
  230. public
  231. constructor Create;override;
  232. destructor Destroy;override;
  233. procedure insertdef(unused:TAsmList;def:tdef);override;
  234. procedure insertmoduleinfo;override;
  235. procedure inserttypeinfo;override;
  236. procedure referencesections(list:TAsmList);override;
  237. procedure insertlineinfo(list:TAsmList);override;
  238. function dwarf_version: Word; virtual; abstract;
  239. procedure write_symtable_defs(unused:TAsmList;st:tsymtable);override;
  240. end;
  241. { TDebugInfoDwarf2 }
  242. TDebugInfoDwarf2 = class(TDebugInfoDwarf)
  243. private
  244. protected
  245. procedure appenddef_file(def:tfiledef); override;
  246. procedure appenddef_formal(def:tformaldef); override;
  247. procedure appenddef_object(def:tobjectdef); override;
  248. procedure appenddef_set(def:tsetdef); override;
  249. procedure appenddef_unineddef(def:tundefineddef); override;
  250. procedure appenddef_variant(def:tvariantdef); override;
  251. public
  252. function dwarf_version: Word; override;
  253. end;
  254. { TDebugInfoDwarf3 }
  255. TDebugInfoDwarf3 = class(TDebugInfoDwarf)
  256. private
  257. protected
  258. procedure appenddef_file(def:tfiledef); override;
  259. procedure appenddef_formal(def:tformaldef); override;
  260. procedure appenddef_object(def:tobjectdef); override;
  261. procedure appenddef_set(def:tsetdef); override;
  262. procedure appenddef_unineddef(def:tundefineddef); override;
  263. procedure appenddef_variant(def:tvariantdef); override;
  264. function symname(sym:tsym): String; override;
  265. public
  266. function dwarf_version: Word; override;
  267. end;
  268. implementation
  269. uses
  270. cutils,cfileutils,
  271. version,globtype,globals,verbose,systems,
  272. cpubase,cgbase,
  273. fmodule,
  274. defutil,symconst,symtable
  275. ;
  276. const
  277. LINE_BASE = 1;
  278. OPCODE_BASE = 13;
  279. const
  280. DW_TAG_lo_user = $4080;
  281. DW_TAG_hi_user = $ffff;
  282. { Flag that tells whether entry has a child or not. }
  283. DW_children_no = 0;
  284. DW_children_yes = 1;
  285. const
  286. { Implementation-defined range start. }
  287. DW_AT_lo_user = $2000;
  288. { Implementation-defined range end. }
  289. DW_AT_hi_user = $3ff0;
  290. type
  291. { Source language names and codes. }
  292. tdwarf_source_language = (DW_LANG_C89 := $0001,DW_LANG_C := $0002,DW_LANG_Ada83 := $0003,
  293. DW_LANG_C_plus_plus := $0004,DW_LANG_Cobol74 := $0005,
  294. DW_LANG_Cobol85 := $0006,DW_LANG_Fortran77 := $0007,
  295. DW_LANG_Fortran90 := $0008,DW_LANG_Pascal83 := $0009,
  296. DW_LANG_Modula2 := $000a,DW_LANG_Java := $000b,
  297. { DWARF 3. }
  298. DW_LANG_C99 := $000c,DW_LANG_Ada95 := $000d,
  299. DW_LANG_Fortran95 := $000e,
  300. { MIPS. }
  301. DW_LANG_Mips_Assembler := $8001,
  302. { UPC. }
  303. DW_LANG_Upc := $8765
  304. );
  305. const
  306. { Implementation-defined range start. }
  307. DW_LANG_lo_user = $8000;
  308. { Implementation-defined range start. }
  309. DW_LANG_hi_user = $ffff;
  310. type
  311. { Names and codes for macro information. }
  312. tdwarf_macinfo_record_type = (DW_MACINFO_define := 1,DW_MACINFO_undef := 2,
  313. DW_MACINFO_start_file := 3,DW_MACINFO_end_file := 4,
  314. DW_MACINFO_vendor_ext := 255);
  315. type
  316. { Type encodings. }
  317. Tdwarf_type = (DW_ATE_void := $0,DW_ATE_address := $1,
  318. DW_ATE_boolean := $2,DW_ATE_complex_float := $3,
  319. DW_ATE_float := $4,DW_ATE_signed := $5,
  320. DW_ATE_signed_char := $6,DW_ATE_unsigned := $7,
  321. DW_ATE_unsigned_char := $8,DW_ATE_imaginary_float := $9,
  322. { HP extensions. }
  323. DW_ATE_HP_float80 := $80,DW_ATE_HP_complex_float80 := $81,
  324. DW_ATE_HP_float128 := $82,DW_ATE_HP_complex_float128 := $83,
  325. DW_ATE_HP_floathpintel := $84,DW_ATE_HP_imaginary_float80 := $85,
  326. DW_ATE_HP_imaginary_float128 := $86
  327. );
  328. const
  329. DW_ATE_lo_user = $80;
  330. DW_ATE_hi_user = $ff;
  331. type
  332. Tdwarf_array_dim_ordering = (DW_ORD_row_major := 0,DW_ORD_col_major := 1
  333. );
  334. { Access attribute. }
  335. Tdwarf_access_attribute = (DW_ACCESS_public := 1,DW_ACCESS_protected := 2,
  336. DW_ACCESS_private := 3);
  337. { Visibility. }
  338. Tdwarf_visibility_attribute = (DW_VIS_local := 1,DW_VIS_exported := 2,
  339. DW_VIS_qualified := 3);
  340. { Virtuality. }
  341. Tdwarf_virtuality_attribute = (DW_VIRTUALITY_none := 0,DW_VIRTUALITY_virtual := 1,
  342. DW_VIRTUALITY_pure_virtual := 2);
  343. { Case sensitivity. }
  344. Tdwarf_id_case = (DW_ID_case_sensitive := 0,DW_ID_up_case := 1,
  345. DW_ID_down_case := 2,DW_ID_case_insensitive := 3
  346. );
  347. { Calling convention. }
  348. Tdwarf_calling_convention = (DW_CC_normal := $1,DW_CC_program := $2,
  349. DW_CC_nocall := $3,DW_CC_GNU_renesas_sh := $40
  350. );
  351. { Location atom names and codes. }
  352. Tdwarf_location_atom = (DW_OP_addr := $03,DW_OP_deref := $06,DW_OP_const1u := $08,
  353. DW_OP_const1s := $09,DW_OP_const2u := $0a,
  354. DW_OP_const2s := $0b,DW_OP_const4u := $0c,
  355. DW_OP_const4s := $0d,DW_OP_const8u := $0e,
  356. DW_OP_const8s := $0f,DW_OP_constu := $10,
  357. DW_OP_consts := $11,DW_OP_dup := $12,DW_OP_drop := $13,
  358. DW_OP_over := $14,DW_OP_pick := $15,DW_OP_swap := $16,
  359. DW_OP_rot := $17,DW_OP_xderef := $18,DW_OP_abs := $19,
  360. DW_OP_and := $1a,DW_OP_div := $1b,DW_OP_minus := $1c,
  361. DW_OP_mod := $1d,DW_OP_mul := $1e,DW_OP_neg := $1f,
  362. DW_OP_not := $20,DW_OP_or := $21,DW_OP_plus := $22,
  363. DW_OP_plus_uconst := $23,DW_OP_shl := $24,
  364. DW_OP_shr := $25,DW_OP_shra := $26,DW_OP_xor := $27,
  365. DW_OP_bra := $28,DW_OP_eq := $29,DW_OP_ge := $2a,
  366. DW_OP_gt := $2b,DW_OP_le := $2c,DW_OP_lt := $2d,
  367. DW_OP_ne := $2e,DW_OP_skip := $2f,DW_OP_lit0 := $30,
  368. DW_OP_lit1 := $31,DW_OP_lit2 := $32,DW_OP_lit3 := $33,
  369. DW_OP_lit4 := $34,DW_OP_lit5 := $35,DW_OP_lit6 := $36,
  370. DW_OP_lit7 := $37,DW_OP_lit8 := $38,DW_OP_lit9 := $39,
  371. DW_OP_lit10 := $3a,DW_OP_lit11 := $3b,
  372. DW_OP_lit12 := $3c,DW_OP_lit13 := $3d,
  373. DW_OP_lit14 := $3e,DW_OP_lit15 := $3f,
  374. DW_OP_lit16 := $40,DW_OP_lit17 := $41,
  375. DW_OP_lit18 := $42,DW_OP_lit19 := $43,
  376. DW_OP_lit20 := $44,DW_OP_lit21 := $45,
  377. DW_OP_lit22 := $46,DW_OP_lit23 := $47,
  378. DW_OP_lit24 := $48,DW_OP_lit25 := $49,
  379. DW_OP_lit26 := $4a,DW_OP_lit27 := $4b,
  380. DW_OP_lit28 := $4c,DW_OP_lit29 := $4d,
  381. DW_OP_lit30 := $4e,DW_OP_lit31 := $4f,
  382. DW_OP_reg0 := $50,DW_OP_reg1 := $51,DW_OP_reg2 := $52,
  383. DW_OP_reg3 := $53,DW_OP_reg4 := $54,DW_OP_reg5 := $55,
  384. DW_OP_reg6 := $56,DW_OP_reg7 := $57,DW_OP_reg8 := $58,
  385. DW_OP_reg9 := $59,DW_OP_reg10 := $5a,DW_OP_reg11 := $5b,
  386. DW_OP_reg12 := $5c,DW_OP_reg13 := $5d,
  387. DW_OP_reg14 := $5e,DW_OP_reg15 := $5f,
  388. DW_OP_reg16 := $60,DW_OP_reg17 := $61,
  389. DW_OP_reg18 := $62,DW_OP_reg19 := $63,
  390. DW_OP_reg20 := $64,DW_OP_reg21 := $65,
  391. DW_OP_reg22 := $66,DW_OP_reg23 := $67,
  392. DW_OP_reg24 := $68,DW_OP_reg25 := $69,
  393. DW_OP_reg26 := $6a,DW_OP_reg27 := $6b,
  394. DW_OP_reg28 := $6c,DW_OP_reg29 := $6d,
  395. DW_OP_reg30 := $6e,DW_OP_reg31 := $6f,
  396. DW_OP_breg0 := $70,DW_OP_breg1 := $71,
  397. DW_OP_breg2 := $72,DW_OP_breg3 := $73,
  398. DW_OP_breg4 := $74,DW_OP_breg5 := $75,
  399. DW_OP_breg6 := $76,DW_OP_breg7 := $77,
  400. DW_OP_breg8 := $78,DW_OP_breg9 := $79,
  401. DW_OP_breg10 := $7a,DW_OP_breg11 := $7b,
  402. DW_OP_breg12 := $7c,DW_OP_breg13 := $7d,
  403. DW_OP_breg14 := $7e,DW_OP_breg15 := $7f,
  404. DW_OP_breg16 := $80,DW_OP_breg17 := $81,
  405. DW_OP_breg18 := $82,DW_OP_breg19 := $83,
  406. DW_OP_breg20 := $84,DW_OP_breg21 := $85,
  407. DW_OP_breg22 := $86,DW_OP_breg23 := $87,
  408. DW_OP_breg24 := $88,DW_OP_breg25 := $89,
  409. DW_OP_breg26 := $8a,DW_OP_breg27 := $8b,
  410. DW_OP_breg28 := $8c,DW_OP_breg29 := $8d,
  411. DW_OP_breg30 := $8e,DW_OP_breg31 := $8f,
  412. DW_OP_regx := $90,DW_OP_fbreg := $91,DW_OP_bregx := $92,
  413. DW_OP_piece := $93,DW_OP_deref_size := $94,
  414. DW_OP_xderef_size := $95,DW_OP_nop := $96,
  415. { DWARF 3 extensions. }
  416. DW_OP_push_object_address := $97,DW_OP_call2 := $98,
  417. DW_OP_call4 := $99,DW_OP_call_ref := $9a,
  418. { GNU extensions. }
  419. DW_OP_GNU_push_tls_address := $e0,
  420. { HP extensions. }
  421. DW_OP_HP_unknown := $e0,
  422. DW_OP_HP_is_value := $e1,DW_OP_HP_fltconst4 := $e2,
  423. DW_OP_HP_fltconst8 := $e3,DW_OP_HP_mod_range := $e4,
  424. DW_OP_HP_unmod_range := $e5,DW_OP_HP_tls := $e6
  425. );
  426. const
  427. { Implementation-defined range start. }
  428. DW_OP_lo_user = $e0;
  429. { Implementation-defined range end. }
  430. DW_OP_hi_user = $ff;
  431. const
  432. DW_LNS_extended_op = $00;
  433. { next copied from cfidwarf, need to go to something shared }
  434. DW_LNS_copy = $01;
  435. DW_LNS_advance_pc = $02;
  436. DW_LNS_advance_line = $03;
  437. DW_LNS_set_file = $04;
  438. DW_LNS_set_column = $05;
  439. DW_LNS_negate_stmt = $06;
  440. DW_LNS_set_basic_block = $07;
  441. DW_LNS_const_add_pc = $08;
  442. DW_LNS_fixed_advance_pc = $09;
  443. DW_LNS_set_prologue_end = $0a;
  444. DW_LNS_set_epilogue_begin = $0b;
  445. DW_LNS_set_isa = $0c;
  446. DW_LNE_end_sequence = $01;
  447. DW_LNE_set_address = $02;
  448. DW_LNE_define_file = $03;
  449. DW_LNE_lo_user = $80;
  450. DW_LNE_hi_user = $ff;
  451. type
  452. { TDirIndexItem }
  453. TDirIndexItem = class(TFPHashObject)
  454. private
  455. FFiles: TFPHashObjectList;
  456. public
  457. IndexNr : Integer;
  458. constructor Create(AList:TFPHashObjectList;const AName: String; AIndex: Integer);
  459. destructor Destroy;override;
  460. property Files: TFPHashObjectList read FFiles;
  461. end;
  462. { TFileIndexItem }
  463. TFileIndexItem = class(TFPHashObject)
  464. private
  465. FDirIndex: Integer;
  466. public
  467. IndexNr : Integer;
  468. constructor Create(AList:TFPHashObjectList;const AName: String; ADirIndex, AIndex: Integer);
  469. property DirIndex: Integer read FDirIndex;
  470. end;
  471. {****************************************************************************
  472. procs
  473. ****************************************************************************}
  474. function DirListSortCompare(AItem1, AItem2: Pointer): Integer;
  475. begin
  476. Result := TDirIndexItem(AItem1).IndexNr - TDirIndexItem(AItem2).IndexNr;
  477. end;
  478. function FileListSortCompare(AItem1, AItem2: Pointer): Integer;
  479. begin
  480. Result := TFileIndexItem(AItem1).IndexNr - TFileIndexItem(AItem2).IndexNr;
  481. end;
  482. {****************************************************************************
  483. TDirIndexItem
  484. ****************************************************************************}
  485. constructor TDirIndexItem.Create(AList:TFPHashObjectList;const AName: String; AIndex: Integer);
  486. begin
  487. inherited Create(AList,AName);
  488. FFiles := TFPHashObjectList.Create;
  489. IndexNr := AIndex;
  490. end;
  491. destructor TDirIndexItem.Destroy;
  492. begin
  493. FFiles.Free;
  494. inherited Destroy;
  495. end;
  496. {****************************************************************************
  497. TFileIndexItem
  498. ****************************************************************************}
  499. constructor TFileIndexItem.Create(AList:TFPHashObjectList;const AName: String; ADirIndex, AIndex: Integer);
  500. begin
  501. inherited Create(AList,Aname);
  502. FDirIndex := ADirIndex;
  503. IndexNr := AIndex;
  504. end;
  505. {****************************************************************************
  506. TDebugInfoDwarf
  507. ****************************************************************************}
  508. function TDebugInfoDwarf.def_dwarf_lab(def:tdef) : tasmsymbol;
  509. begin
  510. { Keep track of used dwarf entries, this info is only usefull for dwarf entries
  511. referenced by the symbols. Definitions will always include all
  512. required stabs }
  513. if def.dbg_state=dbg_state_unused then
  514. def.dbg_state:=dbg_state_used;
  515. { Need a new label? }
  516. if not assigned(def.dwarf_lab) then
  517. begin
  518. if (df_has_dwarf_dbg_info in def.defoptions) then
  519. begin
  520. if not assigned(def.typesym) then
  521. internalerror(200610011);
  522. def.dwarf_lab:=current_asmdata.RefAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym)));
  523. def.dbg_state:=dbg_state_written;
  524. end
  525. else
  526. begin
  527. { Create an exported DBG symbol if we are generating a def defined in the
  528. globalsymtable of the current unit }
  529. if assigned(def.typesym) and
  530. (def.owner.symtabletype=globalsymtable) and
  531. (def.owner.iscurrentunit) then
  532. begin
  533. def.dwarf_lab:=current_asmdata.DefineAsmSymbol(make_mangledname('DBG',def.owner,symname(def.typesym)),AB_GLOBAL,AT_DATA);
  534. include(def.defoptions,df_has_dwarf_dbg_info);
  535. end
  536. else
  537. { The pointer typecast is needed to prevent a problem with range checking
  538. on when the typecast is changed to 'as' }
  539. current_asmdata.getdatalabel(TAsmLabel(pointer(def.dwarf_lab)));
  540. if def.dbg_state=dbg_state_used then
  541. deftowritelist.Add(def);
  542. end;
  543. defnumberlist.Add(def);
  544. end;
  545. result:=def.dwarf_lab;
  546. end;
  547. constructor TDebugInfoDwarf.Create;
  548. begin
  549. inherited Create;
  550. isdwarf64 := target_cpu in [cpu_iA64,cpu_x86_64,cpu_powerpc64];
  551. dirlist := TFPHashObjectList.Create;
  552. { add current dir as first item (index=0) }
  553. TDirIndexItem.Create(dirlist,'.', 0);
  554. asmline := TAsmList.create;
  555. loclist := tdynamicarray.Create(4096);
  556. end;
  557. destructor TDebugInfoDwarf.Destroy;
  558. begin
  559. dirlist.Free;
  560. dirlist := nil;
  561. loclist.Free;
  562. loclist := nil;
  563. inherited Destroy;
  564. end;
  565. procedure TDebugInfoDwarf.enum_membersyms_callback(p: Tnamedindexitem; arg: pointer);
  566. begin
  567. case tsym(p).typ of
  568. fieldvarsym:
  569. appendsym_fieldvar(tfieldvarsym(p));
  570. propertysym:
  571. appendsym_property(tpropertysym(p));
  572. procsym:
  573. appendsym_proc(tprocsym(p));
  574. end;
  575. end;
  576. function TDebugInfoDwarf.get_file_index(afile: tinputfile): Integer;
  577. var
  578. dirname: String;
  579. diritem: TDirIndexItem;
  580. diridx: Integer;
  581. fileitem: TFileIndexItem;
  582. begin
  583. if afile.path^ = '' then
  584. dirname := '.'
  585. else
  586. dirname := afile.path^;
  587. diritem := TDirIndexItem(dirlist.Find(dirname));
  588. if diritem = nil then
  589. diritem := TDirIndexItem.Create(dirlist,dirname, dirlist.Count);
  590. diridx := diritem.IndexNr;
  591. fileitem := TFileIndexItem(diritem.files.Find(afile.name^));
  592. if fileitem = nil then
  593. begin
  594. Inc(filesequence);
  595. fileitem := TFileIndexItem.Create(diritem.files,afile.name^, diridx, filesequence);
  596. end;
  597. Result := fileitem.IndexNr;
  598. end;
  599. { writing the data through a few simply procedures allows to create easily extra information
  600. for debugging of debug info }
  601. procedure TDebugInfoDwarf.append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const);
  602. var
  603. i : longint;
  604. begin
  605. { todo: store defined abbrevs, so you have to define tehm only once (for this unit) (MWE) }
  606. inc(currabbrevnumber);
  607. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_comment.Create(strpnew('Abbrev '+tostr(currabbrevnumber))));
  608. { abbrev number }
  609. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(currabbrevnumber));
  610. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(currabbrevnumber));
  611. { tag }
  612. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(tag)));
  613. { children? }
  614. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(ord(has_children)));
  615. i:=0;
  616. while i<=high(data) do
  617. begin
  618. { attribute }
  619. if data[i].VType=vtInteger then
  620. begin
  621. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(data[i].VInteger));
  622. end
  623. else
  624. internalerror(200601261);
  625. inc(i);
  626. { form }
  627. if data[i].VType=vtInteger then
  628. begin
  629. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(data[i].VInteger));
  630. end
  631. else
  632. internalerror(200601262);
  633. inc(i);
  634. { info itself }
  635. case tdwarf_form(data[i-1].VInteger) of
  636. DW_FORM_string:
  637. case data[i].VType of
  638. vtChar:
  639. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(data[i].VChar));
  640. vtString:
  641. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(data[i].VString^));
  642. vtAnsistring:
  643. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(Ansistring(data[i].VAnsiString)));
  644. else
  645. internalerror(200601264);
  646. end;
  647. DW_FORM_flag:
  648. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(byte(data[i].VBoolean)));
  649. DW_FORM_data1:
  650. case data[i].VType of
  651. vtInteger:
  652. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
  653. vtInt64:
  654. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInt64^));
  655. vtQWord:
  656. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(data[i].VQWord^));
  657. else
  658. internalerror(200602143);
  659. end;
  660. DW_FORM_data2:
  661. case data[i].VType of
  662. vtInteger:
  663. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit(data[i].VInteger));
  664. vtInt64:
  665. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit(data[i].VInt64^));
  666. vtQWord:
  667. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit(data[i].VQWord^));
  668. else
  669. internalerror(200602144);
  670. end;
  671. DW_FORM_data4:
  672. case data[i].VType of
  673. vtInteger:
  674. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(data[i].VInteger));
  675. vtInt64:
  676. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(data[i].VInt64^));
  677. vtQWord:
  678. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(data[i].VQWord^));
  679. else
  680. internalerror(200602145);
  681. end;
  682. DW_FORM_data8:
  683. case data[i].VType of
  684. vtInteger:
  685. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(data[i].VInteger));
  686. vtInt64:
  687. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(data[i].VInt64^));
  688. vtQWord:
  689. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(data[i].VQWord^));
  690. else
  691. internalerror(200602146);
  692. end;
  693. DW_FORM_sdata:
  694. case data[i].VType of
  695. vtInteger:
  696. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(data[i].VInteger));
  697. vtInt64:
  698. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(data[i].VInt64^));
  699. vtQWord:
  700. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(data[i].VQWord^));
  701. else
  702. internalerror(200601285);
  703. end;
  704. DW_FORM_udata:
  705. case data[i].VType of
  706. vtInteger:
  707. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(data[i].VInteger));
  708. vtInt64:
  709. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(data[i].VInt64^));
  710. vtQWord:
  711. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(data[i].VQWord^));
  712. else
  713. internalerror(200601284);
  714. end;
  715. { block gets only the size, the rest is appended manually by the caller }
  716. DW_FORM_block1:
  717. case data[i].VType of
  718. vtInteger:
  719. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
  720. vtInt64:
  721. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInt64^));
  722. vtQWord:
  723. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(data[i].VQWord^));
  724. else
  725. internalerror(200602141);
  726. end;
  727. else
  728. internalerror(200601263);
  729. end;
  730. inc(i);
  731. end;
  732. end;
  733. procedure TDebugInfoDwarf.append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
  734. begin
  735. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  736. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_addr)));
  737. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sym(sym));
  738. end;
  739. procedure TDebugInfoDwarf.append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
  740. begin
  741. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  742. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_ref_addr)));
  743. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sym(sym));
  744. end;
  745. procedure TDebugInfoDwarf.append_labelentry_data(attr : tdwarf_attribute;sym : tasmsymbol);
  746. begin
  747. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  748. if isdwarf64 then
  749. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)))
  750. else
  751. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  752. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sym(sym));
  753. end;
  754. procedure TDebugInfoDwarf.finish_entry;
  755. begin
  756. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  757. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  758. end;
  759. procedure TDebugInfoDwarf.finish_children;
  760. begin
  761. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  762. end;
  763. procedure TDebugInfoDwarf.appenddef_ord(def:torddef);
  764. begin
  765. case def.typ of
  766. s8bit,
  767. s16bit,
  768. s32bit :
  769. begin
  770. { we should generate a subrange type here }
  771. if assigned(def.typesym) then
  772. append_entry(DW_TAG_base_type,false,[
  773. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  774. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  775. DW_AT_byte_size,DW_FORM_data1,def.size
  776. ])
  777. else
  778. append_entry(DW_TAG_base_type,false,[
  779. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  780. DW_AT_byte_size,DW_FORM_data1,def.size
  781. ]);
  782. finish_entry;
  783. end;
  784. u8bit,
  785. u16bit,
  786. u32bit :
  787. begin
  788. { we should generate a subrange type here }
  789. if assigned(def.typesym) then
  790. append_entry(DW_TAG_base_type,false,[
  791. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  792. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  793. DW_AT_byte_size,DW_FORM_data1,def.size
  794. ])
  795. else
  796. append_entry(DW_TAG_base_type,false,[
  797. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  798. DW_AT_byte_size,DW_FORM_data1,def.size
  799. ]);
  800. finish_entry;
  801. end;
  802. uvoid :
  803. begin
  804. { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
  805. replace it with a unsigned type with size 0 (FK)
  806. }
  807. append_entry(DW_TAG_base_type,false,[
  808. DW_AT_name,DW_FORM_string,'Void'#0,
  809. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  810. DW_AT_byte_size,DW_FORM_data1,0
  811. ]);
  812. finish_entry;
  813. end;
  814. uchar :
  815. begin
  816. append_entry(DW_TAG_base_type,false,[
  817. DW_AT_name,DW_FORM_string,'Char'#0,
  818. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  819. DW_AT_byte_size,DW_FORM_data1,1
  820. ]);
  821. finish_entry;
  822. end;
  823. uwidechar :
  824. begin
  825. append_entry(DW_TAG_base_type,false,[
  826. DW_AT_name,DW_FORM_string,'WideChar'#0,
  827. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  828. DW_AT_byte_size,DW_FORM_data1,2
  829. ]);
  830. finish_entry;
  831. end;
  832. bool8bit :
  833. begin
  834. append_entry(DW_TAG_base_type,false,[
  835. DW_AT_name,DW_FORM_string,'Boolean'#0,
  836. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  837. DW_AT_byte_size,DW_FORM_data1,1
  838. ]);
  839. finish_entry;
  840. end;
  841. bool16bit :
  842. begin
  843. append_entry(DW_TAG_base_type,false,[
  844. DW_AT_name,DW_FORM_string,'WordBool'#0,
  845. DW_AT_encoding,DW_FORM_data1,DW_ATE_boolean,
  846. DW_AT_byte_size,DW_FORM_data1,2
  847. ]);
  848. finish_entry;
  849. end;
  850. bool32bit :
  851. begin
  852. append_entry(DW_TAG_base_type,false,[
  853. DW_AT_name,DW_FORM_string,'LongBool'#0,
  854. DW_AT_encoding,DW_FORM_data1,DW_ATE_boolean,
  855. DW_AT_byte_size,DW_FORM_data1,4
  856. ]);
  857. finish_entry;
  858. end;
  859. bool64bit :
  860. begin
  861. append_entry(DW_TAG_base_type,false,[
  862. DW_AT_name,DW_FORM_string,'QWordBool'#0,
  863. DW_AT_encoding,DW_FORM_data1,DW_ATE_boolean,
  864. DW_AT_byte_size,DW_FORM_data1,8
  865. ]);
  866. finish_entry;
  867. end;
  868. u64bit :
  869. begin
  870. append_entry(DW_TAG_base_type,false,[
  871. DW_AT_name,DW_FORM_string,'QWord'#0,
  872. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  873. DW_AT_byte_size,DW_FORM_data1,8
  874. ]);
  875. finish_entry;
  876. end;
  877. scurrency :
  878. begin
  879. { we should use DW_ATE_signed_fixed, however it isn't supported yet by GDB (FK) }
  880. append_entry(DW_TAG_base_type,false,[
  881. DW_AT_name,DW_FORM_string,'Currency'#0,
  882. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  883. DW_AT_byte_size,DW_FORM_data1,8
  884. ]);
  885. finish_entry;
  886. end;
  887. s64bit :
  888. begin
  889. append_entry(DW_TAG_base_type,false,[
  890. DW_AT_name,DW_FORM_string,'Int64'#0,
  891. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  892. DW_AT_byte_size,DW_FORM_data1,8
  893. ]);
  894. finish_entry;
  895. end;
  896. else
  897. internalerror(200601287);
  898. end;
  899. end;
  900. procedure TDebugInfoDwarf.appenddef_float(def:tfloatdef);
  901. begin
  902. case def.typ of
  903. s32real,
  904. s64real,
  905. s80real:
  906. if assigned(def.typesym) then
  907. append_entry(DW_TAG_base_type,false,[
  908. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  909. DW_AT_encoding,DW_FORM_data1,DW_ATE_float,
  910. DW_AT_byte_size,DW_FORM_data1,def.size
  911. ])
  912. else
  913. append_entry(DW_TAG_base_type,false,[
  914. DW_AT_encoding,DW_FORM_data1,DW_ATE_float,
  915. DW_AT_byte_size,DW_FORM_data1,def.size
  916. ]);
  917. s64currency:
  918. { we should use DW_ATE_signed_fixed, however it isn't supported yet by GDB (FK) }
  919. if assigned(def.typesym) then
  920. append_entry(DW_TAG_base_type,false,[
  921. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  922. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  923. DW_AT_byte_size,DW_FORM_data1,8
  924. ])
  925. else
  926. append_entry(DW_TAG_base_type,false,[
  927. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  928. DW_AT_byte_size,DW_FORM_data1,8
  929. ]);
  930. s64comp:
  931. if assigned(def.typesym) then
  932. append_entry(DW_TAG_base_type,false,[
  933. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  934. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  935. DW_AT_byte_size,DW_FORM_data1,8
  936. ])
  937. else
  938. append_entry(DW_TAG_base_type,false,[
  939. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  940. DW_AT_byte_size,DW_FORM_data1,8
  941. ]);
  942. else
  943. internalerror(200601289);
  944. end;
  945. finish_entry;
  946. end;
  947. procedure TDebugInfoDwarf.appenddef_formal(def: tformaldef);
  948. begin
  949. { implemented in derived classes }
  950. end;
  951. procedure TDebugInfoDwarf.appenddef_enum(def:tenumdef);
  952. var
  953. hp : tenumsym;
  954. begin
  955. if assigned(def.typesym) then
  956. append_entry(DW_TAG_enumeration_type,true,[
  957. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  958. DW_AT_byte_size,DW_FORM_data1,def.size
  959. ])
  960. else
  961. append_entry(DW_TAG_enumeration_type,true,[
  962. DW_AT_byte_size,DW_FORM_data1,def.size
  963. ]);
  964. if assigned(def.basedef) then
  965. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.basedef));
  966. finish_entry;
  967. { write enum symbols }
  968. hp:=tenumsym(def.firstenum);
  969. while assigned(hp) do
  970. begin
  971. append_entry(DW_TAG_enumerator,false,[
  972. DW_AT_name,DW_FORM_string,symname(hp)+#0,
  973. DW_AT_const_value,DW_FORM_data4,hp.value
  974. ]);
  975. finish_entry;
  976. hp:=tenumsym(hp).nextenum;
  977. end;
  978. finish_children;
  979. end;
  980. procedure TDebugInfoDwarf.appenddef_file(def: tfiledef);
  981. begin
  982. { implemented in derived classes }
  983. end;
  984. procedure TDebugInfoDwarf.appenddef_array(def:tarraydef);
  985. var
  986. size : aint;
  987. elesize : aint;
  988. begin
  989. if is_special_array(def) then
  990. size:=def.elesize
  991. else
  992. size:=def.size;
  993. if not is_packed_array(def) then
  994. elesize := def.elesize*8
  995. else
  996. elesize := def.elepackedbitsize;
  997. if assigned(def.typesym) then
  998. append_entry(DW_TAG_array_type,true,[
  999. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  1000. DW_AT_byte_size,DW_FORM_udata,size,
  1001. DW_AT_stride_size,DW_FORM_udata,elesize
  1002. ])
  1003. else
  1004. append_entry(DW_TAG_array_type,true,[
  1005. DW_AT_byte_size,DW_FORM_udata,size,
  1006. DW_AT_stride_size,DW_FORM_udata,elesize
  1007. ]);
  1008. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.elementdef));
  1009. if is_dynamic_array(def) then
  1010. begin
  1011. { !!! FIXME !!! }
  1012. { gdb's dwarf implementation sucks, so we can't use DW_OP_push_object here (FK)
  1013. { insert location attribute manually }
  1014. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(DW_AT_data_location));
  1015. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(DW_FORM_block1));
  1016. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(1));
  1017. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(DW_OP_push_object));
  1018. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(DW_OP_deref));
  1019. }
  1020. finish_entry;
  1021. { to simplify things, we don't write a multidimensional array here }
  1022. append_entry(DW_TAG_subrange_type,false,[
  1023. DW_AT_lower_bound,DW_FORM_udata,0,
  1024. DW_AT_upper_bound,DW_FORM_udata,0
  1025. ]);
  1026. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.rangedef));
  1027. finish_entry;
  1028. end
  1029. else
  1030. begin
  1031. finish_entry;
  1032. { to simplify things, we don't write a multidimensional array here }
  1033. append_entry(DW_TAG_subrange_type,false,[
  1034. DW_AT_lower_bound,DW_FORM_sdata,def.lowrange,
  1035. DW_AT_upper_bound,DW_FORM_sdata,def.highrange
  1036. ]);
  1037. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.rangedef));
  1038. finish_entry;
  1039. end;
  1040. finish_children;
  1041. end;
  1042. procedure TDebugInfoDwarf.appenddef_record(def:trecorddef);
  1043. begin
  1044. if assigned(def.typesym) then
  1045. append_entry(DW_TAG_structure_type,true,[
  1046. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  1047. DW_AT_byte_size,DW_FORM_udata,def.size
  1048. ])
  1049. else
  1050. append_entry(DW_TAG_structure_type,true,[
  1051. DW_AT_byte_size,DW_FORM_udata,def.size
  1052. ]);
  1053. finish_entry;
  1054. def.symtable.foreach(@enum_membersyms_callback,nil);
  1055. finish_children;
  1056. end;
  1057. procedure TDebugInfoDwarf.appenddef_pointer(def:tpointerdef);
  1058. begin
  1059. append_entry(DW_TAG_pointer_type,false,[]);
  1060. if not(is_voidpointer(def)) then
  1061. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.pointeddef));
  1062. finish_entry;
  1063. end;
  1064. procedure TDebugInfoDwarf.appenddef_string(def:tstringdef);
  1065. var
  1066. slen : aint;
  1067. arr : tasmlabel;
  1068. begin
  1069. case def.string_typ of
  1070. st_shortstring:
  1071. begin
  1072. { fix length of openshortstring }
  1073. slen:=def.len;
  1074. if slen=0 then
  1075. slen:=255;
  1076. { create a structure with two elements }
  1077. current_asmdata.getdatalabel(arr);
  1078. append_entry(DW_TAG_structure_type,true,[
  1079. DW_AT_name,DW_FORM_string,'ShortString'#0,
  1080. DW_AT_byte_size,DW_FORM_data1,2*sizeof(aint)
  1081. ]);
  1082. finish_entry;
  1083. { length entry }
  1084. append_entry(DW_TAG_member,false,[
  1085. DW_AT_name,DW_FORM_string,'Length'#0,
  1086. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(0)
  1087. ]);
  1088. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1089. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(0));
  1090. append_labelentry_ref(DW_AT_type,def_dwarf_lab(u8inttype));
  1091. finish_entry;
  1092. { string data entry }
  1093. append_entry(DW_TAG_member,false,[
  1094. DW_AT_name,DW_FORM_string,'Data'#0,
  1095. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(1)
  1096. ]);
  1097. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1098. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(1));
  1099. append_labelentry_ref(DW_AT_type,arr);
  1100. finish_entry;
  1101. finish_children;
  1102. { now the data array }
  1103. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(arr,0));
  1104. append_entry(DW_TAG_array_type,true,[
  1105. DW_AT_byte_size,DW_FORM_udata,def.size,
  1106. DW_AT_stride_size,DW_FORM_udata,1*8
  1107. ]);
  1108. append_labelentry_ref(DW_AT_type,def_dwarf_lab(cchartype));
  1109. finish_entry;
  1110. append_entry(DW_TAG_subrange_type,false,[
  1111. DW_AT_lower_bound,DW_FORM_udata,0,
  1112. DW_AT_upper_bound,DW_FORM_udata,slen
  1113. ]);
  1114. append_labelentry_ref(DW_AT_type,def_dwarf_lab(u8inttype));
  1115. finish_entry;
  1116. finish_children;
  1117. end;
  1118. st_longstring:
  1119. begin
  1120. {
  1121. charst:=def_stab_number(cchartype);
  1122. bytest:=def_stab_number(u8inttype);
  1123. longst:=def_stab_number(u32inttype);
  1124. result:=def_stabstr_evaluate(def,'s$1length:$2,0,32;dummy:$6,32,8;st:ar$2;1;$3;$4,40,$5;;',
  1125. [tostr(def.len+5),longst,tostr(def.len),charst,tostr(def.len*8),bytest]);
  1126. }
  1127. end;
  1128. st_ansistring:
  1129. begin
  1130. { looks like a pchar }
  1131. append_entry(DW_TAG_pointer_type,false,[]);
  1132. append_labelentry_ref(DW_AT_type,def_dwarf_lab(cchartype));
  1133. finish_entry;
  1134. end;
  1135. st_widestring:
  1136. begin
  1137. { looks like a pwidechar }
  1138. append_entry(DW_TAG_pointer_type,false,[]);
  1139. append_labelentry_ref(DW_AT_type,def_dwarf_lab(cwidechartype));
  1140. finish_entry;
  1141. end;
  1142. end;
  1143. end;
  1144. procedure TDebugInfoDwarf.appenddef_procvar(def:tprocvardef);
  1145. procedure doappend;
  1146. var
  1147. i : longint;
  1148. begin
  1149. if assigned(def.typesym) then
  1150. append_entry(DW_TAG_subroutine_type,true,[
  1151. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  1152. DW_AT_prototyped,DW_FORM_flag,true
  1153. ])
  1154. else
  1155. append_entry(DW_TAG_subroutine_type,true,[
  1156. DW_AT_prototyped,DW_FORM_flag,true
  1157. ]);
  1158. if not(is_void(tprocvardef(def).returndef)) then
  1159. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tprocvardef(def).returndef));
  1160. finish_entry;
  1161. { write parameters }
  1162. for i:=0 to def.paras.count-1 do
  1163. begin
  1164. append_entry(DW_TAG_formal_parameter,false,[
  1165. DW_AT_name,DW_FORM_string,symname(tsym(def.paras[i]))+#0
  1166. ]);
  1167. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tparavarsym(def.paras[i]).vardef));
  1168. finish_entry;
  1169. end;
  1170. finish_children;
  1171. end;
  1172. var
  1173. proc : tasmlabel;
  1174. begin
  1175. if def.is_methodpointer then
  1176. begin
  1177. { create a structure with two elements }
  1178. current_asmdata.getdatalabel(proc);
  1179. append_entry(DW_TAG_structure_type,true,[
  1180. DW_AT_byte_size,DW_FORM_data1,2*sizeof(aint)
  1181. ]);
  1182. finish_entry;
  1183. { proc entry }
  1184. append_entry(DW_TAG_member,false,[
  1185. DW_AT_name,DW_FORM_string,'Proc'#0,
  1186. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(0)
  1187. ]);
  1188. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1189. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(0));
  1190. append_labelentry_ref(DW_AT_type,proc);
  1191. finish_entry;
  1192. { self entry }
  1193. append_entry(DW_TAG_member,false,[
  1194. DW_AT_name,DW_FORM_string,'Self'#0,
  1195. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(sizeof(aint))
  1196. ]);
  1197. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1198. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sizeof(aint)));
  1199. append_labelentry_ref(DW_AT_type,def_dwarf_lab(class_tobject));
  1200. finish_entry;
  1201. finish_children;
  1202. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(proc,0));
  1203. doappend;
  1204. end
  1205. else
  1206. doappend;
  1207. end;
  1208. procedure TDebugInfoDwarf.appenddef(def:tdef);
  1209. var
  1210. labsym : tasmsymbol;
  1211. begin
  1212. if (def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  1213. exit;
  1214. { never write generic template defs }
  1215. if df_generic in def.defoptions then
  1216. begin
  1217. def.dbg_state:=dbg_state_written;
  1218. exit;
  1219. end;
  1220. { to avoid infinite loops }
  1221. def.dbg_state := dbg_state_writing;
  1222. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Definition '+def.typename)));
  1223. labsym:=def_dwarf_lab(def);
  1224. if df_has_dwarf_dbg_info in def.defoptions then
  1225. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create_global(labsym,0))
  1226. else
  1227. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(labsym,0));
  1228. case def.deftype of
  1229. stringdef :
  1230. appenddef_string(tstringdef(def));
  1231. enumdef :
  1232. appenddef_enum(tenumdef(def));
  1233. orddef :
  1234. appenddef_ord(torddef(def));
  1235. pointerdef :
  1236. appenddef_pointer(tpointerdef(def));
  1237. floatdef :
  1238. appenddef_float(tfloatdef(def));
  1239. filedef :
  1240. appenddef_file(tfiledef(def));
  1241. recorddef :
  1242. appenddef_record(trecorddef(def));
  1243. variantdef :
  1244. appenddef_variant(tvariantdef(def));
  1245. classrefdef :
  1246. appenddef_pointer(tpointerdef(pvmttype));
  1247. setdef :
  1248. appenddef_set(tsetdef(def));
  1249. formaldef :
  1250. appenddef_formal(tformaldef(def));
  1251. arraydef :
  1252. appenddef_array(tarraydef(def));
  1253. procvardef :
  1254. appenddef_procvar(tprocvardef(def));
  1255. objectdef :
  1256. appenddef_object(tobjectdef(def));
  1257. undefineddef :
  1258. appenddef_unineddef(tundefineddef(def));
  1259. else
  1260. internalerror(200601281);
  1261. end;
  1262. def.dbg_state := dbg_state_written;
  1263. end;
  1264. procedure TDebugInfoDwarf.insertdef(unused:TAsmList; def:tdef);
  1265. begin
  1266. appenddef(def);
  1267. end;
  1268. procedure TDebugInfoDwarf.write_symtable_defs(unused:TAsmList;st:tsymtable);
  1269. procedure dowritedwarf(st:tsymtable);
  1270. var
  1271. p : tdef;
  1272. begin
  1273. p:=tdef(st.defindex.first);
  1274. while assigned(p) do
  1275. begin
  1276. if (p.dbg_state=dbg_state_used) then
  1277. appenddef(p);
  1278. p:=tdef(p.indexnext);
  1279. end;
  1280. end;
  1281. var
  1282. old_writing_def_dwarf : boolean;
  1283. begin
  1284. case st.symtabletype of
  1285. staticsymtable :
  1286. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Defs - Begin Staticsymtable')));
  1287. globalsymtable :
  1288. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Defs - Begin unit '+st.name^+' has index '+tostr(st.moduleid))));
  1289. end;
  1290. old_writing_def_dwarf:=writing_def_dwarf;
  1291. writing_def_dwarf:=true;
  1292. dowritedwarf(st);
  1293. writing_def_dwarf:=old_writing_def_dwarf;
  1294. case st.symtabletype of
  1295. staticsymtable :
  1296. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Defs - End Staticsymtable')));
  1297. globalsymtable :
  1298. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Defs - End unit '+st.name^+' has index '+tostr(st.moduleid))));
  1299. end;
  1300. end;
  1301. procedure TDebugInfoDwarf.appendprocdef(pd:tprocdef);
  1302. var
  1303. procendlabel : tasmlabel;
  1304. mangled_length : longint;
  1305. p : pchar;
  1306. hs : string;
  1307. begin
  1308. if assigned(pd.procstarttai) then
  1309. begin
  1310. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Procdef '+pd.fullprocname(true))));
  1311. append_entry(DW_TAG_subprogram,true,
  1312. [DW_AT_name,DW_FORM_string,symname(pd.procsym)+#0
  1313. { data continues below }
  1314. { problem: base reg isn't known here
  1315. DW_AT_frame_base,DW_FORM_block1,1
  1316. }
  1317. ]);
  1318. { append block data }
  1319. { current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(dwarf_reg(pd.))); }
  1320. if not(is_void(tprocdef(pd).returndef)) then
  1321. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tprocdef(pd).returndef));
  1322. { mark end of procedure }
  1323. current_asmdata.getlabel(procendlabel,alt_dbgtype);
  1324. current_asmdata.asmlists[al_procedures].insertbefore(tai_label.create(procendlabel),pd.procendtai);
  1325. append_labelentry(DW_AT_low_pc,current_asmdata.RefAsmSymbol(pd.mangledname));
  1326. append_labelentry(DW_AT_high_pc,procendlabel);
  1327. {
  1328. if assigned(pd.funcretsym) and
  1329. (tabstractnormalvarsym(pd.funcretsym).refs>0) then
  1330. begin
  1331. if tabstractnormalvarsym(pd.funcretsym).localloc.loc=LOC_REFERENCE then
  1332. begin
  1333. {$warning Need to add gdb support for ret in param register calling}
  1334. if paramanager.ret_in_param(pd.returndef,pd.proccalloption) then
  1335. hs:='X*'
  1336. else
  1337. hs:='X';
  1338. templist.concat(Tai_stab.create(stab_stabs,strpnew(
  1339. '"'+pd.procsym.name+':'+hs+def_stab_number(pd.returndef)+'",'+
  1340. tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
  1341. if (m_result in current_settings.modeswitches) then
  1342. templist.concat(Tai_stab.create(stab_stabs,strpnew(
  1343. '"RESULT:'+hs+def_stab_number(pd.returndef)+'",'+
  1344. tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
  1345. end;
  1346. end;
  1347. }
  1348. finish_entry;
  1349. {
  1350. { para types }
  1351. write_def_stabstr(templist,pd);
  1352. }
  1353. if assigned(pd.parast) then
  1354. write_symtable_syms(pd.parast);
  1355. { local type defs and vars should not be written
  1356. inside the main proc stab }
  1357. if assigned(pd.localst) and
  1358. (pd.localst.symtabletype=localsymtable) then
  1359. write_symtable_syms(pd.localst);
  1360. { last write the types from this procdef }
  1361. if assigned(pd.parast) then
  1362. write_symtable_defs(nil,pd.parast);
  1363. if assigned(pd.localst) and
  1364. (pd.localst.symtabletype=localsymtable) then
  1365. write_symtable_defs(nil,pd.localst);
  1366. finish_children;
  1367. end;
  1368. end;
  1369. procedure TDebugInfoDwarf.appendsym_var(sym:tabstractnormalvarsym);
  1370. var
  1371. templist : TAsmList;
  1372. blocksize : longint;
  1373. tag : tdwarf_tag;
  1374. dreg : byte;
  1375. begin
  1376. { external symbols can't be resolved at link time, so we
  1377. can't generate stabs for them
  1378. not sure if this applies to dwarf as well (FK)
  1379. }
  1380. if vo_is_external in sym.varoptions then
  1381. exit;
  1382. { There is no space allocated for not referenced locals }
  1383. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  1384. exit;
  1385. templist:=TAsmList.create;
  1386. case sym.localloc.loc of
  1387. LOC_REGISTER,
  1388. LOC_CREGISTER,
  1389. LOC_MMREGISTER,
  1390. LOC_CMMREGISTER,
  1391. LOC_FPUREGISTER,
  1392. LOC_CFPUREGISTER :
  1393. begin
  1394. templist.concat(tai_const.create_8bit(ord(DW_OP_regx)));
  1395. dreg:=dwarf_reg(sym.localloc.register);
  1396. templist.concat(tai_const.create_uleb128bit(dreg));
  1397. blocksize:=1+Lengthuleb128(dreg);
  1398. end;
  1399. else
  1400. begin
  1401. case sym.typ of
  1402. globalvarsym:
  1403. begin
  1404. if (vo_is_thread_var in sym.varoptions) then
  1405. begin
  1406. {$warning !!! FIXME: dwarf for thread vars !!!}
  1407. blocksize:=0;
  1408. end
  1409. else
  1410. begin
  1411. templist.concat(tai_const.create_8bit(3));
  1412. templist.concat(tai_const.createname(sym.mangledname,0));
  1413. blocksize:=1+sizeof(aword);
  1414. end;
  1415. end;
  1416. paravarsym,
  1417. localvarsym:
  1418. begin
  1419. dreg:=dwarf_reg(sym.localloc.reference.base);
  1420. templist.concat(tai_const.create_8bit(ord(DW_OP_breg0)+dreg));
  1421. templist.concat(tai_const.create_sleb128bit(sym.localloc.reference.offset));
  1422. blocksize:=1+Lengthsleb128(sym.localloc.reference.offset);
  1423. end
  1424. else
  1425. internalerror(200601288);
  1426. end;
  1427. end;
  1428. end;
  1429. if sym.typ=paravarsym then
  1430. tag:=DW_TAG_formal_parameter
  1431. else
  1432. tag:=DW_TAG_variable;
  1433. append_entry(tag,false,[
  1434. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  1435. {
  1436. DW_AT_decl_file,DW_FORM_data1,0,
  1437. DW_AT_decl_line,DW_FORM_data1,
  1438. }
  1439. DW_AT_external,DW_FORM_flag,true,
  1440. { data continues below }
  1441. DW_AT_location,DW_FORM_block1,blocksize
  1442. ]);
  1443. { append block data }
  1444. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  1445. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  1446. templist.free;
  1447. finish_entry;
  1448. end;
  1449. procedure TDebugInfoDwarf.appendsym_fieldvar(sym: tfieldvarsym);
  1450. begin
  1451. if sp_static in sym.symoptions then Exit;
  1452. append_entry(DW_TAG_member,false,[
  1453. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  1454. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(sym.fieldoffset)
  1455. ]);
  1456. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  1457. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(sym.fieldoffset));
  1458. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  1459. finish_entry;
  1460. end;
  1461. procedure TDebugInfoDwarf.appendsym_const(sym:tconstsym);
  1462. begin
  1463. append_entry(DW_TAG_constant,false,[
  1464. DW_AT_name,DW_FORM_string,symname(sym)+#0
  1465. ]);
  1466. { for string constants, constdef isn't set because they have no real type }
  1467. if not(sym.consttyp in [conststring,constresourcestring]) then
  1468. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.constdef));
  1469. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_AT_const_value)));
  1470. case sym.consttyp of
  1471. conststring:
  1472. begin
  1473. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_string)));
  1474. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(strpas(pchar(sym.value.valueptr))));
  1475. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  1476. end;
  1477. constset,
  1478. constwstring,
  1479. constguid,
  1480. constresourcestring:
  1481. begin
  1482. { write dummy for now }
  1483. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_string)));
  1484. current_asmdata.asmlists[al_dwarf_info].concat(tai_string.create(''));
  1485. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  1486. end;
  1487. constord:
  1488. begin
  1489. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_sdata)));
  1490. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_sleb128bit(sym.value.valueord));
  1491. end;
  1492. constnil:
  1493. begin
  1494. if isdwarf64 then
  1495. begin
  1496. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  1497. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(0));
  1498. end
  1499. else
  1500. begin
  1501. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  1502. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(0));
  1503. end;
  1504. end;
  1505. constpointer:
  1506. begin
  1507. if isdwarf64 then
  1508. begin
  1509. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  1510. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_64bit(sym.value.valueordptr));
  1511. end
  1512. else
  1513. begin
  1514. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  1515. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_32bit(sym.value.valueordptr));
  1516. end;
  1517. end;
  1518. constreal:
  1519. begin
  1520. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_block1)));
  1521. case tfloatdef(sym.constdef).typ of
  1522. s32real:
  1523. begin
  1524. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(4));
  1525. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_32bit.create(psingle(sym.value.valueptr)^));
  1526. end;
  1527. s64comp,
  1528. s64currency,
  1529. s64real:
  1530. begin
  1531. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(8));
  1532. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_64bit.create(pdouble(sym.value.valueptr)^));
  1533. end;
  1534. s80real:
  1535. begin
  1536. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(10));
  1537. current_asmdata.asmlists[al_dwarf_info].concat(tai_real_80bit.create(pextended(sym.value.valueptr)^));
  1538. end;
  1539. else
  1540. internalerror(200601291);
  1541. end;
  1542. end;
  1543. else
  1544. internalerror(200601292);
  1545. end;
  1546. finish_entry;
  1547. end;
  1548. procedure TDebugInfoDwarf.appendsym_typedconst(sym: ttypedconstsym);
  1549. begin
  1550. append_entry(DW_TAG_variable,false,[
  1551. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  1552. {
  1553. DW_AT_decl_file,DW_FORM_data1,0,
  1554. DW_AT_decl_line,DW_FORM_data1,
  1555. }
  1556. DW_AT_external,DW_FORM_flag,true,
  1557. { data continues below }
  1558. DW_AT_location,DW_FORM_block1,1+sizeof(aword)
  1559. ]);
  1560. { append block data }
  1561. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(3));
  1562. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.createname(sym.mangledname,0));
  1563. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.typedconstdef));
  1564. finish_entry;
  1565. end;
  1566. procedure TDebugInfoDwarf.appendsym_label(sym: tlabelsym);
  1567. begin
  1568. { ignore label syms for now, the problem is that a label sym
  1569. can have more than one label associated e.g. in case of
  1570. an inline procedure expansion }
  1571. end;
  1572. procedure TDebugInfoDwarf.appendsym_proc(sym:tprocsym);
  1573. var
  1574. i : longint;
  1575. begin
  1576. for i:=1 to sym.procdef_count do
  1577. appendprocdef(sym.procdef[i]);
  1578. end;
  1579. procedure TDebugInfoDwarf.appendsym_property(sym: tpropertysym);
  1580. begin
  1581. { ignored for now }
  1582. end;
  1583. procedure TDebugInfoDwarf.appendsym_type(sym: ttypesym);
  1584. begin
  1585. append_entry(DW_TAG_typedef,false,[
  1586. DW_AT_name,DW_FORM_string,symname(sym)+#0
  1587. ]);
  1588. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.typedef));
  1589. finish_entry;
  1590. { Moved fom append sym, do we need this (MWE)
  1591. { For object types write also the symtable entries }
  1592. if (sym.typ=typesym) and (ttypesym(sym).typedef.deftype=objectdef) then
  1593. write_symtable_syms(list,tobjectdef(ttypesym(sym).typedef).symtable);
  1594. }
  1595. end;
  1596. procedure TDebugInfoDwarf.appendsym_unit(sym: tunitsym);
  1597. begin
  1598. { for now, we ignore unit symbols }
  1599. end;
  1600. procedure TDebugInfoDwarf.appendsym_absolute(sym:tabsolutevarsym);
  1601. var
  1602. templist : TAsmList;
  1603. blocksize : longint;
  1604. symlist : ppropaccesslistitem;
  1605. begin
  1606. templist:=TAsmList.create;
  1607. case tabsolutevarsym(sym).abstyp of
  1608. toaddr :
  1609. begin
  1610. { MWE: replaced ifdef i368 }
  1611. {
  1612. if target_cpu = cpu_i386 then
  1613. begin
  1614. { in theory, we could write a DW_AT_segment entry here for sym.absseg,
  1615. however I doubt that gdb supports this (FK) }
  1616. end;
  1617. }
  1618. templist.concat(tai_const.create_8bit(3));
  1619. templist.concat(tai_const.create_aint(sym.addroffset));
  1620. blocksize:=1+sizeof(aword);
  1621. end;
  1622. toasm :
  1623. begin
  1624. templist.concat(tai_const.create_8bit(3));
  1625. templist.concat(tai_const.createname(sym.mangledname,0));
  1626. blocksize:=1+sizeof(aword);
  1627. end;
  1628. tovar:
  1629. begin
  1630. symlist:=tabsolutevarsym(sym).ref.firstsym;
  1631. { can we insert the symbol? }
  1632. if assigned(symlist) and
  1633. (symlist^.sltype=sl_load) then
  1634. appendsym(symlist^.sym);
  1635. templist.free;
  1636. exit;
  1637. end;
  1638. end;
  1639. append_entry(DW_TAG_variable,false,[
  1640. DW_AT_name,DW_FORM_string,symname(sym)+#0,
  1641. {
  1642. DW_AT_decl_file,DW_FORM_data1,0,
  1643. DW_AT_decl_line,DW_FORM_data1,
  1644. }
  1645. DW_AT_external,DW_FORM_flag,true,
  1646. { data continues below }
  1647. DW_AT_location,DW_FORM_block1,blocksize
  1648. ]);
  1649. { append block data }
  1650. current_asmdata.asmlists[al_dwarf_info].concatlist(templist);
  1651. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vardef));
  1652. templist.free;
  1653. finish_entry;
  1654. end;
  1655. procedure TDebugInfoDwarf.appendsym(sym:tsym);
  1656. begin
  1657. if sym.isdbgwritten then
  1658. exit;
  1659. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Symbol '+symname(sym))));
  1660. case sym.typ of
  1661. globalvarsym :
  1662. appendsym_var(tglobalvarsym(sym));
  1663. unitsym:
  1664. appendsym_unit(tunitsym(sym));
  1665. procsym :
  1666. appendsym_proc(tprocsym(sym));
  1667. labelsym :
  1668. appendsym_label(tlabelsym(sym));
  1669. localvarsym :
  1670. appendsym_var(tlocalvarsym(sym));
  1671. paravarsym :
  1672. appendsym_var(tparavarsym(sym));
  1673. typedconstsym :
  1674. appendsym_typedconst(ttypedconstsym(sym));
  1675. constsym :
  1676. appendsym_const(tconstsym(sym));
  1677. typesym :
  1678. appendsym_type(ttypesym(sym));
  1679. enumsym :
  1680. { ignore enum syms, they are written by the owner }
  1681. ;
  1682. rttisym :
  1683. { ignore rtti syms, they are only of internal use }
  1684. ;
  1685. syssym :
  1686. { ignore sys syms, they are only of internal use }
  1687. ;
  1688. absolutevarsym :
  1689. appendsym_absolute(tabsolutevarsym(sym));
  1690. propertysym :
  1691. appendsym_property(tpropertysym(sym));
  1692. else
  1693. begin
  1694. writeln(ord(sym.typ));
  1695. internalerror(200601242);
  1696. end;
  1697. end;
  1698. sym.isdbgwritten:=true;
  1699. end;
  1700. procedure TDebugInfoDwarf.write_symtable_syms(st:tsymtable);
  1701. var
  1702. p : tsym;
  1703. old_writing_def_dwarf : boolean;
  1704. begin
  1705. old_writing_def_dwarf:=writing_def_dwarf;
  1706. writing_def_dwarf:=false;
  1707. p:=tsym(st.symindex.first);
  1708. while assigned(p) do
  1709. begin
  1710. if (not p.isdbgwritten) then
  1711. appendsym(p);
  1712. p:=tsym(p.indexnext);
  1713. end;
  1714. writing_def_dwarf:=old_writing_def_dwarf;
  1715. end;
  1716. procedure TDebugInfoDwarf.insertmoduleinfo;
  1717. var
  1718. templist: TAsmList;
  1719. linelist: TAsmList;
  1720. lbl : tasmlabel;
  1721. n,m : Integer;
  1722. ditem : TDirIndexItem;
  1723. fitem : TFileIndexItem;
  1724. flist : TFPList;
  1725. begin
  1726. { insert .Ltext0 label }
  1727. templist:=TAsmList.create;
  1728. new_section(templist,sec_code,'',0);
  1729. templist.concat(tai_symbol.createname('.Ltext0',AT_DATA,0));
  1730. current_asmdata.asmlists[al_start].insertlist(templist);
  1731. templist.free;
  1732. { insert .Letext0 label }
  1733. templist:=TAsmList.create;
  1734. new_section(templist,sec_code,'',0);
  1735. templist.concat(tai_symbol.createname('.Letext0',AT_DATA,0));
  1736. current_asmdata.asmlists[al_end].insertlist(templist);
  1737. templist.free;
  1738. { insert .Ldebug_abbrev0 label }
  1739. templist:=TAsmList.create;
  1740. new_section(templist,sec_debug_abbrev,'',0);
  1741. templist.concat(tai_symbol.createname('.Ldebug_abbrev0',AT_DATA,0));
  1742. current_asmdata.asmlists[al_start].insertlist(templist);
  1743. templist.free;
  1744. { insert .Ldebug_line0 label }
  1745. templist:=TAsmList.create;
  1746. new_section(templist,sec_debug_line,'',0);
  1747. templist.concat(tai_symbol.createname('.Ldebug_line0',AT_DATA,0));
  1748. current_asmdata.asmlists[al_start].insertlist(templist);
  1749. templist.free;
  1750. { debug line header }
  1751. linelist := current_asmdata.asmlists[al_dwarf_line];
  1752. new_section(linelist,sec_debug_line,'',0);
  1753. linelist.concat(tai_comment.Create(strpnew('=== header start ===')));
  1754. { size }
  1755. current_asmdata.getlabel(lbl,alt_dbgfile);
  1756. { currently we create only 32 bit dwarf }
  1757. linelist.concat(tai_const.create_rel_sym(aitconst_32bit,
  1758. lbl,current_asmdata.RefAsmSymbol('.Ledebug_line0')));
  1759. linelist.concat(tai_label.create(lbl));
  1760. { version }
  1761. linelist.concat(tai_const.create_16bit(dwarf_version));
  1762. { header length }
  1763. current_asmdata.getlabel(lbl,alt_dbgfile);
  1764. { currently we create only 32 bit dwarf }
  1765. linelist.concat(tai_const.create_rel_sym(aitconst_32bit,
  1766. lbl,current_asmdata.RefAsmSymbol('.Lehdebug_line0')));
  1767. linelist.concat(tai_label.create(lbl));
  1768. { minimum_instruction_length }
  1769. linelist.concat(tai_const.create_8bit(1));
  1770. { default_is_stmt }
  1771. linelist.concat(tai_const.create_8bit(1));
  1772. { line_base }
  1773. linelist.concat(tai_const.create_8bit(LINE_BASE));
  1774. { line_range }
  1775. { only line increase, no adress }
  1776. linelist.concat(tai_const.create_8bit(255));
  1777. { opcode_base }
  1778. linelist.concat(tai_const.create_8bit(OPCODE_BASE));
  1779. { standard_opcode_lengths }
  1780. { MWE: sigh... why adding the default lengths (and make those sizes sense with LEB encoding) }
  1781. { DW_LNS_copy }
  1782. linelist.concat(tai_const.create_8bit(0));
  1783. { DW_LNS_advance_pc }
  1784. linelist.concat(tai_const.create_8bit(1));
  1785. { DW_LNS_advance_line }
  1786. linelist.concat(tai_const.create_8bit(1));
  1787. { DW_LNS_set_file }
  1788. linelist.concat(tai_const.create_8bit(1));
  1789. { DW_LNS_set_column }
  1790. linelist.concat(tai_const.create_8bit(1));
  1791. { DW_LNS_negate_stmt }
  1792. linelist.concat(tai_const.create_8bit(0));
  1793. { DW_LNS_set_basic_block }
  1794. linelist.concat(tai_const.create_8bit(0));
  1795. { DW_LNS_const_add_pc }
  1796. linelist.concat(tai_const.create_8bit(0));
  1797. { DW_LNS_fixed_advance_pc }
  1798. linelist.concat(tai_const.create_8bit(1));
  1799. { DW_LNS_set_prologue_end }
  1800. linelist.concat(tai_const.create_8bit(0));
  1801. { DW_LNS_set_epilogue_begin }
  1802. linelist.concat(tai_const.create_8bit(0));
  1803. { DW_LNS_set_isa }
  1804. linelist.concat(tai_const.create_8bit(1));
  1805. { Create single list of filenames sorted in IndexNr }
  1806. flist:=TFPList.Create;
  1807. for n := 0 to dirlist.Count - 1 do
  1808. begin
  1809. ditem := TDirIndexItem(dirlist[n]);
  1810. for m := 0 to ditem.Files.Count - 1 do
  1811. flist.Add(ditem.Files[m]);
  1812. end;
  1813. flist.Sort(@FileListSortCompare);
  1814. { include_directories }
  1815. linelist.concat(tai_comment.Create(strpnew('include_directories')));
  1816. for n := 0 to dirlist.Count - 1 do
  1817. begin
  1818. ditem := TDirIndexItem(dirlist[n]);
  1819. if ditem.Name = '.' then
  1820. Continue;
  1821. linelist.concat(tai_string.create(ditem.Name+#0));
  1822. end;
  1823. linelist.concat(tai_const.create_8bit(0));
  1824. { file_names }
  1825. linelist.concat(tai_comment.Create(strpnew('file_names')));
  1826. for n := 0 to flist.Count - 1 do
  1827. begin
  1828. fitem := TFileIndexItem(flist[n]);
  1829. { file name }
  1830. linelist.concat(tai_string.create(fitem.Name+#0));
  1831. { directory index }
  1832. linelist.concat(tai_const.create_uleb128bit(fitem.DirIndex));
  1833. { last modification }
  1834. linelist.concat(tai_const.create_uleb128bit(0));
  1835. { file length }
  1836. linelist.concat(tai_const.create_uleb128bit(0));
  1837. end;
  1838. linelist.concat(tai_const.create_8bit(0));
  1839. { end of debug line header }
  1840. linelist.concat(tai_symbol.createname('.Lehdebug_line0',AT_DATA,0));
  1841. linelist.concat(tai_comment.Create(strpnew('=== header end ===')));
  1842. { add line program }
  1843. linelist.concatList(asmline);
  1844. { end of debug line table }
  1845. linelist.concat(tai_symbol.createname('.Ledebug_line0',AT_DATA,0));
  1846. end;
  1847. procedure TDebugInfoDwarf.inserttypeinfo;
  1848. procedure write_defs_to_write;
  1849. var
  1850. n : integer;
  1851. looplist,
  1852. templist: TFPObjectList;
  1853. def : tdef;
  1854. begin
  1855. templist := TFPObjectList.Create(False);
  1856. looplist := deftowritelist;
  1857. while looplist.count > 0 do
  1858. begin
  1859. deftowritelist := templist;
  1860. for n := 0 to looplist.count - 1 do
  1861. begin
  1862. def := tdef(looplist[n]);
  1863. case def.dbg_state of
  1864. dbg_state_written:
  1865. continue;
  1866. dbg_state_writing:
  1867. internalerror(200610052);
  1868. dbg_state_unused:
  1869. internalerror(200610053);
  1870. dbg_state_used:
  1871. appenddef(def)
  1872. else
  1873. internalerror(200610054);
  1874. end;
  1875. end;
  1876. looplist.clear;
  1877. templist := looplist;
  1878. looplist := deftowritelist;
  1879. end;
  1880. templist.free;
  1881. end;
  1882. var
  1883. storefilepos : tfileposinfo;
  1884. lenstartlabel : tasmlabel;
  1885. i : longint;
  1886. def: tdef;
  1887. begin
  1888. storefilepos:=current_filepos;
  1889. current_filepos:=current_module.mainfilepos;
  1890. currabbrevnumber:=0;
  1891. writing_def_dwarf:=false;
  1892. { not used (MWE)
  1893. nextdefnumber:=0;
  1894. }
  1895. defnumberlist:=TFPObjectList.create(false);
  1896. deftowritelist:=TFPObjectList.create(false);
  1897. { not exported (FK)
  1898. filerecdef:=getderefdef('FILEREC');
  1899. textrecdef:=getderefdef('TEXTREC');
  1900. }
  1901. vardatadef:=trecorddef(search_system_type('TVARDATA').typedef);
  1902. { write start labels }
  1903. current_asmdata.asmlists[al_dwarf_info].concat(tai_section.create(sec_debug_info,'',0));
  1904. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.createname('.Ldebug_info0',AT_DATA,0));
  1905. { start abbrev section }
  1906. new_section(current_asmdata.asmlists[al_dwarf_abbrev],sec_debug_abbrev,'',0);
  1907. { debug info header }
  1908. current_asmdata.getlabel(lenstartlabel,alt_dbgfile);
  1909. { size }
  1910. { currently we create only 32 bit dwarf }
  1911. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_rel_sym(aitconst_32bit,
  1912. lenstartlabel,current_asmdata.RefAsmSymbol('.Ledebug_info0')));
  1913. current_asmdata.asmlists[al_dwarf_info].concat(tai_label.create(lenstartlabel));
  1914. { version }
  1915. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_16bit(dwarf_version));
  1916. { abbrev table (=relative from section start)}
  1917. if isdwarf64 then
  1918. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_type_sym(aitconst_64bit,
  1919. current_asmdata.RefAsmSymbol('.Ldebug_abbrev0')))
  1920. else
  1921. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_type_sym(aitconst_32bit,
  1922. current_asmdata.RefAsmSymbol('.Ldebug_abbrev0')));
  1923. { address size }
  1924. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(sizeof(aint)));
  1925. append_entry(DW_TAG_compile_unit,true,[
  1926. DW_AT_name,DW_FORM_string,FixFileName(current_module.sourcefiles.get_file(1).name^)+#0,
  1927. DW_AT_producer,DW_FORM_string,'Free Pascal '+full_version_string+' '+date_string+#0,
  1928. DW_AT_comp_dir,DW_FORM_string,BsToSlash(FixPath(current_module.sourcefiles.get_file(1).path^,false))+#0,
  1929. DW_AT_language,DW_FORM_data1,DW_LANG_Pascal83,
  1930. DW_AT_identifier_case,DW_FORM_data1,DW_ID_case_insensitive]);
  1931. { reference to line info section }
  1932. append_labelentry_data(DW_AT_stmt_list,current_asmdata.RefAsmSymbol('.Ldebug_line0'));
  1933. append_labelentry(DW_AT_low_pc,current_asmdata.RefAsmSymbol('.Ltext0'));
  1934. append_labelentry(DW_AT_high_pc,current_asmdata.RefAsmSymbol('.Letext0'));
  1935. finish_entry;
  1936. { first write all global/local symbols. This will flag all required tdefs }
  1937. if assigned(current_module.globalsymtable) then
  1938. begin
  1939. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Syms - Begin unit '+current_module.globalsymtable.name^+' has index '+tostr(current_module.globalsymtable.moduleid))));
  1940. write_symtable_syms(current_module.globalsymtable);
  1941. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Syms - End unit '+current_module.globalsymtable.name^+' has index '+tostr(current_module.globalsymtable.moduleid))));
  1942. end;
  1943. if assigned(current_module.localsymtable) then
  1944. begin
  1945. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Syms - Begin Staticsymtable')));
  1946. write_symtable_syms(current_module.localsymtable);
  1947. current_asmdata.asmlists[al_dwarf_info].concat(tai_comment.Create(strpnew('Syms - End Staticsymtable')));
  1948. end;
  1949. { reset unit type info flag }
  1950. reset_unit_type_info;
  1951. { write used types from the used units }
  1952. write_used_unit_type_info(current_asmdata.asmlists[al_dwarf_info],current_module);
  1953. { last write the types from this unit }
  1954. if assigned(current_module.globalsymtable) then
  1955. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.globalsymtable);
  1956. if assigned(current_module.localsymtable) then
  1957. write_symtable_defs(current_asmdata.asmlists[al_dwarf_info],current_module.localsymtable);
  1958. { write defs not written yet }
  1959. write_defs_to_write;
  1960. { close compilation unit entry }
  1961. finish_children;
  1962. { end of debug info table }
  1963. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(0));
  1964. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.createname('.Ledebug_info0',AT_DATA,0));
  1965. { end of abbrev table }
  1966. current_asmdata.asmlists[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  1967. { reset all def labels }
  1968. for i:=0 to defnumberlist.count-1 do
  1969. begin
  1970. def := tdef(defnumberlist[i]);
  1971. if assigned(def) then
  1972. begin
  1973. def.dwarf_lab:=nil;
  1974. def.dbg_state:=dbg_state_unused;
  1975. end;
  1976. end;
  1977. defnumberlist.free;
  1978. defnumberlist:=nil;
  1979. deftowritelist.free;
  1980. deftowritelist:=nil;
  1981. current_filepos:=storefilepos;
  1982. end;
  1983. procedure TDebugInfoDwarf.referencesections(list:TAsmList);
  1984. begin
  1985. end;
  1986. function TDebugInfoDwarf.symname(sym: tsym): String;
  1987. begin
  1988. result := sym.Name;
  1989. end;
  1990. procedure TDebugInfoDwarf.insertlineinfo(list:TAsmList);
  1991. var
  1992. currfileinfo,
  1993. lastfileinfo : tfileposinfo;
  1994. currfuncname : pshortstring;
  1995. currsectype : TAsmSectiontype;
  1996. hlabel : tasmlabel;
  1997. hp : tai;
  1998. infile : tinputfile;
  1999. current_file : tai_file;
  2000. prevcolumn,
  2001. diffline,
  2002. prevline,
  2003. prevfileidx,
  2004. currfileidx: Integer;
  2005. prevlabel,
  2006. currlabel : tasmlabel;
  2007. begin
  2008. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  2009. currfuncname:=nil;
  2010. currsectype:=sec_code;
  2011. hp:=Tai(list.first);
  2012. prevcolumn := 0;
  2013. prevline := 1;
  2014. prevfileidx := 1;
  2015. prevlabel := nil;
  2016. while assigned(hp) do
  2017. begin
  2018. case hp.typ of
  2019. ait_section :
  2020. currsectype:=tai_section(hp).sectype;
  2021. ait_function_name :
  2022. begin
  2023. currfuncname:=tai_function_name(hp).funcname;
  2024. asmline.concat(tai_comment.Create(strpnew('function: '+currfuncname^)));
  2025. end;
  2026. ait_force_line : begin
  2027. lastfileinfo.line:=-1;
  2028. end;
  2029. end;
  2030. if (currsectype=sec_code) and
  2031. (hp.typ=ait_instruction) then
  2032. begin
  2033. currfileinfo:=tailineinfo(hp).fileinfo;
  2034. { file changed ? (must be before line info) }
  2035. if (currfileinfo.fileindex<>0) and
  2036. (lastfileinfo.fileindex<>currfileinfo.fileindex) then
  2037. begin
  2038. infile:=current_module.sourcefiles.get_file(currfileinfo.fileindex);
  2039. if assigned(infile) then
  2040. begin
  2041. currfileidx := get_file_index(infile);
  2042. if prevfileidx <> currfileidx then
  2043. begin
  2044. list.insertbefore(tai_comment.Create(strpnew('path: '+infile.path^)), hp);
  2045. list.insertbefore(tai_comment.Create(strpnew('file: '+infile.name^)), hp);
  2046. list.insertbefore(tai_comment.Create(strpnew('indx: '+tostr(currfileidx))), hp);
  2047. { set file }
  2048. asmline.concat(tai_comment.Create(strpnew('path: '+infile.path^)));
  2049. asmline.concat(tai_comment.Create(strpnew('file: '+infile.name^)));
  2050. asmline.concat(tai_const.create_8bit(DW_LNS_set_file));
  2051. asmline.concat(tai_const.create_uleb128bit(currfileidx));
  2052. prevfileidx := currfileidx;
  2053. end;
  2054. { force new line info }
  2055. lastfileinfo.line:=-1;
  2056. end;
  2057. end;
  2058. { line changed ? }
  2059. if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
  2060. begin
  2061. { set address }
  2062. current_asmdata.getlabel(currlabel, alt_dbgline);
  2063. list.insertbefore(tai_label.create(currlabel), hp);
  2064. asmline.concat(tai_comment.Create(strpnew('['+tostr(currfileinfo.line)+':'+tostr(currfileinfo.column)+']')));
  2065. if prevlabel = nil then
  2066. begin
  2067. asmline.concat(tai_const.create_8bit(DW_LNS_extended_op));
  2068. if isdwarf64 then
  2069. asmline.concat(tai_const.create_uleb128bit(9)) { 1 + 8 }
  2070. else
  2071. asmline.concat(tai_const.create_uleb128bit(5)); { 1 + 4 }
  2072. asmline.concat(tai_const.create_8bit(DW_LNE_set_address));
  2073. if isdwarf64 then
  2074. asmline.concat(tai_const.create_type_sym(aitconst_64bit, currlabel))
  2075. else
  2076. asmline.concat(tai_const.create_type_sym(aitconst_32bit, currlabel));
  2077. end
  2078. else
  2079. begin
  2080. asmline.concat(tai_const.create_8bit(DW_LNS_advance_pc));
  2081. asmline.concat(tai_const.create_rel_sym(aitconst_uleb128bit, prevlabel, currlabel));
  2082. end;
  2083. prevlabel := currlabel;
  2084. { set column }
  2085. if prevcolumn <> currfileinfo.column then
  2086. begin
  2087. asmline.concat(tai_const.create_8bit(DW_LNS_set_column));
  2088. asmline.concat(tai_const.create_uleb128bit(currfileinfo.column));
  2089. prevcolumn := currfileinfo.column;
  2090. end;
  2091. { set line }
  2092. diffline := currfileinfo.line - prevline;
  2093. if (diffline >= LINE_BASE) and (OPCODE_BASE + diffline - LINE_BASE <= 255) then
  2094. begin
  2095. { use special opcode, this also adds a row }
  2096. asmline.concat(tai_const.create_8bit(OPCODE_BASE + diffline - LINE_BASE));
  2097. end
  2098. else
  2099. begin
  2100. if diffline <> 0 then
  2101. begin
  2102. asmline.concat(tai_const.create_8bit(DW_LNS_advance_line));
  2103. asmline.concat(tai_const.create_sleb128bit(diffline));
  2104. end;
  2105. { no row added yet, do it manually }
  2106. asmline.concat(tai_const.create_8bit(DW_LNS_copy));
  2107. end;
  2108. prevline := currfileinfo.line;
  2109. end;
  2110. lastfileinfo:=currfileinfo;
  2111. end;
  2112. hp:=tai(hp.next);
  2113. end;
  2114. { end sequence }
  2115. asmline.concat(tai_const.Create_8bit(DW_LNS_extended_op));
  2116. asmline.concat(tai_const.Create_8bit(1));
  2117. asmline.concat(tai_const.Create_8bit(DW_LNE_end_sequence));
  2118. asmline.concat(tai_comment.Create(strpnew('###################')));
  2119. end;
  2120. {****************************************************************************
  2121. TDebugInfoDwarf2
  2122. ****************************************************************************}
  2123. procedure TDebugInfoDwarf2.appenddef_file(def: tfiledef);
  2124. begin
  2125. { gdb 6.4 doesn't support files so far so we use some fake recorddef
  2126. file recs. are less than 1k so using data2 is enough }
  2127. if assigned(def.typesym) then
  2128. append_entry(DW_TAG_structure_type,false,[
  2129. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  2130. DW_AT_byte_size,DW_FORM_udata,def.size
  2131. ])
  2132. else
  2133. append_entry(DW_TAG_structure_type,false,[
  2134. DW_AT_byte_size,DW_FORM_udata,def.size
  2135. ]);
  2136. finish_entry;
  2137. end;
  2138. procedure TDebugInfoDwarf2.appenddef_formal(def: tformaldef);
  2139. begin
  2140. { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
  2141. replace it with a unsigned type with size 0 (FK)
  2142. }
  2143. append_entry(DW_TAG_base_type,false,[
  2144. DW_AT_name,DW_FORM_string,'FormalDef'#0,
  2145. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  2146. DW_AT_byte_size,DW_FORM_data1,0
  2147. ]);
  2148. finish_entry;
  2149. end;
  2150. procedure TDebugInfoDwarf2.appenddef_object(def: tobjectdef);
  2151. procedure doappend;
  2152. begin
  2153. if assigned(def.objname) then
  2154. append_entry(DW_TAG_structure_type,true,[
  2155. DW_AT_name,DW_FORM_string,def.objname^+#0,
  2156. DW_AT_byte_size,DW_FORM_udata,def.size
  2157. ])
  2158. else
  2159. append_entry(DW_TAG_structure_type,true,[
  2160. DW_AT_byte_size,DW_FORM_udata,def.size
  2161. ]);
  2162. finish_entry;
  2163. if assigned(def.childof) then
  2164. begin
  2165. append_entry(DW_TAG_inheritance,false,[
  2166. DW_AT_accessibility,DW_FORM_data1,DW_ACCESS_public,
  2167. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(0)
  2168. ]);
  2169. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  2170. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(0));
  2171. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.childof));
  2172. finish_entry;
  2173. end;
  2174. def.symtable.foreach(@enum_membersyms_callback,nil);
  2175. finish_children;
  2176. end;
  2177. var
  2178. obj : tasmlabel;
  2179. begin
  2180. case def.objecttype of
  2181. odt_cppclass,
  2182. odt_object:
  2183. doappend;
  2184. odt_interfacecom,
  2185. odt_interfacecorba,
  2186. odt_dispinterface,
  2187. odt_class:
  2188. begin
  2189. current_asmdata.getdatalabel(obj);
  2190. { implicit pointer }
  2191. append_entry(DW_TAG_pointer_type,false,[]);
  2192. append_labelentry_ref(DW_AT_type,obj);
  2193. finish_entry;
  2194. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(obj,0));
  2195. doappend;
  2196. end;
  2197. else
  2198. internalerror(200602041);
  2199. end;
  2200. end;
  2201. procedure TDebugInfoDwarf2.appenddef_set(def: tsetdef);
  2202. begin
  2203. { at least gdb up to 6.4 doesn't support sets in dwarf, there is a patch available to fix this:
  2204. http://sources.redhat.com/ml/gdb-patches/2005-05/msg00278.html (FK) }
  2205. if assigned(def.typesym) then
  2206. append_entry(DW_TAG_base_type,false,[
  2207. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  2208. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  2209. DW_AT_byte_size,DW_FORM_data2,def.size
  2210. ])
  2211. else
  2212. append_entry(DW_TAG_base_type,false,[
  2213. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  2214. DW_AT_byte_size,DW_FORM_data2,def.size
  2215. ]);
  2216. finish_entry;
  2217. end;
  2218. procedure TDebugInfoDwarf2.appenddef_unineddef(def: tundefineddef);
  2219. begin
  2220. { gdb 6.4 doesn't support DW_TAG_unspecified_type so we
  2221. replace it with a unsigned type with size 0 (FK)
  2222. }
  2223. append_entry(DW_TAG_base_type,false,[
  2224. DW_AT_name,DW_FORM_string,'FormalDef'#0,
  2225. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned,
  2226. DW_AT_byte_size,DW_FORM_data1,0
  2227. ]);
  2228. finish_entry;
  2229. end;
  2230. procedure TDebugInfoDwarf2.appenddef_variant(def: tvariantdef);
  2231. begin
  2232. { variants aren't known to dwarf2 but writting tvardata should be enough }
  2233. appenddef_record(trecorddef(vardatadef));
  2234. end;
  2235. function TDebugInfoDwarf2.dwarf_version: Word;
  2236. begin
  2237. Result:=2;
  2238. end;
  2239. {****************************************************************************
  2240. TDebugInfoDwarf3
  2241. ****************************************************************************}
  2242. procedure TDebugInfoDwarf3.appenddef_file(def: tfiledef);
  2243. begin
  2244. if assigned(def.typesym) then
  2245. append_entry(DW_TAG_file_type,false,[
  2246. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  2247. DW_AT_byte_size,DW_FORM_data2,def.size
  2248. ])
  2249. else
  2250. append_entry(DW_TAG_file_type,false,[
  2251. DW_AT_byte_size,DW_FORM_data2,def.size
  2252. ]);
  2253. if tfiledef(def).filetyp=ft_typed then
  2254. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tfiledef(def).typedfiledef));
  2255. finish_entry;
  2256. end;
  2257. procedure TDebugInfoDwarf3.appenddef_formal(def: tformaldef);
  2258. begin
  2259. append_entry(DW_TAG_unspecified_type,false,[
  2260. ]);
  2261. finish_entry;
  2262. end;
  2263. procedure TDebugInfoDwarf3.appenddef_object(def: tobjectdef);
  2264. procedure dostruct(tag: tdwarf_tag);
  2265. begin
  2266. if assigned(def.objname) then
  2267. append_entry(tag,true,[
  2268. DW_AT_name,DW_FORM_string,def.objrealname^+#0,
  2269. DW_AT_byte_size,DW_FORM_udata,def.size
  2270. ])
  2271. else
  2272. append_entry(DW_TAG_structure_type,true,[
  2273. DW_AT_byte_size,DW_FORM_udata,def.size
  2274. ]);
  2275. finish_entry;
  2276. end;
  2277. procedure doimplicitpointer;
  2278. var
  2279. obj : tasmlabel;
  2280. begin
  2281. current_asmdata.getdatalabel(obj);
  2282. { implicit pointer }
  2283. append_entry(DW_TAG_pointer_type,false,[]);
  2284. append_labelentry_ref(DW_AT_type,obj);
  2285. finish_entry;
  2286. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(obj,0));
  2287. end;
  2288. procedure doparent(isinterface: boolean);
  2289. begin
  2290. if not assigned(def.childof) then
  2291. exit;
  2292. if isinterface then
  2293. begin
  2294. append_entry(DW_TAG_inheritance,false,[]);
  2295. end
  2296. else
  2297. begin
  2298. append_entry(DW_TAG_inheritance,false,[
  2299. DW_AT_accessibility,DW_FORM_data1,DW_ACCESS_public,
  2300. DW_AT_data_member_location,DW_FORM_block1,1+lengthuleb128(0)
  2301. ]);
  2302. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_8bit(ord(DW_OP_plus_uconst)));
  2303. current_asmdata.asmlists[al_dwarf_info].concat(tai_const.create_uleb128bit(0));
  2304. end;
  2305. append_labelentry_ref(DW_AT_type,def_dwarf_lab(def.childof));
  2306. finish_entry;
  2307. end;
  2308. var
  2309. n: integer;
  2310. begin
  2311. case def.objecttype of
  2312. odt_cppclass,
  2313. odt_object:
  2314. begin
  2315. dostruct(DW_TAG_structure_type);
  2316. doparent(false);
  2317. end;
  2318. odt_interfacecom,
  2319. odt_interfacecorba,
  2320. odt_dispinterface:
  2321. begin
  2322. dostruct(DW_TAG_interface_type);
  2323. doparent(true);
  2324. end;
  2325. odt_class:
  2326. begin
  2327. { not sure if the implicit pointer is needed for tag_class (MWE)}
  2328. {
  2329. doimplicitpointer;
  2330. }
  2331. dostruct(DW_TAG_class_type);
  2332. doparent(false);
  2333. end;
  2334. else
  2335. internalerror(200609171);
  2336. end;
  2337. { add implemented interfaces }
  2338. if assigned(def.ImplementedInterfaces) then
  2339. for n := 0 to def.ImplementedInterfaces.count-1 do
  2340. begin
  2341. append_entry(DW_TAG_inheritance,false,[]);
  2342. append_labelentry_ref(DW_AT_type,def_dwarf_lab(TImplementedInterface(def.ImplementedInterfaces[n]).IntfDef));
  2343. finish_entry;
  2344. end;
  2345. { add members }
  2346. def.symtable.foreach(@enum_membersyms_callback,nil);
  2347. finish_children;
  2348. end;
  2349. procedure TDebugInfoDwarf3.appenddef_set(def: tsetdef);
  2350. begin
  2351. if assigned(def.typesym) then
  2352. append_entry(DW_TAG_set_type,false,[
  2353. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0,
  2354. DW_AT_byte_size,DW_FORM_data2,def.size
  2355. ])
  2356. else
  2357. append_entry(DW_TAG_set_type,false,[
  2358. DW_AT_byte_size,DW_FORM_data2,def.size
  2359. ]);
  2360. if assigned(tsetdef(def).elementdef) then
  2361. append_labelentry_ref(DW_AT_type,def_dwarf_lab(tsetdef(def).elementdef));
  2362. finish_entry;
  2363. end;
  2364. procedure TDebugInfoDwarf3.appenddef_unineddef(def: tundefineddef);
  2365. begin
  2366. { ??? can a undefined def have a typename ? }
  2367. if assigned(def.typesym) then
  2368. append_entry(DW_TAG_unspecified_type,false,[
  2369. DW_AT_name,DW_FORM_string,symname(def.typesym)+#0
  2370. ])
  2371. else
  2372. append_entry(DW_TAG_unspecified_type,false,[
  2373. ]);
  2374. finish_entry;
  2375. end;
  2376. procedure TDebugInfoDwarf3.appenddef_variant(def: tvariantdef);
  2377. const
  2378. VARIANTS: array[1..27] of record Value: Word; Name: String end = (
  2379. (value:0; name:''),
  2380. (value:1; name:''),
  2381. (value:2; name:'VSMALLINT'),
  2382. (value:3; name:'VINTEGER'),
  2383. (value:4; name:'VSINGLE'),
  2384. (value:5; name:'VDOUBLE'),
  2385. (value:6; name:'VCURRENCY'),
  2386. (value:7; name:'VDATE'),
  2387. (value:8; name:'VOLESTR'),
  2388. (value:9; name:'VDISPATCH'),
  2389. (value:10; name:'VERROR'),
  2390. (value:11; name:'VBOOLEAN'),
  2391. (value:12; name:''),
  2392. (value:13; name:'VUNKNOWN'),
  2393. (value:14; name:''),
  2394. (value:16; name:'VSHORTINT'),
  2395. (value:17; name:'VBYTE'),
  2396. (value:18; name:'VWORD'),
  2397. (value:19; name:'VLONGWORD'),
  2398. (value:20; name:'VINT64'),
  2399. (value:21; name:'VQWORD'),
  2400. (value:36; name:'VRECORD'),
  2401. (value:$48; name:''),
  2402. (value:$100; name:'VSTRING'),
  2403. (value:$101; name:'VANY'),
  2404. (value:$2000; name:'VARRAY'),
  2405. (value:$4000; name:'VPOINTER')
  2406. );
  2407. var
  2408. fs: tfieldvarsym;
  2409. lbl: tasmlabel;
  2410. idx: integer;
  2411. begin
  2412. { it could be done with DW_TAG_variant for the union part (if that info was available)
  2413. now we do it manually for variants (MWE) }
  2414. { struct }
  2415. append_entry(DW_TAG_structure_type,true,[
  2416. DW_AT_name,DW_FORM_string,'Variant'#0,
  2417. DW_AT_byte_size,DW_FORM_udata,vardatadef.size
  2418. ]);
  2419. finish_entry;
  2420. append_entry(DW_TAG_variant_part,true,[
  2421. ]);
  2422. current_asmdata.getaddrlabel(lbl);
  2423. append_labelentry_ref(DW_AT_discr,lbl);
  2424. finish_entry;
  2425. { discriminant }
  2426. fs := tfieldvarsym(vardatadef.symtable.search('VTYPE'));
  2427. if (fs = nil) or (fs.typ <> fieldvarsym) then
  2428. internalerror(200609271);
  2429. current_asmdata.asmlists[al_dwarf_info].concat(tai_symbol.create(lbl,0));
  2430. appendsym_fieldvar(fs);
  2431. { variants }
  2432. for idx := Low(VARIANTS) to High(VARIANTS) do
  2433. begin
  2434. append_entry(DW_TAG_variant,true,[
  2435. DW_AT_discr_value,DW_FORM_udata,VARIANTS[idx].value
  2436. ]);
  2437. finish_entry;
  2438. if VARIANTS[idx].name <> '' then
  2439. begin
  2440. fs := tfieldvarsym(vardatadef.symtable.search(VARIANTS[idx].name));
  2441. if (fs = nil) or (fs.typ <> fieldvarsym) then
  2442. internalerror(20060927200+idx);
  2443. appendsym_fieldvar(fs);
  2444. end;
  2445. finish_children; { variant }
  2446. end;
  2447. finish_children; { variant part }
  2448. finish_children; { struct }
  2449. end;
  2450. function TDebugInfoDwarf3.dwarf_version: Word;
  2451. begin
  2452. Result:=3;
  2453. end;
  2454. function TDebugInfoDwarf3.symname(sym: tsym): String;
  2455. begin
  2456. Result:=sym.realname;
  2457. end;
  2458. {****************************************************************************
  2459. ****************************************************************************}
  2460. const
  2461. dbg_dwarf2_info : tdbginfo =
  2462. (
  2463. id : dbg_dwarf2;
  2464. idtxt : 'DWARF2';
  2465. );
  2466. dbg_dwarf3_info : tdbginfo =
  2467. (
  2468. id : dbg_dwarf3;
  2469. idtxt : 'DWARF3';
  2470. );
  2471. initialization
  2472. RegisterDebugInfo(dbg_dwarf2_info,TDebugInfoDwarf2);
  2473. RegisterDebugInfo(dbg_dwarf3_info,TDebugInfoDwarf3);
  2474. end.