dbgdwarf.pas 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374
  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. }
  23. unit dbgdwarf;
  24. {$i fpcdefs.inc}
  25. interface
  26. uses
  27. aasmbase,aasmtai,
  28. symbase,symtype,symdef,
  29. DbgBase;
  30. type
  31. { Tag names and codes. }
  32. tdwarf_tag = (DW_TAG_padding := $00,DW_TAG_array_type := $01,
  33. DW_TAG_class_type := $02,DW_TAG_entry_point := $03,
  34. DW_TAG_enumeration_type := $04,DW_TAG_formal_parameter := $05,
  35. DW_TAG_imported_declaration := $08,DW_TAG_label := $0a,
  36. DW_TAG_lexical_block := $0b,DW_TAG_member := $0d,
  37. DW_TAG_pointer_type := $0f,DW_TAG_reference_type := $10,
  38. DW_TAG_compile_unit := $11,DW_TAG_string_type := $12,
  39. DW_TAG_structure_type := $13,DW_TAG_subroutine_type := $15,
  40. DW_TAG_typedef := $16,DW_TAG_union_type := $17,
  41. DW_TAG_unspecified_parameters := $18,
  42. DW_TAG_variant := $19,DW_TAG_common_block := $1a,
  43. DW_TAG_common_inclusion := $1b,DW_TAG_inheritance := $1c,
  44. DW_TAG_inlined_subroutine := $1d,DW_TAG_module := $1e,
  45. DW_TAG_ptr_to_member_type := $1f,DW_TAG_set_type := $20,
  46. DW_TAG_subrange_type := $21,DW_TAG_with_stmt := $22,
  47. DW_TAG_access_declaration := $23,DW_TAG_base_type := $24,
  48. DW_TAG_catch_block := $25,DW_TAG_const_type := $26,
  49. DW_TAG_constant := $27,DW_TAG_enumerator := $28,
  50. DW_TAG_file_type := $29,DW_TAG_friend := $2a,
  51. DW_TAG_namelist := $2b,DW_TAG_namelist_item := $2c,
  52. DW_TAG_packed_type := $2d,DW_TAG_subprogram := $2e,
  53. DW_TAG_template_type_param := $2f,DW_TAG_template_value_param := $30,
  54. DW_TAG_thrown_type := $31,DW_TAG_try_block := $32,
  55. DW_TAG_variant_part := $33,DW_TAG_variable := $34,
  56. DW_TAG_volatile_type := $35,
  57. { DWARF 3. }
  58. DW_TAG_dwarf_procedure := $36,
  59. DW_TAG_restrict_type := $37,DW_TAG_interface_type := $38,
  60. DW_TAG_namespace := $39,DW_TAG_imported_module := $3a,
  61. DW_TAG_unspecified_type := $3b,DW_TAG_partial_unit := $3c,
  62. DW_TAG_imported_unit := $3d,
  63. { SGI/MIPS Extensions. }
  64. DW_TAG_MIPS_loop := $4081,
  65. { HP extensions. See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . }
  66. DW_TAG_HP_array_descriptor := $4090,
  67. { GNU extensions. }
  68. { For FORTRAN 77 and Fortran 90. }
  69. DW_TAG_format_label := $4101,
  70. { For C++. }
  71. DW_TAG_function_template := $4102,DW_TAG_class_template := $4103,
  72. DW_TAG_GNU_BINCL := $4104,DW_TAG_GNU_EINCL := $4105,
  73. { Extensions for UPC. See: http://upc.gwu.edu/~upc. }
  74. DW_TAG_upc_shared_type := $8765,DW_TAG_upc_strict_type := $8766,
  75. DW_TAG_upc_relaxed_type := $8767,
  76. { PGI (STMicroelectronics) extensions. No documentation available. }
  77. DW_TAG_PGI_kanji_type := $A000,
  78. DW_TAG_PGI_interface_block := $A020);
  79. { Attribute names and codes. }
  80. tdwarf_attribute = (DW_AT_sibling := $01,DW_AT_location := $02,
  81. DW_AT_name := $03,DW_AT_ordering := $09,
  82. DW_AT_subscr_data := $0a,DW_AT_byte_size := $0b,
  83. DW_AT_bit_offset := $0c,DW_AT_bit_size := $0d,
  84. DW_AT_element_list := $0f,DW_AT_stmt_list := $10,
  85. DW_AT_low_pc := $11,DW_AT_high_pc := $12,
  86. DW_AT_language := $13,DW_AT_member := $14,
  87. DW_AT_discr := $15,DW_AT_discr_value := $16,
  88. DW_AT_visibility := $17,DW_AT_import := $18,
  89. DW_AT_string_length := $19,DW_AT_common_reference := $1a,
  90. DW_AT_comp_dir := $1b,DW_AT_const_value := $1c,
  91. DW_AT_containing_type := $1d,DW_AT_default_value := $1e,
  92. DW_AT_inline := $20,DW_AT_is_optional := $21,
  93. DW_AT_lower_bound := $22,DW_AT_producer := $25,
  94. DW_AT_prototyped := $27,DW_AT_return_addr := $2a,
  95. DW_AT_start_scope := $2c,DW_AT_stride_size := $2e,
  96. DW_AT_upper_bound := $2f,DW_AT_abstract_origin := $31,
  97. DW_AT_accessibility := $32,DW_AT_address_class := $33,
  98. DW_AT_artificial := $34,DW_AT_base_types := $35,
  99. DW_AT_calling_convention := $36,DW_AT_count := $37,
  100. DW_AT_data_member_location := $38,DW_AT_decl_column := $39,
  101. DW_AT_decl_file := $3a,DW_AT_decl_line := $3b,
  102. DW_AT_declaration := $3c,DW_AT_discr_list := $3d,
  103. DW_AT_encoding := $3e,DW_AT_external := $3f,
  104. DW_AT_frame_base := $40,DW_AT_friend := $41,
  105. DW_AT_identifier_case := $42,DW_AT_macro_info := $43,
  106. DW_AT_namelist_items := $44,DW_AT_priority := $45,
  107. DW_AT_segment := $46,DW_AT_specification := $47,
  108. DW_AT_static_link := $48,DW_AT_type := $49,
  109. DW_AT_use_location := $4a,DW_AT_variable_parameter := $4b,
  110. DW_AT_virtuality := $4c,DW_AT_vtable_elem_location := $4d,
  111. { DWARF 3 values. }
  112. DW_AT_allocated := $4e,DW_AT_associated := $4f,
  113. DW_AT_data_location := $50,DW_AT_stride := $51,
  114. DW_AT_entry_pc := $52,DW_AT_use_UTF8 := $53,
  115. DW_AT_extension := $54,DW_AT_ranges := $55,
  116. DW_AT_trampoline := $56,DW_AT_call_column := $57,
  117. DW_AT_call_file := $58,DW_AT_call_line := $59,
  118. { SGI/MIPS extensions. }
  119. DW_AT_MIPS_fde := $2001,DW_AT_MIPS_loop_begin := $2002,
  120. DW_AT_MIPS_tail_loop_begin := $2003,DW_AT_MIPS_epilog_begin := $2004,
  121. DW_AT_MIPS_loop_unroll_factor := $2005,
  122. DW_AT_MIPS_software_pipeline_depth := $2006,
  123. DW_AT_MIPS_linkage_name := $2007,DW_AT_MIPS_stride := $2008,
  124. DW_AT_MIPS_abstract_name := $2009,DW_AT_MIPS_clone_origin := $200a,
  125. DW_AT_MIPS_has_inlines := $200b,
  126. { HP extensions. }
  127. DW_AT_HP_block_index := $2000,
  128. DW_AT_HP_unmodifiable := $2001,DW_AT_HP_actuals_stmt_list := $2010,
  129. DW_AT_HP_proc_per_section := $2011,DW_AT_HP_raw_data_ptr := $2012,
  130. DW_AT_HP_pass_by_reference := $2013,DW_AT_HP_opt_level := $2014,
  131. DW_AT_HP_prof_version_id := $2015,DW_AT_HP_opt_flags := $2016,
  132. DW_AT_HP_cold_region_low_pc := $2017,DW_AT_HP_cold_region_high_pc := $2018,
  133. DW_AT_HP_all_variables_modifiable := $2019,
  134. DW_AT_HP_linkage_name := $201a,DW_AT_HP_prof_flags := $201b,
  135. { GNU extensions. }
  136. DW_AT_sf_names := $2101,DW_AT_src_info := $2102,
  137. DW_AT_mac_info := $2103,DW_AT_src_coords := $2104,
  138. DW_AT_body_begin := $2105,DW_AT_body_end := $2106,
  139. DW_AT_GNU_vector := $2107,
  140. { VMS extensions. }
  141. DW_AT_VMS_rtnbeg_pd_address := $2201,
  142. { UPC extension. }
  143. DW_AT_upc_threads_scaled := $3210,
  144. { PGI (STMicroelectronics) extensions. }
  145. DW_AT_PGI_lbase := $3a00,
  146. DW_AT_PGI_soffset := $3a01,DW_AT_PGI_lstride := $3a02
  147. );
  148. { Form names and codes. }
  149. Tdwarf_form = (DW_FORM_addr := $01,DW_FORM_block2 := $03,
  150. DW_FORM_block4 := $04,DW_FORM_data2 := $05,
  151. DW_FORM_data4 := $06,DW_FORM_data8 := $07,
  152. DW_FORM_string := $08,DW_FORM_block := $09,
  153. DW_FORM_block1 := $0a,DW_FORM_data1 := $0b,
  154. DW_FORM_flag := $0c,DW_FORM_sdata := $0d,
  155. DW_FORM_strp := $0e,DW_FORM_udata := $0f,
  156. DW_FORM_ref_addr := $10,DW_FORM_ref1 := $11,
  157. DW_FORM_ref2 := $12,DW_FORM_ref4 := $13,
  158. DW_FORM_ref8 := $14,DW_FORM_ref_udata := $15,
  159. DW_FORM_indirect := $16);
  160. TDebugInfoDwarf = class(TDebugInfo)
  161. private
  162. currfileidx : longint;
  163. currabbrevnumber : longint;
  164. writing_def_dwarf : boolean;
  165. function append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const) : longint;
  166. procedure append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
  167. procedure append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
  168. procedure append_labelentry_data(attr : tdwarf_attribute;sym : tasmsymbol);
  169. procedure finish_entry;
  170. procedure finish_children;
  171. procedure append_procdef(list:taasmoutput;pd:tprocdef);
  172. procedure append_dwarftag(list:taasmoutput;def:tdef);
  173. procedure insertsym(list:taasmoutput;sym:tsym);
  174. procedure write_symtable_syms(list:taasmoutput;st:tsymtable);
  175. function def_dwarf_lab(def:tdef) : tasmsymbol;
  176. public
  177. procedure insertdef(list:taasmoutput;def:tdef);override;
  178. procedure insertmoduleinfo;override;
  179. procedure inserttypeinfo;override;
  180. procedure referencesections(list:taasmoutput);override;
  181. procedure insertlineinfo(list:taasmoutput);override;
  182. procedure write_symtable_defs(list:taasmoutput;st:tsymtable);override;
  183. end;
  184. implementation
  185. uses
  186. version,
  187. cutils,
  188. globtype,
  189. globals,
  190. verbose,
  191. systems,
  192. cpubase,
  193. finput,
  194. fmodule,
  195. symconst,symsym
  196. ;
  197. const
  198. DW_TAG_lo_user = $4080;
  199. DW_TAG_hi_user = $ffff;
  200. { Flag that tells whether entry has a child or not. }
  201. DW_children_no = 0;
  202. DW_children_yes = 1;
  203. const
  204. { Implementation-defined range start. }
  205. DW_AT_lo_user = $2000;
  206. { Implementation-defined range end. }
  207. DW_AT_hi_user = $3ff0;
  208. type
  209. { Source language names and codes. }
  210. tdwarf_source_language = (DW_LANG_C89 := $0001,DW_LANG_C := $0002,DW_LANG_Ada83 := $0003,
  211. DW_LANG_C_plus_plus := $0004,DW_LANG_Cobol74 := $0005,
  212. DW_LANG_Cobol85 := $0006,DW_LANG_Fortran77 := $0007,
  213. DW_LANG_Fortran90 := $0008,DW_LANG_Pascal83 := $0009,
  214. DW_LANG_Modula2 := $000a,DW_LANG_Java := $000b,
  215. { DWARF 3. }
  216. DW_LANG_C99 := $000c,DW_LANG_Ada95 := $000d,
  217. DW_LANG_Fortran95 := $000e,
  218. { MIPS. }
  219. DW_LANG_Mips_Assembler := $8001,
  220. { UPC. }
  221. DW_LANG_Upc := $8765
  222. );
  223. const
  224. { Implementation-defined range start. }
  225. DW_LANG_lo_user = $8000;
  226. { Implementation-defined range start. }
  227. DW_LANG_hi_user = $ffff;
  228. type
  229. { Names and codes for macro information. }
  230. tdwarf_macinfo_record_type = (DW_MACINFO_define := 1,DW_MACINFO_undef := 2,
  231. DW_MACINFO_start_file := 3,DW_MACINFO_end_file := 4,
  232. DW_MACINFO_vendor_ext := 255);
  233. type
  234. { Type encodings. }
  235. Tdwarf_type = (DW_ATE_void := $0,DW_ATE_address := $1,
  236. DW_ATE_boolean := $2,DW_ATE_complex_float := $3,
  237. DW_ATE_float := $4,DW_ATE_signed := $5,
  238. DW_ATE_signed_char := $6,DW_ATE_unsigned := $7,
  239. DW_ATE_unsigned_char := $8,DW_ATE_imaginary_float := $9,
  240. { HP extensions. }
  241. DW_ATE_HP_float80 := $80,DW_ATE_HP_complex_float80 := $81,
  242. DW_ATE_HP_float128 := $82,DW_ATE_HP_complex_float128 := $83,
  243. DW_ATE_HP_floathpintel := $84,DW_ATE_HP_imaginary_float80 := $85,
  244. DW_ATE_HP_imaginary_float128 := $86
  245. );
  246. const
  247. DW_ATE_lo_user = $80;
  248. DW_ATE_hi_user = $ff;
  249. type
  250. Tdwarf_array_dim_ordering = (DW_ORD_row_major := 0,DW_ORD_col_major := 1
  251. );
  252. { Access attribute. }
  253. Tdwarf_access_attribute = (DW_ACCESS_public := 1,DW_ACCESS_protected := 2,
  254. DW_ACCESS_private := 3);
  255. { Visibility. }
  256. Tdwarf_visibility_attribute = (DW_VIS_local := 1,DW_VIS_exported := 2,
  257. DW_VIS_qualified := 3);
  258. { Virtuality. }
  259. Tdwarf_virtuality_attribute = (DW_VIRTUALITY_none := 0,DW_VIRTUALITY_virtual := 1,
  260. DW_VIRTUALITY_pure_virtual := 2);
  261. { Case sensitivity. }
  262. Tdwarf_id_case = (DW_ID_case_sensitive := 0,DW_ID_up_case := 1,
  263. DW_ID_down_case := 2,DW_ID_case_insensitive := 3
  264. );
  265. { Calling convention. }
  266. Tdwarf_calling_convention = (DW_CC_normal := $1,DW_CC_program := $2,
  267. DW_CC_nocall := $3,DW_CC_GNU_renesas_sh := $40
  268. );
  269. { Location atom names and codes. }
  270. Tdwarf_location_atom = (DW_OP_addr := $03,DW_OP_deref := $06,DW_OP_const1u := $08,
  271. DW_OP_const1s := $09,DW_OP_const2u := $0a,
  272. DW_OP_const2s := $0b,DW_OP_const4u := $0c,
  273. DW_OP_const4s := $0d,DW_OP_const8u := $0e,
  274. DW_OP_const8s := $0f,DW_OP_constu := $10,
  275. DW_OP_consts := $11,DW_OP_dup := $12,DW_OP_drop := $13,
  276. DW_OP_over := $14,DW_OP_pick := $15,DW_OP_swap := $16,
  277. DW_OP_rot := $17,DW_OP_xderef := $18,DW_OP_abs := $19,
  278. DW_OP_and := $1a,DW_OP_div := $1b,DW_OP_minus := $1c,
  279. DW_OP_mod := $1d,DW_OP_mul := $1e,DW_OP_neg := $1f,
  280. DW_OP_not := $20,DW_OP_or := $21,DW_OP_plus := $22,
  281. DW_OP_plus_uconst := $23,DW_OP_shl := $24,
  282. DW_OP_shr := $25,DW_OP_shra := $26,DW_OP_xor := $27,
  283. DW_OP_bra := $28,DW_OP_eq := $29,DW_OP_ge := $2a,
  284. DW_OP_gt := $2b,DW_OP_le := $2c,DW_OP_lt := $2d,
  285. DW_OP_ne := $2e,DW_OP_skip := $2f,DW_OP_lit0 := $30,
  286. DW_OP_lit1 := $31,DW_OP_lit2 := $32,DW_OP_lit3 := $33,
  287. DW_OP_lit4 := $34,DW_OP_lit5 := $35,DW_OP_lit6 := $36,
  288. DW_OP_lit7 := $37,DW_OP_lit8 := $38,DW_OP_lit9 := $39,
  289. DW_OP_lit10 := $3a,DW_OP_lit11 := $3b,
  290. DW_OP_lit12 := $3c,DW_OP_lit13 := $3d,
  291. DW_OP_lit14 := $3e,DW_OP_lit15 := $3f,
  292. DW_OP_lit16 := $40,DW_OP_lit17 := $41,
  293. DW_OP_lit18 := $42,DW_OP_lit19 := $43,
  294. DW_OP_lit20 := $44,DW_OP_lit21 := $45,
  295. DW_OP_lit22 := $46,DW_OP_lit23 := $47,
  296. DW_OP_lit24 := $48,DW_OP_lit25 := $49,
  297. DW_OP_lit26 := $4a,DW_OP_lit27 := $4b,
  298. DW_OP_lit28 := $4c,DW_OP_lit29 := $4d,
  299. DW_OP_lit30 := $4e,DW_OP_lit31 := $4f,
  300. DW_OP_reg0 := $50,DW_OP_reg1 := $51,DW_OP_reg2 := $52,
  301. DW_OP_reg3 := $53,DW_OP_reg4 := $54,DW_OP_reg5 := $55,
  302. DW_OP_reg6 := $56,DW_OP_reg7 := $57,DW_OP_reg8 := $58,
  303. DW_OP_reg9 := $59,DW_OP_reg10 := $5a,DW_OP_reg11 := $5b,
  304. DW_OP_reg12 := $5c,DW_OP_reg13 := $5d,
  305. DW_OP_reg14 := $5e,DW_OP_reg15 := $5f,
  306. DW_OP_reg16 := $60,DW_OP_reg17 := $61,
  307. DW_OP_reg18 := $62,DW_OP_reg19 := $63,
  308. DW_OP_reg20 := $64,DW_OP_reg21 := $65,
  309. DW_OP_reg22 := $66,DW_OP_reg23 := $67,
  310. DW_OP_reg24 := $68,DW_OP_reg25 := $69,
  311. DW_OP_reg26 := $6a,DW_OP_reg27 := $6b,
  312. DW_OP_reg28 := $6c,DW_OP_reg29 := $6d,
  313. DW_OP_reg30 := $6e,DW_OP_reg31 := $6f,
  314. DW_OP_breg0 := $70,DW_OP_breg1 := $71,
  315. DW_OP_breg2 := $72,DW_OP_breg3 := $73,
  316. DW_OP_breg4 := $74,DW_OP_breg5 := $75,
  317. DW_OP_breg6 := $76,DW_OP_breg7 := $77,
  318. DW_OP_breg8 := $78,DW_OP_breg9 := $79,
  319. DW_OP_breg10 := $7a,DW_OP_breg11 := $7b,
  320. DW_OP_breg12 := $7c,DW_OP_breg13 := $7d,
  321. DW_OP_breg14 := $7e,DW_OP_breg15 := $7f,
  322. DW_OP_breg16 := $80,DW_OP_breg17 := $81,
  323. DW_OP_breg18 := $82,DW_OP_breg19 := $83,
  324. DW_OP_breg20 := $84,DW_OP_breg21 := $85,
  325. DW_OP_breg22 := $86,DW_OP_breg23 := $87,
  326. DW_OP_breg24 := $88,DW_OP_breg25 := $89,
  327. DW_OP_breg26 := $8a,DW_OP_breg27 := $8b,
  328. DW_OP_breg28 := $8c,DW_OP_breg29 := $8d,
  329. DW_OP_breg30 := $8e,DW_OP_breg31 := $8f,
  330. DW_OP_regx := $90,DW_OP_fbreg := $91,DW_OP_bregx := $92,
  331. DW_OP_piece := $93,DW_OP_deref_size := $94,
  332. DW_OP_xderef_size := $95,DW_OP_nop := $96,
  333. { DWARF 3 extensions. }
  334. DW_OP_push_object_address := $97,DW_OP_call2 := $98,
  335. DW_OP_call4 := $99,DW_OP_call_ref := $9a,
  336. { GNU extensions. }
  337. DW_OP_GNU_push_tls_address := $e0,
  338. { HP extensions. }
  339. DW_OP_HP_unknown := $e0,
  340. DW_OP_HP_is_value := $e1,DW_OP_HP_fltconst4 := $e2,
  341. DW_OP_HP_fltconst8 := $e3,DW_OP_HP_mod_range := $e4,
  342. DW_OP_HP_unmod_range := $e5,DW_OP_HP_tls := $e6
  343. );
  344. const
  345. { Implementation-defined range start. }
  346. DW_OP_lo_user = $e0;
  347. { Implementation-defined range end. }
  348. DW_OP_hi_user = $ff;
  349. function TDebugInfoDwarf.def_dwarf_lab(def:tdef) : tasmsymbol;
  350. begin
  351. { procdefs only need a number, mark them as already written
  352. so they won't be written implicitly }
  353. if (def.deftype=procdef) then
  354. def.dbg_state:=dbg_state_written;
  355. { dwarf must already be written, or we must be busy writing it }
  356. if writing_def_dwarf and
  357. not(def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  358. internalerror(200601241);
  359. { Keep track of used dwarf entries, this info is only usefull for dwarf entries
  360. referenced by the symbols. Definitions will always include all
  361. required stabs }
  362. if def.dbg_state=dbg_state_unused then
  363. def.dbg_state:=dbg_state_used;
  364. { Need a new label? }
  365. if def.dwarf_lab=nil then
  366. begin
  367. objectlibrary.getdatalabel(def.dwarf_lab);
  368. end;
  369. result:=def.dwarf_lab;
  370. end;
  371. { writing the data through a few simply procedures allows to create easily extra information
  372. for debugging of debug info }
  373. function TDebugInfoDwarf.append_entry(tag : tdwarf_tag;has_children : boolean;data : array of const) : longint;
  374. var
  375. i : longint;
  376. begin
  377. inc(currabbrevnumber);
  378. asmlist[al_dwarf_abbrev].concat(tai_comment.Create(strpnew('Abbrev '+tostr(currabbrevnumber))));
  379. { abbrev number }
  380. asmlist[al_dwarf_info].concat(tai_const.create_uleb128bit(currabbrevnumber));
  381. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(currabbrevnumber));
  382. { tag }
  383. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(tag)));
  384. { children? }
  385. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(ord(has_children)));
  386. i:=0;
  387. while i<=high(data) do
  388. begin
  389. { attribute }
  390. if data[i].VType=vtInteger then
  391. begin
  392. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(data[i].VInteger));
  393. end
  394. else
  395. internalerror(200601261);
  396. inc(i);
  397. { form }
  398. if data[i].VType=vtInteger then
  399. begin
  400. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(data[i].VInteger));
  401. end
  402. else
  403. internalerror(200601262);
  404. inc(i);
  405. { info itself }
  406. case tdwarf_form(data[i-1].VInteger) of
  407. DW_FORM_string:
  408. case data[i].VType of
  409. vtChar:
  410. asmlist[al_dwarf_info].concat(tai_string.create(data[i].VChar));
  411. vtString:
  412. asmlist[al_dwarf_info].concat(tai_string.create(data[i].VString^));
  413. vtAnsistring:
  414. asmlist[al_dwarf_info].concat(tai_string.create(Ansistring(data[i].VAnsiString^)));
  415. else
  416. begin
  417. writeln(data[i].VType);
  418. internalerror(200601264);
  419. end;
  420. end;
  421. DW_FORM_flag:
  422. asmlist[al_dwarf_info].concat(tai_const.create_8bit(byte(data[i].VBoolean)));
  423. DW_FORM_data1:
  424. asmlist[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
  425. DW_FORM_data2:
  426. asmlist[al_dwarf_info].concat(tai_const.create_16bit(data[i].VInteger));
  427. DW_FORM_data4:
  428. asmlist[al_dwarf_info].concat(tai_const.create_32bit(data[i].VInteger));
  429. DW_FORM_data8:
  430. asmlist[al_dwarf_info].concat(tai_const.create_64bit(data[i].VInteger));
  431. { block gets only the size, the rest is appended manually by the caller }
  432. DW_FORM_block1:
  433. asmlist[al_dwarf_info].concat(tai_const.create_8bit(data[i].VInteger));
  434. else
  435. internalerror(200601263);
  436. end;
  437. inc(i);
  438. end;
  439. end;
  440. procedure TDebugInfoDwarf.append_labelentry(attr : tdwarf_attribute;sym : tasmsymbol);
  441. begin
  442. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  443. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_addr)));
  444. asmlist[al_dwarf_info].concat(tai_const.create_sym(sym));
  445. end;
  446. procedure TDebugInfoDwarf.append_labelentry_ref(attr : tdwarf_attribute;sym : tasmsymbol);
  447. begin
  448. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  449. {$ifdef cpu64bit}
  450. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_ref8)));
  451. {$else cpu64bit}
  452. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_ref4)));
  453. {$endif cpu64bit}
  454. asmlist[al_dwarf_info].concat(tai_const.create_sym(sym));
  455. end;
  456. procedure TDebugInfoDwarf.append_labelentry_data(attr : tdwarf_attribute;sym : tasmsymbol);
  457. begin
  458. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(attr)));
  459. {$ifdef cpu64bit}
  460. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data8)));
  461. {$else cpu64bit}
  462. asmlist[al_dwarf_abbrev].concat(tai_const.create_uleb128bit(ord(DW_FORM_data4)));
  463. {$endif cpu64bit}
  464. asmlist[al_dwarf_info].concat(tai_const.create_sym(sym));
  465. end;
  466. procedure TDebugInfoDwarf.finish_entry;
  467. begin
  468. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  469. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  470. end;
  471. procedure TDebugInfoDwarf.finish_children;
  472. begin
  473. asmlist[al_dwarf_abbrev].concat(tai_const.create_8bit(0));
  474. end;
  475. procedure TDebugInfoDwarf.append_dwarftag(list:taasmoutput;def:tdef);
  476. procedure append_dwarftag_orddef(list:taasmoutput;def:torddef);
  477. begin
  478. case def.typ of
  479. s32bit :
  480. begin
  481. append_entry(DW_TAG_base_type,false,[
  482. DW_AT_name,DW_FORM_string,'Longint'#0,
  483. DW_AT_encoding,DW_FORM_data1,DW_ATE_signed,
  484. DW_AT_byte_size,DW_FORM_data1,4
  485. ]);
  486. finish_entry;
  487. end;
  488. uvoid :
  489. begin
  490. append_entry(DW_TAG_unspecified_type,false,[
  491. DW_AT_name,DW_FORM_string,'Void'#0]);
  492. finish_entry;
  493. end;
  494. uchar :
  495. begin
  496. append_entry(DW_TAG_base_type,false,[
  497. DW_AT_name,DW_FORM_string,'Char'#0,
  498. DW_AT_encoding,DW_FORM_data1,DW_ATE_unsigned_char,
  499. DW_AT_byte_size,DW_FORM_data1,1
  500. ]);
  501. finish_entry;
  502. end;
  503. uwidechar :
  504. ;
  505. bool8bit :
  506. ;
  507. bool16bit :
  508. ;
  509. bool32bit :
  510. ;
  511. u64bit :
  512. ;
  513. s64bit :
  514. ;
  515. {u32bit : result:=def_stab_number(s32inttype.def)+';0;-1;'); }
  516. else
  517. ;
  518. end;
  519. end;
  520. begin
  521. list.concat(tai_symbol.create(def_dwarf_lab(def),0));
  522. case def.deftype of
  523. {
  524. stringdef :
  525. result:=stringdef_stabstr(tstringdef(def));
  526. enumdef :
  527. result:=enumdef_stabstr(tenumdef(def));
  528. }
  529. orddef :
  530. append_dwarftag_orddef(list,torddef(def));
  531. {
  532. floatdef :
  533. result:=floatdef_stabstr(tfloatdef(def));
  534. filedef :
  535. result:=filedef_stabstr(tfiledef(def));
  536. recorddef :
  537. result:=recorddef_stabstr(trecorddef(def));
  538. variantdef :
  539. result:=def_stabstr_evaluate(def,'formal${numberstring};',[]);
  540. pointerdef :
  541. result:=strpnew('*'+def_stab_number(tpointerdef(def).pointertype.def));
  542. classrefdef :
  543. result:=strpnew(def_stab_number(pvmttype.def));
  544. setdef :
  545. result:=def_stabstr_evaluate(def,'@s$1;S$2',[tostr(def.size*8),def_stab_number(tsetdef(def).elementtype.def)]);
  546. formaldef :
  547. result:=def_stabstr_evaluate(def,'formal${numberstring};',[]);
  548. arraydef :
  549. result:=def_stabstr_evaluate(def,'ar$1;$2;$3;$4',[def_stab_number(tarraydef(def).rangetype.def),
  550. tostr(tarraydef(def).lowrange),tostr(tarraydef(def).highrange),def_stab_number(tarraydef(def).elementtype.def)]);
  551. procdef :
  552. result:=procdef_stabstr(tprocdef(def));
  553. procvardef :
  554. result:=strpnew('*f'+def_stab_number(tprocvardef(def).rettype.def));
  555. objectdef :
  556. result:=objectdef_stabstr(tobjectdef(def));
  557. undefineddef :
  558. result:=def_stabstr_evaluate(def,'formal${numberstring};',[]);
  559. }
  560. else
  561. internalerror(200601281);
  562. end;
  563. end;
  564. procedure TDebugInfoDwarf.insertdef(list:taasmoutput;def:tdef);
  565. var
  566. anc : tobjectdef;
  567. oldtypesym : tsym;
  568. begin
  569. if (def.dbg_state in [dbg_state_writing,dbg_state_written]) then
  570. exit;
  571. { never write generic template defs }
  572. if df_generic in def.defoptions then
  573. begin
  574. def.dbg_state:=dbg_state_written;
  575. exit;
  576. end;
  577. { to avoid infinite loops }
  578. def.dbg_state := dbg_state_writing;
  579. { write dependencies first }
  580. case def.deftype of
  581. stringdef :
  582. begin
  583. if tstringdef(def).string_typ=st_widestring then
  584. insertdef(list,cwidechartype.def)
  585. else
  586. begin
  587. insertdef(list,cchartype.def);
  588. insertdef(list,u8inttype.def);
  589. end;
  590. end;
  591. floatdef :
  592. insertdef(list,s32inttype.def);
  593. filedef :
  594. begin
  595. insertdef(list,s32inttype.def);
  596. {$ifdef cpu64bit}
  597. insertdef(list,s64inttype.def);
  598. {$endif cpu64bit}
  599. insertdef(list,u8inttype.def);
  600. insertdef(list,cchartype.def);
  601. end;
  602. classrefdef :
  603. insertdef(list,pvmttype.def);
  604. pointerdef :
  605. insertdef(list,tpointerdef(def).pointertype.def);
  606. setdef :
  607. insertdef(list,tsetdef(def).elementtype.def);
  608. procvardef,
  609. procdef :
  610. insertdef(list,tprocdef(def).rettype.def);
  611. arraydef :
  612. begin
  613. insertdef(list,tarraydef(def).rangetype.def);
  614. insertdef(list,tarraydef(def).elementtype.def);
  615. end;
  616. recorddef :
  617. trecorddef(def).symtable.foreach(@field_write_defs,list);
  618. objectdef :
  619. begin
  620. insertdef(list,vmtarraytype.def);
  621. { first the parents }
  622. anc:=tobjectdef(def);
  623. while assigned(anc.childof) do
  624. begin
  625. anc:=anc.childof;
  626. insertdef(list,anc);
  627. end;
  628. tobjectdef(def).symtable.foreach(@field_write_defs,list);
  629. tobjectdef(def).symtable.foreach(@method_write_defs,list);
  630. end;
  631. end;
  632. case def.deftype of
  633. objectdef :
  634. begin
  635. { classes require special code to write the record and the invisible pointer }
  636. if is_class(def) then
  637. begin
  638. { Write the record class itself }
  639. tobjectdef(def).writing_class_record_dbginfo:=true;
  640. append_dwarftag(list,def);
  641. tobjectdef(def).writing_class_record_dbginfo:=false;
  642. { Write the invisible pointer class }
  643. oldtypesym:=def.typesym;
  644. def.typesym:=nil;
  645. append_dwarftag(list,def);
  646. def.typesym:=oldtypesym;
  647. end
  648. else
  649. append_dwarftag(list,def);
  650. { VMT symbol }
  651. if (oo_has_vmt in tobjectdef(def).objectoptions) and
  652. assigned(def.owner) and
  653. assigned(def.owner.name) then
  654. {
  655. list.concat(Tai_stab.create(stab_stabs,strpnew('"vmt_'+def.owner.name^+tobjectdef(def).name+':S'+
  656. def_stab_number(vmttype.def)+'",'+tostr(N_STSYM)+',0,0,'+tobjectdef(def).vmt_mangledname)));
  657. }
  658. ;
  659. end;
  660. procdef :
  661. begin
  662. { procdefs are handled separatly }
  663. end;
  664. else
  665. append_dwarftag(list,def);
  666. end;
  667. def.dbg_state := dbg_state_written;
  668. end;
  669. procedure TDebugInfoDwarf.write_symtable_defs(list:taasmoutput;st:tsymtable);
  670. procedure dowritedwarf(list:taasmoutput;st:tsymtable);
  671. var
  672. p : tdef;
  673. begin
  674. p:=tdef(st.defindex.first);
  675. while assigned(p) do
  676. begin
  677. if (p.dbg_state=dbg_state_used) then
  678. insertdef(list,p);
  679. p:=tdef(p.indexnext);
  680. end;
  681. end;
  682. var
  683. old_writing_def_dwarf : boolean;
  684. begin
  685. case st.symtabletype of
  686. staticsymtable :
  687. list.concat(tai_comment.Create(strpnew('Defs - Begin Staticsymtable')));
  688. globalsymtable :
  689. list.concat(tai_comment.Create(strpnew('Defs - Begin unit '+st.name^+' has index '+tostr(st.moduleid))));
  690. end;
  691. old_writing_def_dwarf:=writing_def_dwarf;
  692. writing_def_dwarf:=true;
  693. dowritedwarf(list,st);
  694. writing_def_dwarf:=old_writing_def_dwarf;
  695. case st.symtabletype of
  696. staticsymtable :
  697. list.concat(tai_comment.Create(strpnew('Defs - End Staticsymtable')));
  698. globalsymtable :
  699. list.concat(tai_comment.Create(strpnew('Defs - End unit '+st.name^+' has index '+tostr(st.moduleid))));
  700. end;
  701. end;
  702. procedure TDebugInfoDwarf.append_procdef(list:taasmoutput;pd:tprocdef);
  703. {
  704. var
  705. templist : taasmoutput;
  706. stabsendlabel : tasmlabel;
  707. mangled_length : longint;
  708. p : pchar;
  709. hs : string;
  710. }
  711. begin
  712. {
  713. if assigned(pd.procstarttai) then
  714. begin
  715. templist:=taasmoutput.create;
  716. { para types }
  717. write_def_stabstr(templist,pd);
  718. if assigned(pd.parast) then
  719. write_symtable_syms(templist,pd.parast);
  720. { local type defs and vars should not be written
  721. inside the main proc stab }
  722. if assigned(pd.localst) and
  723. (pd.localst.symtabletype=localsymtable) then
  724. write_symtable_syms(templist,pd.localst);
  725. asmlist[al_procedures].insertlistbefore(pd.procstarttai,templist);
  726. { end of procedure }
  727. objectlibrary.getlabel(stabsendlabel,alt_dbgtype);
  728. templist.concat(tai_label.create(stabsendlabel));
  729. if assigned(pd.funcretsym) and
  730. (tabstractnormalvarsym(pd.funcretsym).refs>0) then
  731. begin
  732. if tabstractnormalvarsym(pd.funcretsym).localloc.loc=LOC_REFERENCE then
  733. begin
  734. {$warning Need to add gdb support for ret in param register calling}
  735. if paramanager.ret_in_param(pd.rettype.def,pd.proccalloption) then
  736. hs:='X*'
  737. else
  738. hs:='X';
  739. templist.concat(Tai_stab.create(stab_stabs,strpnew(
  740. '"'+pd.procsym.name+':'+hs+def_stab_number(pd.rettype.def)+'",'+
  741. tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
  742. if (m_result in aktmodeswitches) then
  743. templist.concat(Tai_stab.create(stab_stabs,strpnew(
  744. '"RESULT:'+hs+def_stab_number(pd.rettype.def)+'",'+
  745. tostr(N_tsym)+',0,0,'+tostr(tabstractnormalvarsym(pd.funcretsym).localloc.reference.offset))));
  746. end;
  747. end;
  748. mangled_length:=length(pd.mangledname);
  749. getmem(p,2*mangled_length+50);
  750. strpcopy(p,'192,0,0,');
  751. {$IFDEF POWERPC64}strpcopy(strend(p), '.');{$ENDIF POWERPC64}
  752. strpcopy(strend(p),pd.mangledname);
  753. if (tf_use_function_relative_addresses in target_info.flags) then
  754. begin
  755. strpcopy(strend(p),'-');
  756. {$IFDEF POWERPC64}strpcopy(strend(p), '.');{$ENDIF POWERPC64}
  757. strpcopy(strend(p),pd.mangledname);
  758. end;
  759. templist.concat(Tai_stab.Create(stab_stabn,strnew(p)));
  760. strpcopy(p,'224,0,0,'+stabsendlabel.name);
  761. if (tf_use_function_relative_addresses in target_info.flags) then
  762. begin
  763. strpcopy(strend(p),'-');
  764. {$IFDEF POWERPC64}strpcopy(strend(p), '.');{$ENDIF POWERPC64}
  765. strpcopy(strend(p),pd.mangledname);
  766. end;
  767. templist.concat(Tai_stab.Create(stab_stabn,strnew(p)));
  768. freemem(p,2*mangled_length+50);
  769. asmlist[al_procedures].insertlistbefore(pd.procendtai,templist);
  770. templist.free;
  771. end;
  772. }
  773. end;
  774. procedure TDebugInfoDwarf.insertsym(list:taasmoutput;sym:tsym);
  775. function fieldvarsym_stabstr(sym:tfieldvarsym):Pchar;
  776. begin
  777. {
  778. result:=nil;
  779. if (sym.owner.symtabletype=objectsymtable) and
  780. (sp_static in sym.symoptions) then
  781. result:=sym_stabstr_evaluate(sym,'"${ownername}__${name}:S$1",${N_LCSYM},0,${line},${mangledname}',
  782. [def_stab_number(sym.vartype.def)]);
  783. }
  784. end;
  785. procedure append_globalvarsym(sym:tglobalvarsym);
  786. begin
  787. { external symbols can't be resolved at link time, so we
  788. can't generate stabs for them
  789. not sure if this applies to dwarf as well (FK)
  790. }
  791. if vo_is_external in sym.varoptions then
  792. exit;
  793. append_entry(DW_TAG_variable,false,[
  794. DW_AT_name,DW_FORM_string,sym.name+#0,
  795. {
  796. DW_AT_decl_file,DW_FORM_data1,0,
  797. DW_AT_decl_line,DW_FORM_data1,
  798. }
  799. DW_AT_external,DW_FORM_flag,true,
  800. { data continues below }
  801. DW_AT_location,DW_FORM_block1,1+sizeof(aword)
  802. ]);
  803. { append block data }
  804. asmlist[al_dwarf_info].concat(tai_const.create_8bit(3));
  805. asmlist[al_dwarf_info].concat(tai_const.createname(sym.mangledname,AT_DATA,0));
  806. append_labelentry_ref(DW_AT_type,def_dwarf_lab(sym.vartype.def));
  807. // ,,
  808. {
  809. case sym.localloc.loc of
  810. LOC_REGISTER,
  811. LOC_CREGISTER,
  812. LOC_MMREGISTER,
  813. LOC_CMMREGISTER,
  814. LOC_FPUREGISTER,
  815. LOC_CFPUREGISTER :
  816. begin
  817. regidx:=findreg_by_number(sym.localloc.register);
  818. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  819. { this is the register order for GDB}
  820. if regidx<>0 then
  821. result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  822. end;
  823. else
  824. begin
  825. if (vo_is_thread_var in sym.varoptions) then
  826. threadvaroffset:='+'+tostr(sizeof(aint))
  827. else
  828. threadvaroffset:='';
  829. { Here we used S instead of
  830. because with G GDB doesn't look at the address field
  831. but searches the same name or with a leading underscore
  832. but these names don't exist in pascal !}
  833. st:='S'+st;
  834. result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
  835. end;
  836. end;
  837. }
  838. finish_entry;
  839. end;
  840. function localvarsym_stabstr(sym:tlocalvarsym):Pchar;
  841. var
  842. st : string;
  843. regidx : Tregisterindex;
  844. begin
  845. {
  846. result:=nil;
  847. { There is no space allocated for not referenced locals }
  848. if (sym.owner.symtabletype=localsymtable) and (sym.refs=0) then
  849. exit;
  850. st:=def_stab_number(sym.vartype.def);
  851. case sym.localloc.loc of
  852. LOC_REGISTER,
  853. LOC_CREGISTER,
  854. LOC_MMREGISTER,
  855. LOC_CMMREGISTER,
  856. LOC_FPUREGISTER,
  857. LOC_CFPUREGISTER :
  858. begin
  859. regidx:=findreg_by_number(sym.localloc.register);
  860. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  861. { this is the register order for GDB}
  862. if regidx<>0 then
  863. result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  864. end;
  865. LOC_REFERENCE :
  866. { offset to ebp => will not work if the framepointer is esp
  867. so some optimizing will make things harder to debug }
  868. result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(sym.localloc.reference.offset)])
  869. else
  870. internalerror(2003091814);
  871. end;
  872. }
  873. end;
  874. function paravarsym_stabstr(sym:tparavarsym):Pchar;
  875. var
  876. st : string;
  877. regidx : Tregisterindex;
  878. c : char;
  879. begin
  880. {
  881. result:=nil;
  882. { set loc to LOC_REFERENCE to get somewhat usable debugging info for -Or }
  883. { while stabs aren't adapted for regvars yet }
  884. if (vo_is_self in sym.varoptions) then
  885. begin
  886. case sym.localloc.loc of
  887. LOC_REGISTER,
  888. LOC_CREGISTER:
  889. regidx:=findreg_by_number(sym.localloc.register);
  890. LOC_REFERENCE: ;
  891. else
  892. internalerror(2003091815);
  893. end;
  894. if (po_classmethod in tabstractprocdef(sym.owner.defowner).procoptions) or
  895. (po_staticmethod in tabstractprocdef(sym.owner.defowner).procoptions) then
  896. begin
  897. if (sym.localloc.loc=LOC_REFERENCE) then
  898. result:=sym_stabstr_evaluate(sym,'"pvmt:p$1",${N_TSYM},0,0,$2',
  899. [def_stab_number(pvmttype.def),tostr(sym.localloc.reference.offset)]);
  900. (* else
  901. result:=sym_stabstr_evaluate(sym,'"pvmt:r$1",${N_RSYM},0,0,$2',
  902. [def_stab_number(pvmttype.def),tostr(regstabs_table[regidx])]) *)
  903. end
  904. else
  905. begin
  906. if not(is_class(tprocdef(sym.owner.defowner)._class)) then
  907. c:='v'
  908. else
  909. c:='p';
  910. if (sym.localloc.loc=LOC_REFERENCE) then
  911. result:=sym_stabstr_evaluate(sym,'"$$t:$1",${N_TSYM},0,0,$2',
  912. [c+def_stab_number(tprocdef(sym.owner.defowner)._class),tostr(sym.localloc.reference.offset)]);
  913. (* else
  914. result:=sym_stabstr_evaluate(sym,'"$$t:r$1",${N_RSYM},0,0,$2',
  915. [c+def_stab_number(tprocdef(sym.owner.defowner)._class),tostr(regstabs_table[regidx])]); *)
  916. end;
  917. end
  918. else
  919. begin
  920. st:=def_stab_number(sym.vartype.def);
  921. if paramanager.push_addr_param(sym.varspez,sym.vartype.def,tprocdef(sym.owner.defowner).proccalloption) and
  922. not(vo_has_local_copy in sym.varoptions) and
  923. not is_open_string(sym.vartype.def) then
  924. st := 'v'+st { should be 'i' but 'i' doesn't work }
  925. else
  926. st := 'p'+st;
  927. case sym.localloc.loc of
  928. LOC_REGISTER,
  929. LOC_CREGISTER,
  930. LOC_MMREGISTER,
  931. LOC_CMMREGISTER,
  932. LOC_FPUREGISTER,
  933. LOC_CFPUREGISTER :
  934. begin
  935. regidx:=findreg_by_number(sym.localloc.register);
  936. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  937. { this is the register order for GDB}
  938. if regidx<>0 then
  939. result:=sym_stabstr_evaluate(sym,'"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(longint(regstabs_table[regidx]))]);
  940. end;
  941. LOC_REFERENCE :
  942. { offset to ebp => will not work if the framepointer is esp
  943. so some optimizing will make things harder to debug }
  944. result:=sym_stabstr_evaluate(sym,'"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(sym.localloc.reference.offset)])
  945. else
  946. internalerror(2003091814);
  947. end;
  948. end;
  949. }
  950. end;
  951. function constsym_stabstr(sym:tconstsym):Pchar;
  952. var
  953. st : string;
  954. begin
  955. {
  956. case sym.consttyp of
  957. conststring:
  958. begin
  959. if sym.value.len<200 then
  960. st:='s'''+backspace_quote(octal_quote(strpas(pchar(sym.value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+''''
  961. else
  962. st:='<constant string too long>';
  963. end;
  964. constord:
  965. st:='i'+tostr(sym.value.valueord);
  966. constpointer:
  967. st:='i'+tostr(sym.value.valueordptr);
  968. constreal:
  969. begin
  970. system.str(pbestreal(sym.value.valueptr)^,st);
  971. st := 'r'+st;
  972. end;
  973. else
  974. begin
  975. { if we don't know just put zero !! }
  976. st:='i0';
  977. end;
  978. end;
  979. { valgrind does not support constants }
  980. if cs_gdb_valgrind in aktglobalswitches then
  981. result:=nil
  982. else
  983. result:=sym_stabstr_evaluate(sym,'"${name}:c=$1;",${N_FUNCTION},0,${line},0',[st]);
  984. }
  985. end;
  986. function typesym_stabstr(sym:ttypesym) : pchar;
  987. var
  988. stabchar : string[2];
  989. begin
  990. {
  991. result:=nil;
  992. if not assigned(sym.restype.def) then
  993. internalerror(200509262);
  994. if sym.restype.def.deftype in tagtypes then
  995. stabchar:='Tt'
  996. else
  997. stabchar:='t';
  998. result:=sym_stabstr_evaluate(sym,'"${name}:$1$2",${N_LSYM},0,${line},0',[stabchar,def_stab_number(sym.restype.def)]);
  999. }
  1000. end;
  1001. procedure append_procsym(sym:tprocsym);
  1002. var
  1003. i : longint;
  1004. begin
  1005. for i:=1 to sym.procdef_count do
  1006. append_procdef(list,sym.procdef[i]);
  1007. end;
  1008. begin
  1009. case sym.typ of
  1010. globalvarsym :
  1011. append_globalvarsym(tglobalvarsym(sym));
  1012. unitsym:
  1013. { for now, we ignore unit symbols }
  1014. ;
  1015. procsym :
  1016. append_procsym(tprocsym(sym));
  1017. {
  1018. labelsym :
  1019. stabstr:=sym_stabstr_evaluate(sym,'"${name}",${N_LSYM},0,${line},0',[]);
  1020. fieldvarsym :
  1021. stabstr:=fieldvarsym_stabstr(tfieldvarsym(sym));
  1022. localvarsym :
  1023. stabstr:=localvarsym_stabstr(tlocalvarsym(sym));
  1024. paravarsym :
  1025. stabstr:=paravarsym_stabstr(tparavarsym(sym));
  1026. typedconstsym :
  1027. stabstr:=sym_stabstr_evaluate(sym,'"${name}:S$1",${N_STSYM},0,${line},${mangledname}',
  1028. [def_stab_number(ttypedconstsym(sym).typedconsttype.def)]);
  1029. constsym :
  1030. stabstr:=constsym_stabstr(tconstsym(sym));
  1031. typesym :
  1032. stabstr:=typesym_stabstr(ttypesym(sym));
  1033. }
  1034. else
  1035. internalerror(200601242);
  1036. end;
  1037. {
  1038. if stabstr<>nil then
  1039. list.concat(Tai_stab.create(stab_stabs,stabstr));
  1040. { For object types write also the symtable entries }
  1041. if (sym.typ=typesym) and (ttypesym(sym).restype.def.deftype=objectdef) then
  1042. write_symtable_syms(list,tobjectdef(ttypesym(sym).restype.def).symtable);
  1043. sym.isstabwritten:=true;
  1044. }
  1045. end;
  1046. procedure TDebugInfoDwarf.write_symtable_syms(list:taasmoutput;st:tsymtable);
  1047. var
  1048. p : tsym;
  1049. begin
  1050. case st.symtabletype of
  1051. staticsymtable :
  1052. list.concat(tai_comment.Create(strpnew('Syms - Begin Staticsymtable')));
  1053. globalsymtable :
  1054. list.concat(tai_comment.Create(strpnew('Syms - Begin unit '+st.name^+' has index '+tostr(st.moduleid))));
  1055. end;
  1056. p:=tsym(st.symindex.first);
  1057. while assigned(p) do
  1058. begin
  1059. if (not p.isstabwritten) then
  1060. insertsym(list,p);
  1061. p:=tsym(p.indexnext);
  1062. end;
  1063. case st.symtabletype of
  1064. staticsymtable :
  1065. list.concat(tai_comment.Create(strpnew('Syms - End Staticsymtable')));
  1066. globalsymtable :
  1067. list.concat(tai_comment.Create(strpnew('Syms - End unit '+st.name^+' has index '+tostr(st.moduleid))));
  1068. end;
  1069. end;
  1070. procedure TDebugInfoDwarf.insertmoduleinfo;
  1071. var
  1072. templist : taasmoutput;
  1073. begin
  1074. { insert .Ltext0 label }
  1075. templist:=taasmoutput.create;
  1076. new_section(templist,sec_code,'',0);
  1077. templist.concat(tai_symbol.createname('.Ltext0',AT_DATA,0));
  1078. asmlist[al_start].insertlist(templist);
  1079. templist.free;
  1080. { insert .Letext0 label }
  1081. templist:=taasmoutput.create;
  1082. new_section(templist,sec_code,'',0);
  1083. templist.concat(tai_symbol.createname('.Letext0',AT_DATA,0));
  1084. asmlist[al_end].insertlist(templist);
  1085. templist.free;
  1086. { insert .Ldebug_abbrev0 label }
  1087. templist:=taasmoutput.create;
  1088. new_section(templist,sec_debug_abbrev,'',0);
  1089. templist.concat(tai_symbol.createname('.Ldebug_abbrev0',AT_DATA,0));
  1090. asmlist[al_start].insertlist(templist);
  1091. templist.free;
  1092. { insert .Ldebug_line0 label }
  1093. templist:=taasmoutput.create;
  1094. new_section(templist,sec_debug_line,'',0);
  1095. templist.concat(tai_symbol.createname('.Ldebug_line0',AT_DATA,0));
  1096. asmlist[al_start].insertlist(templist);
  1097. templist.free;
  1098. end;
  1099. procedure TDebugInfoDwarf.inserttypeinfo;
  1100. var
  1101. storefilepos : tfileposinfo;
  1102. lenstartlabel : tasmlabel;
  1103. begin
  1104. storefilepos:=aktfilepos;
  1105. aktfilepos:=current_module.mainfilepos;
  1106. currabbrevnumber:=0;
  1107. writing_def_dwarf:=false;
  1108. { write start labels }
  1109. asmlist[al_dwarf_info].concat(tai_section.create(sec_debug_info,'',0));
  1110. asmlist[al_dwarf_info].concat(tai_symbol.createname('.Ldebug_info0',AT_DATA,0));
  1111. { start abbrev section }
  1112. new_section(asmlist[al_dwarf_abbrev],sec_debug_abbrev,'',0);
  1113. { debug info header }
  1114. objectlibrary.getlabel(lenstartlabel,alt_dbgfile);
  1115. { size }
  1116. asmlist[al_dwarf_info].concat(tai_const.create_rel_sym(aitconst_ptr,
  1117. lenstartlabel,tasmsymbol.create('.Ledebug_info0',AB_COMMON,AT_DATA)));
  1118. asmlist[al_dwarf_info].concat(tai_label.create(lenstartlabel));
  1119. { version }
  1120. asmlist[al_dwarf_info].concat(tai_const.create_16bit(2));
  1121. { abbrev table }
  1122. asmlist[al_dwarf_info].concat(tai_const.createname('.Ldebug_abbrev0',AT_DATA,0));
  1123. { address size }
  1124. asmlist[al_dwarf_info].concat(tai_const.create_8bit(sizeof(aint)));
  1125. append_entry(DW_TAG_compile_unit,true,[
  1126. // reference DW_AT_stmt_list,,,
  1127. DW_AT_name,DW_FORM_string,'test.pp'#0,
  1128. DW_AT_producer,DW_FORM_string,'Free Pascal '+full_version_string+' '+date_string+#0,
  1129. DW_AT_comp_dir,DW_FORM_string,''#0,
  1130. DW_AT_language,DW_FORM_data1,DW_LANG_Pascal83,
  1131. DW_AT_identifier_case,DW_FORM_data1,DW_ID_case_insensitive]);
  1132. { reference to line info section }
  1133. append_labelentry_data(DW_AT_stmt_list,objectlibrary.newasmsymbol('.Ldebug_line0',AB_LOCAL,AT_DATA));
  1134. append_labelentry(DW_AT_low_pc,objectlibrary.newasmsymbol('.Ltext0',AB_LOCAL,AT_DATA));
  1135. append_labelentry(DW_AT_high_pc,objectlibrary.newasmsymbol('.Letext0',AB_LOCAL,AT_DATA));
  1136. finish_entry;
  1137. { first write all global/local symbols. This will flag all required tdefs }
  1138. if assigned(current_module.globalsymtable) then
  1139. write_symtable_syms(asmlist[al_dwarf_info],current_module.globalsymtable);
  1140. if assigned(current_module.localsymtable) then
  1141. write_symtable_syms(asmlist[al_dwarf_info],current_module.localsymtable);
  1142. { reset unit type info flag }
  1143. reset_unit_type_info;
  1144. { write used types from the used units }
  1145. write_used_unit_type_info(asmlist[al_dwarf_info],current_module);
  1146. { last write the types from this unit }
  1147. if assigned(current_module.globalsymtable) then
  1148. write_symtable_defs(asmlist[al_dwarf_info],current_module.globalsymtable);
  1149. if assigned(current_module.localsymtable) then
  1150. write_symtable_defs(asmlist[al_dwarf_info],current_module.localsymtable);
  1151. { close compilation unit entry }
  1152. finish_children;
  1153. { end of debug info table }
  1154. asmlist[al_dwarf_info].concat(tai_const.create_8bit(0));
  1155. asmlist[al_dwarf_info].concat(tai_symbol.createname('.Ledebug_info0',AT_DATA,0));
  1156. aktfilepos:=storefilepos;
  1157. end;
  1158. procedure TDebugInfoDwarf.referencesections(list:taasmoutput);
  1159. begin
  1160. end;
  1161. procedure TDebugInfoDwarf.insertlineinfo(list:taasmoutput);
  1162. var
  1163. currfileinfo,
  1164. lastfileinfo : tfileposinfo;
  1165. currfuncname : pstring;
  1166. currsectype : tasmsectiontype;
  1167. hlabel : tasmlabel;
  1168. hp : tai;
  1169. infile : tinputfile;
  1170. begin
  1171. FillChar(lastfileinfo,sizeof(lastfileinfo),0);
  1172. currfuncname:=nil;
  1173. currsectype:=sec_code;
  1174. hp:=Tai(list.first);
  1175. while assigned(hp) do
  1176. begin
  1177. case hp.typ of
  1178. ait_section :
  1179. currsectype:=tai_section(hp).sectype;
  1180. ait_function_name :
  1181. currfuncname:=tai_function_name(hp).funcname;
  1182. ait_force_line :
  1183. lastfileinfo.line:=-1;
  1184. end;
  1185. if (currsectype=sec_code) and
  1186. (hp.typ=ait_instruction) then
  1187. begin
  1188. currfileinfo:=tailineinfo(hp).fileinfo;
  1189. { file changed ? (must be before line info) }
  1190. if (currfileinfo.fileindex<>0) and
  1191. (lastfileinfo.fileindex<>currfileinfo.fileindex) then
  1192. begin
  1193. infile:=current_module.sourcefiles.get_file(currfileinfo.fileindex);
  1194. if assigned(infile) then
  1195. begin
  1196. inc(currfileidx);
  1197. if (infile.path^<>'') then
  1198. list.insertbefore(tai_file.create(
  1199. BsToSlash(FixPath(infile.path^,false)+FixFileName(infile.name^)),currfileidx
  1200. ),hp)
  1201. else
  1202. list.insertbefore(tai_file.create(
  1203. FixFileName(infile.name^),currfileidx),hp);
  1204. { force new line info }
  1205. lastfileinfo.line:=-1;
  1206. end;
  1207. end;
  1208. { line changed ? }
  1209. if (lastfileinfo.line<>currfileinfo.line) and (currfileinfo.line<>0) then
  1210. list.insertbefore(tai_loc.create(
  1211. currfileidx,currfileinfo.line,currfileinfo.column),hp);
  1212. lastfileinfo:=currfileinfo;
  1213. end;
  1214. hp:=tai(hp.next);
  1215. end;
  1216. end;
  1217. const
  1218. dbg_dwarf_info : tdbginfo =
  1219. (
  1220. id : dbg_dwarf;
  1221. idtxt : 'DWARF';
  1222. );
  1223. initialization
  1224. RegisterDebugInfo(dbg_dwarf_info,TDebugInfoDwarf);
  1225. end.